Coding my own aftermarket ECU [beta available]
- antus
- Site Admin
- Posts: 9002
- Joined: Sat Feb 28, 2009 8:34 pm
- cars: TX Gemini 2L Twincam
TX Gemini SR20 18psi
Datsun 1200 Ute
Subaru Blitzen '06 EZ30 4th gen, 3.0R Spec B - Contact:
Re: Coding my own aftermarket ECU
Why dont you put something in your build system to make an xdf for tunerpro? you can make the xdf in tunerpro but put some magic numbers in for addreses and in your build system setup something to read the address after compilation and search and replace the magic numbers with real numbers in the xdf.
Have you read the FAQ? For lots of information and links to significant threads see here: http://pcmhacking.net/forums/viewtopic.php?f=7&t=1396
Re: Coding my own aftermarket ECU
This will be easier and just as capable.
Unless it shits itself when I tell it to combine all the values into a single string with appropriate punctuation/syntax.
Unless it shits itself when I tell it to combine all the values into a single string with appropriate punctuation/syntax.
Last edited by AngelMarc on Tue Jun 10, 2025 8:25 pm, edited 2 times in total.
Don't stress specific units.
Re: Coding my own aftermarket ECU
Also, I know enough about computers and engines to go back and forth with AI until it spits out chunks of code that actually do what I expect, then Integrate those chunks as I go, manually making small edits here and there. This stuff is 99% AI written. I'm more.... CEO than coder on this one.
The crank signal generator code was all me; not the ECU.
The crank signal generator code was all me; not the ECU.
Don't stress specific units.
- antus
- Site Admin
- Posts: 9002
- Joined: Sat Feb 28, 2009 8:34 pm
- cars: TX Gemini 2L Twincam
TX Gemini SR20 18psi
Datsun 1200 Ute
Subaru Blitzen '06 EZ30 4th gen, 3.0R Spec B - Contact:
Re: Coding my own aftermarket ECU
Yeah all good. It's not how I would approach the problem, and I think I know what you are up against, but I am not closed minded and watching with interest to see how you go. It's not every day someone tries to write their own ECU, especially someone without the programmer background using AI tools.
Have you read the FAQ? For lots of information and links to significant threads see here: http://pcmhacking.net/forums/viewtopic.php?f=7&t=1396
Re: Coding my own aftermarket ECU
Excel has python
Re: Coding my own aftermarket ECU
Any math wiz know how to get the row RPMtime to = the row index, with 1 formula?
The goal is even RPM spacing for VE table. Don't need those exact RPM values in the end. close is good enough.
EDIT: Had index in reverse order. Fixed attachment.
The goal is even RPM spacing for VE table. Don't need those exact RPM values in the end. close is good enough.
EDIT: Had index in reverse order. Fixed attachment.
- Attachments
-
- f71bdd2fa105d5fae564a7165db8947896d1373e.png (95.85 KiB) Viewed 166 times
Last edited by AngelMarc on Wed Jun 11, 2025 9:20 am, edited 1 time in total.
Don't stress specific units.
- antus
- Site Admin
- Posts: 9002
- Joined: Sat Feb 28, 2009 8:34 pm
- cars: TX Gemini 2L Twincam
TX Gemini SR20 18psi
Datsun 1200 Ute
Subaru Blitzen '06 EZ30 4th gen, 3.0R Spec B - Contact:
Re: Coding my own aftermarket ECU
Normally you'd use a 3d lookup function that averages the cells proportionately to the actual value. Once you have the function you'd use that for all your 3d lookups. GM optimised the hell out of it in the VPW computers, and made it complex at the same time, but thats not required. You probably only need x and y resolution to bounds check, x and y values to lookup, and possibly a data type unless you are always using the same data format or have a different lookup per type.
Have you read the FAQ? For lots of information and links to significant threads see here: http://pcmhacking.net/forums/viewtopic.php?f=7&t=1396
Re: Coding my own aftermarket ECU
Ah, found the no decimal number format option.
Getting closer, but dropping more resolution than I want at the stupid high RPM values.
Getting closer, but dropping more resolution than I want at the stupid high RPM values.
- Attachments
-
- Capture.PNG (48.2 KiB) Viewed 160 times
Don't stress specific units.
Re: Coding my own aftermarket ECU
just hope whatever I end up with doesn't add so much to the loop that it can't handle high RPM by the time it's all done, with IAT added and what not... and external correction inputs. That's been in the back of my mind for a while; a way to add wideband, torque reduction for transmission shift etc. That's all end of the list though.
I suppose interpolation between all cells might be enough to solve nearly all of it.
Don't stress specific units.
Re: Coding my own aftermarket ECU
That is a perfect question for AI:
RPMtime = (2,500,000 / ( index - 1 )) * 600
Index = 1 + (2,500,000 * (RPMtime * 600))
https://chatgpt.com/share/6848bfe0-99f0 ... 51d98a254c
Regarding lookup tables, here are some functions I've used before:
These can be used with arrays (which I initialise with defines in a header file specifically for calibration data, keeping code and data in seperate files. These defines are used inside a struct to hold the data in my source file):
It's been interesting watching you try and nut this out. But I would encourage trying to use the AI to help you understand whats happening, rather than writing it all for you. Especially if the goal is to actually learn how to do what you're doing.
Questions like "what could a formula for this be" are great for AI, when theres a highly specific set of data or objective. Open ended questions sometimes not so much.
That being said I do the same. I've never used python much, but recently Ive been working on a project and using python (mainly AI generated) as a tool to do what I need to do (collect data, format it, etc. etc.). After a month or so I feel like I've learnt nothing about python, im still asking it very basic questions (like how do I loop through this, or getting confused betweena list tuple or dictionary). But I've got some absolutely brilliant python scripts to do very useful things and make my life super easy. But my objective isn't to learn python, it's to learn about what I'm working on so I can implement the final project in C / C++
RPMtime = (2,500,000 / ( index - 1 )) * 600
Index = 1 + (2,500,000 * (RPMtime * 600))
https://chatgpt.com/share/6848bfe0-99f0 ... 51d98a254c
Regarding lookup tables, here are some functions I've used before:
Code: Select all
uint16_t lookup_2d_linear(uint16_t reference, uint16_t *table, uint8_t tableSize, uint16_t tableMin, uint16_t tableMax){ //16 bit
uint8_t index = 0; //Index of the first of 2 interpolated table entries
uint16_t cellSize = (tableMax - tableMin) / ( tableSize - 1); // => "range of table" / "number of entries in table"
if(reference < tableMin){
index = 0; //use the first 2 entries
} else if(reference > tableMax){
index = tableSize - 2; //use the last 2 entries
} else {
index = (reference - tableMin) / cellSize;
}
uint16_t x0 = tableMin + (index * cellSize);
uint16_t x1 = tableMin + ((index + 1) * cellSize);
uint16_t y0 = pgm_read_word(&(table[index]));
uint16_t y1 = pgm_read_word(&(table[index + 1]));
return (((uint32_t)y0 * (x1 - reference)) + ((uint32_t)y1 * (reference - x0))) / (x1 - x0); //linear interpolation
}
uint8_t lookup_2d_linear(uint16_t reference, uint8_t *table, uint8_t tableSize, uint16_t tableMin, uint16_t tableMax){ // 8 bit
uint8_t index = 0; //Index of the first of 2 interpolated table entries
uint16_t cellSize = (tableMax - tableMin) / ( tableSize - 1); // => "range of table" / "number of entries in table"
if(reference < tableMin){
index = 0; //use the first 2 entries
} else if(reference > tableMax){
index = tableSize - 2; //use the last 2 entries
} else {
index = (reference - tableMin) / cellSize;
}
uint16_t x0 = tableMin + (index * cellSize);
uint16_t x1 = tableMin + ((index + 1) * cellSize);
uint16_t y0 = pgm_read_byte(&(table[index]));
uint16_t y1 = pgm_read_byte(&(table[index + 1]));
return (((uint32_t)y0 * (x1 - reference)) + ((uint32_t)y1 * (reference - x0))) / (x1 - x0); //linear interpolation
}
uint16_t lookup_3d_linear(uint16_t xRef, uint16_t yRef, uint16_t **table, uint8_t xSize, uint16_t xMin, uint16_t xMax, uint8_t ySize, uint16_t yMin, uint16_t yMax){
/* xRef / yRef = column (x) and row (y) values that we want to lookup
xSize / ySize = number of columns + rows in this table
xMin / xMax / yMin / yMax = minimum/maximum values of each axis of this table (first and last row/columns value)
*/
uint8_t colIndex = 0; //X value
uint8_t rowIndex = 0; //Y value
uint16_t xCellSize = (xMax - xMin) / (xSize - 1);
uint16_t yCellSize = (yMax - yMin) / (ySize - 1);
if(xRef < xMin){
colIndex = 0; //use first 2 entries along x axis
} else if(xRef > xMax){
colIndex = xSize - 2; //use last 2 entries along x axis
} else {
colIndex = xRef / xCellSize;
}
if(yRef < yMin){
rowIndex = 0; //use first 2 entries along y axis
} else if(yRef > yMax){
rowIndex = ySize - 2; //use last 2 entries along y axis
} else {
rowIndex = yRef / yCellSize;
}
uint16_t x1 = xMin + (colIndex * xCellSize); //Column axis value preceding
uint16_t x2 = xMin + ((colIndex + 1) * xCellSize); //column axis value following
uint16_t y1 = yMin + (rowIndex * yCellSize); //Row axis value preceding
uint16_t y2 = yMin + ((rowIndex + 1) * yCellSize); //Row axis value following
//Multiply index's by 2 as reading a 16 bit value:
uint16_t q11 = pgm_read_word((uint16_t)table + ((rowIndex * 2) * xSize) + (colIndex * 2)); //Get value at: row preceding, column preceding
uint16_t q12 = pgm_read_word((uint16_t)table + (((rowIndex + 1) * 2) * xSize) + (colIndex * 2)); //Get value at: row following, column preceding
uint16_t q21 = pgm_read_word((uint16_t)table + ((rowIndex * 2) * xSize) + ((colIndex + 1) * 2)); //Get value at: row preceding, column following
uint16_t q22 = pgm_read_word((uint16_t)table + (((rowIndex + 1) * 2) * xSize) + ((colIndex + 1) * 2)); //Get value at: row following, column following
uint16_t r1 = (q11*((float)(x2 - xRef)/(x2 - x1))) + (q21*((float)(xRef - x1)/(x2 - x1))); //Linear interpolate along X axis, row preceding
uint16_t r2 = (q12*((float)(x2 - xRef)/(x2 - x1))) + (q22*((float)(xRef - x1)/(x2 - x1))); //Linear interpolate along X axis, row following
return (uint16_t)((r1*((float)(y2 - yRef)/(y2 - y1))) + (r2*((float)(yRef - y1)/(y2 - y1)))); //Linear interpolate Y axis down column between 2 interpolated row values
}
These can be used with arrays (which I initialise with defines in a header file specifically for calibration data, keeping code and data in seperate files. These defines are used inside a struct to hold the data in my source file):
Code: Select all
#define TABLE_EGT2_INPUT_CONVERSION_SIZE 26
#define TABLE_EGT2_INPUT_CONVERSION_MIN 0
#define TABLE_EGT2_INPUT_CONVERSION_MAX 5000
#define TABLE_EGT2_INPUT_CONVERSION_3K3 { \
/*3.3K pullup - used to lookup EGT2 temperature from an input voltage*/ \
850, /* 0 - 0 V */ \
688, /* 1 - 0.2V */ \
532, /* 2 - 0.4V */ \
455, /* 3 - 0.6V */ \
404, /* 4 - 0.8V */ \
367, /* 5 - 1.0V */ \
337, /* 6 - 1.2V */ \
312, /* 7 - 1.4V */ \
290, /* 8 - 1.6V */ \
271, /* 9 - 1.8V */ \
254, /* 10 - 2.0V */ \
238, /* 11 - 2.2V */ \
223, /* 12 - 2.4V */ \
208, /* 13 - 2.6V */ \
194, /* 14 - 2.8V */ \
180, /* 15 - 3.0V */ \
167, /* 16 - 3.2V */ \
153, /* 17 - 3.4V */ \
139, /* 18 - 3.6V */ \
124, /* 19 - 3.8V */ \
109, /* 20 - 4.0V */ \
92, /* 21 - 4.2V */ \
72, /* 22 - 4.4V */ \
47, /* 23 - 4.6V */ \
12, /* 24 - 4.8V */ \
0 /* 25 - 5.0V */ \
}
It's been interesting watching you try and nut this out. But I would encourage trying to use the AI to help you understand whats happening, rather than writing it all for you. Especially if the goal is to actually learn how to do what you're doing.
Questions like "what could a formula for this be" are great for AI, when theres a highly specific set of data or objective. Open ended questions sometimes not so much.
That being said I do the same. I've never used python much, but recently Ive been working on a project and using python (mainly AI generated) as a tool to do what I need to do (collect data, format it, etc. etc.). After a month or so I feel like I've learnt nothing about python, im still asking it very basic questions (like how do I loop through this, or getting confused betweena list tuple or dictionary). But I've got some absolutely brilliant python scripts to do very useful things and make my life super easy. But my objective isn't to learn python, it's to learn about what I'm working on so I can implement the final project in C / C++