For testing purposes.
...
What a mess.
Coding my own open source 24x ECU [beta available]
-
AngelMarc
- Posts: 612
- Joined: Sat Apr 08, 2023 11:23 am
- cars: A CB450 running to 8,000RPM with a P59.
Re: Coding my own open source 24x ECU [beta available]
You do not have the required permissions to view the files attached to this post.
Don't stress specific units.
-
AngelMarc
- Posts: 612
- Joined: Sat Apr 08, 2023 11:23 am
- cars: A CB450 running to 8,000RPM with a P59.
Re: Coding my own open source 24x ECU [beta available]
Alright, first test will be a 2 stroke, after I grab some some fuel line and my 'fuel rail' in the morning.
A Tecumseh HSK845 (150 cc), with a wing-it base tune.
A Tecumseh HSK845 (150 cc), with a wing-it base tune.
Code: Select all
volatile unsigned long IATFuel[129] = {128,130,132,134,136,138,140,142,144,146,148,150,152,154,156,158,160,162,164,166,168,170,172,174,176,178,180,182,184,186,188,190,192,194,196,198,200,202,204,206,208,210,212,214,216,218,220,222,224,226,228,230,232,234,236,238,240,242,244,246,248,250,252,254,256,258,260,262,264,266,268,270,272,274,276,278,280,282,284,286,288,290,292,294,296,298,300,302,304,306,308,310,312,314,316,318,320,322,324,326,328,330,332,334,336,338,340,342,344,346,348,350,352,354,356,358,360,362,364,366,368,370,372,374,376,378,380,382,384};
//Comment above and uncomment below for no temp scaling, 256 = 100% or no change
//volatile unsigned long IATFuel[129] = {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256};
//volatile unsigned long IATSpark [129] = {128,130,132,134,136,138,140,142,144,146,148,150,152,154,156,158,160,162,164,166,168,170,172,174,176,178,180,182,184,186,188,190,192,194,196,198,200,202,204,206,208,210,212,214,216,218,220,222,224,226,228,230,232,234,236,238,240,242,244,246,248,250,252,254,256,258,260,262,264,266,268,270,272,274,276,278,280,282,284,286,288,290,292,294,296,298,300,302,304,306,308,310,312,314,316,318,320,322,324,326,328,330,332,334,336,338,340,342,344,346,348,350,352,354,356,358,360,362,364,366,368,370,372,374,376,378,380,382,384};
//Comment above and uncomment below for no temp scaling, 256 = 100% or no change
volatile unsigned long IATSpark [129] = {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256};
volatile unsigned long Limiter = 278 ; //Spark cut rev limiter, microseconds per 15 degrees. divide 2,500,000 by this number to get RPM. Limiter is set after rolling average and before being constrained for table access, can be set beyond table limits
volatile unsigned long EOIT [17] = {500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500};// these were test values, also in microseconds, change as needed
// 0 RPM ---------------------------------------------------------------------------9600 RPM same 600 spacing
volatile unsigned long Dstart [17] [17] = { //lower numbers = more advance, numbers are in microseconds
{2954333, 2954333, 2954333, 2954333, 2954333, 2954333, 2954333, 2954333, 2954333, 2954333, 2954333, 2954333, 2954333, 2954333, 2954333, 2954333, 2954333},//"0" RPM
{94611, 94611, 94611, 94611, 94611, 94611, 94611, 94611, 94611, 94611, 94611, 94611, 94611, 94611, 94611, 94611, 94611},// 600
{44611, 44611, 44611, 44611, 44611, 44611, 44611, 44611, 44611, 44611, 44611, 44611, 44611, 44611, 44611, 44611, 44611},// 1200
{28407, 28407, 28407, 28407, 28407, 28407, 28407, 28407, 28407, 28407, 28407, 28407, 28407, 28407, 28407, 28407, 28407},// 1800
{19958, 19958, 19958, 19958, 19958, 19958, 19958, 19958, 19958, 19958, 19958, 19958, 19958, 19958, 19958, 19958, 19958},// 2400
{15167, 15167, 15167, 15167, 15167, 15167, 15167, 15167, 15167, 15167, 15167, 15167, 15167, 15167, 15167, 15167, 15167},// 3000
{11741, 11741, 11741, 11741, 11741, 11741, 11741, 11741, 11741, 11741, 11741, 11741, 11741, 11741, 11741, 11741, 11741},// 3600
{9294, 9294, 9294, 9294, 9294, 9294, 9294, 9294, 9294, 9294, 9294, 9294, 9294, 9294, 9294, 9294, 9294},// 4200
{7632, 7632, 7632, 7632, 7632, 7632, 7632, 7632, 7632, 7632, 7632, 7632, 7632, 7632, 7632, 7632, 7632},// 4800
{6185, 6185, 6185, 6185, 6185, 6185, 6185, 6185, 6185, 6185, 6185, 6185, 6185, 6185, 6185, 6185, 6185},// 5400
{5167, 5167, 5167, 5167, 5167, 5167, 5167, 5167, 5167, 5167, 5167, 5167, 5167, 5167, 5167, 5167, 5167},// 6000
{4207, 4207, 4207, 4207, 4207, 4207, 4207, 4207, 4207, 4207, 4207, 4207, 4207, 4207, 4207, 4207, 4207},// 6600
{3523, 3523, 3523, 3523, 3523, 3523, 3523, 3523, 3523, 3523, 3523, 3523, 3523, 3523, 3523, 3523, 3523},// 7200
{2944, 2944, 2944, 2944, 2944, 2944, 2944, 2944, 2944, 2944, 2944, 2944, 2944, 2944, 2944, 2944, 2944},// 7800
{2448, 2448, 2448, 2448, 2448, 2448, 2448, 2448, 2448, 2448, 2448, 2448, 2448, 2448, 2448, 2448, 2448},// 8400
{2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019},// 9000
{1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642} // 9600
};//low KPA --------------------------------------------------------------------------------- high KPA
volatile unsigned long Iend [17] [17] = { //injector on time, in microseconds
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266},//"0" RPM
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266},// 600
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266},// 1200
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266},// 1800
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266},// 2400
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266},// 3000
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266},// 3600
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266},// 4200
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266},// 4800
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266},// 5400
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266},// 6000
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266},// 6600
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266},// 7200
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266},// 7800
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266},// 8400
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266},// 9000
{284, 284, 568, 853, 1137, 1422, 1706, 1991, 2275, 1560, 2844, 3129, 3413, 3697, 3982, 4266, 4266}// 9600
};//low KPA --------------------------------------------------------------------------------- high KPA
Code: Select all
#include "TuneArrays.h"
const uint8_t pattern0 = 0b01111101;//0 degrees / TDC #1 and paired cylinder
const uint8_t pattern1 = 0b01110011;//90 degrees
const uint8_t pattern2 = 0b11000101;//180 degrees
const uint8_t pattern3 = 0b01000001;//270 degrees
uint8_t RPMIndex = 0;
uint8_t adcIndex = 0;
unsigned long currentOnDelaySpark = 0;
unsigned long currentOffDelaySpark = 0;
unsigned long currentOnDelayFuel = 0;
unsigned long currentOffDelayFuel = 0;
bool pulseHighSpark0 = false;
bool pulseActiveSpark0 = false;
bool triggerPulseSpark0 = false;
unsigned long pulseStartTimeSpark0 = 0;
unsigned long pulseWidthSpark0 = 0;
bool pulseHighSpark1 = false;
bool pulseActiveSpark1 = false;
bool triggerPulseSpark1 = false;
unsigned long pulseStartTimeSpark1 = 0;
unsigned long pulseWidthSpark1 = 0;
bool pulseHighSpark2 = false;
bool pulseActiveSpark2 = false;
bool triggerPulseSpark2 = false;
unsigned long pulseStartTimeSpark2 = 0;
unsigned long pulseWidthSpark2 = 0;
bool pulseHighSpark3 = false;
bool pulseActiveSpark3 = false;
bool triggerPulseSpark3 = false;
unsigned long pulseStartTimeSpark3 = 0;
unsigned long pulseWidthSpark3 = 0;
bool pulseHighSpark4 = false;
bool pulseActiveSpark4 = false;
bool triggerPulseSpark4 = false;
unsigned long pulseStartTimeSpark4 = 0;
unsigned long pulseWidthSpark4 = 0;
bool pulseHighSpark5 = false;
bool pulseActiveSpark5 = false;
bool triggerPulseSpark5 = false;
unsigned long pulseStartTimeSpark5 = 0;
unsigned long pulseWidthSpark5 = 0;
bool pulseHighSpark6 = false;
bool pulseActiveSpark6 = false;
bool triggerPulseSpark6 = false;
unsigned long pulseStartTimeSpark6 = 0;
unsigned long pulseWidthSpark6 = 0;
bool pulseHighSpark7 = false;
bool pulseActiveSpark7 = false;
bool triggerPulseSpark7 = false;
unsigned long pulseStartTimeSpark7 = 0;
unsigned long pulseWidthSpark7 = 0;
bool pulseHighFuel0 = false;
bool pulseActiveFuel0 = false;
bool triggerPulseFuel0 = false;
unsigned long pulseStartTimeFuel0 = 0;
unsigned long pulseWidthFuel0 = 0;
bool pulseHighFuel1 = false;
bool pulseActiveFuel1 = false;
bool triggerPulseFuel1 = false;
unsigned long pulseStartTimeFuel1 = 0;
unsigned long pulseWidthFuel1 = 0;
bool pulseHighFuel2 = false;
bool pulseActiveFuel2 = false;
bool triggerPulseFuel2 = false;
unsigned long pulseStartTimeFuel2 = 0;
unsigned long pulseWidthFuel2 = 0;
bool pulseHighFuel3 = false;
bool pulseActiveFuel3 = false;
bool triggerPulseFuel3 = false;
unsigned long pulseStartTimeFuel3 = 0;
unsigned long pulseWidthFuel3 = 0;
bool pulseHighFuel4 = false;
bool pulseActiveFuel4 = false;
bool triggerPulseFuel4 = false;
unsigned long pulseStartTimeFuel4 = 0;
unsigned long pulseWidthFuel4 = 0;
bool pulseHighFuel5 = false;
bool pulseActiveFuel5 = false;
bool triggerPulseFuel5 = false;
unsigned long pulseStartTimeFuel5 = 0;
unsigned long pulseWidthFuel5 = 0;
bool pulseHighFuel6 = false;
bool pulseActiveFuel6 = false;
bool triggerPulseFuel6 = false;
unsigned long pulseStartTimeFuel6 = 0;
unsigned long pulseWidthFuel6 = 0;
bool pulseHighFuel7 = false;
bool pulseActiveFuel7 = false;
bool triggerPulseFuel7 = false;
unsigned long pulseStartTimeFuel7 = 0;
unsigned long pulseWidthFuel7 = 0;
int readings[24] {4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095}; // Circular buffer
int bufIndex = 0; // Buffer index
long total = 4095L * 24; // Set this to the initial sum
int readings2[24]; // Circular buffer
int bufIndex2 = 0; // Buffer index
long total2 = 0L * 24; // Set this to the initial sum
int readings3[24]; // Circular buffer
int bufIndex3 = 0; // Buffer index
unsigned long total3 = 0UL * 24; // Set this to the initial sum
unsigned long lastTime = 0;
unsigned long pulseHighTime = 0;
unsigned long pulseLowTime = 0;
uint8_t signalHistory = 0b00000000;
bool newSample = false;
void handleCrankSignal() {
unsigned long currentTime = micros();
if (digitalRead(22) == HIGH) {
pulseLowTime = currentTime - lastTime;
} else {
pulseHighTime = currentTime - lastTime;
uint8_t bit = (pulseHighTime > pulseLowTime) ? 1 : 0;
signalHistory = ((signalHistory << 1) | bit) & 0xFF;
newSample = true; // flag to loop()
}
lastTime = currentTime;
}
void handleSparkPulse(uint8_t pin, unsigned long startTime, bool &highFlag) {
unsigned long now = micros();
unsigned long elapsed = now - startTime;
if (elapsed < currentOnDelaySpark) {
digitalWrite(pin, LOW);
} else {
highFlag = true;
}
}
void handleSparkPulse2(uint8_t pin, unsigned long startTime, bool &activeFlag, bool &highFlag, unsigned long &OnTime) {
unsigned long now = micros();
unsigned long elapsed = now - startTime;
if (activeFlag){
OnTime = currentOnDelaySpark + currentOffDelaySpark;
activeFlag = false;
digitalWrite(pin, HIGH);
}
if (elapsed > OnTime) {
digitalWrite(pin, LOW);
highFlag = false;
}
}
void handleFuelPulse(uint8_t pin, unsigned long startTime, bool &highFlag) {
unsigned long now = micros();
unsigned long elapsed = now - startTime;
if (elapsed < currentOnDelayFuel) {
digitalWrite(pin, LOW);
} else {
highFlag = true;
}
}
void handleFuelPulse2(uint8_t pin, unsigned long startTime, bool &activeFlag, bool &highFlag, unsigned long &OnTime) {
unsigned long now = micros();
unsigned long elapsed = now - startTime;
if (activeFlag){
OnTime = currentOnDelayFuel + currentOffDelayFuel;
activeFlag = false;
digitalWrite(pin, HIGH);
}
if (elapsed > OnTime) {
digitalWrite(pin, LOW);
highFlag = false;
}
}
void setup() {
analogReadResolution(12);
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
pinMode(14, OUTPUT);
pinMode(15, OUTPUT);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(22, INPUT);
pinMode(21, INPUT);
attachInterrupt(digitalPinToInterrupt(22), handleCrankSignal, CHANGE);
}
void loop() {
if (newSample) {
newSample = false;
//if (digitalRead(21) == HIGH){
// Spark patterns
if (signalHistory == pattern0) {triggerPulseSpark0 = true; triggerPulseFuel0 = true;}
if (signalHistory == pattern1) {triggerPulseSpark2 = true; triggerPulseFuel2 = true;}
if (signalHistory == pattern2) {triggerPulseSpark4 = true; triggerPulseFuel4 = true;}
if (signalHistory == pattern3) {triggerPulseSpark6 = true; triggerPulseFuel6 = true;}
//}
//if (digitalRead(21) == LOW) {
if (signalHistory == pattern0) {triggerPulseSpark1 = true; triggerPulseFuel1 = true;}
if (signalHistory == pattern1) {triggerPulseSpark3 = true; triggerPulseFuel3 = true;}
if (signalHistory == pattern2) {triggerPulseSpark5 = true; triggerPulseFuel5 = true;}
if (signalHistory == pattern3) {triggerPulseSpark7 = true; triggerPulseFuel7 = true;}
//}
unsigned long RPMTime = pulseHighTime + pulseLowTime;//Calculate RPMtime (µs per 15 degrees)
total2 -= readings2[bufIndex2];
unsigned long newVal2 = RPMTime;
readings2[bufIndex2] = newVal2;
total2 += newVal2;
bufIndex2 = (bufIndex2 + 1) % 24;
unsigned long RPMTimeavg = total2 / 24UL;
uint Predicted360Time = RPMTimeavg * 24;//48 for full sequential, 720 degrees. 24 for waste spark, 360 degrees.
// FIXED: Rev limiter + low-RPM cutoff
unsigned long Dwell = 4000UL;
if (RPMTimeavg < Limiter) {
Dwell = 0UL; // spark cut when RPM too high
} else if (RPMTimeavg > 125000UL) {
Dwell = 0UL; // below 20 RPM, also cut spark
}
RPMTimeavg = constrain(RPMTimeavg, 278UL, 3000000UL); // 9600 RPM to 0 RPM. Always round the decimal up, even if it's 0.0001. Not overflowing arrays is important
// --- ADC rolling average (12-bit to 7-bit scale) ---
total -= readings[bufIndex];
int newVal = analogRead(A0);
readings[bufIndex] = newVal;
total += newVal;
bufIndex = (bufIndex + 1) % 24;
int avg12bit = total / 24;
adcIndex = avg12bit >> 8; //Discarding LSBs to match array resolution
uint32_t IndexFull = ((uint64_t)2500000 << 8) / ((uint32_t)RPMTimeavg * 600);
uint16_t IndexWhole = IndexFull >> 8;
uint8_t Frac = IndexFull & 0xFF;
int Frac2 = avg12bit & 0x1F;
int TerpA = Dstart[IndexWhole][adcIndex];
int TerpB = Dstart[IndexWhole +1][adcIndex];
int TerpD = TerpA + (((TerpB - TerpA) * Frac) >> 8);
int TerpA2 = Dstart[IndexWhole][adcIndex +1];
int TerpB2 = Dstart[IndexWhole +1][adcIndex +1];
int TerpD2 = TerpA2 + (((TerpB2 - TerpA2) * Frac) >> 8);
int TerpD5 = TerpD + (((TerpD2 - TerpD) * Frac2) >> 8);
int TerpA3 = Iend[IndexWhole][adcIndex+1];
int TerpB3 = Iend[IndexWhole +1][adcIndex +1];
int TerpD3 = TerpA3 + (((TerpB3 - TerpA3) * Frac) >> 8);
int TerpA4 = Iend[IndexWhole][adcIndex];
int TerpB4 = Iend[IndexWhole +1][adcIndex];
int TerpD4 = TerpA4 + (((TerpB4 - TerpA4) * Frac) >> 8);
int TerpD6 = TerpD4 + (((TerpD3 - TerpD4) * Frac2) >> 8);
total3 -= readings3[bufIndex3];
int newVal3 = analogRead(A1);
readings3[bufIndex3] = newVal3;
total3 += newVal3;
bufIndex3 = (bufIndex3 + 1) % 24;
int IATavg = total3 / 24;
int IAT7bit = IATavg >> 5;
int Temp = IATSpark [IAT7bit];
int Scaled = ((TerpD5 * Temp) >>8);
int TrimA = EOIT [IndexWhole];
int TrimB = EOIT [IndexWhole +1];
int TrimTerp = TrimA + (((TrimB - TrimA) * Frac) >> 8);
int Temp2 = IATFuel [IAT7bit];
int Scaled3 = ((TerpD6 * Temp2) >>8);
int ScaledOffset = Predicted360Time - (Scaled3 + TrimTerp);
if (ScaledOffset < 0) ScaledOffset = 0;
if (RPMTimeavg > 125000UL){ //if RPM below minimum = 20RPM
Scaled3 = 0UL; //Fuel off
signalHistory = 0b00000000;//Sync reset
}
// --- Update delay values from tables ---
currentOnDelaySpark = Scaled;
currentOffDelaySpark = Dwell;
currentOnDelayFuel = ScaledOffset;
currentOffDelayFuel = Scaled3;
}
// --- Check for new pulse triggers from crank handler ---
// --- Spark pulse triggers ---
if (triggerPulseSpark0) { triggerPulseSpark0 = false; pulseStartTimeSpark0 = micros(); pulseActiveSpark0 = true; }
if (triggerPulseSpark1) { triggerPulseSpark1 = false; pulseStartTimeSpark1 = micros(); pulseActiveSpark1 = true; }
if (triggerPulseSpark2) { triggerPulseSpark2 = false; pulseStartTimeSpark2 = micros(); pulseActiveSpark2 = true; }
if (triggerPulseSpark3) { triggerPulseSpark3 = false; pulseStartTimeSpark3 = micros(); pulseActiveSpark3 = true; }
if (triggerPulseSpark4) { triggerPulseSpark4 = false; pulseStartTimeSpark4 = micros(); pulseActiveSpark4 = true; }
if (triggerPulseSpark5) { triggerPulseSpark5 = false; pulseStartTimeSpark5 = micros(); pulseActiveSpark5 = true; }
if (triggerPulseSpark6) { triggerPulseSpark6 = false; pulseStartTimeSpark6 = micros(); pulseActiveSpark6 = true; }
if (triggerPulseSpark7) { triggerPulseSpark7 = false; pulseStartTimeSpark7 = micros(); pulseActiveSpark7 = true; }
// --- Fuel pulse triggers ---
if (triggerPulseFuel0) { triggerPulseFuel0 = false; pulseStartTimeFuel0 = micros(); pulseActiveFuel0 = true; }
if (triggerPulseFuel1) { triggerPulseFuel1 = false; pulseStartTimeFuel1 = micros(); pulseActiveFuel1 = true; }
if (triggerPulseFuel2) { triggerPulseFuel2 = false; pulseStartTimeFuel2 = micros(); pulseActiveFuel2 = true; }
if (triggerPulseFuel3) { triggerPulseFuel3 = false; pulseStartTimeFuel3 = micros(); pulseActiveFuel3 = true; }
if (triggerPulseFuel4) { triggerPulseFuel4 = false; pulseStartTimeFuel4 = micros(); pulseActiveFuel4 = true; }
if (triggerPulseFuel5) { triggerPulseFuel5 = false; pulseStartTimeFuel5 = micros(); pulseActiveFuel5 = true; }
if (triggerPulseFuel6) { triggerPulseFuel6 = false; pulseStartTimeFuel6 = micros(); pulseActiveFuel6 = true; }
if (triggerPulseFuel7) { triggerPulseFuel7 = false; pulseStartTimeFuel7 = micros(); pulseActiveFuel7 = true; }
// --- Spark pulse timing (Pins 0 to 7) ---
if (pulseHighSpark0) handleSparkPulse2(0, pulseStartTimeSpark0, pulseActiveSpark0, pulseHighSpark0, pulseWidthSpark0);
if (pulseHighSpark1) handleSparkPulse2(1, pulseStartTimeSpark1, pulseActiveSpark1, pulseHighSpark1, pulseWidthSpark1);
if (pulseHighSpark2) handleSparkPulse2(2, pulseStartTimeSpark2, pulseActiveSpark2, pulseHighSpark2, pulseWidthSpark2);
if (pulseHighSpark3) handleSparkPulse2(3, pulseStartTimeSpark3, pulseActiveSpark3, pulseHighSpark3, pulseWidthSpark3);
if (pulseHighSpark4) handleSparkPulse2(4, pulseStartTimeSpark4, pulseActiveSpark4, pulseHighSpark4, pulseWidthSpark4);
if (pulseHighSpark5) handleSparkPulse2(5, pulseStartTimeSpark5, pulseActiveSpark5, pulseHighSpark5, pulseWidthSpark5);
if (pulseHighSpark6) handleSparkPulse2(6, pulseStartTimeSpark6, pulseActiveSpark6, pulseHighSpark6, pulseWidthSpark6);
if (pulseHighSpark7) handleSparkPulse2(7, pulseStartTimeSpark7, pulseActiveSpark7, pulseHighSpark7, pulseWidthSpark7);
if (pulseActiveSpark0) handleSparkPulse(0, pulseStartTimeSpark0, pulseHighSpark0);
if (pulseActiveSpark1) handleSparkPulse(1, pulseStartTimeSpark1, pulseHighSpark1);
if (pulseActiveSpark2) handleSparkPulse(2, pulseStartTimeSpark2, pulseHighSpark2);
if (pulseActiveSpark3) handleSparkPulse(3, pulseStartTimeSpark3, pulseHighSpark3);
if (pulseActiveSpark4) handleSparkPulse(4, pulseStartTimeSpark4, pulseHighSpark4);
if (pulseActiveSpark5) handleSparkPulse(5, pulseStartTimeSpark5, pulseHighSpark5);
if (pulseActiveSpark6) handleSparkPulse(6, pulseStartTimeSpark6, pulseHighSpark6);
if (pulseActiveSpark7) handleSparkPulse(7, pulseStartTimeSpark7, pulseHighSpark7);
// --- Fuel pulse timing (Pins 8 to 15) ---
if (pulseHighFuel0) handleFuelPulse2(8, pulseStartTimeFuel0, pulseActiveFuel0, pulseHighFuel0, pulseWidthFuel0);
if (pulseHighFuel1) handleFuelPulse2(9, pulseStartTimeFuel1, pulseActiveFuel1, pulseHighFuel1, pulseWidthFuel1);
if (pulseHighFuel2) handleFuelPulse2(10, pulseStartTimeFuel2, pulseActiveFuel2, pulseHighFuel2, pulseWidthFuel2);
if (pulseHighFuel3) handleFuelPulse2(11, pulseStartTimeFuel3, pulseActiveFuel3, pulseHighFuel3, pulseWidthFuel3);
if (pulseHighFuel4) handleFuelPulse2(12, pulseStartTimeFuel4, pulseActiveFuel4, pulseHighFuel4, pulseWidthFuel4);
if (pulseHighFuel5) handleFuelPulse2(13, pulseStartTimeFuel5, pulseActiveFuel5, pulseHighFuel5, pulseWidthFuel5);
if (pulseHighFuel6) handleFuelPulse2(14, pulseStartTimeFuel6, pulseActiveFuel6, pulseHighFuel6, pulseWidthFuel6);
if (pulseHighFuel7) handleFuelPulse2(15, pulseStartTimeFuel7, pulseActiveFuel7, pulseHighFuel7, pulseWidthFuel7);
if (pulseActiveFuel0) handleFuelPulse(8, pulseStartTimeFuel0, pulseHighFuel0);
if (pulseActiveFuel1) handleFuelPulse(9, pulseStartTimeFuel1, pulseHighFuel1);
if (pulseActiveFuel2) handleFuelPulse(10, pulseStartTimeFuel2, pulseHighFuel2);
if (pulseActiveFuel3) handleFuelPulse(11, pulseStartTimeFuel3, pulseHighFuel3);
if (pulseActiveFuel4) handleFuelPulse(12, pulseStartTimeFuel4, pulseHighFuel4);
if (pulseActiveFuel5) handleFuelPulse(13, pulseStartTimeFuel5, pulseHighFuel5);
if (pulseActiveFuel6) handleFuelPulse(14, pulseStartTimeFuel6, pulseHighFuel6);
if (pulseActiveFuel7) handleFuelPulse(15, pulseStartTimeFuel7, pulseHighFuel7);
}
Last edited by AngelMarc on Mon Sep 22, 2025 6:37 am, edited 3 times in total.
Don't stress specific units.
-
MPC001
- Posts: 174
- Joined: Sat May 05, 2018 11:41 am
-
Gareth
- Posts: 2678
- Joined: Fri Mar 14, 2014 10:37 am
- Location: Bacchus Marsh, Vic
Re: Coding my own open source 24x ECU [beta available]
Can't wait to see a video of this running!! 
According to chemistry, alcohol is a solution...
-
AngelMarc
- Posts: 612
- Joined: Sat Apr 08, 2023 11:23 am
- cars: A CB450 running to 8,000RPM with a P59.
Re: Coding my own open source 24x ECU [beta available]
Figured I'd at least do a hardware electrical test. Well, sent a pico 10 volts and fried it. Forgot which voltage regulator I had, and didn't adjust it down before plugging it in.
Good thing I had 2. Hook other one up... I can't get shit out of it. Test it and output board on bench with signal gen and eventually... https://www.youtube.com/watch?v=ozLFKbWECEk
Put a resistor plug in, didn't complain anymore; haven't seen dropped pulses since.
Good thing I had 2. Hook other one up... I can't get shit out of it. Test it and output board on bench with signal gen and eventually... https://www.youtube.com/watch?v=ozLFKbWECEk
Put a resistor plug in, didn't complain anymore; haven't seen dropped pulses since.
Last edited by AngelMarc on Tue Sep 23, 2025 12:39 am, edited 3 times in total.
Don't stress specific units.
-
AngelMarc
- Posts: 612
- Joined: Sat Apr 08, 2023 11:23 am
- cars: A CB450 running to 8,000RPM with a P59.
Re: Coding my own open source 24x ECU [beta available]
... as far as I can tell, my crank sensor is dead. Pulls voltage low whether metal is present or not. Another damn delay and expense.
Last edited by AngelMarc on Mon Sep 22, 2025 11:45 pm, edited 1 time in total.
Don't stress specific units.
-
AngelMarc
- Posts: 612
- Joined: Sat Apr 08, 2023 11:23 am
- cars: A CB450 running to 8,000RPM with a P59.
Re: Coding my own open source 24x ECU [beta available]
And in the process of troubleshooting crank sensor, I sent 5 volts to GPIO of the other one, so it probably died too. I'll find out for sure another day. All the crank sensor wires are black, easy to mix up, and then re-mix up when you think you're sorting them out, especially with that spaghetti mess.
Don't stress specific units.
-
AngelMarc
- Posts: 612
- Joined: Sat Apr 08, 2023 11:23 am
- cars: A CB450 running to 8,000RPM with a P59.
Re: Coding my own open source 24x ECU [beta available]
Thought I'd get back to it today.
You do not have the required permissions to view the files attached to this post.
Don't stress specific units.
-
AngelMarc
- Posts: 612
- Joined: Sat Apr 08, 2023 11:23 am
- cars: A CB450 running to 8,000RPM with a P59.
Re: Coding my own open source 24x ECU [beta available]
Try again a week from now when yet another sensor shows up. Or I use my $12 generic gen 3 LS sensor that works fine and make the appropriate circuit to use it...
Don't stress specific units.
-
AngelMarc
- Posts: 612
- Joined: Sat Apr 08, 2023 11:23 am
- cars: A CB450 running to 8,000RPM with a P59.
Re: Coding my own open source 24x ECU [beta available]
Got the new generic 12595966 sensor. Bench tested fine. Getting closer... again.
Don't stress specific units.