Arduino go kart EMS

Free Open Source Firmware project discussion forum. Post your Free Open Source firmware projects here!
Post Reply
noisymime
DIP8 - Involved
Posts: 29
Joined: Wed Feb 06, 2013 4:12 am

Arduino go kart EMS

Post by noisymime »

OK, so I know whenever anyone mentions an Arduino based EMS that everyone rolls their eyes and goes back to work, but hear me out.

I've started a project with a mate to develop a simple, arduino based EMS for single cylinder 2 and 4 stroke go karts. The important word there being SIMPLE!
The aim is for it to be a learning platform to teach engine concepts as well as about EMS' themselves (As well as teach myself!). Within reason, where there's a choice between more features or better efficiency and a simpler implementation, the simpler path will be the preferred one. Documentation and clear and well documented code (ie NO assembly if it can be avoided!) will take preference over other areas.

The featureset I'm aiming for is:
  • Single injector fuel management. Will investigate support for up to 4cyl batch injection once single cylinder is complete
  • Single cylinder ignition with 5v logic level coil (May add BIP driver for other coils, but will omit initially in the interest of simplicity)
  • 30 degree crank resolution with 12-1 trigger wheel (36-1 currently appears to be a problem given the limited CPU)
  • 8x8 fuel and ignition tables with interpolation
The aim isn't to have a million options like other ECUs, but to provide a basic set of capabilities that will fit nicely with the requirements of most people playing in this space (Small <250cc engines).

So where am I at now? Much of the basics are there in software now (the hardware side will be equally as simple, but is still very much in the breadboarding stage). The fueling calcs (table lookups, interpolation, pulsewidth calc etc) are complete and the scheduler is currently in testing. Ignition is maybe only 20% complete, but hoping to get the fuel working on an engine before really attacking that.

That's it really. It is an open project but I'm not really sure what the most compatible license is yet, so any thoughts here would be appreciated.
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: Arduino go kart EMS

Post by Fred »

Welcome!
noisymime wrote:OK, so I know whenever anyone mentions an Arduino based EMS that everyone rolls their eyes and goes back to work, but hear me out.
Damn, you got me!

Small engines != simple.

It can be done, but it can not be done well.

FreeEMS is currently _very_ simple... at 12k lines of code. Not that it couldn't be done as well or better with MUCH less lines, but with much less peripherals and horsepower, likely not.

There are plenty of cheap dev platforms now for such a simple "low-end" project, why choose aaarrrgghduino?

About licensing, two main choices:

https://en.wikipedia.org/wiki/Copyleft
https://en.wikipedia.org/wiki/Permissiv ... re_licence
Also see http://creativecommons.org/licenses/

Also read this.

Fred.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
noisymime
DIP8 - Involved
Posts: 29
Joined: Wed Feb 06, 2013 4:12 am

Re: Arduino go kart EMS

Post by noisymime »

Fred wrote: Small engines != simple.

It can be done, but it can not be done well.

FreeEMS is currently _very_ simple... at 12k lines of code. Not that it couldn't be done as well or better with MUCH less lines, but with much less peripherals and horsepower, likely not.
The standardised kart platforms (particularly the 2 stroke ones) are INCREDIBLY simple and it doesn't take a very advanced EMS to improve upon it. We're talking a carby with less parts than I have fingers and fixed ignition timing. :)
Still, improving existing systems isn't really the aim. If I can explain a concept to some 18 year old in shop class, say the idea of dwell, and then show him some simple code that says, start charging the coil here, stop charging it 2ms later here, that's what I'm after.
Fred wrote: There are plenty of cheap dev platforms now for such a simple "low-end" project, why choose aaarrrgghduino?
Whilst there are some great dev platforms out there now that are much more powerful for roughly the same price, I haven't seen anything that's as simple in either hardware or software as the Arduino. The point isn't necessarily to teach people about hardware or software, but to have a practical system for teaching engine concepts. Maybe I underestimate what is actually required in a firmware for it to be usable, but I really do think it's possible to keep the code relatively high level and have it function fairly well if we target a limited number of configurations.

I should mention that we'll use the Arduino Mega platform as the extra program space, I/O and, importantly, timers, will make life easier.

