From e761df341e1b4e7d1cec08663c9c10187d0e8b90 Mon Sep 17 00:00:00 2001
From: Stanley Huang <stanleyhuangyc@gmail.com>
Date: Tue, 18 Aug 2015 22:31:08 +1000
Subject: Reference code for cycling data logger

---
 bikelogger/bikelogger.ino |   4 +-
 bikelogger/datalogger.h   | 146 ++++++++++++++++++++++++++++++++--------------
 2 files changed, 105 insertions(+), 45 deletions(-)

diff --git a/bikelogger/bikelogger.ino b/bikelogger/bikelogger.ino
index b864cda..e517a98 100644
--- a/bikelogger/bikelogger.ino
+++ b/bikelogger/bikelogger.ino
@@ -10,11 +10,11 @@
 #include <SPI.h>
 #include <SD.h>
 #include <TinyGPS.h>
+#include <MultiLCD.h>
+#include "config.h"
 #if USE_SOFTSERIAL
 #include <SoftwareSerial.h>
 #endif
-#include "MultiLCD.h"
-#include "config.h"
 #include "datalogger.h"
 
 #define DISPLAY_MODES 1
diff --git a/bikelogger/datalogger.h b/bikelogger/datalogger.h
index 2a58bf3..49cac28 100644
--- a/bikelogger/datalogger.h
+++ b/bikelogger/datalogger.h
@@ -1,13 +1,13 @@
 /*************************************************************************
 * Arduino Data Logger Class
 * Distributed under GPL v2.0
-* Copyright (c) 2013-2014 Stanley Huang <stanleyhuangyc@gmail.com>
-* All rights reserved.
+* Written by Stanley Huang <stanleyhuangyc@gmail.com>
 * Visit http://freematics.com for more information
 *************************************************************************/
 
 #define FORMAT_BIN 0
 #define FORMAT_CSV 1
