Thanks for the info --- I'm going to take a deep look at SWEET64 to see how it works, and I'm looking forward to seeing your new/changed code.
In the meantime I'm able to determine tank size by adding tFuelUsed to tFuelRemaining ... after I better understand SWEET64 that might not be necessary, but I'll look into it anyway.
Keep in mind that when I calculate the 'graph' or 'bar size' all I am doing is passing an integer or float to the raspberry pi via json, all graphical routines are handled in javascript on the pi side.
I will post both repositories to GitHub, today, and will add more meaningful comments.
Ah... it's becoming clearer to me now.
I have started going through the doJsonOutput code. I added a flashTx function that sends flash-based strings to the serial output port. Cleaned up the exception checking for enabling both serial logging and Json output. Added an EEPROM parameter, bingo fuel, with a default value of 2.2 gallons, which will be as editable as the other EEPROM parameters.
Stay tuned...
Edit: I do not do GitHub, mainly because my worksite does not allow GitHub to be accessible any more. F'in dumb, I know.
The Following User Says Thank You to t vago For This Useful Post:
I have completed going through the code. I've made some modifications and clean-ups to the base code itself, and added some comments. Also coded some SWEET64 code for figuring out reserve and bingo fuel, distance to empty, and auto-ranging fuel economy graph output.
Going to test the modifications tonight, and hopefully will have something to report by tomorrow.
The Following User Says Thank You to t vago For This Useful Post:
I am finishing up the drag race functionality. Once that is done, I will test all and report back.
I also added a few more flexibility options for compiling the code, cleaned up the SWEET64 code, simplified a few more things, and added a lot more comments.
I'd have been happy to do the drag race code --- I'd have followed your syntax for the other functions ... once you have that done I'll make improvements to the drag function as follows:
1. rename to acceleration stats
2. Add second line to display (subtitle) to list fuel statistics for accel. This makes the drag useful to all users, as hypermilers will want to know how much fuel it takes them to reach cruising speed, or how much fuel to cover the first n feet/meters.
3. Update distance to show hundredths of miles in decimal format, then feet. Supress showing feet until n mph/kph
4. Update all json functions to be metric/imperial friendly.
5. Add serial config utility (I will hijack the LCD display routines to mirror that over serial, add a cursor designator so that 802576 with a blinking 2 on the LCD will appear as 80_2_576. This will allow serial config using the three main buttons.
This will take me some time, but will pay dividends in the long term. Also, I have new name for the project, it's obvious but it fits. "MPiGuino"
Question: is there a global call for metric/imperial designator? i.e., can I call "units" and have it return miles, mph vs km, kph. If this is obvious in the code I will find it.
The Following User Says Thank You to skybolt For This Useful Post:
I'd have been happy to do the drag race code --- I'd have followed your syntax for the other functions ... once you have that done I'll make improvements to the drag function as follows:
1. rename to acceleration stats
2. Add second line to display (subtitle) to list fuel statistics for accel. This makes the drag useful to all users, as hypermilers will want to know how much fuel it takes them to reach cruising speed, or how much fuel to cover the first n feet/meters.
3. Update distance to show hundredths of miles in decimal format, then feet. Supress showing feet until n mph/kph
4. Update all json functions to be metric/imperial friendly.
5. Add serial config utility (I will hijack the LCD display routines to mirror that over serial, add a cursor designator so that 802576 with a blinking 2 on the LCD will appear as 80_2_576. This will allow serial config using the three main buttons.
This will take me some time, but will pay dividends in the long term. Also, I have new name for the project, it's obvious but it fits. "MPiGuino"
Question: is there a global call for metric/imperial designator? i.e., can I call "units" and have it return miles, mph vs km, kph. If this is obvious in the code I will find it.
There's no global procedure call for "metric or US". Whenever the driver changes between US or Metric, the code goes through all of the EEPROM parameters that require conversion, and performs the necessary unit conversions. There's an accessible global flag that indicates whether US or metric mode is active, and there's a SWEET64 pseudoinstruction that branches on the state of this global flag. This is mainly used by the prgmFuelEconomy routine, since the US MPG and the metric L/100km are reciprocated.
I figure as long as people can recognize it as having roots with "MPGuino," then I would think that "MPiGuino" should work. The original MPGuino author hasn't been seen in many years now.
1. Yah, "Acceleration Stats" sounds better than "drag race" or "drag function."
2. I'll have to re-write #2 a little bit to measure fuel usage. I had repurposed the fuel measurement elements of the one trip variable set aside for acceleration measurement. Not a big deal, though.
3. Intriguing. I suspect you'll have to do something similar to what I had to do for autoranging the decimal point format function.
4. Has already been done, in a manner of speaking. The code fully supports metric/US measurements, including performing parameter conversions when metric or US measurements are selected.
5. Sounds very doable, but will take a lot of work.
So, here's the updated code. Haven't gotten the drag race functionality working fully yet. Be sure to configure the #defines to match your Arduino before compiling.
There is a chance that the LCD display may not work. Haven't gotten to test the LCD output with the code re-write.
A doOutputJSON serial speed of 38400 baud appears to keep the CPU loading at around 100%. Not a big deal, as all that really means is that the it'll take slightly over 1/2 a second to complete a display update loop, instead of under 1/2 a second. The injector and VSS measurements are not affected at all.
Do not try to swap between US and metric modes - something apparently broke that causes the code to hang when switching between modes is attempted.
Perhaps increasing the serial buffer size, in conjunction with disabling the LCD output, may drop the CPU loading to well under 100%. I may also look at trying to speed up the SWEET64 primitive operations.
Other code improvements center around making various low-level operations more memory efficient, improving readability of some configuration selections, and a good amount of commenting.
Thanks for posting the code! I was logging in to check just that ....
Regarding metric: it crashes while running --- but otherwise takes? So live data is lost .... I'm not really asking, I'll check the behavior ...
I'm fairly certain calling the LCD or writing the JSON output takes longer than any of the primary functions, but I haven't measured yet (it's fairly easy to measure using a quick millis() check) --- If I'm correct, then 38.4 should be plenty fast. Let me run a quick calculation:
json file is about 579 bytes, depending. 38.4bps is 4,800Bps, so about an 8th of a second or 125ms to send the payload. the javascript routines on the Pi are set for 100ms by default, adding a total delay from real-time to .225 per second.
Standard mpguino is .250 seconds ..... so I'd say we are well within operating parameters.
In order to accurately measure acceleration functions the standard loop delays needs to be suppressed. I will have more questions about how to deal with LCD delays ... but all in good time.
Also, I notice you support the tinkerkit LCD ... does the tinkerkit use fewer pins than the standard method of using 8 (+ 1 for contrast and 3 grounds) wires to connect to the LCD? Both Adafruit and Osepp have shields that claim to use 2 pins to connect to soft buttons and LCD. The soft buttons are irrelevant here but using 1 or 2 pins for LCD communication would make it very easy to attach an LCD for programming and detach it for a small footprint.
The Following User Says Thank You to skybolt For This Useful Post:
Regarding metric: it crashes while running --- but otherwise takes? So live data is lost .... I'm not really asking, I'll check the behavior ...
I solved the crashing behavior - it was affecting changing any parameter, not just metric mode. It was due to a bug in the post-parameter-saving display output initialization that I was able to provide a stable workaround for.
I did, however, find another bug that is specific to setting metric mode - the metric parameter conversion routine no longer seems to work at all. That is, distances are still given in miles and fuel quantities are still given in gallons, for instance, when metric mode is active. It's very strange.
Quote:
Originally Posted by skybolt
I'm fairly certain calling the LCD or writing the JSON output takes longer than any of the primary functions, but I haven't measured yet (it's fairly easy to measure using a quick millis() check) --- If I'm correct, then 38.4 should be plenty fast. Let me run a quick calculation:
json file is about 579 bytes, depending. 38.4bps is 4,800Bps, so about an 8th of a second or 125ms to send the payload. the javascript routines on the Pi are set for 100ms by default, adding a total delay from real-time to .225 per second.
No, the buffered LCD or JSON serial output actually provides fairly quick response. Rather, the nature of SWEET64 being a generalized pseudoprocessor for maximum flexibility, also makes it very slow.
Quote:
Originally Posted by skybolt
In order to accurately measure acceleration functions the standard loop delays needs to be suppressed. I will have more questions about how to deal with LCD delays ... but all in good time.
The loop delay ( ... delay(500); ... ) was something I got rid of, early on. It offended my tender sensibilities.
Delays are now handled by the primary timer, with a tick of about 1 ms. (I say "about" because a 20 MHz MPGuino actually has a 0.8125 ms tick, and the 16 MHz MPGuino has a 1.024 ms tick). The primary timer cycles down a counter from a preset value to generate a 500 ms wait (which is why processor speed is specified early on in the code). Once the counter goes to zero, the main timer sets a flag bit to signal the main loop to do its display update.
The main loop delay "routine" is now little more than the main loop staring at that flag bit that is set by the primary timer, performing its display updating when that flag sets, clearing that flag, and setting another flag to let the primary timer know it should perform another loop delay.
The accel test function uses a similar mechanism, except that 4 flag bits are used instead of just one. There's a target speed bit, target distance bit, an active bit, and a cancelled bit. This enables the code to sense if many separate conditions arise which would cause the accel test function to cancel, like if the vehicle engine were to stop, or if the vehicle speed dropped back down to zero.
Quote:
Originally Posted by skybolt
Also, I notice you support the tinkerkit LCD ... does the tinkerkit use fewer pins than the standard method of using 8 (+ 1 for contrast and 3 grounds) wires to connect to the LCD? Both Adafruit and Osepp have shields that claim to use 2 pins to connect to soft buttons and LCD. The soft buttons are irrelevant here but using 1 or 2 pins for LCD communication would make it very easy to attach an LCD for programming and detach it for a small footprint.
Yah, the code is able to turn a Tinkerkit LCD module into a standalone MPGuino. It just needs a few components to interface to the VSS and the fuel injector signals, and a few more components for the switches. Internally, the Tinkerkit LCD module uses the same LCD hookup as the legacy MPGuino (4 bits, plus one for contrast and one for brightness). It uses different pins, though, and my code does not yet support the USB functionality of the Tinkerkit LCD module. I don't think the Tinkerkit LCD module has a serial port, but I remember that it does have an I2C bus.
I am currently using a Arduino Mega2560 as the test platform, which has two serial output ports. One port is being used by a Parallax serial LCD module which uses the serial tx pin, and the other is being used by the JSON output routine. Here's a three-year old video showing the setup.
Found the metric conversion bug - when I re-wrote the conversion routine, forgot to change the denominator from loading into register 3, to loading into register 1. It works now. Derp.
Modified the 64-bit left-shift and right-shift routines, and gained a 31% speed improvement, but at the cost of adding 200 bytes to the compiled output code. This is important because the 64-bit division routine performs about 100 shifts on average, for each division operation (depending on the bit patterns of both the numerator and denominator).
Substantially re-wrote the 64-bit multiplication routine. It now takes up 300 more bytes, but also nets about a 6% speed improvement. Also experimented with substantially re-writing the 64-bit addition routine, and while it netted about a 1% speed improvement, it also added 400 bytes. So, the 64-bit shift routine modifications stay, the 64-bit multiplication improvement stays, but the addition modification goes away.
Might look at re-writing the 64-bit integer to string output formatting routine, because each formatted number currently requires four 64-bit divisions, and the JSON output routine alone outputs at least 32 separate numbers.