deviant
Join Date: Oct 2016
Location: Seattle, WA
Posts: 69
Thanks: 12
Thanked 47 Times in 35 Posts
|
Updated JSON function
Here is the updated JSON function, in zip form and in CODE block
Code:
void doOutputJSON(void) //skybolt added json output function
{
digitalWrite(LED_BUILTIN, LOW);
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
uint64_t instFuelEcon;
uint64_t tankFuelEcon;
uint64_t tankFuelEcon53;
//if->then using timerChecker allows for changing the subtitle to show multiple lines of information
uint32_t timerChecker = cycles0(); //wastes 20 bytes but ensures all lines will change on the same cycle
unsigned long reserveQuantity = SWEET64(prgmReserveFuelRemaining, 0);
#ifdef usePartialRefuel
unsigned long tankSize = eepromReadVal(pTankSizeIdx) + eepromReadVal(pRefuelSizeIdx);
#else // usePartialRefuel
unsigned long tankSize = eepromReadVal(pTankSizeIdx);
#endif // usePartialRefuel
text::stringOut(devLogSerial, PSTR("\n\n[")); // begin JSON payload
// first graph, fuel
text::stringOut(devLogSerial, PSTR("{\"title\":\""));
if (reserveQuantity == 0) text::stringOut(devLogSerial, PSTR("fumes remaining, ")); // fumes left
else doOutputNumberJSON(prgmReserveFuelRemaining, 0, 3, PSTR(" \xfbgal\xfcL\xfd remaining, ")); // reserve remaining fuel left
doOutputNumberJSON(prgmBingoFuelRemaining, 0, 3, PSTR(" \xfbgal\xfcL\xfd e-reserve\",\n")); // bingo remaining fuel left
// doOutputNumberJSON(instantIdx, tEngineSpeed, 0, PSTR(" RPM\",\n")); // rpm to test latency only vs tachometer and LCD vs raspi indicator (expect 2x looptime)
if ( (timerChecker / 100) % 8000 > 4000 ) {
text::stringOut(devLogSerial, PSTR("\"subtitle\":\"fuel used: "));
doOutputNumberJSON(currentIdx, tFuelUsed, 3, PSTR(" trip \xfbgal\xfcL\xfd; ")); // current trip fuel used
doOutputNumberJSON(tankIdx, tFuelUsed, 3, PSTR(" tank \xfbgal\xfcL\xfd; ")); // tank trip fuel used
doOutputNumberJSON(instantIdx, tFuelRate, 3, PSTR(" using \xfbgal\xfcL\xfd/hr\",\n")); // current rate of fuel burn in units/time
} else {
text::stringOut(devLogSerial, PSTR("\"subtitle\":\"eco stats: "));
#ifdef trackIdleEOCdata
doOutputNumberJSON(eocIdleTankIdx, tFuelUsed, 3, PSTR(" \xfbgal\xfcL\xfd used@idle, "));
doOutputNumberJSON(eocIdleTankIdx, tDistance, 1, PSTR(" \xfbmi\xfckm\xfd fuel cut\",\n"));
#else
if (reserveQuantity == 0) text::stringOut(devLogSerial, PSTR("fumes remaining, ")); // fumes left
else doOutputNumberJSON(prgmReserveFuelRemaining, 0, 3, PSTR(" \xfbgal\xfcL\xfd remaining, ")); // reserve remaining fuel left
doOutputNumberJSON(prgmBingoFuelRemaining, 0, 3, PSTR(" \xfbgal\xfcL\xfd e-reserve\",\n")); // bingo remaining fuel left
#endif
}
reserveQuantity = eepromReadVal(pTankBingoIdx);
text::stringOut(devLogSerial, PSTR("\"ranges\":[")); //ranges do not have to be in order, d3js libraries will auto sort, so you can make it easier to read the code by changing the order
doOutputNumberJSON(tankSize, 3, PSTR(",")); // largest, full tank size (e.g, 13.8 g)
doOutputNumberJSON(tankSize - reserveQuantity, 3, PSTR(",")); // full tank less reserve (e.g.13.8g - 2.2g = 11.6g)
doOutputNumberJSON(reserveQuantity, 3, PSTR("],\n")); // reserve amount (e.g. 2.2g)
text::stringOut(devLogSerial, PSTR("\"measures\":["));
doOutputNumberJSON(prgmReserveFuelRemaining, 0, 3, PSTR(",")); // reserve remaining fuel left
doOutputNumberJSON(prgmRemainingFuel, 0, 3, PSTR("],\n")); // total remaining fuel left
text::stringOut(devLogSerial, PSTR("\"markers\":["));
doOutputNumberJSON(instantIdx, tFuelRate, 3, PSTR("]},\n\n")); // current rate of fuel burn in units/time
// second graph, distance
text::stringOut(devLogSerial, PSTR("{\"title\":\""));
doOutputNumberJSON(prgmReserveDTE, tankIdx, 2, PSTR("\xfbmi\xfckm\xfd to e, ")); // distance to bingo
doOutputNumberJSON(prgmBingoDTE, tankIdx, 2, PSTR(" \xfbmi\xfckm\xfd e-reserve\",\n")); // distance to fully empty tank from bingo
if ( (timerChecker / 100) % 8000 > 4000 ) {
// text::stringOut(devLogSerial, PSTR("\"subtitle\":\"trip/tank distance: "));
// doOutputNumberJSON(currentIdx, tDistance, 2, PSTR(" \xfbmi\xfckm\xfd/")); // current trip distance
// doOutputNumberJSON(tankIdx, tDistance, 2, PSTR(" \xfbmi\xfckm\xfd\",\n")); // current trip distance
text::stringOut(devLogSerial, PSTR("\"subtitle\":\""));
doOutputNumberJSON(currentIdx, tDistance, 2, PSTR(" \xfbmi\xfckm\xfd trip distance, ")); // current trip distance
doOutputNumberJSON(tankIdx, tDistance, 2, PSTR(" \xfbmi\xfckm\xfd tank distance\",\n")); // current trip distance
} else {
text::stringOut(devLogSerial, PSTR("\"subtitle\":\""));
doOutputNumberJSON(prgmFindReserveRange, tankIdx, 2, PSTR(" \xfbmi\xfckm\xfd safe range, ")); // reserve range
doOutputNumberJSON(prgmFindRange, tankIdx, 2, PSTR(" \xfbmi\xfckm\xfd dry range\",\n")); // distance to fully empty tank
}
text::stringOut(devLogSerial, PSTR("\"ranges\":["));
doOutputNumberJSON(prgmFindRange, tankIdx, 1, PSTR(",")); // maximum range
doOutputNumberJSON(prgmFindReserveRange, tankIdx, 1, PSTR(",")); // range 2, safe range
doOutputNumberJSON(prgmFindHalfReserveRange, tankIdx, 1, PSTR("],\n")); // range 3, half of safe range
text::stringOut(devLogSerial, PSTR("\"measures\":["));
doOutputNumberJSON(prgmFindBingoRange, tankIdx, 2, PSTR("],\n")); // shows miles of e-reserve in bar form
text::stringOut(devLogSerial, PSTR("\"markers\":["));
doOutputNumberJSON(tankIdx, tDistanceToEmpty, 2, PSTR("]},\n\n")); // line is distance to empty
// third graph, econ
text::stringOut(devLogSerial, PSTR("{\"title\":\"")); //\xfbgal\xfcL\xfd/
#ifdef useDragRaceFunction
// text::stringOut(devLogSerial, PSTR("("));
// doOutputNumberJSON(lastAccelTestStatus, 3, PSTR(") "));
// doOutputNumberJSON(msInstantIdx, tSpeed, 3, PSTR(" ")); // current fuel economy
// if (accelerationFlags & accelTestTriggered) { //display if we are waiting for a drag start
// there was a bug in some of the drag cancel logic when using Adafruit. I disabled some statements
// to get it to work. (Was tripping at 0.718 or 0.0718 seconds (don't remember exact digits)
//some kind of bit mask; full and half-speed seem to be backwards (0 means tripped)
//unclear on syntax for building if/then statements
//accelerationFlags & accelTestTriggered
// 120, waiting
// 184, testing.
// 176, distance met.
// 160, distance and half-speed met. (Full speed then meets all conditions, test ends)
// 168 half-speed met. (not distance)
// 136 full-speed met. (Meeting distance then meets all three conditions, race ends).
// what the hell is 156? Did this actually come up?
// lastAccelTestStatus = 120; //use to force trigger
if (lastAccelTestStatus == 120) { //display if we are waiting for a drag start
text::stringOut(devLogSerial, PSTR("Drag Ready ...\",\n"));
//did these in reverse order when i was checking for bits, with numbers order is irrelevant
} else if (lastAccelTestStatus == 136) { //display once test started //too hard to reverse engineer and/or/contains | &, from numeric tests. Numbers work fine.
text::stringOut(devLogSerial, PSTR("Full speed reached ...\",\n"));
} else if (lastAccelTestStatus == 168) { //display at half speed
text::stringOut(devLogSerial, PSTR("Half-speed reached ...\",\n"));
} else if (lastAccelTestStatus == 176) { //display at half speed
text::stringOut(devLogSerial, PSTR("Distance reached ...\",\n"));
} else if (lastAccelTestStatus == 184) { //display once test started
text::stringOut(devLogSerial, PSTR("Testing ...\",\n"));
} else if ( lastAccelTestStatus == 160) { //display once test started
text::stringOut(devLogSerial, PSTR("Half-speed and distance reached ...\",\n"));
} else { //else not racing or waiting, go to normal
text::stringOut(devLogSerial, PSTR("trip/tank/inst: ")); //\xfbgal\xfcL\xfd/
doOutputNumberJSON(currentIdx, tFuelEcon, 3, PSTR("/ ")); // current fuel economy
doOutputNumberJSON(tankIdx, tFuelEcon, 3, PSTR("/ ")); // tank fuel economy
reserveQuantity = doCalculate(instantIdx, tFuelEcon);
if (reserveQuantity > 9999999) text::stringOut(devLogSerial, PSTR("infinite\",\n"));
else doOutputNumberJSON(instantIdx, tFuelEcon, 3, PSTR("\",\n")); // instantaneous fuel economy
}
if ( ( ((timerChecker / 100) % 12000) > 8000) ) {
//1 & 2 seconds display
text::stringOut(devLogSerial, PSTR("\"subtitle\":\"accel time: 0-"));
doOutputNumberJSON(eepromReadVal(pDragSpeedIdx) / 2, 0, PSTR("/"));
doOutputNumberJSON(eepromReadVal(pDragSpeedIdx), 0, PSTR(": "));
doOutputNumberJSON(dragHalfSpeedIdx, tAccelTestTime, 2, PSTR("/")); // 0-30 time
doOutputNumberJSON(dragFullSpeedIdx, tAccelTestTime, 2, PSTR(", ")); // 0-60 time
doOutputNumberJSON(dragDistanceIdx, tDistance * 1, 2, PSTR("\xfbmi\xfckm\xfd in ")); // trap distance
doOutputNumberJSON(dragDistanceIdx, tAccelTestTime, 2, PSTR(" @")); // trap time
doOutputNumberJSON(dragDistanceIdx, tSpeed, 3, PSTR("\xfbmph\xfckph\xfd; ")); // trap speed
doOutputNumberJSON(dragHalfSpeedIdx, tEstimatedEnginePower, 0, PSTR("\xfbhp\xfckW\xfd @")); // estimated engine power
doOutputNumberJSON(dragHalfSpeedIdx, tDragSpeed, 0, PSTR("\xfbmph\xfckph\xfd\",\n")); // max speed
} else {
//"subtitle":"accel fuel: 0.000 (0.00mpg) to 15, 0.000 (0.00mpg) to 30; 0.000 (0.000) to 0",
text::stringOut(devLogSerial, PSTR("\"subtitle\":\"accel fuel: "));
// this dumps the flag values to the screen
// text::stringOut(devLogSerial, PSTR("("));
// doOutputNumberJSON(lastAccelTestStatus, 3, PSTR(" "));
// text::stringOut(devLogSerial, PSTR(" "));
// doOutputNumberJSON(accelTestActive, 3, PSTR(" ")); //0.128
// text::stringOut(devLogSerial, PSTR(" "));
// doOutputNumberJSON(accelTestTriggered, 3, PSTR(" ")); //0.064
// text::stringOut(devLogSerial, PSTR(" "));
// doOutputNumberJSON(accelTestFullSpeed, 3, PSTR(" ")); //0.032
// text::stringOut(devLogSerial, PSTR(" "));
// doOutputNumberJSON(accelTestHalfSpeed, 3, PSTR(" ")); //0.016
// text::stringOut(devLogSerial, PSTR(" "));
// doOutputNumberJSON(accelTestDistance, 3, PSTR(" ")); //0.008
// text::stringOut(devLogSerial, PSTR(" "));
// doOutputNumberJSON(accelTestCancelled, 3, PSTR(" ")); //0.004
// text::stringOut(devLogSerial, PSTR(" "));
// doOutputNumberJSON(accelTestFinished, 3, PSTR(") ")); //0.002
if ( ( ((timerChecker / 100) % 12000) > 4000) ) {
doOutputNumberJSON(dragHalfSpeedIdx, tFuelUsed, 3, PSTR("\xfbga\xfcL\xfd to ")); // 0-half fuel
doOutputNumberJSON(eepromReadVal(pDragSpeedIdx) / 2, 0, PSTR(", ")); // 0-half speed
doOutputNumberJSON(dragFullSpeedIdx, tFuelUsed, 3, PSTR("\xfbga\xfcL\xfd to ")); // 0-full fuel
doOutputNumberJSON(eepromReadVal(pDragSpeedIdx), 0, PSTR(", ")); // 0-full speed
doOutputNumberJSON(dragDistanceIdx, tFuelUsed, 3, PSTR("\xfbga\xfcL\xfd to ")); //trap fuel
doOutputNumberJSON(dragDistanceIdx, tDistance * 1, 2, PSTR("\xfbmi\xfckm\xfd\",\n")); // "to [trap distance]" \xfbft\xfcm\xfd;
} else {
doOutputNumberJSON(dragHalfSpeedIdx, tFuelEcon, 3, PSTR("\xfbmpg\xfcL100\xfd to ")); // 0-30 mpg
doOutputNumberJSON(eepromReadVal(pDragSpeedIdx) / 2, 0, PSTR(", ")); // 0-half speed
doOutputNumberJSON(dragFullSpeedIdx, tFuelEcon, 3, PSTR("\xfbmpg\xfcL100\xfd to ")); // 0-60 mpg
doOutputNumberJSON(eepromReadVal(pDragSpeedIdx), 0, PSTR(", ")); // 0-60 speed
doOutputNumberJSON(dragDistanceIdx, tFuelEcon, 3, PSTR("\xfbmpg\xfcL100\xfd to ")); //trap mpg
doOutputNumberJSON(dragDistanceIdx, tDistance * 1, 2, PSTR("\xfbmi\xfckm\xfd\",\n")); // "to [trap distance]" \xfbft\xfcm\xfd;
}
}
#else
text::stringOut(devLogSerial, PSTR("\"subtitle\":\"[this space intentionally left blank]\",\n"));
#endif
text::stringOut(devLogSerial, PSTR("\"ranges\":[18,24,"));
// text::stringOut(devLogSerial, PSTR("\"ranges\":["));
// doOutputNumberJSON(2 * fuelEconomyFIRvalue / 3, 3, PSTR(",")); // 2/3 averaged instantaneous fuel economy over time
// doOutputNumberJSON(fuelEconomyFIRvalue, 3, PSTR(",")); // averaged instantaneous fuel economy over time
doOutputNumberJSON(
min(
max(40000, doCalculate(instantIdx, tFuelEcon))
, 999000),
3, PSTR("],\n")); // set scale at 40mpg or instant econ up to 999 mpg. Folks like to watch their mpg meter go to extremes
text::stringOut(devLogSerial, PSTR("\"measures\":["));
doOutputNumberJSON(currentIdx, tFuelEcon, 3, PSTR(",")); // current fuel economy
doOutputNumberJSON(tankIdx, tFuelEcon, 3, PSTR("],\n")); // tank fuel economy
text::stringOut(devLogSerial, PSTR("\"markers\":["));
doOutputNumberJSON(
min(
999000, //do not let scale exceed 999
doCalculate(instantIdx, tFuelEcon))
// instantIdx, tFuelEcon
, 3
, PSTR("]")); // instantaneous fuel economy
// doOutputNumberJSON(5 * fuelEconomyFIRvalue / 3, 3, PSTR("]\xfd")); // 5/3 averaged instantaneous fuel economy over time
// text::stringOut(devLogSerial, PSTR("\}]\r")); // end JSON payload, and go trigger read on python.script
text::stringOut(devLogSerial, PSTR("\}]\n")); // end JSON payload, and go trigger read on python.script
text::stringOut(devLogSerial, PSTR("\r"));
} //end sendJson function
|