Home › Forums › Mayfly Data Logger › How to dump contents of file on SD card to serial
Tagged: BT, SerialCOmmand
- This topic has 6 replies, 3 voices, and was last updated 2021-08-13 at 11:14 PM by neilh20.
-
AuthorPosts
-
-
2021-07-01 at 1:08 PM #15641
I had a working sketch that allowed me to transfer the contents of a file on the SD card using bluetooth. I switched over to the Mayfly board and am now using code from the menu-a-la-carte; however, when incorporating the lines of code previously used to dump the file contents. I get an error indicating ‘reference to File is ambiguous’. I think this has something to do with how Loggerbase.h and SD.h name files. The lines of code to execute the file dump is contained in Void ShowData() in the sketch. Anyone able to do this for their own sketches?
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247/** =========================================================================* @file simple_logging.ino* @brief A simple data logging example.** @author Sara Geleskie Damiano <sdamiano@stroudcenter.org>* @copyright (c) 2017-2020 Stroud Water Research Center (SWRC)* and the EnviroDIY Development Team* This example is published under the BSD-3 license.** Build Environment: Visual Studios Code with PlatformIO* Hardware Platform: EnviroDIY Mayfly Arduino Datalogger** DISCLAIMER:* THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN.* ======================================================================= */// ==========================================================================// Include the libraries required for any data logger// ==========================================================================/** Start [includes] */// The Arduino library is needed for every Arduino program.#include <Arduino.h>// EnableInterrupt is used by ModularSensors for external and pin change// interrupts and must be explicitly included in the main program.#include <EnableInterrupt.h>// To get all of the base classes for ModularSensors, include LoggerBase.// NOTE: Individual sensor definitions must be included separately.#include <LoggerBase.h>#include<SoftwareSerial.h>#include <SD.h>#include <Wire.h>#include "Sodaq_DS3231.h"DateTime dt(2021, 06, 29, 4, 10, 0, 0); //Set the date and time everytime you download the program to initiate the clock// ==========================================================================// Data Logging Options// ==========================================================================/** Start [logging_options] */String fileName;// The name of this program fileconst char* sketchName = "Madison Wetpond.ino";// Logger ID, also becomes the prefix for the name of the data file on SD cardconst char* LoggerID = "East";// How frequently (in minutes) to log dataconst uint8_t loggingInterval = 15;// Your logger's timezone.const int8_t timeZone = -6; // Eastern Standard Time// NOTE: Daylight savings time will not be applied! Please use standard time!// Set the input and output pins for the logger// NOTE: Use -1 for pins that do not applyconst int32_t serialBaud = 115200; // Baud rate for debuggingconst int8_t greenLED = 8; // Pin for the green LEDconst int8_t redLED = 9; // Pin for the red LEDconst int8_t buttonPin = 21; // Pin for debugging mode (ie, button pin)const int8_t wakePin = A7; // MCU interrupt/alarm pin to wake from sleep// Set the wake pin to -1 if you do not want the main processor to sleep.// In a SAMD system where you are using the built-in rtc, set wakePin to 1const int8_t sdCardPwrPin = -1; // MCU SD card power pinconst int8_t sdCardSSPin = 12; // SD card chip select/slave select pinconst int8_t sensorPowerPin = 22; // MCU pin controlling main sensor power/** End [logging_options] */// ==========================================================================// Using the Processor as a Sensor// ==========================================================================/** Start [processor_sensor] */#include <sensors/ProcessorStats.h>// Create the main processor chip "sensor" - for general metadataconst char* mcuBoardVersion = "v0.5b";ProcessorStats mcuBoard(mcuBoardVersion);/** End [processor_sensor] */// ==========================================================================// Maxim DS3231 RTC (Real Time Clock)// ==========================================================================/** Start [ds3231] */#include <sensors/MaximDS3231.h> // Includes wrapper functions for Maxim DS3231 RTC// Create a DS3231 sensor object, using this constructor function:MaximDS3231 ds3231(1);/** End [ds3231] */// ==========================================================================// InSitu RDO PRO-X Rugged Dissolved Oxygen Probe// ==========================================================================#include <sensors/InSituRDO.h>const char* RDOSDI12address = "5"; // The SDI-12 Address of the RDO PRO-Xconst int8_t RDOPower = -1;//sensorPowerPin; // Power pin (-1 if unconnected)const int8_t RDOData = 7; // The SDI12 data pinconst uint8_t RDONumberReadings = 3;// Create an In-Situ RDO PRO-X dissolved oxygen sensor objectInSituRDO insituRDO(*RDOSDI12address, RDOPower, RDOData, RDONumberReadings);// ==========================================================================// Decagon ES2 Conductivity and Temperature Sensor// ==========================================================================#include <sensors/DecagonES2.h>const char* ES2SDI12address = "1"; // The SDI-12 Address of the ES2const int8_t ES2Power = sensorPowerPin; // Power pin (-1 if unconnected)const int8_t ES2Data = 11; // The SDI12 data pinconst uint8_t ES2NumberReadings = 5;// Create a Decagon ES2 sensor objectDecagonES2 es2(*ES2SDI12address, ES2Power, ES2Data, ES2NumberReadings);// ==========================================================================// Creating the Variable Array[s] and Filling with Variable Objects// ==========================================================================/** Start [variable_arrays] */Variable* variableList[] = {new ProcessorStats_SampleNumber(&mcuBoard),// new ProcessorStats_FreeRam(&mcuBoard),new ProcessorStats_Battery(&mcuBoard),new MaximDS3231_Temp(&ds3231),new InSituRDO_DOpct(&insituRDO,""),new InSituRDO_DOmgL(&insituRDO,""),new InSituRDO_Temp(&insituRDO,""),new InSituRDO_Pressure(&insituRDO,""),new DecagonES2_Cond(&es2),new DecagonES2_Temp(&es2),};// Count up the number of pointers in the arrayint variableCount = sizeof(variableList) / sizeof(variableList[0]);// Create the VariableArray objectVariableArray varArray;/** End [variable_arrays] */// ==========================================================================// The Logger Object[s]// ==========================================================================/** Start [loggers] */// Create a logger instanceLogger dataLogger;/** End [loggers] */// ==========================================================================// Working Functions// ==========================================================================/** Start [working_functions] */// Flashes the LED's on the primary boardvoid greenredflash(uint8_t numFlash = 4, uint8_t rate = 75) {for (uint8_t i = 0; i < numFlash; i++) {digitalWrite(greenLED, HIGH);digitalWrite(redLED, LOW);delay(rate);digitalWrite(greenLED, LOW);digitalWrite(redLED, HIGH);delay(rate);}digitalWrite(redLED, LOW);}/** End [working_functions] */// ==========================================================================// Arduino Setup Function// ==========================================================================/** Start [setup] */void setup() {// Start the primary serial connectionSerial.begin(serialBaud);Serial1.begin(9600);Wire.begin();rtc.begin();// rtc.setDateTime(dt);// Print a start-up note to the first serial portSerial.print(F("Now running "));Serial.print(sketchName);Serial.print(F(" on Logger "));Serial.println(LoggerID);Serial.println();Serial.print(F("Using ModularSensors Library version "));Serial.println(MODULAR_SENSORS_VERSION);// Set up pins for the LED'spinMode(greenLED, OUTPUT);digitalWrite(greenLED, LOW);pinMode(redLED, OUTPUT);digitalWrite(redLED, LOW);// Blink the LEDs to show the board is on and starting upgreenredflash();// Set the timezones for the logger/data and the RTC// Logging in the given time zoneLogger::setLoggerTimeZone(timeZone);// It is STRONGLY RECOMMENDED that you set the RTC to be in UTC (UTC+0)Logger::setRTCTimeZone(0);// Set information pinsdataLogger.setLoggerPins(wakePin, sdCardSSPin, sdCardPwrPin, buttonPin,greenLED);// Begin the variable array[s], logger[s], and publisher[s]varArray.begin(variableCount, variableList);dataLogger.begin(LoggerID, loggingInterval, &varArray);// Set up the sensorsSerial.println(F("Setting up sensors..."));varArray.setupSensors();// Create the log file, adding the default header to it// Do this last so we have the best chance of getting the time correct and// all sensor names correctdataLogger.createLogFile(true); // true = write a new header// Call the processor sleepdataLogger.systemSleep();}/** End [setup] */// ==========================================================================// Arduino Loop Function// ==========================================================================/** Start [loop] */void loop() {if (Serial1.available() > 0) {ShowData();}dataLogger.logData();}/** End [loop] *//*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/void ShowData() {File fileName = SD.open("East_2021-07-01.csv");if (fileName) {while (fileName.available()) {Serial1.write(fileName.read());}fileName.close();}// if the file isn't open, pop up an error:else {Serial1.println("error opening datalog.txt");}} -
2021-07-13 at 1:58 PM #15665
Hi @Selbig. Here is a very simple sketch that prints a file from the microSD card to the serial monitor. It might be too rudimentary for your purposes, but thought I would share it here. Notice the line “// SD.remove(“datalog.txt”);” is commented out. Uncomment this line to DELETE the file specified instead of printing it to the serial monitor. I find it is helpful for my work to have this option available when I need it.
Arduino12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970//This sketch displays the files on a Mayfly Data Logger microSD card to the serial monitor and then outputs//a specific file named in the sketch below to the serial monitor.#include <SPI.h>#include <SD.h>File root;void setup() {Serial.begin(9600); // Open serial communications and wait for port to openwhile (!Serial) {; // wait for serial port to connect. Needed for native USB port only}Serial.print("Initializing SD card...");if (!SD.begin(12)) { // digital pin 12 is the microSD slave select pin on Mayfly; see if the card is present and can be initializedSerial.println("Card failed, or not present"); // don't do anything morewhile (1);}Serial.println("card initialized.");Serial.println("");root = SD.open("/");Serial.println("Files on microSD card");printDirectory(root, 0);Serial.println("");Serial.println("Displaying file:");// SD.remove("datalog.txt"); // THE NUCLEAR OPTION!!! UNCOMMENT TO DELETE THE FILE!File dataFile = SD.open("datalog.txt"); // Name the file to be opened.if (dataFile) { // if the file is available, write to it:while (dataFile.available()) {Serial.write(dataFile.read());}dataFile.close();}else {Serial.println("error opening datalog.txt"); // if the file isn't open, pop up an error:}}void loop() {// put your main code here, to run repeatedly:}void printDirectory(File dir, int numTabs) { //This is a function that displays all the files on the SD card to the serial monitor.while (true) {File entry = dir.openNextFile();if (! entry) {// no more filesbreak;}for (uint8_t i = 0; i < numTabs; i++) {Serial.print('\t');}Serial.print(entry.name());if (entry.isDirectory()) {Serial.println("/");printDirectory(entry, numTabs + 1);} else {// files have sizes, directories do notSerial.print("\t\t");Serial.println(entry.size(), DEC);}entry.close();}} -
2021-08-08 at 3:01 PM #15820
This sketch is also available here: https://github.com/ScottEnsign/SDoutput. I’d welcome input and refinement.
-
2021-08-11 at 6:16 PM #15830
Hi I’ve been thinking/working on something slightly similar when @ensign posted above.
BTW I found the github.com/ScottEnsign/SDoutput hasn’t got the actual code, I think it probably needs a “git push” to send the code up.
Seems to me the issue with the @selbig original post #15641 above, is that the SD card is initialized in Logger, so ShowData() needs to be an extension to LoggerBase.x : Class Logger {}
From @selbig post transfer-file-from-sd-card-to-ios-android-via-bluetooth post I’ve been thinking about adding BT ……
So I believe the Software Use Case is:
User approaches a Mayfly/BT logger, and with the BT enabled phone, connects to the Mayfly-BT logger, and downloads the readings, also verifies the logger time is accurate.
This could be done with developing an App that possibly uses an embedded remote procedure call (eRpc). However its a lot of skills.
Another version might be ; User approaches a Mayfly/BT logger, and with the BT enabled phone, connects to the Mayfly-BT logger with a terminal app that uses the BT serial pass through, and then commands the Mayfly to downloads the readings with “LR” (list readings) . Another separate command can list the time Mayfly date/time (D?), and also set the Mayfly time with D YYMMDD HHMM.
I have a system that I am thinking of this for,  inexpensive-diy-conductivity-sensor  that currently has Boot Net (walk up and get data).
Some baby steps in getting there, has been developing a Mayfly SerialCommand interface, and its just about there – see Arduino-SerialCommand This solves a problem of how to check date in the field.
Initially I developed an interface using a simple String to collect the serial user input data. However using String led to a terrible bug, as the Mayfly Rx input is floating (Mayfly Issue#28) and so can cause random bursts of characters, which with String meant it periodically fractured the heap and lobotomized the ram. See eight-tips-to-use-the-string-class-efficiently. The hardware fix for the Mayfly is to add a dongle to J2 “FTDI Programmer” port, with a 1M resistor pull down to the Rx pin3
I’ve just switched to a serial command – and added the context for “LR” and “L?” to tu_serialCmd.h
The next stages are to get the file listing, and then to try the BT context with the Serial Command being processed from the BT serial interface.
One other issue is that with the UART serial port 115200baud, the serial input is misread about 20% of the time – I’m guessing the baud rate doesn’t quite line up. I wouldn’t think this would happen with BT.
-
2021-08-13 at 10:29 PM #15833
So it worked for me. I took @ensign basic structure, and added it as an extension in the Class Logger, and then attached it to the two SerialCommands LR and L?
and
-
2021-08-13 at 11:10 PM #15834
Listing the active logger file, recorded by TeraTerm with time stamp,
1234567891011121314151617181920212223242526272829[2021-08-13 18:56:11.013] Enter cmd: ?<CR> for help.(need a key to be typed every 20 secs)[2021-08-13 18:56:11.607] LR[2021-08-13 18:56:12.982] Data Logger: TU_RC_test04b[2021-08-13 18:56:13.013] Data Logger File: TU_RC_test04b_2021-08-13.csv[2021-08-13 18:56:13.060] Location: "At TU-RCtest04 simRiverX Monitor"[2021-08-13 18:56:13.107] LoggingInterval (min): 2[2021-08-13 18:56:13.138] Tz: -8[2021-08-13 18:56:13.154] BatteryType: 2[2021-08-13 18:56:13.169] Sw Name: nano MMW/LTE. Sw Build: src\tu_xx01.cpp Aug 13 2021 16:24:58[2021-08-13 18:56:13.247] ModularSensors vers 0.30.0[2021-08-13 18:56:13.279] Board: mayfly rev:'0.5bR02' sn:'MAYFLY20395'[2021-08-13 18:56:13.326] Digi XBee Wi-Fi Sn 409D8F66F1 HwVer 2730 FwVer 2026[2021-08-13 18:56:13.497] Sampling Feature UUID: 2c7bd08e-355c-4ba5-80a3-f61745ff2e0c,[2021-08-13 18:56:13.560] "Sensor Name:","EnviroDIY Mayfly","Stc3100Sensor","Stc3100Sensor","Calculated","EnviroDIY Mayfly","KellerNanolevel","KellerNanolevel"[2021-08-13 18:56:13.716] "Variable Name:","sequenceNumber","electricEnergy","electricEnergy","batteryVoltage","batteryVoltage","temperature","gaugeHeight"[2021-08-13 18:56:13.872] "Result Unit:","Dimensionless","milliAmpHour","milliAmpHour","volts","volt","degreeCelsius","meter"[2021-08-13 18:56:13.982] "Result UUID:","c49c2646-57a5-4706-982e-234c5e68d878","5aa7c45b-aa60-41c9-ba0f-2449583a8080","9614a087-744b-4dc1-a657-5e6b234212d0","563f2971-ebe4-4a74-9ed7-f8cd2907215a","78e07e3b-5660-4118-930a-e91b489f5142","b188e862-2e0a-4381-8918-be777ac48735","c673e643-7d8b-4a7c-9bf5-eabcdcedea17"[2021-08-13 18:56:14.279] "Date and Time in UTC-8","SampNum","STC3100avblmAhr","STC3100usedmAhr","Stc3100_V","Battery","kellerNanoTemp","kellerNanoHeight"[2021-08-13 18:56:14.419] 2021-08-13 15:27:22,1,-9999.000,-9999.000,0.0000,4.700,-9999.00,-9999.0000[2021-08-13 18:56:14.497] 2021-08-13 15:29:29,1,-9999.000,-9999.000,0.0000,4.685,-9999.00,-9999.0000[2021-08-13 18:56:14.607] 2021-08-13 15:32:00,2,-9999.000,-9999.000,0.0000,4.776,-9999.00,-9999.0000[2021-08-13 18:56:14.685] 2021-08-13 15:34:00,3,-9999.000,-9999.000,0.0000,4.776,-9999.00,-9999.0000[2021-08-13 18:56:14.763] 2021-08-13 15:36:00,4,-9999.000,-9999.000,0.0000,4.776,-9999.00,-9999.0000[2021-08-13 18:56:14.841] 2021-08-13 15:38:57,1,-9999.000,-9999.000,0.0000,4.670,-9999.00,-9999.0000[2021-08-13 18:56:14.935] 2021-08-13 15:40:00,2,-9999.000,-9999.000,0.0000,4.776,-9999.00,-9999.0000[2021-08-13 18:56:15.013] 2021-08-13 15:42:00,3,-9999.000,-9999.000,0.0000,4.776,-9999.00,-9999.0000[2021-08-13 18:56:15.091] 2021-08-13 15:44:00,4,-9999.000,-9999.000,0.0000,4.776,-9999.00,-9999.0000[2021-08-13 18:56:15.169] 2021-08-13 15:46:00,5,-9999.000,-9999.000,0.0000,4.776,-9999.00,-9999.0000[2021-08-13 18:56:15.263] 2021-08-13 15:50:00,1,-9999.000,-9999.000,0.0000,4.776,-9999.00,-9999.0000 -
2021-08-13 at 11:14 PM #15835
Listing the directory with L? needs a bit of cleanup but looks like this
12345678910111213[2021-08-13 18:55:32.110] Enter cmd: ?<CR> for help.(need a key to be typed every 20 secs)[2021-08-13 18:55:42.232] L?[2021-08-13 18:55:42.232] Files on microSD card[2021-08-13 18:55:42.232] System Volume Information/[2021-08-13 18:55:42.232] TU_RC_test04b_2021-07-29a.csv 2116[2021-08-13 18:55:42.232] DBG2108.log 255147[2021-08-13 18:55:42.232] TU_RC_test04b_2021-07-29.csv 140664[2021-08-13 18:55:42.232] TU_RC_test04b_2021-08-01.csv 32606[2021-08-13 18:55:42.232] TU_RC_test04b_2021-08-02.csv 48810[2021-08-13 18:55:42.232] TU_RC_test04b_2021-08-03.csv 7969[2021-08-13 18:55:42.232] TU_RC_test04b_2021-08-10.csv 1312[2021-08-13 18:55:42.232] TU_RC_test04b_2021-08-13.csv 6212[2021-08-13 18:55:42.294] ms_cfg.ini 3518
-
-
AuthorPosts
- You must be logged in to reply to this topic.