From e6ac35b49a45a22716987cf5c04ef0e60b7160be Mon Sep 17 00:00:00 2001 From: Stanley Huang Date: Sat, 15 Nov 2014 00:01:43 +1100 Subject: Improve Mega Logger --- megalogger/datalogger.h | 2 - megalogger/megalogger.ino | 320 ++++++++++++++++++++++++++-------------------- 2 files changed, 178 insertions(+), 144 deletions(-) (limited to 'megalogger') diff --git a/megalogger/datalogger.h b/megalogger/datalogger.h index 95f688a..e7342ed 100644 --- a/megalogger/datalogger.h +++ b/megalogger/datalogger.h @@ -42,8 +42,6 @@ typedef struct { #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) SoftwareSerial SerialBLE(A8, A9); /* for BLE Shield on MEGA*/ -#elif defined(__AVR_ATmega644P__) - SoftwareSerial SerialBLE(9, 10); /* for Microduino */ #else SoftwareSerial SerialBLE(A2, A3); /* for BLE Shield on UNO/leonardo*/ #endif diff --git a/megalogger/megalogger.ino b/megalogger/megalogger.ino index 34d7840..4e7e5e8 100644 --- a/megalogger/megalogger.ino +++ b/megalogger/megalogger.ino @@ -54,6 +54,7 @@ static uint32_t distance = 0; static uint32_t startTime = 0; static uint16_t lastSpeed = 0; static uint32_t lastSpeedTime = 0; +static int gpsSpeed = -1; static byte pidTier1[]= {PID_RPM, PID_SPEED, PID_ENGINE_LOAD, PID_THROTTLE}; static byte pidTier2[] = {PID_INTAKE_MAP, PID_MAF_FLOW, PID_TIMING_ADVANCE}; @@ -99,7 +100,7 @@ void setColorByValue(int value, int threshold1, int threshold2, int threshold3) } } -void showSensorData(byte pid, int value) +void showPIDData(byte pid, int value) { char buf[8]; switch (pid) { @@ -111,33 +112,61 @@ void showSensorData(byte pid, int value) lcd.printInt(value, 4); break; case PID_SPEED: - lcd.setFontSize(FONT_SIZE_XLARGE); - lcd.setCursor(50, 2); - if (value > 350) break; - setColorByValue(value, 50, 80, 160); - lcd.printInt((unsigned int)value % 1000, 3); - break; - case PID_THROTTLE: - lcd.setFontSize(FONT_SIZE_SMALL); - lcd.setCursor(38, 10); - if (value >= 100) value = 99; - setColorByValue(value, 50, 75, 90); - lcd.printInt(value, 2); + if (value < 1000) { + lcd.setFontSize(FONT_SIZE_XLARGE); + lcd.setCursor(50, 2); + setColorByValue(value, 60, 100, 160); + lcd.printInt(value, 3); + + if (gpsSpeed != -1) { + lcd.setFontSize(FONT_SIZE_SMALL); + lcd.setCursor(110, 2); + lcd.setColor(RGB16_YELLOW); + int diff = gpsSpeed - value; + if (diff >= 0) { + lcd.write('+'); + lcd.printInt(diff); + } else { + lcd.write('-'); + lcd.printInt(-diff); + } + lcd.write(' '); + } + } break; case PID_ENGINE_LOAD: - lcd.setFontSize(FONT_SIZE_SMALL); - lcd.setCursor(108, 10); + lcd.setFontSize(FONT_SIZE_XLARGE); + lcd.setCursor(50, 10); if (value >= 100) value = 99; - setColorByValue(value, 50, 75, 90); - lcd.printInt(value, 2); + setColorByValue(value, 75, 80, 100); + lcd.printInt(value, 3); + break; + case PID_THROTTLE: + lcd.setFontSize(FONT_SIZE_MEDIUM); + lcd.setCursor(80, 21); + if (value > 100) value = 100; + setColorByValue(value, 50, 75, 100); + lcd.printInt(value, 3); break; case PID_ENGINE_FUEL_RATE: if (value < 1000) { - lcd.setFontSize(FONT_SIZE_SMALL); - lcd.setCursor(38, 12); - lcd.printInt(value); + lcd.setFontSize(FONT_SIZE_MEDIUM); + lcd.setCursor(80, 24); + lcd.printInt(value, 3); } break; + case PID_INTAKE_TEMP: + lcd.setFontSize(FONT_SIZE_MEDIUM); + lcd.setCursor(80, 27); + lcd.printInt(value, 3); + break; + case PID_VOLTAGE: + lcd.setFontSize(FONT_SIZE_MEDIUM); + lcd.setCursor(72, 18); + lcd.printInt(value / 10, 2); + lcd.write('.'); + lcd.printInt(value % 10); + break; } lcd.setColor(RGB16_WHITE); } @@ -157,55 +186,54 @@ void initScreen() lcd.setFontSize(FONT_SIZE_SMALL); lcd.setCursor(110, 4); lcd.print("km/h"); - lcd.setCursor(110, 7); - lcd.print("rpm"); - lcd.setCursor(8, 10); - lcd.print("THR: %"); - lcd.setCursor(78, 10); - lcd.print("LOAD: %"); - lcd.setCursor(8, 12); - lcd.print("FUEL: L/h"); - lcd.setCursor(78, 12); - lcd.print("BATT: V"); + lcd.setCursor(110, 8); + lcd.print("RPM"); + lcd.setCursor(110, 11); + lcd.print("ENGINE"); + lcd.setCursor(110, 12); + lcd.print("LOAD %"); //lcd.setFont(FONT_SIZE_MEDIUM); lcd.setColor(RGB16_CYAN); - lcd.setCursor(185, 2); + lcd.setCursor(184, 2); lcd.print("ELAPSED:"); - lcd.setCursor(185, 5); - lcd.print("DISTANCE:"); - lcd.setCursor(185, 6); - lcd.print("(km)"); - lcd.setCursor(185, 8); - lcd.print("AVG SPEED:"); - lcd.setCursor(185, 9); - lcd.print("(km/h)"); - lcd.setCursor(185, 11); - lcd.print("OBD TIME:"); - lcd.setCursor(185, 12); - lcd.print("(ms)"); - - lcd.setCursor(20, 18); + lcd.setCursor(184, 5); + lcd.print("DISTANCE: km"); + lcd.setCursor(184, 8); + lcd.print("AVG SPEED: kph"); + lcd.setCursor(184, 11); + lcd.print("ALTITUDE: m"); + + lcd.setCursor(18, 18); + lcd.print("BATTERY: V"); + lcd.setCursor(18, 21); + lcd.print("THROTTLE: %"); + lcd.setCursor(18, 24); + lcd.print("FUEL RATE: L/h"); + lcd.setCursor(18, 27); + lcd.print("INTAKE: C"); + + lcd.setCursor(184, 18); lcd.print("LAT:"); - lcd.setCursor(20, 21); - lcd.print("LON:"); - lcd.setCursor(20, 24); - lcd.print("ALT:"); - lcd.setCursor(20, 27); + lcd.setCursor(280, 18); lcd.print("SAT:"); + lcd.setCursor(184, 19); + lcd.print("LON:"); lcd.setFontSize(FONT_SIZE_SMALL); - lcd.setCursor(204, 18); - lcd.print("ACCELEROMETER"); - lcd.setCursor(214, 22); - lcd.print("GYROSCOPE"); - lcd.setCursor(185, 27); + lcd.setCursor(184, 21); + lcd.print("ACC:"); + lcd.setCursor(184, 22); + lcd.print("GYR:"); + + lcd.setCursor(184, 24); + lcd.print("OBD FREQ:"); + + lcd.setCursor(184, 25); + lcd.print("GPS FREQ:"); + + lcd.setCursor(184, 26); lcd.print("LOG SIZE:"); - lcd.setCursor(185, 20); - lcd.setColor(RGB16_WHITE); - lcd.print("X: Y: Z:"); - lcd.setCursor(185, 24); - lcd.print("X: Y: Z:"); //lcd.setColor(0xFFFF); /* @@ -254,7 +282,7 @@ bool checkSD() lcd.setCursor(0, 4); lcd.setFontSize(FONT_SIZE_MEDIUM); - if (card.init(SPI_FULL_SPEED, SD_CS_PIN)) { + if (card.init(SPI_HALF_SPEED, SD_CS_PIN)) { const char* type; switch(card.type()) { case SD_CARD_TYPE_SD1: @@ -317,39 +345,56 @@ void processGPS() logger.dataTime = millis(); gps.get_datetime(&date, &time, 0); - logger.logData(PID_GPS_TIME, (int32_t)time); - int kph = gps.speed() * 1852 / 100000; - logger.logData(PID_GPS_SPEED, kph); + gpsSpeed = gps.speed() * 1852 / 100000; + + int32_t lat, lon; + gps.get_position(&lat, &lon, 0); - // no need to log GPS data when vehicle has not been moving - // that's when previous speed is zero and current speed is also zero byte sat = gps.satellites(); - if (sat >= 3 && sat < 100) { - int32_t lat, lon; - gps.get_position(&lat, &lon, 0); + // skip bad data + if (sat > 100) return; + + // show GPS data interval + lcd.setFontSize(FONT_SIZE_SMALL); + if (lastGPSDataTime) { + lcd.setCursor(242, 25); + lcd.printInt((uint16_t)logger.dataTime - lastGPSDataTime); + lcd.print("ms "); + } + + + lastGPSDataTime = logger.dataTime; + + // display GPS data + char buf[16]; + sprintf(buf, "%d.%ld", (int)(lat / 100000), abs(lat) % 100000); + lcd.setCursor(214, 18); + lcd.print(buf); + sprintf(buf, "%d.%ld", (int)(lon / 100000), abs(lon) % 100000); + lcd.setCursor(214, 19); + lcd.print(buf); + lcd.setCursor(280, 19); + lcd.printInt(gps.satellites()); + lcd.write(' '); + + int32_t alt = gps.altitude(); + if (alt < 1000000) { + lcd.setFontSize(FONT_SIZE_MEDIUM); + lcd.setCursor(250, 11); + lcd.printInt(alt / 100); + lcd.write(' '); + } + + // only log GPS data when satellite status is good + if (sat >= 3) { + logger.logData(PID_GPS_TIME, (int32_t)time); + logger.logData(PID_GPS_SPEED, gpsSpeed); logger.logData(PID_GPS_LATITUDE, lat); logger.logData(PID_GPS_LONGITUDE, lon); logger.logData(PID_GPS_ALTITUDE, (int)(gps.altitude() / 100)); - - lcd.setFontSize(FONT_SIZE_MEDIUM); - char buf[16]; - sprintf(buf, "%d.%ld", (int)(lat / 100000), abs(lat) % 100000); - lcd.setCursor(50, 18); - lcd.print(buf); - sprintf(buf, "%d.%ld", (int)(lon / 100000), abs(lon) % 100000); - lcd.setCursor(50, 21); - lcd.print(buf); - int32_t alt = gps.altitude(); - if (alt < 1000000) { - sprintf(buf, "%dm ", (int)(alt / 100)); - lcd.setCursor(50, 24); - lcd.print(buf); - } - lcd.setCursor(50, 27); - lcd.printInt(gps.satellites()); } - lastGPSDataTime = logger.dataTime; + } #endif @@ -375,29 +420,27 @@ void processAccelerometer() data.value.y_gyro /= GYRO_DATA_RATIO; data.value.z_gyro /= GYRO_DATA_RATIO; - sprintf(buf, "%3d", data.value.x_accel); + // display acc data + lcd.setCursor(214, 21); setColorByValue(data.value.x_accel, 50, 100, 200); - lcd.setCursor(197, 20); - lcd.print(buf); - sprintf(buf, "%3d", data.value.y_accel); + lcd.print(data.value.x_accel); setColorByValue(data.value.y_accel, 50, 100, 200); - lcd.setCursor(239, 20); - lcd.print(buf); - sprintf(buf, "%3d", data.value.z_accel); + lcd.write('/'); + lcd.print(data.value.y_accel); setColorByValue(data.value.z_accel, 50, 100, 200); - lcd.setCursor(281, 20); - lcd.print(buf); + lcd.write('/'); + lcd.print(data.value.z_accel); + lcd.printSpace(8); + // display gyro data + lcd.setCursor(214, 22); lcd.setColor(RGB16_WHITE); - sprintf(buf, "%3d ", data.value.x_gyro); - lcd.setCursor(197, 24); - lcd.print(buf); - sprintf(buf, "%3d ", data.value.y_gyro); - lcd.setCursor(239, 24); - lcd.print(buf); - sprintf(buf, "%3d ", data.value.z_gyro); - lcd.setCursor(281, 24); - lcd.print(buf); + lcd.print(data.value.x_gyro); + lcd.write('/'); + lcd.print(data.value.y_gyro); + lcd.write('/'); + lcd.print(data.value.z_gyro); + lcd.printSpace(8); // log x/y/z of accelerometer logger.logData(PID_ACC, data.value.x_accel, data.value.y_accel, data.value.z_accel); @@ -416,6 +459,7 @@ void logOBDData(byte pid) // send query for OBD-II PID obd->sendQuery(pid); + // let PID parsed from response pid = 0; // read responded PID and data if (!obd->getResult(pid, value)) { @@ -424,26 +468,25 @@ void logOBDData(byte pid) logger.dataTime = millis(); // display data - showSensorData(pid, value); + showPIDData(pid, value); // log data to SD card logger.logData(0x100 | pid, value); if (pid == PID_SPEED) { - if (lastSpeedTime) { - // estimate distance travelled since last speed update - distance += (uint32_t)(value + lastSpeed) * (logger.dataTime - lastSpeedTime) / 2 / 3600; - // display speed - lcd.setFontSize(FONT_SIZE_MEDIUM); - lcd.setCursor(250, 5); - lcd.printInt(distance / 1000); - lcd.write('.'); - lcd.printInt(((uint16_t)distance % 1000) / 100); - // calculate and display average speed - int avgSpeed = (unsigned long)distance * 1000 / (millis() - startTime) * 36 / 10; - lcd.setCursor(250, 8); - lcd.printInt(avgSpeed); - } + // estimate distance travelled since last speed update + distance += (uint32_t)(value + lastSpeed) * (logger.dataTime - lastSpeedTime) / 5760; + // display speed + lcd.setFontSize(FONT_SIZE_MEDIUM); + lcd.setCursor(250, 5); + lcd.printInt(distance / 1000); + lcd.write('.'); + lcd.printInt(((uint16_t)distance % 1000) / 100); + // calculate and display average speed + int avgSpeed = (unsigned long)distance * 3600 / (millis() - startTime); + lcd.setCursor(250, 8); + lcd.printInt(avgSpeed); + lastSpeed = value; lastSpeedTime = logger.dataTime; } @@ -453,7 +496,7 @@ void logOBDData(byte pid) logger.flushFile(); // display logged data size lcd.setFontSize(FONT_SIZE_SMALL); - lcd.setCursor(242, 27); + lcd.setCursor(242, 26); lcd.print((unsigned int)(logger.dataSize >> 10)); lcd.print("KB"); lastFileSize = logger.dataSize >> 10; @@ -478,7 +521,7 @@ void showECUCap() for (byte i = 0; i < sizeof(pidlist) / sizeof(pidlist[0]); i += 2) { lcd.setCursor(184, i + 4); for (byte j = 0; j < 2; j++) { - lcd.print(" "); + lcd.printSpace(2); lcd.print((int)pidlist[i + j] | 0x100, HEX); bool valid = obd->isValidPID(pidlist[i + j]); if (valid) { @@ -486,7 +529,7 @@ void showECUCap() lcd.draw(tick, 16, 16); lcd.setColor(RGB16_WHITE); } else { - lcd.print(" "); + lcd.printSpace(2); } } } @@ -518,7 +561,8 @@ void reconnect() // re-initialize state |= STATE_OBD_READY; startTime = millis(); - lastSpeedTime = 0; + lastSpeedTime = startTime; + lastSpeed = 0; distance = 0; #if ENABLE_DATA_LOG logger.openFile(); @@ -574,16 +618,6 @@ void doIdleTasks() processGPS(); } #endif - - if (obd->getState() != OBD_CONNECTED) { - // display while initializing - char buf[10]; - unsigned int t = (millis() - startTime) / 1000; - sprintf(buf, "%02u:%02u", t / 60, t % 60); - lcd.setFontSize(FONT_SIZE_SMALL); - lcd.setCursor(0, 28); - lcd.print(buf); - } } void setup() @@ -591,7 +625,7 @@ void setup() lcd.begin(); lcd.setFontSize(FONT_SIZE_MEDIUM); lcd.setColor(0xFFE0); - lcd.print("MEGA LOGGER - OBD-II/GPS/G-FORCE"); + lcd.print("MEGA LOGGER - OBD-II/GPS/MEMS"); lcd.setColor(RGB16_WHITE); Wire.begin(); @@ -667,6 +701,7 @@ void setup() initScreen(); startTime = millis(); + lastSpeedTime = startTime; lastRefreshTime = millis(); } @@ -690,11 +725,7 @@ void loop() index3 = (index3 + 1) % TIER_NUM3; if (index3 == 0) { int v = obd->getVoltage(); - lcd.setFontSize(FONT_SIZE_SMALL); - lcd.setCursor(108, 12); - lcd.printInt(v / 10); - lcd.write('.'); - lcd.printInt(v % 10); + showPIDData(PID_VOLTAGE, v); logger.logData(PID_VOLTAGE, v); } } else { @@ -707,14 +738,19 @@ void loop() if (logger.dataTime - lastRefreshTime >= 1000) { char buf[12]; + // display elapsed time unsigned int sec = (logger.dataTime - startTime) / 1000; sprintf(buf, "%02u:%02u", sec / 60, sec % 60); lcd.setFontSize(FONT_SIZE_MEDIUM); lcd.setCursor(250, 2); lcd.print(buf); - lcd.setCursor(250, 11); + // display OBD time if (t < 10000) { - lcd.printInt((uint16_t)t); + lcd.setFontSize(FONT_SIZE_SMALL); + lcd.setCursor(242, 24); + lcd.printInt((uint16_t)t); + lcd.print("ms"); + lcd.printSpace(2); } lastRefreshTime = logger.dataTime; } -- cgit v1.2.3