To flip the question around, are there any specific reasons NOT to use an arduino (Other than the obvious speed weakness)?
Fred wrote: Also read this.
That is one hell of an ambitious project. I agree that making something high performance, with good efficiency and passes legal requirements with an arduino seems like a big hill to climb. That said, the new Arduino Due has a comparatively beefy ARM processor that may be a help.
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: Arduino go kart EMS

Post by Fred »

Fred wrote:Small engines != simple.
You'll see. Eventually :-)
noisymime wrote:The standardised kart platforms (particularly the 2 stroke ones) are INCREDIBLY simple and it doesn't take a very advanced EMS to improve upon it. We're talking a carby with less parts than I have fingers and fixed ignition timing. :)
matching that should almost be straight forward, unless you mean fueling too.
Still, improving existing systems isn't really the aim. If I can explain a concept to some 18 year old in shop class, say the idea of dwell, and then show him some simple code that says, start charging the coil here, stop charging it 2ms later here, that's what I'm after.
The trouble is, the simple code often ends up complex once you're done handling error conditions. Pseudo code is good for that :-) FreeEMS has been written with an absolute focus on being easy to understand, so I totally understand your desire to make the code "accessible" to ordinary beginners.
I haven't seen anything that's as simple in either hardware or software as the Arduino.
Scary! You're not planning to use the arduino dev env, are you? Just C, right? Tell me yes, please! :-)
The point isn't necessarily to teach people about hardware or software, but to have a practical system for teaching engine concepts.
Fair enough, you should be able to achieve that no worries at all :-)
Maybe I underestimate what is actually required in a firmware for it to be usable
You have to define usable first :-)
but I really do think it's possible to keep the code relatively high level and have it function fairly well if we target a limited number of configurations.
That certainly ups the chances of success and cuts the dev time. But it doesn't detract from what you need to do a good job, which is quite a lot.
I should mention that we'll use the Arduino Mega platform as the extra program space, I/O and, importantly, timers, will make life easier.
Yes, that's going to help a lot. Timers are your friend :-)
To flip the question around, are there any specific reasons NOT to use an arduino (Other than the obvious speed weakness)?
The hardware, no, the software, no, but the obvious speed weakness in software is a BIG one.
That said, the new Arduino Due has a comparatively beefy ARM processor that may be a help.
It's a nice CPU for GP stuff, yes :-) But it's not an engine management oriented CPU. Very few are. Nothing affordable.

Keep us posted :-)

Fred.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
JareeB
QFP80 - Contributor
Posts: 42
Joined: Tue Dec 25, 2012 12:14 am
Location: Greenville, Wisconsin

Re: Arduino go kart EMS

Post by JareeB »

How did you code in the 8 by 8 tables?
plans to build a 300whp turbo ford ranger with a 2.3l engine the ford lima!
current rig: 1994 ford ranger 2.3. good platform for my almost complete turbo engine. a237 cam, stock t3 turbo, ported and polished head. just needs some mangement!!
noisymime
DIP8 - Involved
Posts: 29
Joined: Wed Feb 06, 2013 4:12 am

Re: Arduino go kart EMS

Post by noisymime »

JareeB wrote:How did you code in the 8 by 8 tables?
Just an 8x8 2D array for the data itself and 2x 1D arrays for the axis values.

A lookup function takes (table, X value, Y value) and returns a bilinear interpolated value.

This is a bit of a first cut to get things working. I'm planing on removing the need for the float math at some point in the future.

Code: Select all

struct table {
  //All tables must be the same size for simplicity
  const static int xSize = 8;
  const static int ySize = 8;
  
  int values[ySize][xSize];
  //int axisX[xSize];
  int axisX[8];
  int axisY[8];
  //static boolean useInterp = false; //Whether or not interpolation should be used (Assuming we have enough CPU for it)
  
};

/*
Tables have an origin (0,0) in the top left hand corner. Vertical axis is expressed first.
Eg: 2x2 table
-----
|2 7|
|1 4|
-----

(0,1) = 7
(0,0) = 2
(1,0) = 1

*/

