/* Airplane Data Logging for Dynon EFIS-D10A, Dynon EMS-D10, Garmin GNS430W (c) 2022 Ken Staton issue: hot insert drive not always starting. don't worry about remove and re-insert. issue: clock sync. how long does backup battery last?? use GPS time for RTC sync when drifts more than 20 seconds measured data rates G: GPS Rx1 115 bytes/sec message end: '\x003' F: EFIS Rx2 3300 bytes/sec message end: '\n' E: EMS Rx3 480 bytes/sec message end: '\n' */ #define DEBUG false // USB serial debug printing // setup will BLOCK until USB serial starts #define UTCm7 (7*60*60) // your timezone relative to UTC in seconds #include "GPS_position.h" #include #include // Setup USBHost_t36 and as many HUB ports as needed. USBHost myusb; // Instances for the number of hubs USBHub hub1(myusb); // Instances for the number of USB drives you are using. USBDrive myDrive1(myusb); // Instances for accessing the files on each drive USBFilesystem myFiles1(myusb); // Timer events IntervalTimer myTimer; // vvv GLOBALS vvv File myFile; volatile bool tick = false; bool LED_ON = false; // https://www.pjrc.com/teensy/td_uart.html #define Serial1RxBufferSIZE 1024 // 10 seconds char Serial1RxBuffer[Serial1RxBufferSIZE]; // global scope or static char. power of 2. #define Serial2RxBufferSIZE 8192 // 2 seconds char Serial2RxBuffer[Serial2RxBufferSIZE]; // global scope or static char. power of 2. #define Serial3RxBufferSIZE 1024 // 2 seconds char Serial3RxBuffer[Serial3RxBufferSIZE]; // global scope or static char. power of 2. // ^^^ end GLOBAL ^^^ void TimerISR() { // callback for myTimer tick = true; // only sets global } void setup() { int i; char fname[16]; myTimer.begin(TimerISR, 100000); // period in microseconds = 0.1 sec setSyncProvider(getTeensy3Time); setSyncInterval(300); // default is 5 min. this call should force a sync if (DEBUG) { Serial.begin(115200); while (!Serial) { ; // wait for Arduino Serial Monitor to connect. } } if (DEBUG) RTCDisplay(); Serial1.begin(9600); // MUST match Garmin Serial1.addMemoryForRead(Serial1RxBuffer, Serial1RxBufferSIZE); Serial2.begin(115200); // MUST match Dynon EMS Serial2.addMemoryForRead(Serial2RxBuffer, Serial2RxBufferSIZE); Serial3.begin(115200); // MUST match Dynon EMS Serial3.addMemoryForRead(Serial3RxBuffer, Serial3RxBufferSIZE); SdFile::dateTimeCallback(dateTime); myusb.begin(); // .begin(USBDrive) is a temporary feature, future USBFilesystem will begin automatically if (DEBUG) Serial.println("\nInitializing USB drive 1..."); if (!myFiles1.begin(&myDrive1)) { if (DEBUG) Serial.print("initialization failed with code: "); if (DEBUG) myFiles1.printError(Serial); return; // setup() is done! } if (DEBUG) Serial.printf(F(" connected: %d\n"), myDrive1.msDriveInfo.connected); if (DEBUG) Serial.printf(F(" initialized: %d\n"), myDrive1.msDriveInfo.initialized); if (DEBUG) Serial.printf(F(" fs started: %d\n"), myDrive1.filesystemsStarted()); if (DEBUG) Serial.printf("Find next file number...\n"); i=next_file_number(); sprintf(fname,"Log%04d.txt",i); if (DEBUG) Serial.printf("Testing for file %s\n",fname); myFile = myFiles1.open(fname, FILE_WRITE); // see https://github.com/wwatson4506/UsbMscFat/blob/UsbMscFat-FS_DATES/examples/ReadWriteUSB/ReadWriteUSB.ino if (myFile) { if (DEBUG) Serial.printf("Writing to %s...\n",fname); myFile.println("Log Started "); // first line } else { // if the file didn't open, print an error: if (DEBUG) Serial.printf("error opening %s \n",fname); } if (DEBUG) RTCDisplay(); if (DEBUG) Serial.printf("t.s = %f\n", getdatetime()); if (DEBUG) Serial.println("init done..."); } // end of setup() int next_file_number() { // returns the first unused file number char fname[16]; bool fileexists = true; // assume true int i=0; // always start at 0 do { sprintf(fname,"Log%04d.txt",i); //Serial.printf("%s",fname); if (myFiles1.exists(fname) == 0) { fileexists=false; } else { i++; } } while (fileexists == true); return(i); } void RTCDisplay() { // display the time Serial.print(year()); Serial.print(" "); Serial.print(month()); Serial.print(" "); Serial.print(day()); Serial.print(" "); Serial.print(hour()); printDigits(minute()); printDigits(second()); Serial.println(); } void printDigits(int digits){ // utility function for digital clock display: prints preceding colon and leading 0 Serial.print(":"); if(digits < 10) Serial.print('0'); Serial.print(digits); } void toggleLED() { if (LED_ON) { digitalWrite(LED_BUILTIN, LOW); LED_ON = false; } else { /* LED_OFF */ digitalWrite(LED_BUILTIN, HIGH); LED_ON = true; } } void halt(int hz) { int t_ms; float period; period = 1.0/hz; t_ms = period * 1000/2; //if (DEBUG) Serial.printf("blink period %d\n",t_ms); // LED_BUILTIN interferes with I2C !! pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); while (true) { toggleLED(); delay(t_ms); } } // read about time https://www.pjrc.com/teensy/td_libs_Time.html // /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/Time/TimeLib.h time_t getTeensy3Time() { return Teensy3Clock.get(); } /* * User provided date time callback function. * See SdFile::dateTimeCallback() for usage. */ void dateTime(uint16_t* date, uint16_t* time) { // User gets date and time from GPS or real-time // clock in real callback function time_t now(); // return date using FAT_DATE macro to format fields via parameter pointer *date = FAT_DATE(year(), month(), day()); // return time using FAT_TIME macro to format fields via parameter pointer *time = FAT_TIME(hour(), minute(), second()); } time_t getdatetime(){ // gets time from GPS // returns time_t with nanoseconds as a float time_t t; TimeElements tm; t = 0 return(t); } void loop(void) { int i; char fname[16]; # process eom uart1 # process eom uart2 # process eom uart3 if (tick) { tick = false; if (myFile) { if (msg1>0) { myFile.print("G:"); # write(Rx1,msg1) msg1=0; } if (msg2>0) { myFile.print("F:"); # write(Rx2,msg2) msg2=0; } if (msg3>0) { myFile.print("E:"); # write(Rx3,msg3) msg3=0; } } else { /* open a new file */ myDrive1.begin(); myDrive1.startFilesystems(); if (DEBUG) Serial.print("try opening new file...\n"); if (DEBUG) Serial.println("\nInitializing USB drive 1..."); if (DEBUG) Serial.printf(F(" connected: %d\n"), myDrive1.msDriveInfo.connected); if (DEBUG) Serial.printf(F(" initialized: %d\n"), myDrive1.msDriveInfo.initialized); if (DEBUG) Serial.printf(F(" fs start: %d\n"), myDrive1.filesystemsStarted()); if (!myFiles1.begin(&myDrive1)) { if (DEBUG) Serial.print("initialization failed with code: "); if (DEBUG) myFiles1.printError(Serial); } i=next_file_number(); sprintf(fname,"Log%04d.txt",i); myFile = myFiles1.open(fname, FILE_WRITE); myFile.println("Log Started "); // first line } /* open new file */ } /* tick */ }