+#define FORMAT_TEXT 2
 
 typedef struct {
     uint32_t time;
@@ -17,8 +17,6 @@ typedef struct {
     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
@@ -34,22 +32,16 @@ typedef struct {
 #define PID_MEMS_TEMP 0x23
 #define PID_BATTERY_VOLTAGE 0x24
 
+#define PID_DATA_SIZE 0x80
+
 #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*/
+SoftwareSerial SerialRF(A2, A3);
 #else
-    SoftwareSerial SerialBLE(A2, A3); /* for BLE Shield on UNO/leonardo*/
-#endif
-
-#else
-
-#define SerialBLE Serial3
-
+#define SerialRF Serial
 #endif
 
 #endif
@@ -58,34 +50,62 @@ typedef struct {
 static File sdfile;
 #endif
 
-static const char* idstr = "FREEMATICS\r";
+typedef struct {
+    uint16_t pid;
+    char name[3];
+} PID_NAME;
+
+const PID_NAME pidNames[] PROGMEM = {
+{PID_ACC, {'A','C','C'}},
+{PID_GYRO, {'G','Y','R'}},
+{PID_COMPASS, {'M','A','G'}},
+{PID_GPS_LATITUDE, {'L','A','T'}},
+{PID_GPS_LONGITUDE, {'L','O','N'}},
+{PID_GPS_ALTITUDE, {'A','L','T'}},
+{PID_GPS_SPEED, {'S','P','D'}},
+{PID_GPS_HEADING, {'C','R','S'}},
+{PID_GPS_SAT_COUNT, {'S','A','T'}},
+{PID_GPS_TIME, {'T','M','E'}},
+{PID_GPS_DATE, {'D','T','E'}},
+{PID_BATTERY_VOLTAGE, {'B','A','T'}},
+{PID_DATA_SIZE, {'D','A','T'}},
+};
 
 class CDataLogger {
 public:
     void initSender()
     {
 #if ENABLE_DATA_OUT
-        SerialBLE.begin(STREAM_BAUDRATE);
-        SerialBLE.print(idstr);
+        SerialRF.begin(STREAM_BAUDRATE);
+        /*
+        SerialRF.print("AT+NAMEFreematics");
+        delay(10);
+        while (SerialRF.available()) SerialRF.read();
+        SerialRF.println();
+        */
+        m_lastSendTime = 0;
 #endif
 #if ENABLE_DATA_LOG
         m_lastDataTime = 0;
 #endif
     }
-    void logTimeElapsed()
+    void recordData(const char* buf)
     {
 #if ENABLE_DATA_LOG
         dataSize += sdfile.print(dataTime - m_lastDataTime);
-        sdfile.write(',');
-        dataSize++;
+        dataSize += sdfile.write(',');
+        dataSize += sdfile.write(buf);
         m_lastDataTime = dataTime;
+#endif
+#if MIN_DATA_INTERVAL
+        uint32_t t = millis();
+        uint32_t elapsed = t - m_lastSendTime;
+        if (elapsed < MIN_DATA_INTERVAL) delay(MIN_DATA_INTERVAL - elapsed);
+        m_lastSendTime = t;
 #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);
@@ -96,56 +116,78 @@ public:
     void logData(uint16_t pid, int value)
     {
         char buf[16];
-        byte n = sprintf(buf, "%X,%d\r", pid, value);
+#if STREAM_FORMAT == FORMAT_TEXT
+        sprintf(buf + translatePIDName(pid, buf), "%d\r", value);
+#else
+        sprintf(buf, "%X,%d\r", pid, value);
+#endif
 #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);
+        SerialRF.write((uint8_t*)&ld, 12);
 #else
-        SerialBLE.write((uint8_t*)buf, n);
+        SerialRF.print(buf);
 #endif
 #endif
-#if ENABLE_DATA_LOG
-        logTimeElapsed();
-        dataSize += sdfile.write((uint8_t*)buf, n);
-#endif
+        recordData(buf);
     }
     void logData(uint16_t pid, int32_t value)
     {
         char buf[20];
-        byte n = sprintf(buf, "%X,%ld\r", pid, value);
+#if STREAM_FORMAT == FORMAT_TEXT
+        sprintf(buf + translatePIDName(pid, buf), "%ld\r", value);
+#else
+        sprintf(buf, "%X,%ld\r", pid, value);
+#endif
 #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);
+        SerialRF.write((uint8_t*)&ld, 12);
 #else
-        SerialBLE.write((uint8_t*)buf, n);
+        SerialRF.print(buf);
 #endif
 #endif
-#if ENABLE_DATA_LOG
-        logTimeElapsed();
-        dataSize += sdfile.write((uint8_t*)buf, n);
+        recordData(buf);
+    }
+    void logData(uint16_t pid, uint32_t value)
+    {
+        char buf[20];
+#if STREAM_FORMAT == FORMAT_TEXT
+        sprintf(buf + translatePIDName(pid, buf), "%lu\r", value);
+#else
+        sprintf(buf, "%X,%lu\r", pid, value);
 #endif
+#if ENABLE_DATA_OUT
+#if STREAM_FORMAT == FORMAT_BIN
+        LOG_DATA_COMM ld = {dataTime, pid, 1, 0, value};
+        ld.checksum = getChecksum((char*)&ld, 12);
+        SerialRF.write((uint8_t*)&ld, 12);
+#else
+        SerialRF.print(buf);
+#endif
+#endif
+        recordData(buf);
     }
     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 STREAM_FORMAT == FORMAT_TEXT
+        sprintf(buf + translatePIDName(pid, buf), "%d,%d,%d\r", value1, value2, value3);
+#else
+        sprintf(buf, "%X,%d,%d,%d\r", pid, value1, value2, value3);
+#endif
 #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);
+        SerialRF.write((uint8_t*)&ld, 20);
 #else
-        SerialBLE.write((uint8_t*)buf, n);
-#endif
+        SerialRF.print(buf);
 #endif
-#if ENABLE_DATA_LOG
-        logTimeElapsed();
-        dataSize += sdfile.write((uint8_t*)buf, n);
 #endif
+        recordData(buf);
     }
 #if ENABLE_DATA_LOG
     uint16_t openFile(uint16_t logFlags = 0, uint32_t dateTime = 0)
@@ -173,6 +215,7 @@ public:
         if (!sdfile) {
             return 0;
         }
+        m_lastDataTime = dateTime;
         return fileIndex;
     }
     void closeFile()
@@ -195,7 +238,24 @@ private:
         }
         return checksum;
     }
+#if STREAM_FORMAT == FORMAT_TEXT
+    byte translatePIDName(uint16_t pid, char* text)
+    {
+        for (uint16_t n = 0; n < sizeof(pidNames) / sizeof(pidNames[0]); n++) {
+            uint16_t id = pgm_read_word(&pidNames[n].pid);
+            if (pid == id) {
+                memcpy_P(text, pidNames[n].name, 3);
+                text[3] = '=';
+                return 4;
+            }
+        }
+        return sprintf(text, "%X=", pid);
+    }
+#endif
 #if ENABLE_DATA_LOG
     uint32_t m_lastDataTime;
 #endif
+#if ENABLE_DATA_OUT
+    uint32_t m_lastSendTime;
+#endif
 };
-- 
cgit v1.2.3