/*
MSC USB Drive datalogger
This example shows how to log data from three analog sensors
to an MSC USB drive using the mscFS library.
created 24 Nov 2010
modified 9 Apr 2012
by Tom Igoe
modified 17 Nov 2020
by Warren Watson
modified 23 June 2024
by J.G. Holstein
This example code is in the public domain.
*/
#include <USBHost_t36.h>
#include <TimeLib.h>
#include <SSD1322_for_Adafruit_GFX.h>
#include <U8g2lib.h>
#include <SPI.h>
#include "Profont29.h"
#include "Profont22.h"
#include "Profont17.h"
#include "Profont13.h"
#include "Profont15.h"
#include "Profont11.h"
#define OLED_CLK 13
#define OLED_MOSI 11
#define OLED_CS 10
#define OLED_DC 9
#define OLED_RESET 255
Adafruit_SSD1322 lcd(256, 64, &SPI, OLED_DC, OLED_RESET, OLED_CS);
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
USBHub hub3(myusb);
USBHub hub4(myusb);
USBDrive myDrive(myusb);
USBFilesystem firstPartition(myusb);
const int toggleSwitchPin = 1; // start stop datalog
bool loggingActive = false;
int switchState = LOW;
int lastSwitchState = LOW;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 200;
long record_count = 0;
bool write_data = false;
File dataFile;
bool usbInitialized = false;
time_t getTeensy3Time() {
return Teensy3Clock.get();
}
void setup() {
lcd.begin();
lcd.clearDisplay();
lcd.display();
lcd.setRotation(0);
lcd.setContrast(155);
Serial.begin(115200);
setSyncProvider(getTeensy3Time); // synchronise time and date after uploading firmware
lcd.setFont(&Profont17);
lcd.setCursor(2, 15);
lcd.print("USB drive data logging");
lcd.setCursor(2, 40);
lcd.print("Push start for logging");
lcd.display();
//setTime(16, 42, 00, 12, 8, 2022); // use this for GUI Pascal to set time and date if needed
pinMode(toggleSwitchPin, INPUT_PULLUP);
myusb.begin();
Serial.print("\nInitializing USB MSC drive...");
while (!firstPartition) {
myusb.Task();
}
Serial.println("USB drive initialized.");
usbInitialized = true;
menu();
}
void loop() {
int reading = digitalRead(toggleSwitchPin);
if (!firstPartition) {
usbInitialized = false;
Serial.println("USB drive removed.");
lcd.setCursor(40, 40);
lcd.print("USB drive removed.");
lcd.display();
lcd.clearDisplay();
}
if (!usbInitialized) {
Serial.print("\nReinitializing USB MSC drive...");
while (!firstPartition) {
myusb.Task();
}
Serial.println("USB drive reinitialized.");
usbInitialized = true;
lcd.setCursor(2, 15);
lcd.print("Push start for logging");
lcd.setCursor(35, 40);
lcd.print("USB drive inserted");
lcd.setCursor(55, 63);
lcd.print("USB drive ready");
lcd.display();
lcd.clearDisplay();
}
if (reading != lastSwitchState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != switchState) {
switchState = reading;
if (switchState == LOW) {
Serial.println(switchState);
loggingActive = !loggingActive;
if (loggingActive) {
startLogging();
} else {
stopLogging();
}
}
}
}
lastSwitchState = reading;
if (write_data) logData();
if (Serial.available()) {
char rr;
rr = Serial.read();
switch (rr) {
case 'l': listFiles(); break;
case 'e': eraseFile(); break;
case 'd': dumpLog(); break;
case '\r':
case '\n':
case 'h': menu(); break;
}
while (Serial.read() != -1);
}
}
void startLogging() {
Serial.println("\nLogging Data!!!");
write_data = true;
dataFile = firstPartition.open("datalog.csv", FILE_WRITE);
if (record_count == 0) {
dataFile.println("Date,Time,Pressure");
}
}
void stopLogging() {
Serial.println("\nStopped Logging Data!!!");
write_data = false;
dataFile.close();
lcd.setCursor(40, 15);
lcd.print("Logging stopped. ");
lcd.setCursor(2, 40);
lcd.print("USB drive, ");
lcd.setCursor(2, 62);
lcd.print("can be removed safely.");
lcd.display();
lcd.clearDisplay();
Serial.printf("Records written = %d\n", record_count);
}
void logData() {
lcd.setCursor(2, 16);
lcd.print("USB drive data logging,");
lcd.setCursor(0, 40);
lcd.print("in progress! ");
lcd.setCursor(0, 63);
lcd.print("Records written= ");
lcd.print(record_count);
lcd.display();
lcd.clearDisplay();
String dataString = "";
char dateBuffer[11]; // YYYY-MM-DD
snprintf(dateBuffer, sizeof(dateBuffer), "%04d-%02d-%02d", year(), month(), day());
char timeBuffer[9]; // HH:MM:SS
snprintf(timeBuffer, sizeof(timeBuffer), "%02d:%02d:%02d", hour(), minute(), second());
// test with A0 as sensor
int sensor = analogRead(A0);
dataString += dateBuffer;
dataString += ",";
dataString += timeBuffer;
dataString += ",";
dataString += String(sensor);
if (dataFile) {
dataFile.println(dataString);
Serial.println(dataString);
record_count += 1;
} else {
Serial.println("error opening datalog.csv");
}
delay(100); // log interval test 100ms
}
void dumpLog() {
Serial.println("\nDumping Log!!!");
// open the file.
dataFile = firstPartition.open("datalog.csv");
if (dataFile) {
while (dataFile.available()) {
Serial.write(dataFile.read());
}
dataFile.close();
}
else {
Serial.println("error opening datalog.csv");
}
}
void menu() {
Serial.println();
Serial.println("Menu Options:");
Serial.println("\tl - List files on disk");
Serial.println("\te - Erase log file on disk");
Serial.println("\td - Dump Log");
Serial.println("\th - Menu");
Serial.println();
}
void listFiles() {
Serial.print("\n Space Used = ");
Serial.println(firstPartition.usedSize());
Serial.print("Filesystem Size = ");
Serial.println(firstPartition.totalSize());
printDirectory(firstPartition);
}
void eraseFile() {
Serial.println("\nErasing datalog.csv");
firstPartition.remove("datalog.csv");
Serial.println("\ndatalog.csv erased !");
}
void printDirectory(FS &fs) {
Serial.println("Directory\n---------");
printDirectory(fs.open("/"), 0);
Serial.println();
}
void printDirectory(File dir, int numSpaces) {
while (true) {
File entry = dir.openNextFile();
if (!entry) {
break;
}
printSpaces(numSpaces);
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numSpaces + 2);
} else {
printSpaces(36 - numSpaces - strlen(entry.name()));
Serial.print(" ");
Serial.print(entry.size(), DEC);
DateTimeFields datetime;
if (entry.getModifyTime(datetime)) {
printSpaces(4);
printTime(datetime);
}
Serial.println();
}
entry.close();
}
}
void printSpaces(int num) {
for (int i = 0; i < num; i++) {
Serial.print(" ");
}
}
void printTime(const DateTimeFields tm) {
const char *months[12] = {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
};
if (tm.hour < 10) Serial.print('0');
Serial.print(tm.hour);
Serial.print(':');
if (tm.min < 10) Serial.print('0');
Serial.print(tm.min);
Serial.print(" ");
Serial.print(months[tm.mon]);
Serial.print(" ");
Serial.print(tm.mday);
Serial.print(", ");
Serial.print(tm.year + 1900);
}