11-10-2009, 01:55 PM
|
#21 (permalink)
|
EcoModding Lurker
Join Date: Feb 2009
Location: Ontario, Canada
Posts: 35
Thanks: 2
Thanked 14 Times in 7 Posts
|
I understand the original developer used the integer math routines, instead of the math.h library, because the library plus his code was too large for the 186. With more memory, this optimization is not necessary. Using the math.h functions will make it easier to modify or extend the program, or discover errors in calculations.
However floating point math takes longer than integer math to execute, which is the main reason embedded developers avoid it ... but I wouldn't think that would be a big issue in this application. Another thing to experiment with ...
|
|
|
Today
|
|
|
Other popular topics in this forum...
|
|
|
11-10-2009, 02:36 PM
|
#22 (permalink)
|
EcoModding Lurker
Join Date: Oct 2009
Location: Austria
Posts: 28
Thanks: 0
Thanked 1 Time in 1 Post
|
I have no good experience with float variables in other projects especialy when it comes to big numbers. I didn't check it, but I think there was a reason to choose unsigned long. This goes up to 4,294,967,295. In float this becomes to 4.2949672E9, so we loose the last 2 digits. That may impact acuraty if there are realy numbers larger then 1E7.
As I understand the code, if its faster it's also more precise because of time for interrupts and so on? (See change to 20MHz crystal)
But it may be an option
|
|
|
11-10-2009, 03:39 PM
|
#23 (permalink)
|
EcoModding Lurker
Join Date: Feb 2009
Location: Ontario, Canada
Posts: 35
Thanks: 2
Thanked 14 Times in 7 Posts
|
Floating Point
I would never use floating point calculations in an interrupt service routine - in this case, it is just incrementing counters or subtracting integers to get pulse widths, anyway.
The CPU percentage is around 50%, so it should be quite safe to throw in floating point calculations for the twice-per-second display updates.
I have an accelerometer project with lots of floating point, it works fine.
I haven't found any floating point benchmarks for the Arduino, it will be interesting to try and quantify the difference between FP and integer math operations.
|
|
|
11-11-2009, 05:12 AM
|
#24 (permalink)
|
EcoModding Lurker
Join Date: Oct 2009
Location: Austria
Posts: 28
Thanks: 0
Thanked 1 Time in 1 Post
|
Quote:
Originally Posted by mluckham
I found bugs in my original post (.77m) thought it would be nice to post a corrected version. If I should be posting in some other manner, I welcome your suggestion please.
|
I like the idea with built-in calibration method so I copied some lines from yours. I think I found the mentioned bug, but I also have another suggestion for you.
Your code:
Code:
parms[calibrationDistanceIdx] = tank.distance(); // distance x 1000, for updating parms[vssPulsesPerDistanceUnitIdx]
parms[calibrationFuelIdx] = tank.fuel(); // fuel x 1000, for updating parms[microSecondsPerFuelUnitIdx]
initGuino(); // edit parms[] array
// if distance or fuel values are different from tank, recalculate VSS and INJECTOR parameters
if (parms[calibrationDistanceIdx] != tank.distance())
parms[vssPulsesPerDistanceUnitIdx] = recalculate(missing_parms[]_BugvssPulsesPerDistanceUnitIdx, tank.distance(), parms[calibrationDistanceIdx]);
if (parms[calibrationFuelIdx] != tank.fuel())
parms[microSecondsPerFuelUnitIdx] = recalculate(parms[microSecondsPerFuelUnitIdx], tank.fuel(), parms[calibrationFuelIdx]);
My one:
Code:
unsigned long tmptankdistance = tank.distance();
unsigned long tmptankfuel = tank.fuel();
parms[calibrationDistanceIdx] = tmptankdistance; // distance x 1000, for updating parms[vssPulsesPerDistanceUnitIdx]
parms[calibrationFuelIdx] = tmptankfuel; // fuel x 1000, for updating parms[microSecondsPerFuelUnitIdx]
initGuino();
// if distance or fuel values are different from tank, recalculate VSS and INJECTOR parameters
if (parms[calibrationDistanceIdx] != tmptankdistance)
parms[vssPulsesPerDistanceUnitIdx] = calibrate(parms[vssPulsesPerDistanceUnitIdx], tmptankdistance, parms[calibrationDistanceIdx]);
if (parms[calibrationFuelIdx] != tmptankfuel)
parms[microSecondsPerFuelUnitIdx] = calibrate(parms[microSecondsPerFuelUnitIdx], tmptankfuel, parms[calibrationFuelIdx]);
I would recommend to save tank.distance() and tank.fuel() into variables first. On the one hand, you save recaculate them 3 more times. On the other hand, doing not so could lead to unexpected behavior like wrong vssPulsesPerDistanceUnit also if you don't change the values in setup menue.
Simply think at a situation, where you go into setup menue while engine is running or you are still driving.
parms[calibrationFuelIdx] != tank.fuel() will always be true, because tank.fuel() increased since last capture
|
|
|
11-11-2009, 09:58 AM
|
#25 (permalink)
|
EcoModding Lurker
Join Date: Feb 2009
Location: Ontario, Canada
Posts: 35
Thanks: 2
Thanked 14 Times in 7 Posts
|
Thanks very much, I'll test it. I made an additional change, to save the calculated values:
Quote:
// set values for math-less calibration method
unsigned long tmptankdistance = tank.distance(); // take a snapshot, in case update occurs during the updates
unsigned long tmptankfuel = tank.fuel();
int tmpdirty = 0;
parms[calibrationDistanceIdx] = tmptankdistance; // distance x 1000, for updating parms[vssPulsesPerDistanceUnitIdx]
parms[calibrationFuelIdx] = tmptankfuel; // fuel x 1000, for updating parms[microSecondsPerFuelUnitIdx]
initGuino(); // edit parms[] array
// math-less calibration method:
// if user has altered distance or fuel values to be different from tank, recalculate VSS and INJECTOR parameters
if (parms[calibrationDistanceIdx] != tmptankdistance)
{
parms[vssPulsesPerDistanceUnitIdx] = recalculate(parms[vssPulsesPerDistanceUnitIdx], tmptankdistance, parms[calibrationDistanceIdx]);
tmpdirty = 1;
}
if (parms[calibrationFuelIdx] != tmptankfuel)
{
parms[microSecondsPerFuelUnitIdx] = recalculate(parms[microSecondsPerFuelUnitIdx], tmptankfuel, parms[calibrationFuelIdx]);
tmpdirty = 1;
}
if (tmpdirty)
save(); // save recalculated settings
|
Last edited by mluckham; 11-11-2009 at 10:16 AM..
Reason: added code snippet
|
|
|
11-11-2009, 05:00 PM
|
#26 (permalink)
|
EcoModding Lurker
Join Date: Feb 2009
Location: Ontario, Canada
Posts: 35
Thanks: 2
Thanked 14 Times in 7 Posts
|
Metric Version 0.80m
Thanks for inspiring me to fix up these problems, all the outstanding issues appear to be fixed now - including the alternate "math-less" method of calibrating fuel and distance.
I also changed the Current and Tank L/100KM displays to alternate metric and US MPG equivalent. Now I can throw away the little chart clipped to my sun visor
|
|
|
The Following 7 Users Say Thank You to mluckham For This Useful Post:
|
|
12-03-2009, 07:38 AM
|
#27 (permalink)
|
My way is the low way
Join Date: Jun 2009
Location: Finland
Posts: 64
Thanks: 4
Thanked 17 Times in 8 Posts
|
Thanks to everybody, who has beem developing this product.
I have used my arduino based mpguino now for 327km and still need some fine tuning with the calibration, but I think I'm quite close already.
I was really surprised about the ecodistance (distance without injection) and the fuel used at idle.
Ecodistance = 17,1 km
Idle Fuel = 2,6 Litres
Have I really gone 17,1 km without any use of fuel? I've always thought that the engine braking does'nt make much difference.
Have I really spend 2,6 litres just idleing at traffic lights? Maybe the Start-stop automatic in the new cars is not so bad thing afterall
One small improvement to the mpguino I would like to have though,
My instant L/100km reading is not steady. On the highway at steady speed it's showing 5,70...6,10...6,30...4,90...5,80...6,30...5,10 L/100km.
Is this normal? How about others? are your instant readings steady?
Would it be possible to have some averaging on the instant reading? Maybe take samples of every 2 seconds and display average from that?
I have studied the code already quite much, but I still don't have the skills to do the averaging stuff.
|
|
|
12-03-2009, 10:31 AM
|
#28 (permalink)
|
EcoModding Lurker
Join Date: Feb 2009
Location: Ontario, Canada
Posts: 35
Thanks: 2
Thanked 14 Times in 7 Posts
|
Quote:
Originally Posted by Superturnier
My instant L/100km reading is not steady. On the highway at steady speed it's showing 5,70...6,10...6,30...4,90...5,80...6,30...5,10 L/100km.
Is this normal? How about others? are your instant readings steady?
Would it be possible to have some averaging on the instant reading? Maybe take samples of every 2 seconds and display average from that?
|
It's normal on mine (5-speed manual). The load on the engine is constantly changing - every little hill and dip in the road, wind change, twitchy accelerator foot - produces a reaction.
I've been thinking of adding a new configuration parameter so the update rate is a user-configurable number of seconds.
|
|
|
12-03-2009, 10:52 AM
|
#29 (permalink)
|
My way is the low way
Join Date: Jun 2009
Location: Finland
Posts: 64
Thanks: 4
Thanked 17 Times in 8 Posts
|
Thank you for your reply.
Glad to hear it's normal. Then my wiring is propably ok.
I was thinking that the variation on the readings is caused by the closed loop operation of the efi. The mixture is constantly changing between lean and rich, as the oxygen sensor gives feedback signal.
That user-configurable update rate would be nice. I mean it would great if it could collect the data for few seconds and calculate the average from that data. Not just update the display at lower rate.
|
|
|
07-26-2010, 10:53 PM
|
#30 (permalink)
|
EcoModding Lurker
Join Date: Apr 2010
Location: Calgary, Canada
Posts: 12
Thanks: 0
Thanked 0 Times in 0 Posts
|
Wow, all the code is over my head - but I sure want one of those Canadian litres and kilometers MPGuino!
Is there one available from the original developer yet? I had heard that they were working on it. I'd buy one tomorrow if it is metric.
|
|
|
|