02-08-2017, 10:58 AM
|
#81 (permalink)
|
MPGuino Supporter
Join Date: Oct 2010
Location: Hungary
Posts: 1,807
iNXS - '10 Opel Zafira 111 Anniversary Suzi - '02 Suzuki Swift GL
Thanks: 830
Thanked 708 Times in 456 Posts
|
Quote:
Originally Posted by skybolt
The following is based on:
Code:
const char overFlowStr[] PROGMEM = "999999";
Code:
reserveQuantity = doCalculate(instantIdx, tFuelEcon); //instant fuel economy
if (doCalculate(instantIdx, tFuelEcon) > 999999) {
text::stringOut(devLogSerial, PSTR("999999\",\n")); //infinte fuel economy, good for overflow and reasonable for anything above 999,999 (current overflow is 4,294,967.295 or (2^32)-1), check decimals is 999999 999.999 vs 999999.000?
} else {
doOutputNumberJSON(reserveQuantity, 3, PSTR("\",\n")); // instantaneous fuel economy
}
|
I modified the formatDecimal() routine a little, to replace the overflow dashes with a string of '9's, if the calling routine specifies this in the procedure call. Now, doOutputJSON() and doOutputDataLog() both use this modification, and everything else still uses dashes.
Quote:
Originally Posted by skybolt
Code:
doOutputNumberJSON(2 * doCalculate(tankIdx, tFuelEcon) / 3, 3, PSTR(",")); // 2/3 tank fuel economy
doOutputNumberJSON(3 * doCalculate(tankIdx, tFuelEcon) / 3, 3, PSTR(",")); // tank fuel economy, helps user differentiate current trip measure vs tank measure, with goal to keep current measure and instant marker above tank range
doOutputNumberJSON(5 * doCalculate(tankIdx, tFuelEcon) / 3, 3, PSTR("],\n")); // 5/3 tank fuel economy
text::stringOut(devLogSerial, PSTR("\"measures\":["));
// min comparison keeps measure bars from extending past range, even if values in text are shown larger than range
doOutputNumberJSON(min(doCalculate(currentIdx, tFuelEcon),5 * doCalculate(tankIdx, tFuelEcon) / 3), 3, PSTR(",")); //return lower of current trip mpg or range high bound
doOutputNumberJSON(min(doCalculate(tankIdx, tFuelEcon),5 * doCalculate(tankIdx, tFuelEcon) / 3), 3, PSTR("],\n")); //return lower of tank mpg or range high bound
text::stringOut(devLogSerial, PSTR("\"markers\":["));
//min compare keeps white marker from extending past range
doOutputNumberJSON(min(doCalculate(instantIdx, tFuelEcon),(5 * doCalculate(tankIdx, tFuelEcon)) / 3), 3, PSTR("]\xfd")); //
|
This certainly works, but the purist in me doesn't like it. min() has to calculate both terms first, then make the comparison. While SWEET64 is much faster now, than when we first tackled doOutputJSON() back in November, it's still kind of a computation hog. Let me chew on this a bit - I might come up with a SWEET64 solution that does this thing.
|
|
|
Today
|
|
|
Other popular topics in this forum...
|
|
|
02-08-2017, 01:18 PM
|
#82 (permalink)
|
MPGuino Supporter
Join Date: Oct 2010
Location: Hungary
Posts: 1,807
iNXS - '10 Opel Zafira 111 Anniversary Suzi - '02 Suzuki Swift GL
Thanks: 830
Thanked 708 Times in 456 Posts
|
Quote:
Originally Posted by skybolt
So, ... if I understand correctly, injector size and pressure must be for fuel use by pure calculation rather than tuning by observation, trial and error. I've noticed that changing # of cylinders alters the uSec saved value, but this doesn't extend to injector size, injector delay and fuel pressure. If I modify injector size and fuel pressure, shouldn't it change the saved value in uSec? Perhaps it has and I haven't noticed. If I have injectors set to 1, and change uSec to value N, and leave injector size at 246, should I expect to have it change fuel pressure to reflect the change in uSec? If so, your calculations must get a bit ... involved. Perhaps changing injector size/pressure overwrites uSec but manually setting uSec in essence overrides size/pressure?
|
Meant to explain what is going on here, but my computer died while I was composing the explanation, and I forgot to get back until now.
Ys, injector size and fuel pressure are meant for calculation purposes. They're meant to get you to the ballpark. Fine-tuning still requires manually fiddling with the usec/gallon and injector delay values.
I tested the code with changing both the fuel pressure and the injector size, and the usec/gallon figure changed. The thing is, you're going to have to do a major change in fuel pressure to see any difference, because the code uses the square root of the fraction difference between the reference and system fuel pressures.
The calculation only goes one way for now. Directly changing the usec/gallon figure does not change either system fuel pressure or the injector size. Hm... It easily could, though, at least with regard to injector size.
I am working on adding matrix math into the code. Once that happens, I can implement a much better way to calculate the usec/gallon and injector delay values, that does not require knowledge of system fuel pressure nor injector sizes. It will not only get you into the ballpark, but it will place you at third base with the batter hitting a home run.
|
|
|
The Following User Says Thank You to t vago For This Useful Post:
|
|
02-16-2017, 09:34 PM
|
#83 (permalink)
|
deviant
Join Date: Oct 2016
Location: Seattle, WA
Posts: 69
Thanks: 12
Thanked 47 Times in 35 Posts
|
I'm impressed by the sheer amount of optimization you did in the 02/08 release. That kind of optimization isn't cheap.
The 02/16 build is working well in the car, including the drag stats. Right now I'm chasing something in the odometer -- I think the in-car odometer rounds up to the nearest tenth, with a resolution of a hundredth. I'll know more once the trip mileage hits 1000 and I show the exact number of ticks (by setting ticks-per-mile to 100). I believe 1 mile was 8196, 10 miles was 8199, and I did a ghetto calculation at 160.1 miles that matched when I set the ticks to 8201. Rounding is the only reason I can think of why the odometer wouldn't match the Arduino exactly I did notice it when the Arduino reported x.996 as the mileage when the odometer changed, but by going to 1000 miles I can measure quite precisely, and I can expose any rounding done by the odometer by shifting all the digits to the left.
My speed sensor should trigger a tick every 5.7 inches, and the duino has a resolution of 5.28 feet. I've noticed the speed sensor won't trigger at under about 0.5 mph, but even in that case the odometer and arduino should match since both are simply counting speed ticks.
Last edited by skybolt; 02-17-2017 at 02:21 PM..
|
|
|
02-22-2017, 02:14 PM
|
#84 (permalink)
|
MPGuino Supporter
Join Date: Oct 2010
Location: Hungary
Posts: 1,807
iNXS - '10 Opel Zafira 111 Anniversary Suzi - '02 Suzuki Swift GL
Thanks: 830
Thanked 708 Times in 456 Posts
|
Quote:
Originally Posted by skybolt
I'm impressed by the sheer amount of optimization you did in the 02/08 release. That kind of optimization isn't cheap.
|
Thank you! That's high praise indeed.
Quote:
Originally Posted by skybolt
The 02/16 build is working well in the car, including the drag stats. Right now I'm chasing something in the odometer -- I think the in-car odometer rounds up to the nearest tenth, with a resolution of a hundredth. I'll know more once the trip mileage hits 1000 and I show the exact number of ticks (by setting ticks-per-mile to 100). I believe 1 mile was 8196, 10 miles was 8199, and I did a ghetto calculation at 160.1 miles that matched when I set the ticks to 8201. Rounding is the only reason I can think of why the odometer wouldn't match the Arduino exactly I did notice it when the Arduino reported x.996 as the mileage when the odometer changed, but by going to 1000 miles I can measure quite precisely, and I can expose any rounding done by the odometer by shifting all the digits to the left.
My speed sensor should trigger a tick every 5.7 inches, and the duino has a resolution of 5.28 feet. I've noticed the speed sensor won't trigger at under about 0.5 mph, but even in that case the odometer and arduino should match since both are simply counting speed ticks.
|
I am thinking that the rationality checks I built into the VSS input capture code, way back when, might be interfering with the MPGuino's ability to measure small distances. I never figured that MPGuino would be used to do this sort of fine measurement.
Come to think of it, I'm not even sure that the VSS needs rationality checks. It's nowhere near as complicated a signal as the fuel injector signal.
|
|
|
02-22-2017, 03:29 PM
|
#85 (permalink)
|
deviant
Join Date: Oct 2016
Location: Seattle, WA
Posts: 69
Thanks: 12
Thanked 47 Times in 35 Posts
|
Quote:
I never figured that MPGuino would be used to do this sort of fine measurement.
|
Well, then now is a good time as any to roll out this potato: I need your routine to calculate mileage down to the ten-thousandth, which will result in resolution of about a foot. (In my car, technically, 6.7 inches, which is actually good to display to the foot; based, sort of, on the 2x sampling principle).
Why? Not sure -- but it had its genesis in me measuring how far apart the monorail support poles are in downtown Seattle. I think they are 60 feet. Once you start looking at short distances in the car you'll be shocked how hard it is for humans to estimate linear distance in a car, while vertical distance remains easy. This is true even while stopped, but I'm sure it's a psychological by-product of driving.
I view an odometer as a threshold event, one that should never round. I'm open to being convinced otherwise, but the math is simple enough: number - (number % .000x) x being the digits to be thrown away and not used for rounding.
Once I can call numbers down to the .0001, I can easily add math that does this:
miles - (miles % .01) * (milesIdx * 5280) = (a number between 0 and 53, inclusive). Then I can render miles as 52.25 miles, 48 feet. At 53 feet (well, 52), then it'd be 52.26 miles, 0 feet. I suppose 52.259 miles and 0-5 feet, but you get the idea. I'll also fool around with 52 miles, 1368 feet, but that'll probably not be pleasing to look at.
Also, I know from experience it's not as pleasant to render feet above certain speeds, primarily due to movement of the output based on single vs. double digit feet, but also it's patently ridiculous to want feet or centimeters at highway speeds. Again, easy for me to code using if/then.
That said, a quick question: Are conditional if/then statements computationally efficient?
Meters can use .0001 and that's a perfectly human way to view centimeters. Or we leave them at 001 and show meters. cm and inches both would jump since .0001 < ticks / milesIdx, but that's OK.
Last edited by skybolt; 02-25-2017 at 02:00 AM..
Reason: grammar, symbol
|
|
|
The Following User Says Thank You to skybolt For This Useful Post:
|
|
03-01-2017, 02:38 AM
|
#86 (permalink)
|
MPGuino Supporter
Join Date: Oct 2010
Location: Hungary
Posts: 1,807
iNXS - '10 Opel Zafira 111 Anniversary Suzi - '02 Suzuki Swift GL
Thanks: 830
Thanked 708 Times in 456 Posts
|
Quote:
Originally Posted by skybolt
Well, then now is a good time as any to roll out this potato: I need your routine to calculate mileage down to the ten-thousandth, which will result in resolution of about a foot. (In my car, technically, 6.7 inches, which is actually good to display to the foot; based, sort of, on the 2x sampling principle).
|
I've been tossing around this potato in my head for the past week. I think I may have come up with a solution - it's based on how my code currently handles metric vs. SAE measurements. Been kind of busy lately, though, so can't give you a definitive date as to when it will be available.
Along with coding this, going to also strip out the validation checks on the VSS signal. I really can't see any point to having them there. Debouncing should work just fine for slower mechanical VSS generators, and more recent solid-state generators don't need debounce anyhow.
Quote:
Originally Posted by skybolt
That said, a quick question: Are conditional if/then statements computationally efficient?
|
Inasmuch as a conditional does not actually calculate anything, then no, they're not computationally efficient. However, conditionals are indispensable to computing, so there is that to consider.
There are different structures that conditionals may take, which tend to minimize the required overhead. Jump tables tend to be the most efficient, because the conditional has been boiled down to an index that can be used to pull an address from said jump table. Jump tables tend to be the most flexible, too, because you can assign a certain action to be performed if the conditional variable reaches a certain value, and then perform another related action that would normally be called for if the conditional variable reached some other value. Jump tables are generated by C++'s switch/case/default statement blocks.
|
|
|
03-01-2017, 09:03 AM
|
#87 (permalink)
|
MPGuino Supporter
Join Date: Oct 2010
Location: Hungary
Posts: 1,807
iNXS - '10 Opel Zafira 111 Anniversary Suzi - '02 Suzuki Swift GL
Thanks: 830
Thanked 708 Times in 456 Posts
|
And for clarity, when I say "conditional," I mean
Code:
If (some comparison performed between value 1 and value 2 happens to be true) then
(do something)
else
(do something else)
end if
In C++, it's quite possible to stuff value 1 and/or value 2, with an assignment statement that contains a computation, within the if-then construct itself, like so:
Code:
if ((unsigned int a = 3 * b + c) == 4) doSomething;
It's certainly valid for C++, but it's frowned upon because it's not all that readable and can lead to very subtle bugs due to programmers mistakenly using "=" when they meant to type "==".
|
|
|
03-01-2017, 12:31 PM
|
#88 (permalink)
|
deviant
Join Date: Oct 2016
Location: Seattle, WA
Posts: 69
Thanks: 12
Thanked 47 Times in 35 Posts
|
That's precisely the kind of conditional I'm curious about -- I want to be able to change display output based on conditions, but after watching the memory footprint of this app get larger and larger, I want to do it in the most computationally efficient manner.
Is the following code (assume it's all inside a single function and variable zap isn't static or persistent:
Code:
int zap = (calculationToGetZap(parameter) );
if (zap > 50) {
doBigThing();
}
else if (zap > 100) {
doBiggerThing();
}
else {
doTinyThing();
}
the same (in terms of memory allocation and other resource efficiency) as this:
Code:
if ((calculationToGetZap(parameter) > 50) {
doBigThing();
}
else if ((calculationToGetZap(parameter) > 100) {
doBiggerThing();
}
else {
doTinyThing();
}
|
|
|
06-14-2017, 06:22 PM
|
#89 (permalink)
|
deviant
Join Date: Oct 2016
Location: Seattle, WA
Posts: 69
Thanks: 12
Thanked 47 Times in 35 Posts
|
Most recent enhancements:
1. Can show multiple lines of text by changing values every N seconds
2. Show acceleration times, acceleration fuel used, and acceleration mpg/l
3. Rearranged tiles and subtitles based on importance of values shown
Not shown:
4. Show 'drag ready', 'testing', 'half-speed reached' etc. in 3rd row title.
|
|
|
The Following 2 Users Say Thank You to skybolt For This Useful Post:
|
|
|