summaryrefslogtreecommitdiff
path: root/datalogger/datalogger.ino
diff options
context:
space:
mode:
authorStanley Huang <stanleyhuangyc@gmail.com>2017-05-08 22:51:25 +1000
committerStanley Huang <stanleyhuangyc@gmail.com>2017-05-08 22:51:25 +1000
commit299de0a90617cb3a0a852aad1df538d1e23272b1 (patch)
tree1c1aa36a89d4a7a457824e47ea407f3f64ad5732 /datalogger/datalogger.ino
parentfced2c33dd5d1daf95e2650f6ca6b9dac9b2024d (diff)
download2021-arduino-obd-299de0a90617cb3a0a852aad1df538d1e23272b1.tar.gz
2021-arduino-obd-299de0a90617cb3a0a852aad1df538d1e23272b1.tar.bz2
2021-arduino-obd-299de0a90617cb3a0a852aad1df538d1e23272b1.zip
Reference data logger sketch for Freematics OBD-II UART Adapter
Diffstat (limited to 'datalogger/datalogger.ino')
-rw-r--r--datalogger/datalogger.ino583
1 files changed, 297 insertions, 286 deletions
diff --git a/datalogger/datalogger.ino b/datalogger/datalogger.ino
index 8bda37d..f348943 100644
--- a/datalogger/datalogger.ino
+++ b/datalogger/datalogger.ino
@@ -1,27 +1,38 @@
/*************************************************************************
-* OBD-II/MEMS/GPS Data Logging Sketch for Freematics ONE
-* Distributed under BSD license
-* Visit http://freematics.com/products/freematics-one for more information
-* Developed by Stanley Huang <stanleyhuangyc@gmail.com>
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-* THE SOFTWARE.
+ OBD-II/GPS/MEMS Data Logging Sketch
+ Requires an Arduino board with 2 serial UARTs (3 if GPS required)
+
+ Serial: serial monitor
+ Serial1: Freematics OBD-II UART Adapter (V2 required for MEMS data)
+ Serial2: GPS Receiver (default 115200bps)
+ Change parameters in config.h
+
+ Distributed under BSD license
+ Visit http://freematics.com/products for more information
+ Developed by Stanley Huang <support@freematics.com.au>
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
*************************************************************************/
#include <Arduino.h>
#include <Wire.h>
-#include <OBD.h>
#include <SPI.h>
#include <SD.h>
+#include <OBD.h>
#include <TinyGPS.h>
#include "config.h"
#include "datalogger.h"
+#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168P__)
+#error This sketch requires at least 2 hardware serial
+#endif
+
// states
#define STATE_SD_READY 0x1
#define STATE_OBD_READY 0x2
@@ -36,7 +47,7 @@ static uint16_t fileIndex = 0;
uint16_t MMDD = 0;
uint32_t UTC = 0;
-#if USE_MPU6050 || USE_MPU9250
+#if USE_MPU6050
byte accCount = 0; // count of accelerometer readings
long accSum[3] = {0}; // sum of accelerometer data
int accCal[3] = {0}; // calibrated reference accelerometer data
@@ -49,289 +60,289 @@ byte deviceTemp; // device temperature (celcius degree)
TinyGPS gps;
typedef struct {
- uint32_t date;
- uint32_t time;
- int32_t lat;
- int32_t lng;
- int16_t alt;
- uint8_t speed;
- uint8_t sat;
- int16_t heading;
+ uint32_t date;
+ uint32_t time;
+ int32_t lat;
+ int32_t lng;
+ int16_t alt;
+ uint8_t speed;
+ uint8_t sat;
+ int16_t heading;
} GPS_DATA;
bool getGPSData(GPS_DATA* gd)
{
- bool parsed = false;
- while (!parsed && GPSUART.available()) {
- char c = GPSUART.read();
- parsed = gps.encode(c);
- }
- if (!parsed) return false;
- gps.get_datetime((unsigned long*)&gd->date, (unsigned long*)&gd->time, 0);
- gps.get_position((long*)&gd->lat, (long*)&gd->lng, 0);
- gd->sat = gps.satellites();
- gd->speed = gps.speed() * 1852 / 100000; /* km/h */
- gd->alt = gps.altitude();
- gd->heading = gps.course() / 100;
- return true;
+ bool parsed = false;
+ while (!parsed && GPSUART.available()) {
+ char c = GPSUART.read();
+ parsed = gps.encode(c);
+ }
+ if (!parsed) return false;
+ gps.get_datetime((unsigned long*)&gd->date, (unsigned long*)&gd->time, 0);
+ gps.get_position((long*)&gd->lat, (long*)&gd->lng, 0);
+ gd->sat = gps.satellites();
+ gd->speed = gps.speed() * 1852 / 100000; /* km/h */
+ gd->alt = gps.altitude();
+ gd->heading = gps.course() / 100;
+ return true;
}
bool initGPS(uint32_t baudrate)
{
- if (baudrate)
- GPSUART.begin(baudrate);
- else
- GPSUART.end();
- return true;
+ if (baudrate)
+ GPSUART.begin(baudrate);
+ else
+ GPSUART.end();
+ return true;
}
#endif
class COBDLogger : public COBD, public CDataLogger
{
-public:
- COBDLogger():state(0) {}
+ public:
+ COBDLogger(): state(0) {}
void setup()
{
- state = 0;
+ state = 0;
- delay(500);
- byte ver = begin();
- Serial.print("Firmware Ver. ");
- Serial.println(ver);
+ delay(500);
+ byte ver = begin();
+ Serial.print("Firmware Ver. ");
+ Serial.println(ver);
-#if USE_MPU6050 || USE_MPU9250
- Serial.print("MEMS ");
- if (memsInit()) {
- state |= STATE_MEMS_READY;
- Serial.println("OK");
- } else {
- Serial.println("NO");
- }
+#if USE_MPU6050
+ Serial.print("MEMS ");
+ if (memsInit()) {
+ state |= STATE_MEMS_READY;
+ Serial.println("OK");
+ } else {
+ Serial.println("NO");
+ }
#endif
#if ENABLE_DATA_LOG
- Serial.print("SD ");
- uint16_t volsize = initSD();
- if (volsize) {
- Serial.print(volsize);
- Serial.println("MB");
- } else {
- Serial.println("NO");
- }
+ Serial.print("SD ");
+ uint16_t volsize = initSD();
+ if (volsize) {
+ Serial.print(volsize);
+ Serial.println("MB");
+ } else {
+ Serial.println("NO");
+ }
#endif
- Serial.print("OBD ");
- if (init()) {
- Serial.println("OK");
- } else {
- Serial.println("NO");
- reconnect();
- }
- state |= STATE_OBD_READY;
+ Serial.print("OBD ");
+ if (init()) {
+ Serial.println("OK");
+ } else {
+ Serial.println("NO");
+ reconnect();
+ }
+ state |= STATE_OBD_READY;
#if 0
- // retrieve VIN
- char buffer[128];
- if ((state & STATE_OBD_READY) && getVIN(buffer, sizeof(buffer))) {
- Serial.print("VIN:");
- Serial.println(buffer);
- }
+ // retrieve VIN
+ char buffer[128];
+ if ((state & STATE_OBD_READY) && getVIN(buffer, sizeof(buffer))) {
+ Serial.print("VIN:");
+ Serial.println(buffer);
+ }
#endif
#if USE_GPS
- Serial.print("GPS ");
- if (initGPS(GPS_SERIAL_BAUDRATE)) {
- state |= STATE_GPS_FOUND;
- Serial.println("OK");
- } else {
- Serial.println("NO");
- }
+ Serial.print("GPS ");
+ if (initGPS(GPS_SERIAL_BAUDRATE)) {
+ state |= STATE_GPS_FOUND;
+ Serial.println("OK");
+ } else {
+ Serial.println("NO");
+ }
#endif
-#if USE_MPU6050 || USE_MPU9250
- // obtain reference MEMS data
- Serial.print("Calibrating MEMS...");
- for (uint32_t t = millis(); millis() - t < 1000; ) {
- readMEMS();
- }
- calibrateMEMS();
- Serial.print(accCal[0]);
- Serial.print('/');
- Serial.print(accCal[1]);
- Serial.print('/');
- Serial.println(accCal[2]);
+#if USE_MPU6050
+ // obtain reference MEMS data
+ Serial.print("Calibrating MEMS...");
+ for (uint32_t t = millis(); millis() - t < 1000; ) {
+ readMEMS();
+ }
+ calibrateMEMS();
+ Serial.print(accCal[0]);
+ Serial.print('/');
+ Serial.print(accCal[1]);
+ Serial.print('/');
+ Serial.println(accCal[2]);
#endif
- delay(500);
+ delay(500);
}
#if USE_GPS
void logGPSData()
{
#if LOG_GPS_NMEA_DATA
- // issue the command to get NMEA data (one line per request)
- char buf[255];
- byte n = getGPSRawData(buf, sizeof(buf));
- if (n) {
- dataTime = millis();
- // strip heading $GPS and ending \r\n
- logData(buf + 4, n - 6);
- }
+ // issue the command to get NMEA data (one line per request)
+ char buf[255];
+ byte n = getGPSRawData(buf, sizeof(buf));
+ if (n) {
+ dataTime = millis();
+ // strip heading $GPS and ending \r\n
+ logData(buf + 4, n - 6);
+ }
#endif
#if LOG_GPS_PARSED_DATA
- // issue the command to get parsed GPS data
- GPS_DATA gd = {0};
-
- if (getGPSData(&gd)) {
- dataTime = millis();
- if (gd.time && gd.time != UTC) {
- byte day = gd.date / 10000;
- if (MMDD % 100 != day) {
- logData(PID_GPS_DATE, gd.date);
- }
- logData(PID_GPS_TIME, gd.time);
- logData(PID_GPS_LATITUDE, gd.lat);
- logData(PID_GPS_LONGITUDE, gd.lng);
- logData(PID_GPS_ALTITUDE, gd.alt);
- logData(PID_GPS_SPEED, gd.speed);
- logData(PID_GPS_SAT_COUNT, gd.sat);
- // save current date in MMDD format
- unsigned int DDMM = gd.date / 100;
- UTC = gd.time;
- MMDD = (DDMM % 100) * 100 + (DDMM / 100);
- // set GPS ready flag
- state |= STATE_GPS_READY;
- }
+ // issue the command to get parsed GPS data
+ GPS_DATA gd = {0};
+
+ if (getGPSData(&gd)) {
+ dataTime = millis();
+ if (gd.time && gd.time != UTC) {
+ byte day = gd.date / 10000;
+ if (MMDD % 100 != day) {
+ logData(PID_GPS_DATE, gd.date);
+ }
+ logData(PID_GPS_TIME, gd.time);
+ logData(PID_GPS_LATITUDE, gd.lat);
+ logData(PID_GPS_LONGITUDE, gd.lng);
+ logData(PID_GPS_ALTITUDE, gd.alt);
+ logData(PID_GPS_SPEED, gd.speed);
+ logData(PID_GPS_SAT_COUNT, gd.sat);
+ // save current date in MMDD format
+ unsigned int DDMM = gd.date / 100;
+ UTC = gd.time;
+ MMDD = (DDMM % 100) * 100 + (DDMM / 100);
+ // set GPS ready flag
+ state |= STATE_GPS_READY;
}
+ }
#endif
}
#endif
#if ENABLE_DATA_LOG
uint16_t initSD()
{
- state &= ~STATE_SD_READY;
- pinMode(SS, OUTPUT);
+ state &= ~STATE_SD_READY;
+ pinMode(SS, OUTPUT);
- Sd2Card card;
- uint32_t volumesize = 0;
- if (card.init(SPI_HALF_SPEED, SD_CS_PIN)) {
- SdVolume volume;
- if (volume.init(card)) {
- volumesize = volume.blocksPerCluster();
- volumesize >>= 1; // 512 bytes per block
- volumesize *= volume.clusterCount();
- volumesize /= 1000;
- }
- }
- if (SD.begin(SD_CS_PIN)) {
- state |= STATE_SD_READY;
- return volumesize;
- } else {
- return 0;
+ Sd2Card card;
+ uint32_t volumesize = 0;
+ if (card.init(SPI_HALF_SPEED, SD_CS_PIN)) {
+ SdVolume volume;
+ if (volume.init(card)) {
+ volumesize = volume.blocksPerCluster();
+ volumesize >>= 1; // 512 bytes per block
+ volumesize *= volume.clusterCount();
+ volumesize /= 1000;
}
+ }
+ if (SD.begin(SD_CS_PIN)) {
+ state |= STATE_SD_READY;
+ return volumesize;
+ } else {
+ return 0;
+ }
}
void flushData()
{
// flush SD data every 1KB
- byte dataSizeKB = dataSize >> 10;
- if (dataSizeKB != lastFileSize) {
- flushFile();
- lastFileSize = dataSizeKB;
+ byte dataSizeKB = dataSize >> 10;
+ if (dataSizeKB != lastFileSize) {
+ flushFile();
+ lastFileSize = dataSizeKB;
#if MAX_LOG_FILE_SIZE
- if (dataSize >= 1024L * MAX_LOG_FILE_SIZE) {
- closeFile();
- state &= ~STATE_FILE_READY;
- }
-#endif
+ if (dataSize >= 1024L * MAX_LOG_FILE_SIZE) {
+ closeFile();
+ state &= ~STATE_FILE_READY;
}
+#endif
+ }
}
#endif
void reconnect()
{
- Serial.println("Reconnecting");
- // try to re-connect to OBD
- if (init()) return;
+ Serial.println("Reconnecting");
+ // try to re-connect to OBD
+ if (init()) return;
#if ENABLE_DATA_LOG
- closeFile();
+ closeFile();
#endif
- // turn off GPS power
+ // turn off GPS power
#if USE_GPS
- initGPS(0);
+ initGPS(0);
#endif
- state &= ~(STATE_OBD_READY | STATE_GPS_READY);
- Serial.println("Standby");
- // put OBD chips into low power mode
- enterLowPowerMode();
-
- // calibrate MEMS for several seconds
- for (;;) {
-#if USE_MPU6050 || USE_MPU9250
- accSum[0] = 0;
- accSum[1] = 0;
- accSum[2] = 0;
- for (accCount = 0; accCount < 10; ) {
- readMEMS();
- delay(30);
- }
- // calculate relative movement
- unsigned long motion = 0;
- for (byte i = 0; i < 3; i++) {
- long n = accSum[i] / accCount - accCal[i];
- motion += n * n;
- }
- // check movement
- if (motion > START_MOTION_THRESHOLD) {
- Serial.println(motion);
- // try OBD reading
+ state &= ~(STATE_OBD_READY | STATE_GPS_READY);
+ Serial.println("Standby");
+ // put OBD chips into low power mode
+ enterLowPowerMode();
+
+ // calibrate MEMS for several seconds
+ for (;;) {
+#if USE_MPU6050
+ accSum[0] = 0;
+ accSum[1] = 0;
+ accSum[2] = 0;
+ for (accCount = 0; accCount < 10; ) {
+ readMEMS();
+ delay(30);
+ }
+ // calculate relative movement
+ unsigned long motion = 0;
+ for (byte i = 0; i < 3; i++) {
+ long n = accSum[i] / accCount - accCal[i];
+ motion += n * n;
+ }
+ // check movement
+ if (motion > START_MOTION_THRESHOLD) {
+ Serial.println(motion);
+ // try OBD reading
#endif
- leaveLowPowerMode();
- if (init()) {
- // OBD is accessible
- break;
- }
- enterLowPowerMode();
-#if USE_MPU6050 || USE_MPU9250
- // calibrate MEMS again in case the device posture changed
- calibrateMEMS();
+ leaveLowPowerMode();
+ if (init()) {
+ // OBD is accessible
+ break;
}
-#endif
+ enterLowPowerMode();
+#if USE_MPU6050
+ // calibrate MEMS again in case the device posture changed
+ calibrateMEMS();
}
+#endif
+ }
#ifdef ARDUINO_ARCH_AVR
- // reset device
- void(* resetFunc) (void) = 0; //declare reset function at address 0
- resetFunc();
+ // reset device
+ void(* resetFunc) (void) = 0; //declare reset function at address 0
+ resetFunc();
#else
- setup();
+ setup();
#endif
}
-#if USE_MPU6050 || USE_MPU9250
+#if USE_MPU6050
void calibrateMEMS()
{
- // get accelerometer calibration reference data
- if (accCount) {
- accCal[0] = accSum[0] / accCount;
- accCal[1] = accSum[1] / accCount;
- accCal[2] = accSum[2] / accCount;
- }
- }
+ // get accelerometer calibration reference data
+ if (accCount) {
+ accCal[0] = accSum[0] / accCount;
+ accCal[1] = accSum[1] / accCount;
+ accCal[2] = accSum[2] / accCount;
+ }
+ }
void readMEMS()
{
- // load accelerometer and temperature data
- int16_t acc[3] = {0};
- int16_t temp; // device temperature (in 0.1 celcius degree)
- memsRead(acc, 0, 0, &temp);
- if (accCount >= 250) {
- accSum[0] >>= 1;
- accSum[1] >>= 1;
- accSum[2] >>= 1;
- accCount >>= 1;
- }
- accSum[0] += acc[0];
- accSum[1] += acc[1];
- accSum[2] += acc[2];
- accCount++;
- deviceTemp = temp / 10;
+ // load accelerometer and temperature data
+ int16_t acc[3] = {0};
+ int16_t temp; // device temperature (in 0.1 celcius degree)
+ memsRead(acc, 0, 0, &temp);
+ if (accCount >= 250) {
+ accSum[0] >>= 1;
+ accSum[1] >>= 1;
+ accSum[2] >>= 1;
+ accCount >>= 1;
+ }
+ accSum[0] += acc[0];
+ accSum[1] += acc[1];
+ accSum[2] += acc[2];
+ accCount++;
+ deviceTemp = temp / 10;
}
- #endif
+#endif
byte state;
};
@@ -339,87 +350,87 @@ static COBDLogger one;
void setup()
{
- Serial.begin(115200);
- one.initSender();
- one.setup();
+ Serial.begin(115200);
+ one.initSender();
+ one.setup();
}
void loop()
{
#if ENABLE_DATA_LOG
- if (!(one.state & STATE_FILE_READY) && (one.state & STATE_SD_READY)) {
- if (one.state & STATE_GPS_FOUND) {
- // GPS connected
- Serial.print("File ");
- if (one.state & STATE_GPS_READY) {
- uint32_t dateTime = (uint32_t)MMDD * 10000 + UTC / 10000;
- if (one.openFile(dateTime) != 0) {
- Serial.println(dateTime);
- MMDD = 0;
- one.state |= STATE_FILE_READY;
- } else {
- Serial.println("File error");
- }
- }
- } else {
- // no GPS connected
- int index = one.openFile(0);
- if (index != 0) {
+ if (!(one.state & STATE_FILE_READY) && (one.state & STATE_SD_READY)) {
+ if (one.state & STATE_GPS_FOUND) {
+ // GPS connected
+ Serial.print("File ");
+ if (one.state & STATE_GPS_READY) {
+ uint32_t dateTime = (uint32_t)MMDD * 10000 + UTC / 10000;
+ if (one.openFile(dateTime) != 0) {
+ Serial.println(dateTime);
+ MMDD = 0;
one.state |= STATE_FILE_READY;
- Serial.println(index);
} else {
Serial.println("File error");
}
}
+ } else {
+ // no GPS connected
+ int index = one.openFile(0);
+ if (index != 0) {
+ one.state |= STATE_FILE_READY;
+ Serial.println(index);
+ } else {
+ Serial.println("File error");
+ }
}
+ }
#endif
- if (one.state & STATE_OBD_READY) {
- byte pids[]= {0, PID_RPM, PID_SPEED, PID_THROTTLE, PID_ENGINE_LOAD};
- byte pids2[] = {PID_COOLANT_TEMP, PID_INTAKE_TEMP, PID_DISTANCE};
- int values[sizeof(pids)];
- static byte index2 = 0;
- pids[0] = pids2[index2 = (index2 + 1) % sizeof(pids2)];
- // read multiple OBD-II PIDs
- if (one.readPID(pids, sizeof(pids), values) == sizeof(pids)) {
- one.dataTime = millis();
- for (byte n = 0; n < sizeof(pids); n++) {
- one.logData((uint16_t)pids[n] | 0x100, values[n]);
- }
- }
- if (one.errors >= 10) {
- one.reconnect();
- }
- } else {
- if (!OBD_ATTEMPT_TIME || millis() < OBD_ATTEMPT_TIME * 1000) {
- if (one.init()) {
- one.state |= STATE_OBD_READY;
- }
+ if (one.state & STATE_OBD_READY) {
+ byte pids[] = {0, PID_RPM, PID_SPEED, PID_THROTTLE, PID_ENGINE_LOAD};
+ byte pids2[] = {PID_COOLANT_TEMP, PID_INTAKE_TEMP, PID_DISTANCE};
+ int values[sizeof(pids)];
+ static byte index2 = 0;
+ pids[0] = pids2[index2 = (index2 + 1) % sizeof(pids2)];
+ // read multiple OBD-II PIDs
+ if (one.readPID(pids, sizeof(pids), values) == sizeof(pids)) {
+ one.dataTime = millis();
+ for (byte n = 0; n < sizeof(pids); n++) {
+ one.logData((uint16_t)pids[n] | 0x100, values[n]);
}
}
-
- // log battery voltage (from voltmeter), data in 0.01v
- int v = one.getVoltage() * 100;
- one.dataTime = millis();
- one.logData(PID_BATTERY_VOLTAGE, v);
-
-#if USE_MPU6050 || USE_MPU9250
- if ((one.state & STATE_MEMS_READY) && accCount) {
- // log the loaded MEMS data
- one.logData(PID_ACC, accSum[0] / accCount / ACC_DATA_RATIO, accSum[1] / accCount / ACC_DATA_RATIO, accSum[2] / accCount / ACC_DATA_RATIO);
+ if (one.errors >= 10) {
+ one.reconnect();
}
+ } else {
+ if (!OBD_ATTEMPT_TIME || millis() < OBD_ATTEMPT_TIME * 1000) {
+ if (one.init()) {
+ one.state |= STATE_OBD_READY;
+ }
+ }
+ }
+
+ // log battery voltage (from voltmeter), data in 0.01v
+ int v = one.getVoltage() * 100;
+ one.dataTime = millis();
+ one.logData(PID_BATTERY_VOLTAGE, v);
+
+#if USE_MPU6050
+ if ((one.state & STATE_MEMS_READY) && accCount) {
+ // log the loaded MEMS data
+ one.logData(PID_ACC, accSum[0] / accCount / ACC_DATA_RATIO, accSum[1] / accCount / ACC_DATA_RATIO, accSum[2] / accCount / ACC_DATA_RATIO);
+ }
#endif
#if USE_GPS
- if (one.state & STATE_GPS_FOUND) {
- one.logGPSData();
- }
+ if (one.state & STATE_GPS_FOUND) {
+ one.logGPSData();
+ }
#endif
#if ENABLE_DATA_LOG
- uint32_t logsize = sdfile.size();
- if (logsize > 0) {
- one.flushData();
- Serial.print(sdfile.size());
- Serial.println(" bytes");
- }
+ uint32_t logsize = sdfile.size();
+ if (logsize > 0) {
+ one.flushData();
+ Serial.print(sdfile.size());
+ Serial.println(" bytes");
+ }
#endif
}