From 9a0730a5d9422441d3cfb168fb35772232a4e385 Mon Sep 17 00:00:00 2001 From: Stanley Huang Date: Fri, 4 Apr 2014 21:42:13 +0800 Subject: add OBD-II data player --- utilities/dataplayer/config.h | 55 +++ utilities/dataplayer/datalogger.h | 340 ++++++++++++++++++ utilities/dataplayer/dataplayer.cbp | 666 ++++++++++++++++++++++++++++++++++++ utilities/dataplayer/dataplayer.ino | 401 ++++++++++++++++++++++ 4 files changed, 1462 insertions(+) create mode 100644 utilities/dataplayer/config.h create mode 100644 utilities/dataplayer/datalogger.h create mode 100644 utilities/dataplayer/dataplayer.cbp create mode 100644 utilities/dataplayer/dataplayer.ino (limited to 'utilities/dataplayer') diff --git a/utilities/dataplayer/config.h b/utilities/dataplayer/config.h new file mode 100644 index 0000000..8b166fe --- /dev/null +++ b/utilities/dataplayer/config.h @@ -0,0 +1,55 @@ +#ifndef CONFIG_H_INCLUDED +#define CONFIG_H_INCLUDED + +/************************************** +* OBD-II options +**************************************/ +#define OBD_MODEL OBD_MODEL_UART +#define OBD_PROTOCOL 0 /* 0 for auto */ + +/************************************** +* Data logging/streaming out +**************************************/ +#define ENABLE_DATA_OUT 1 +#define ENABLE_DATA_LOG 0 +#define USE_SOFTSERIAL 1 +//this defines the format of log file +#define LOG_FORMAT FORMAT_CSV + +/************************************** +* Default working mode +**************************************/ +#define MODE_DEFAULT MODE_LOGGER /* MODE_LOGGER/MODE_TIMER */ +//#define MODE_SWITCH_PIN 8 + +/************************************** +* 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 + +/************************************** +* Config GPS here +**************************************/ +#define USE_GPS 0 +#define GPS_BAUDRATE 38400 /* bps */ +//#define GPS_OPEN_BAUDRATE 4800 /* bps */ + +/************************************** +* Choose LCD model here +**************************************/ +LCD_ILI9341 lcd; +//LCD_SSD1306 lcd; +//LCD_Null lcd; + +/************************************** +* Other options +**************************************/ +#define USE_MPU6050 0 +#define GPS_DATA_TIMEOUT 2000 /* ms */ +//#define DEBUG Serial +#define DEBUG_BAUDRATE 9600 + +#endif // CONFIG_H_INCLUDED diff --git a/utilities/dataplayer/datalogger.h b/utilities/dataplayer/datalogger.h new file mode 100644 index 0000000..467131f --- /dev/null +++ b/utilities/dataplayer/datalogger.h @@ -0,0 +1,340 @@ +typedef enum { + LOG_TYPE_DEFAULT = 0, + LOG_TYPE_0_60, + LOG_TYPE_0_100, + LOG_TYPE_100_200, + LOG_TYPE_400M, + LOG_TYPE_LAPS, + LOG_TYPE_ROUTE, +} LOG_TYPES; + +#define FLAG_CAR 0x1 +#define FLAG_CYCLING 0x2 +#define FLAG_OBD 0x10 +#define FLAG_GPS 0x20 +#define FLAG_ACC 0x40 + +#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; + uint8_t flags; + uint8_t checksum; + 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_ACC 0xF020 +#define PID_GYRO 0xF021 + +#define PID_MESSAGE 0xFE00 +#define PID_HEART_BEAT 0xFFEE + +#define MSG_FILE_LIST_BEGIN 0x1 +#define MSG_FILE_LIST_END 0x2 +#define MSG_FILE_INFO 0x3 +#define MSG_FILE_REQUEST 0x4 + +#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 +#if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) + SoftwareSerial mySerial(A8, A9); /* for BLE Shield on MEGA*/ +#elif defined(__AVR_ATmega644P__) + SoftwareSerial mySerial(9, 10); /* for Microduino */ +#else + SoftwareSerial mySerial(A2, A3); /* for BLE Shield on UNO*/ +#endif +#endif + +class CDataLogger { +public: + void initSender() + { +#if ENABLE_DATA_OUT + mySerial.begin(9600); +#endif +#if ENABLE_DATA_LOG && LOG_FORMAT == FORMAT_CSV + m_lastDataTime = 0; +#endif + } +#if ENABLE_DATA_OUT + void sendFileInfo(File& file) + { + if (file.size() < HEADER_LEN) return; + + LOG_DATA_FILE_INFO info = {0}; + info.fileIndex = atol(file.name() + 3); + if (info.fileIndex == 0) return; + + HEADER hdr; + if (file.readBytes((char*)&hdr, sizeof(hdr)) != sizeof(hdr)) return; + + info.pid = PID_MESSAGE; + info.message = MSG_FILE_INFO; + info.fileSize = file.size(); + info.time = hdr.dateTime; + info.logType = hdr.logType; + info.logFlags = hdr.flags; + info.checksum = getChecksum((char*)&info, sizeof(info)); + mySerial.write((uint8_t*)&info, sizeof(info)); + } + void sendCommand(byte message, void* data = 0, byte bytes = 0) + { + LOG_DATA_COMMAND msg = {0, PID_MESSAGE, message}; + if (data) memcpy(msg.data, data, bytes); + msg.checksum = getChecksum((char*)&msg, sizeof(msg)); + mySerial.write((uint8_t*)&msg, sizeof(msg)); + } + bool receiveCommand(LOG_DATA_COMMAND& msg) + { + if (!mySerial.available()) + return false; + + if (mySerial.readBytes((char*)&msg, sizeof(msg)) != sizeof(msg)) + return false; + + uint8_t checksum = msg.checksum; + msg.checksum = 0; + if (getChecksum((char*)&msg, sizeof(msg)) != msg.checksum) { + return false; + } + return true; + } +#endif + void logData(uint16_t pid, int value) + { + LOG_DATA_COMM ld = {dataTime, pid, 1, 0, value}; + ld.checksum = getChecksum((char*)&ld, 12); +#if ENABLE_DATA_OUT + mySerial.write((uint8_t*)&ld, 12); +#endif +#if ENABLE_DATA_LOG +#if LOG_FORMAT == FORMAT_BIN + sdfile.write((uint8_t*)&ld, 12); + dataSize += 12; +#else + dataSize += sdfile.print(dataTime - m_lastDataTime); + dataSize += sdfile.write(','); + dataSize += sdfile.print(pid, HEX); + dataSize += sdfile.write(','); + dataSize += sdfile.print(value); + dataSize += sdfile.write('\n'); + m_lastDataTime = dataTime; +#endif +#endif + } + void logData(uint16_t pid, float value) + { + LOG_DATA_COMM ld = {dataTime, pid, 1, 0, value}; + ld.checksum = getChecksum((char*)&ld, 12); +#if ENABLE_DATA_OUT + mySerial.write((uint8_t*)&ld, 12); +#endif +#if ENABLE_DATA_LOG +#if LOG_FORMAT == FORMAT_BIN + sdfile.write((uint8_t*)&ld, 12); + dataSize += 12; +#else + dataSize += sdfile.print(dataTime - m_lastDataTime); + dataSize += sdfile.write(','); + dataSize += sdfile.print(pid, HEX); + dataSize += sdfile.write(','); + dataSize += sdfile.print(value); + dataSize += sdfile.write('\n'); + m_lastDataTime = dataTime; +#endif +#endif + } + void logData(uint16_t pid, float value1, float value2) + { + LOG_DATA_COMM ld = {dataTime, pid, 2, 0, {value1, value2}}; + ld.checksum = getChecksum((char*)&ld, 16); +#if ENABLE_DATA_OUT + mySerial.write((uint8_t*)&ld, 16); +#endif +#if ENABLE_DATA_LOG +#if LOG_FORMAT == FORMAT_BIN + sdfile.write((uint8_t*)&ld, 16); + dataSize += 16; +#else + dataSize += sdfile.print(dataTime - m_lastDataTime); + dataSize += sdfile.write(','); + dataSize += sdfile.print(pid, HEX); + dataSize += sdfile.write(','); + dataSize += sdfile.print(value1, 6); + dataSize += sdfile.write(','); + dataSize += sdfile.print(value2, 6); + dataSize += sdfile.write('\n'); + m_lastDataTime = dataTime; +#endif +#endif + } + void logData(uint16_t pid, uint32_t value1, uint32_t value2) + { + LOG_DATA_COMM ld = {dataTime, pid, 2, 0, {value1, value2}}; + ld.checksum = getChecksum((char*)&ld, 16); +#if ENABLE_DATA_OUT + mySerial.write((uint8_t*)&ld, 16); +#endif +#if ENABLE_DATA_LOG +#if LOG_FORMAT == FORMAT_BIN + sdfile.write((uint8_t*)&ld, 16); + dataSize += 16; +#else + dataSize += sdfile.print(dataTime - m_lastDataTime); + dataSize += sdfile.write(','); + dataSize += sdfile.print(pid, HEX); + dataSize += sdfile.write(','); + dataSize += sdfile.print(value1); + dataSize += sdfile.write(','); + dataSize += sdfile.print(value2); + dataSize += sdfile.write('\n'); + m_lastDataTime = dataTime; +#endif +#endif + } + void logData(uint16_t pid, int value1, int value2, int value3) + { + LOG_DATA_COMM ld = {dataTime, pid, 3, 0, {value1, value2, value3}}; + ld.checksum = getChecksum((char*)&ld, 20); +#if ENABLE_DATA_OUT + mySerial.write((uint8_t*)&ld, 20); +#endif +#if ENABLE_DATA_LOG +#if LOG_FORMAT == FORMAT_BIN + sdfile.write((uint8_t*)&ld, 20); + dataSize += 20; +#else + dataSize += sdfile.print(dataTime - m_lastDataTime); + dataSize += sdfile.write(','); + dataSize += sdfile.print(pid, HEX); + dataSize += sdfile.write(','); + dataSize += sdfile.print(value1); + dataSize += sdfile.write(','); + dataSize += sdfile.print(value2); + dataSize += sdfile.write(','); + dataSize += sdfile.print(value3); + dataSize += sdfile.write('\n'); + m_lastDataTime = dataTime; +#endif +#endif + } +#if ENABLE_DATA_LOG + uint16_t openFile(LOG_TYPES logType, uint16_t logFlags = 0, uint32_t dateTime = 0) + { + uint16_t fileIndex; + char filename[24] = "/FRMATICS"; + + 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; + } + +#if LOG_FORMAT == FORMAT_BIN + HEADER hdr = {'UDUS', HEADER_LEN, 1, logType, 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; +#endif + return fileIndex; + } + void closeFile() + { + sdfile.close(); + } + void flushFile() + { + sdfile.flush(); + } +#endif + uint32_t dataTime; + uint32_t dataSize; +private: + static 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 + File sdfile; +#if LOG_FORMAT == FORMAT_CSV + uint32_t m_lastDataTime; +#endif +#endif +}; diff --git a/utilities/dataplayer/dataplayer.cbp b/utilities/dataplayer/dataplayer.cbp new file mode 100644 index 0000000..662f664 --- /dev/null +++ b/utilities/dataplayer/dataplayer.cbp @@ -0,0 +1,666 @@ + + + + + + diff --git a/utilities/dataplayer/dataplayer.ino b/utilities/dataplayer/dataplayer.ino new file mode 100644 index 0000000..2e7e1f7 --- /dev/null +++ b/utilities/dataplayer/dataplayer.ino @@ -0,0 +1,401 @@ +#include +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "datalogger.h" + +CDataLogger sender; + +#define LOG_DATA_LEN sizeof(LOG_DATA) +#define REPLAY_SPEED 1 + +/////////////////////////////////////////////////////////////////////////// +#define PID_GPS_LATITUDE 0xF00A +#define PID_GPS_LONGITUDE 0xF00B +#define PID_GPS_ALTITUDE 0xF00C +#define PID_GPS_SPEED 0xF00D + +void sendLogFile(File logfile, byte noWait); +// +//unsigned int hex2uint16(const char *p) +//{ +// char c = *p; +// unsigned int i = 0; +// for (char n = 0; c && n < 4; c = *(++p)) { +// if (c >= 'A' && c <= 'F') { +// c -= 7; +// } else if (c>='a' && c<='f') { +// c -= 39; +// } else if (c == ' ') { +// continue; +// } else if (c < '0' || c > '9') { +// break; +// } +// i = (i << 4) | (c & 0xF); +// n++; +// } +// return i; +//} + +void initScreen() +{ + lcd.clear(); + lcd.backlight(true); + lcd.setFont(FONT_SIZE_SMALL); + lcd.setTextColor(RGB16_CYAN); + lcd.setCursor(4, 0); + lcd.print("ENGINE RPM"); + lcd.setCursor(104, 0); + lcd.print("SPEED"); + lcd.setCursor(164, 0); + lcd.print("ENGINE LOAD"); + lcd.setCursor(248, 0); + lcd.print("INTAKE TEMP"); + + lcd.setCursor(4, 7); + lcd.print("COOLANT TEMP"); + lcd.setCursor(104, 7); + lcd.print("DISTANCE"); + lcd.setCursor(164, 7); + lcd.print("INTAKE MAP"); + + lcd.setCursor(260, 7); + lcd.print("ELAPSED"); + lcd.setCursor(260, 10); + lcd.print("LOG SIZE"); + + lcd.setTextColor(RGB16_YELLOW); + lcd.setCursor(24, 5); + lcd.print("rpm"); + lcd.setCursor(110, 5); + lcd.print("km/h"); + lcd.setCursor(216, 4); + lcd.print("%"); + lcd.setCursor(304, 4); + lcd.print("C"); + lcd.setCursor(64, 11); + lcd.print("C"); + lcd.setCursor(110, 12); + lcd.print("km"); + lcd.setCursor(200, 12); + lcd.print("kpa"); + lcd.setCursor(296, 12); + lcd.print("KB"); + + lcd.setTextColor(RGB16_WHITE); + + + //lcd.setCursor(0, 5); + //lcd.print("THR: %"); + //lcd.setCursor(80, 5); + //lcd.print("AIR: C"); +} + +void showChart(int value) +{ + static uint16_t pos = 0; + if (value < 500) return; + byte n = (value - 600) / 30; + lcd.fill(pos, pos, 239 - n, 239, RGB16_CYAN); + pos = (pos + 1) % 320; + lcd.fill(pos, pos, 120, 239); +} + +void showData(byte pid, int value) +{ + switch (pid) { + case PID_RPM: + lcd.setCursor(0, 2); + lcd.setFont(FONT_SIZE_XLARGE); + lcd.printInt((unsigned int)value % 10000, 4); + showChart(value); + break; + case PID_SPEED: + lcd.setCursor(90, 2); + lcd.setFont(FONT_SIZE_XLARGE); + lcd.printInt((unsigned int)value % 1000, 3); + break; + case PID_ENGINE_LOAD: + lcd.setCursor(164, 2); + lcd.setFont(FONT_SIZE_XLARGE); + lcd.printInt(value % 100, 3); + break; + case PID_INTAKE_TEMP: + if ((uint16_t)value < 1000) { + lcd.setCursor(248, 2); + lcd.setFont(FONT_SIZE_XLARGE); + lcd.printInt(value, 3); + } + break; + case PID_INTAKE_MAP: + lcd.setCursor(164, 9); + lcd.setFont(FONT_SIZE_XLARGE); + lcd.printInt((uint16_t)value % 1000, 3); + break; + case PID_COOLANT_TEMP: + lcd.setCursor(8, 9); + lcd.setFont(FONT_SIZE_XLARGE); + lcd.printInt((uint16_t)value % 1000, 3); + break; + case PID_DISTANCE: + lcd.setFont(FONT_SIZE_XLARGE); + lcd.setCursor(90, 9); + lcd.printInt((uint16_t)value % 1000, 3); + break; + } +} + +/////////////////////////////////////////////////////////////////////////// + +void setup() +{ + // Open serial communications and wait for port to open: + Serial.begin(115200); + + lcd.begin(); + lcd.clear(); + sender.initSender(); + + // On the Ethernet Shield, CS is pin 4. It's set as an output by default. + // Note that even if it's not used as the CS pin, the hardware SS pin + // (10 on Arduino Uno boards, 53 on the Mega) must be left as an output + // or the SD library functions will not work. + pinMode(SD_CS_PIN, OUTPUT); + + Sd2Card card; + + if (card.init(SPI_FULL_SPEED, SD_CS_PIN)) { + SdVolume volume; +#if 0 + char buf[20]; + if (!volume.init(card)) { + Serial.println("No FAT!"); + } else { + uint32_t volumesize = volume.blocksPerCluster(); + volumesize >>= 1; // 512 bytes per block + volumesize *= volume.clusterCount(); + volumesize >>= 10; + + sprintf(buf, "%dGB", (int)((volumesize + 511) / 1000)); + Serial.println(buf); + lcd.print("SD "); + lcd.println(buf); + } +#endif + if (!SD.begin(SD_CS_PIN)) { + Serial.println("SD error"); + } + } else { + lcd.print("No SD"); + Serial.println("No SD"); + } +} + +/////////////////////////////////////////////////////////////////////////// +#if 0 +void ShowSensorData(uint16_t pid, float data) +{ + uint16_t value; + Serial.print('['); + Serial.print(pid, HEX); + Serial.print("]="); + if (pid < 0xf000) { + value = (uint16_t)data; + Serial.print(value); + } + + char buf[16]; + switch (pid) { + case PID_RPM: + lcd.setCursor(64, 0); + lcd.setFont(FONT_SIZE_XLARGE); + lcd.printInt(value, 4); + break; + case PID_SPEED: + lcd.setCursor(0, 0); + lcd.setFont(FONT_SIZE_XLARGE); + lcd.printInt(value, 3); + break; + case PID_THROTTLE: + lcd.setCursor(24, 5); + lcd.setFont(FONT_SIZE_SMALL); + lcd.printInt(value, 3); + break; + case PID_INTAKE_TEMP: + lcd.setCursor(104, 5); + lcd.setFont(FONT_SIZE_SMALL); + lcd.printInt(value, 3); + break; + case PID_DISTANCE: + sprintf(buf, "%5ukm", value); + lcd.setFont(FONT_SIZE_SMALL); + lcd.setCursor(86, 6); + lcd.print(buf); + break; + case PID_GPS_LATITUDE: { + int32_t lat = (int32_t)(data * 100000); + sprintf(buf, "LAT:%d.%05ld ", (int)(lat / 100000), lat % 100000); + lcd.setFont(FONT_SIZE_SMALL); + lcd.setCursor(0, 6); + lcd.print(buf); + //Serial.print(buf); + break; + } + case PID_GPS_LONGITUDE: { + int32_t lon = (int32_t)(data * 100000); + sprintf(buf, "LON:%d.%05ld ", (int)(lon / 100000), lon % 100000); + lcd.setFont(FONT_SIZE_SMALL); + lcd.setCursor(0, 7); + lcd.print(buf); + //Serial.print(buf); + break; + } + } +} +#endif + +/////////////////////////////////////////////////////////////////////////// +uint8_t getDataInt8(LOG_DATA_COMMAND& msg, int offset = 0) +{ + return msg.data[offset]; +} + +uint16_t getDataInt16(LOG_DATA_COMMAND& msg, int offset = 0) +{ + return *(uint16_t *)(&msg.data[offset]); +} + +uint32_t getDataInt32(LOG_DATA_COMMAND& msg, int offset = 0) +{ + return *(uint32_t *)(&msg.data[offset]); +} + +void sendLogFile(File logfile, byte noWait = 0) +{ + uint32_t timestamp = 0; + uint32_t dataSize = 0; + int value; + int pid; + char buf[64]; + byte n = 0; + + Serial.println("Start"); + while (logfile.available()) { + byte c = logfile.read(); + dataSize++; + if (c <= 13) { + // process one line + if (n > 0) do { + buf[n] = 0; + n = 0; + // TODO: parse line + int t = atoi(buf); + char *p = strchr(buf, ','); + if (!p++) break; + Serial.print(p); + Serial.write('\n'); + int pid = hex2uint16(p); + p = strchr(p, ','); + if (!p++) break; + int value = atoi(p); + timestamp += t; + showData((byte)pid, value); + if (Serial.available()) { + lcd.setCursor(0, 20); + do { + lcd.write(Serial.read()); + } while (Serial.available()); + } + if (!noWait && t > 0) delay(t / REPLAY_SPEED); + } while(0); + + // show time elapsed + uint16_t elapsed = timestamp / 1000; + lcd.setFont(FONT_SIZE_MEDIUM); + lcd.setCursor(260, 8); + lcd.printInt(elapsed / 60, 2); + lcd.write(':'); + lcd.setFlags(FLAG_PAD_ZERO); + lcd.printInt(elapsed % 60, 2); + lcd.setFlags(0); + + lcd.setCursor(260, 11); + lcd.printInt(dataSize >> 10, 4); + + continue; + } + if (n >= sizeof(buf) - 1) continue; + buf[n++] = c; + + //Show on LCD: + + //Serial.print(" T:"); + //Serial.print(ld.time); + //Serial.print(" F:"); + //Serial.print(ld.flags); + + // display KB counter +#if 0 + lcd.setCursor(96, 7); + lcd.setFont(FONT_SIZE_SMALL); + byte percent = (byte)(dataSendLen * 100 / logsize); + lcd.printInt(percent, 3); + + Serial.print(' '); + Serial.print(percent); + Serial.println('%'); +#endif + //checkReceiveCommand(); + } while (logfile.available()); +} + +void enumDirectoryAndSend(File dir) +{ + // Begin at the start of the directory + dir.rewindDirectory(); + + while(true) { + File entry = dir.openNextFile(); + if (! entry) { + // no more files + //Serial.println("**nomorefiles**"); + break; + } + + if (entry.isDirectory()) { + enumDirectoryAndSend(entry); + } else { + lcd.clear(); + lcd.setFont(FONT_SIZE_MEDIUM); + lcd.print(entry.name()); + delay(1000); + initScreen(); + sendLogFile(entry); + } + entry.close(); + } +} + +void loop() +{ +#if 0 + if (!checkReceiveCommand()) { + delay(100); + } +#else + File root = SD.open("/FRMATICS"); + if (!root || !root.isDirectory()) { + lcd.println("NO LOG"); + Serial.println("NO LOG"); + } else { + enumDirectoryAndSend(root); + root.close(); + } + delay(5000); +#endif + +} -- cgit v1.2.3