From 1b6cfad76c5057c2a70c3038ae88ca9e3882488f Mon Sep 17 00:00:00 2001 From: Stanley Huang Date: Tue, 18 Aug 2015 10:24:37 +1000 Subject: Reference code for cycling data logger --- bikelogger/bikelogger.ino | 9 +- bikelogger/config.h | 39 +++++++ bikelogger/datalogger.h | 201 ++++++++++++++++++++++++++++++++ gpslogger/datalogger.h | 288 +++++++++++----------------------------------- 4 files changed, 312 insertions(+), 225 deletions(-) create mode 100644 bikelogger/config.h create mode 100644 bikelogger/datalogger.h diff --git a/bikelogger/bikelogger.ino b/bikelogger/bikelogger.ino index db92865..b864cda 100644 --- a/bikelogger/bikelogger.ino +++ b/bikelogger/bikelogger.ino @@ -1,5 +1,7 @@ /************************************************************************* -* A prototype for cycling data logger (based on GPS and MEMS) +* Reference code for cycling data logger (based on GPS and MEMS) +* Works with Freematics OBD-II Telematics Advanced Kit +* Visit http://freematics.com for more information * Distributed under GPL v2.0 * Written by Stanley Huang *************************************************************************/ @@ -84,7 +86,7 @@ void processGPS() uint32_t date; gps.get_datetime(&date, &time, 0); - logger.logData(PID_GPS_TIME, time, date); + logger.logData(PID_GPS_TIME, (int32_t)time); speed = (int)(gps.speed() * 1852 / 100); if (speed < 1000) speed = 0; @@ -103,7 +105,8 @@ void processGPS() gps.get_position(&lat, &lon, 0); curLat = (float)lat / 100000; curLon = (float)lon / 100000; - logger.logData(PID_GPS_COORDINATES, curLat, curLon); + logger.logData(PID_GPS_LATITUDE, lat); + logger.logData(PID_GPS_LONGITUDE, lon); if (logger.dataTime - lastTime >= 3000 && speed > 0) { if (lastLat == 0) lastLat = lat; diff --git a/bikelogger/config.h b/bikelogger/config.h new file mode 100644 index 0000000..ee7abba --- /dev/null +++ b/bikelogger/config.h @@ -0,0 +1,39 @@ +#ifndef CONFIG_H_INCLUDED +#define CONFIG_H_INCLUDED + +/************************************** +* Data logging/streaming out +**************************************/ +#define ENABLE_DATA_OUT 1 +#define ENABLE_DATA_LOG 1 +#define USE_SOFTSERIAL 0 +//this defines the format of log file +#define LOG_FORMAT FORMAT_CSV +#define STREAM_FORMAT FORMAT_CSV +#define STREAM_BAUDRATE 115200 + +/************************************** +* Choose SD pin here +**************************************/ +#define SD_CS_PIN SS // generic +//#define SD_CS_PIN 4 // ethernet shield +//#define SD_CS_PIN 7 // microduino +//#define SD_CS_PIN 10 // SD breakout + +/************************************** +* Choose LCD model here +**************************************/ +LCD_SSD1289 lcd; +//LCD_ILI9341 lcd; +//LCD_Null lcd; + +/************************************** +* Other options +**************************************/ +#define USE_MPU6050 0 +#define GPS_BAUDRATE 38400 +#define GPS_DATA_TIMEOUT 2000 /* ms */ +//#define DEBUG Serial +#define DEBUG_BAUDRATE 9600 + +#endif // CONFIG_H_INCLUDED diff --git a/bikelogger/datalogger.h b/bikelogger/datalogger.h new file mode 100644 index 0000000..2a58bf3 --- /dev/null +++ b/bikelogger/datalogger.h @@ -0,0 +1,201 @@ +/************************************************************************* +* Arduino Data Logger Class +* Distributed under GPL v2.0 +* Copyright (c) 2013-2014 Stanley Huang +* All rights reserved. +* Visit http://freematics.com for more information +*************************************************************************/ + +#define FORMAT_BIN 0 +#define FORMAT_CSV 1 + +typedef struct { + uint32_t time; + uint16_t pid; + uint8_t flags; + uint8_t checksum; + float value[3]; +} LOG_DATA_COMM; + +#define HEADER_LEN 128 /* bytes */ + +#define PID_GPS_LATITUDE 0xA +#define PID_GPS_LONGITUDE 0xB +#define PID_GPS_ALTITUDE 0xC +#define PID_GPS_SPEED 0xD +#define PID_GPS_HEADING 0xE +#define PID_GPS_SAT_COUNT 0xF +#define PID_GPS_TIME 0x10 +#define PID_GPS_DATE 0x11 + +#define PID_ACC 0x20 +#define PID_GYRO 0x21 +#define PID_COMPASS 0x22 +#define PID_MEMS_TEMP 0x23 +#define PID_BATTERY_VOLTAGE 0x24 + +#define FILE_NAME_FORMAT "/DAT%05d.CSV" + +#if ENABLE_DATA_OUT + +#if USE_SOFTSERIAL + +#if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) + SoftwareSerial SerialBLE(A8, A9); /* for BLE Shield on MEGA*/ +#else + SoftwareSerial SerialBLE(A2, A3); /* for BLE Shield on UNO/leonardo*/ +#endif + +#else + +#define SerialBLE Serial3 + +#endif + +#endif + +#if ENABLE_DATA_LOG +static File sdfile; +#endif + +static const char* idstr = "FREEMATICS\r"; + +class CDataLogger { +public: + void initSender() + { +#if ENABLE_DATA_OUT + SerialBLE.begin(STREAM_BAUDRATE); + SerialBLE.print(idstr); +#endif +#if ENABLE_DATA_LOG + m_lastDataTime = 0; +#endif + } + void logTimeElapsed() + { +#if ENABLE_DATA_LOG + dataSize += sdfile.print(dataTime - m_lastDataTime); + sdfile.write(','); + dataSize++; + m_lastDataTime = dataTime; +#endif + } + void logData(char c) + { +#if ENABLE_DATA_OUT && STREAM_FORMAT == FORMAT_CSV + SerialBLE.write(c); +#endif +#if ENABLE_DATA_LOG + if (c >= ' ') { + sdfile.write(c); + dataSize++; + } +#endif + } + void logData(uint16_t pid, int value) + { + char buf[16]; + byte n = sprintf(buf, "%X,%d\r", pid, value); +#if ENABLE_DATA_OUT +#if STREAM_FORMAT == FORMAT_BIN + LOG_DATA_COMM ld = {dataTime, pid, 1, 0, value}; + ld.checksum = getChecksum((char*)&ld, 12); + SerialBLE.write((uint8_t*)&ld, 12); +#else + SerialBLE.write((uint8_t*)buf, n); +#endif +#endif +#if ENABLE_DATA_LOG + logTimeElapsed(); + dataSize += sdfile.write((uint8_t*)buf, n); +#endif + } + void logData(uint16_t pid, int32_t value) + { + char buf[20]; + byte n = sprintf(buf, "%X,%ld\r", pid, value); +#if ENABLE_DATA_OUT +#if STREAM_FORMAT == FORMAT_BIN + LOG_DATA_COMM ld = {dataTime, pid, 1, 0, value}; + ld.checksum = getChecksum((char*)&ld, 12); + SerialBLE.write((uint8_t*)&ld, 12); +#else + SerialBLE.write((uint8_t*)buf, n); +#endif +#endif +#if ENABLE_DATA_LOG + logTimeElapsed(); + dataSize += sdfile.write((uint8_t*)buf, n); +#endif + } + void logData(uint16_t pid, int value1, int value2, int value3) + { + char buf[24]; + byte n = sprintf(buf, "%X,%d,%d,%d\r", pid, value1, value2, value3); +#if ENABLE_DATA_OUT +#if STREAM_FORMAT == FORMAT_BIN + LOG_DATA_COMM ld = {dataTime, pid, 3, 0, {value1, value2, value3}}; + ld.checksum = getChecksum((char*)&ld, 20); + SerialBLE.write((uint8_t*)&ld, 20); +#else + SerialBLE.write((uint8_t*)buf, n); +#endif +#endif +#if ENABLE_DATA_LOG + logTimeElapsed(); + dataSize += sdfile.write((uint8_t*)buf, n); +#endif + } +#if ENABLE_DATA_LOG + uint16_t openFile(uint16_t logFlags = 0, uint32_t dateTime = 0) + { + uint16_t fileIndex; + char filename[24] = "/FRMATICS"; + + dataSize = 0; + if (SD.exists(filename)) { + for (fileIndex = 1; fileIndex; fileIndex++) { + sprintf(filename + 9, FILE_NAME_FORMAT, fileIndex); + if (!SD.exists(filename)) { + break; + } + } + if (fileIndex == 0) + return 0; + } else { + SD.mkdir(filename); + fileIndex = 1; + sprintf(filename + 9, FILE_NAME_FORMAT, 1); + } + + sdfile = SD.open(filename, FILE_WRITE); + if (!sdfile) { + return 0; + } + return fileIndex; + } + void closeFile() + { + sdfile.close(); + } + void flushFile() + { + sdfile.flush(); + } +#endif + uint32_t dataTime; + uint32_t dataSize; +private: + byte getChecksum(char* buffer, byte len) + { + uint8_t checksum = 0; + for (byte i = 0; i < len; i++) { + checksum ^= buffer[i]; + } + return checksum; + } +#if ENABLE_DATA_LOG + uint32_t m_lastDataTime; +#endif +}; diff --git a/gpslogger/datalogger.h b/gpslogger/datalogger.h index 8eb9421..2a58bf3 100644 --- a/gpslogger/datalogger.h +++ b/gpslogger/datalogger.h @@ -1,14 +1,14 @@ +/************************************************************************* +* Arduino Data Logger Class +* Distributed under GPL v2.0 +* Copyright (c) 2013-2014 Stanley Huang +* All rights reserved. +* Visit http://freematics.com for more information +*************************************************************************/ + #define FORMAT_BIN 0 #define FORMAT_CSV 1 -typedef struct { - uint32_t time; - uint16_t pid; - uint8_t flags; - uint8_t checksum; - float value; -} LOG_DATA; - typedef struct { uint32_t time; uint16_t pid; @@ -17,57 +17,24 @@ typedef struct { float value[3]; } LOG_DATA_COMM; -typedef struct { - uint32_t time; /* e.g. 1307281259 */ - uint16_t pid; - uint8_t message; - uint8_t checksum; - uint16_t fileIndex; - uint16_t fileSize; /* KB */ - uint16_t logFlags; - uint8_t logType; - uint8_t data[5]; -} LOG_DATA_FILE_INFO; - -typedef struct { - uint32_t time; - uint16_t pid; - uint8_t message; - uint8_t checksum; - uint8_t data[12]; -} LOG_DATA_COMMAND; - -typedef struct { - uint32_t id; - uint32_t dataOffset; - uint8_t ver; - uint8_t logType; - uint16_t flags; - uint32_t dateTime; //4, YYMMDDHHMM, e.g. 1305291359 - /* - uint8_t devid[8]; - uint8_t vin[24]; - uint8_t unused[84]; - */ -} HEADER; - #define HEADER_LEN 128 /* bytes */ -#define PID_GPS_COORDINATES 0xF00A -#define PID_GPS_ALTITUDE 0xF00C -#define PID_GPS_SPEED 0xF00D -#define PID_GPS_HEADING 0xF00E -#define PID_GPS_SAT_COUNT 0xF00F -#define PID_GPS_TIME 0xF010 +#define PID_GPS_LATITUDE 0xA +#define PID_GPS_LONGITUDE 0xB +#define PID_GPS_ALTITUDE 0xC +#define PID_GPS_SPEED 0xD +#define PID_GPS_HEADING 0xE +#define PID_GPS_SAT_COUNT 0xF +#define PID_GPS_TIME 0x10 +#define PID_GPS_DATE 0x11 + +#define PID_ACC 0x20 +#define PID_GYRO 0x21 +#define PID_COMPASS 0x22 +#define PID_MEMS_TEMP 0x23 +#define PID_BATTERY_VOLTAGE 0x24 -#define PID_ACC 0xF020 -#define PID_GYRO 0xF021 - -#if LOG_FORMAT == FORMAT_BIN -#define FILE_NAME_FORMAT "/DAT%05d.LOG" -#else #define FILE_NAME_FORMAT "/DAT%05d.CSV" -#endif #if ENABLE_DATA_OUT @@ -75,29 +42,43 @@ 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 #else -#define SerialBLE Serial +#define SerialBLE Serial3 #endif #endif +#if ENABLE_DATA_LOG +static File sdfile; +#endif + +static const char* idstr = "FREEMATICS\r"; + class CDataLogger { public: void initSender() { #if ENABLE_DATA_OUT SerialBLE.begin(STREAM_BAUDRATE); + SerialBLE.print(idstr); #endif -#if ENABLE_DATA_LOG && LOG_FORMAT == FORMAT_CSV +#if ENABLE_DATA_LOG m_lastDataTime = 0; +#endif + } + void logTimeElapsed() + { +#if ENABLE_DATA_LOG + dataSize += sdfile.print(dataTime - m_lastDataTime); + sdfile.write(','); + dataSize++; + m_lastDataTime = dataTime; #endif } void logData(char c) @@ -106,188 +87,64 @@ public: SerialBLE.write(c); #endif #if ENABLE_DATA_LOG - if (sdfile) dataSize += sdfile.write(c); + if (c >= ' ') { + sdfile.write(c); + dataSize++; + } #endif } void logData(uint16_t pid, int value) { -#if LOG_FORMAT == FORMAT_BIN || STREAM_FORMAT == FORMAT_BIN - LOG_DATA_COMM ld = {dataTime, pid, 1, 0, value}; - ld.checksum = getChecksum((char*)&ld, 12); -#endif + char buf[16]; + byte n = sprintf(buf, "%X,%d\r", pid, value); #if ENABLE_DATA_OUT #if STREAM_FORMAT == FORMAT_BIN - SerialBLE.write((uint8_t*)&ld, 12); -#else - SerialBLE.print(pid, HEX); - SerialBLE.write(','); - SerialBLE.print(value); - SerialBLE.write('\n'); -#endif -#endif -#if ENABLE_DATA_LOG - if (!sdfile) return; -#if LOG_FORMAT == FORMAT_BIN - sdfile.write((uint8_t*)&ld, 12); - dataSize += 12; -#else - dataSize += sdfile.print(dataTime - m_lastDataTime); - sdfile.write(','); - dataSize += sdfile.print(pid, HEX); - sdfile.write(','); - dataSize += sdfile.print(value); - sdfile.write('\n'); - dataSize += 3; - m_lastDataTime = dataTime; -#endif -#endif - } - void logData(uint16_t pid, float value) - { -#if LOG_FORMAT == FORMAT_BIN || STREAM_FORMAT == FORMAT_BIN LOG_DATA_COMM ld = {dataTime, pid, 1, 0, value}; ld.checksum = getChecksum((char*)&ld, 12); -#endif -#if ENABLE_DATA_OUT -#if STREAM_FORMAT == FORMAT_BIN SerialBLE.write((uint8_t*)&ld, 12); #else - SerialBLE.print(pid, HEX); - SerialBLE.write(','); - SerialBLE.print(value); - SerialBLE.write('\n'); + SerialBLE.write((uint8_t*)buf, n); #endif #endif #if ENABLE_DATA_LOG - if (!sdfile) return; -#if LOG_FORMAT == FORMAT_BIN - sdfile.write((uint8_t*)&ld, 12); - dataSize += 12; -#else - dataSize += sdfile.print(dataTime - m_lastDataTime); - sdfile.write(','); - dataSize += sdfile.print(pid, HEX); - sdfile.write(','); - dataSize += sdfile.print(value); - sdfile.write('\n'); - dataSize += 3; - m_lastDataTime = dataTime; -#endif + logTimeElapsed(); + dataSize += sdfile.write((uint8_t*)buf, n); #endif } - void logData(uint16_t pid, float value1, float value2) + void logData(uint16_t pid, int32_t value) { -#if LOG_FORMAT == FORMAT_BIN || STREAM_FORMAT == FORMAT_BIN - LOG_DATA_COMM ld = {dataTime, pid, 2, 0, {value1, value2}}; - ld.checksum = getChecksum((char*)&ld, 16); -#endif + char buf[20]; + byte n = sprintf(buf, "%X,%ld\r", pid, value); #if ENABLE_DATA_OUT #if STREAM_FORMAT == FORMAT_BIN - SerialBLE.write((uint8_t*)&ld, 16); + LOG_DATA_COMM ld = {dataTime, pid, 1, 0, value}; + ld.checksum = getChecksum((char*)&ld, 12); + SerialBLE.write((uint8_t*)&ld, 12); #else - SerialBLE.print(pid, HEX); - SerialBLE.write(','); - SerialBLE.print(value1, 6); - SerialBLE.write(','); - SerialBLE.print(value2, 6); - SerialBLE.write('\n'); + SerialBLE.write((uint8_t*)buf, n); #endif #endif #if ENABLE_DATA_LOG - if (!sdfile) return; -#if LOG_FORMAT == FORMAT_BIN - sdfile.write((uint8_t*)&ld, 16); - dataSize += 16; -#else - dataSize += sdfile.print(dataTime - m_lastDataTime); - sdfile.write(','); - dataSize += sdfile.print(pid, HEX); - sdfile.write(','); - dataSize += sdfile.print(value1, 6); - sdfile.write(','); - dataSize += sdfile.print(value2, 6); - sdfile.write('\n'); - dataSize += 4; - m_lastDataTime = dataTime; -#endif + logTimeElapsed(); + dataSize += sdfile.write((uint8_t*)buf, n); #endif } - void logData(uint16_t pid, uint32_t value1, uint32_t value2) + void logData(uint16_t pid, int value1, int value2, int value3) { -#if LOG_FORMAT == FORMAT_BIN || STREAM_FORMAT == FORMAT_BIN - LOG_DATA_COMM ld = {dataTime, pid, 2, 0, {value1, value2}}; - ld.checksum = getChecksum((char*)&ld, 16); -#endif + char buf[24]; + byte n = sprintf(buf, "%X,%d,%d,%d\r", pid, value1, value2, value3); #if ENABLE_DATA_OUT #if STREAM_FORMAT == FORMAT_BIN - SerialBLE.write((uint8_t*)&ld, 16); -#else - SerialBLE.print(pid, HEX); - SerialBLE.write(','); - SerialBLE.print(value1); - SerialBLE.write(','); - SerialBLE.print(value2); - SerialBLE.write('\n'); -#endif -#endif -#if ENABLE_DATA_LOG - if (!sdfile) return; -#if LOG_FORMAT == FORMAT_BIN - sdfile.write((uint8_t*)&ld, 16); - dataSize += 16; -#else - dataSize += sdfile.print(dataTime - m_lastDataTime); - sdfile.write(','); - dataSize += sdfile.print(pid, HEX); - sdfile.write(','); - dataSize += sdfile.print(value1); - sdfile.write(','); - dataSize += sdfile.print(value2); - sdfile.write('\n'); - dataSize += 4; - m_lastDataTime = dataTime; -#endif -#endif - } - void logData(uint16_t pid, int value1, int value2, int value3) - { -#if LOG_FORMAT == FORMAT_BIN || STREAM_FORMAT == FORMAT_BIN LOG_DATA_COMM ld = {dataTime, pid, 3, 0, {value1, value2, value3}}; ld.checksum = getChecksum((char*)&ld, 20); -#endif -#if ENABLE_DATA_OUT -#if STREAM_FORMAT == FORMAT_BIN SerialBLE.write((uint8_t*)&ld, 20); #else - SerialBLE.print(pid, HEX); - SerialBLE.write(','); - SerialBLE.print(value1); - SerialBLE.write(','); - SerialBLE.print(value2); - SerialBLE.write(','); - SerialBLE.print(value3); - SerialBLE.write('\n'); + SerialBLE.write((uint8_t*)buf, n); #endif #endif #if ENABLE_DATA_LOG - if (!sdfile) return; -#if LOG_FORMAT == FORMAT_BIN - sdfile.write((uint8_t*)&ld, 20); - dataSize += 20; -#else - dataSize += sdfile.print(dataTime - m_lastDataTime); - sdfile.write(','); - dataSize += sdfile.print(pid, HEX); - sdfile.write(','); - dataSize += sdfile.print(value1); - sdfile.write(','); - dataSize += sdfile.print(value2); - sdfile.write(','); - dataSize += sdfile.print(value3); - sdfile.write('\n'); - dataSize += 5; - m_lastDataTime = dataTime; -#endif + logTimeElapsed(); + dataSize += sdfile.write((uint8_t*)buf, n); #endif } #if ENABLE_DATA_LOG @@ -296,6 +153,7 @@ public: uint16_t fileIndex; char filename[24] = "/FRMATICS"; + dataSize = 0; if (SD.exists(filename)) { for (fileIndex = 1; fileIndex; fileIndex++) { sprintf(filename + 9, FILE_NAME_FORMAT, fileIndex); @@ -315,17 +173,6 @@ public: if (!sdfile) { return 0; } - -#if LOG_FORMAT == FORMAT_BIN - HEADER hdr = {'UDUS', HEADER_LEN, 1, 0, logFlags, dateTime}; - sdfile.write((uint8_t*)&hdr, sizeof(hdr)); - for (byte i = 0; i < HEADER_LEN - sizeof(hdr); i++) - sdfile.write((uint8_t)0); - dataSize = HEADER_LEN; -#else - sdfile.println("# Freematics Log File"); -#endif - sdfile.flush(); return fileIndex; } void closeFile() @@ -334,7 +181,7 @@ public: } void flushFile() { - if (sdfile) sdfile.flush(); + sdfile.flush(); } #endif uint32_t dataTime; @@ -349,9 +196,6 @@ private: return checksum; } #if ENABLE_DATA_LOG - File sdfile; -#if LOG_FORMAT == FORMAT_CSV uint32_t m_lastDataTime; #endif -#endif }; -- cgit v1.2.3