//This function pulls a value from a table given a target for X and Y coordinates.
//It performs a 2D linear interpolation as descibred in: http://www.megamanual.com/v22manual/ve_tuner.pdf
int getTableValue(struct table fromTable, int Y, int X)
  {
    //Loop through the X axis bins for the min/max pair
    //Note: For the X axis specifically, rather than looping from tableAxisX[0] up to tableAxisX[max], we start at tableAxisX[Max] and go down. 
    //      This is because the important tables (fuel and injection) will have the highest RPM at the top of the X axis, so starting there will mean the best case occurs when the RPM is highest (And hence the CPU is needed most)
    int xMin = fromTable.axisX[0];
    int xMax = fromTable.axisX[fromTable.xSize-1];
    int xMinValue = 0;
    int xMaxValue = 0;    
    
    for (int x = fromTable.xSize-1; x > 0; x--)
    {
      if ( (X <= fromTable.axisX[x]) && (X >= fromTable.axisX[x-1]) )
      {
        xMaxValue = fromTable.axisX[x];
        xMinValue = fromTable.axisX[x-1];
        xMax = x;
        xMin = x-1;
        break;
      }   
    }
    
    //Loop through the Y axis bins for the min/max pair
    int yMin = fromTable.axisY[0];
    int yMax = fromTable.axisY[fromTable.ySize-1];
    int yMinValue = 0;
    int yMaxValue = 0;
    
    for (int y = fromTable.ySize-1; y > 0; y--)
    {
      if ( (Y >= fromTable.axisY[y]) && (Y <= fromTable.axisY[y-1]) )
      {
        
        yMaxValue = fromTable.axisY[y];
        yMinValue = fromTable.axisY[y-1];
        yMax = y;
        yMin = y-1;
        break;
      }   
    }
        
    
    /* 
    At this point we have the 4 corners of the map where the interpolated value will fall in
    Eg: (yMin,xMin)  (yMin,xMax)
    
        (yMax,xMin)  (yMax,xMax)
        
    In the following calculation the table values are referred to by the following variables:
              A          B
              
              C          D
    
    */
    int A = fromTable.values[yMin][xMin];
    int B = fromTable.values[yMin][xMax];
    int C = fromTable.values[yMax][xMin];
    int D = fromTable.values[yMax][xMax];
    
    //Create some normalised position values
    //These are essentially percentages (between 0 and 1) of where the desired value falls between the nearest bins on each axis
    float p = ((float)(X - xMinValue)) / (float)(xMaxValue - xMinValue);
    float q = ((float)(Y - yMaxValue)) / (float)(yMinValue - yMaxValue);
    
    float m = (1.0-p) * (1.0-q);
    float n = p * (1-q);
    float o = (1-p) * q;
    float r = p * q;
    
    
    return ( (A * m) + (B * n) + (C * o) + (D * r) ); 
  }
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: Arduino go kart EMS

Post by Fred »

You need to get rid of the floats ASAP, they're worthless on any small non-FPU CPU. If you were on the DUE, it'd be acceptable, but not on ours and not on yours.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
JareeB
QFP80 - Contributor
Posts: 42
Joined: Tue Dec 25, 2012 12:14 am
Location: Greenville, Wisconsin

Re: Arduino go kart EMS

Post by JareeB »

Thanks for the sample. I'm working on a basic ardunino ecu as well. (I know in that tread above I said it was junk. But I was only to referring(spelling lol) to it controling a car engine.) I think it can handle a small engine fine. Maybe not the uno but I'm sure the Mega is fine.
plans to build a 300whp turbo ford ranger with a 2.3l engine the ford lima!
current rig: 1994 ford ranger 2.3. good platform for my almost complete turbo engine. a237 cam, stock t3 turbo, ported and polished head. just needs some mangement!!
noisymime
DIP8 - Involved
Posts: 29
Joined: Wed Feb 06, 2013 4:12 am

Re: Arduino go kart EMS

Post by noisymime »

Fred wrote:You need to get rid of the floats ASAP, they're worthless on any small non-FPU CPU. If you were on the DUE, it'd be acceptable, but not on ours and not on yours.
I thought that would probably be the case, but haven't got far enough down the rabbit hole yet to figure out what the impact actually is. The one in the above is a pretty simple change thankfully and it's the only place I've resorted to them so far. Once I've got the hardware side sorted, which will hopefully happen over the next 3-4 weeks, I'll be in a better position to see what's actually working and what's not. I'm also waiting on a stim to help in the testing.
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: Arduino go kart EMS

Post by Fred »

It's not a big deal, you just need to pick a fixed point format inside an integer type, and then cast up to the larger type during multiplies/adds, and down again on divides/subtracts, etc. 32 bit math is also slow on 16 bit cores, but no where NEAR as bad as floats.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
Post Reply