Found main logging routine (lines 611-740):
//Appends a stream of serial data to a given file
//Assumes the currentDirectory variable has been set before entering the routine
//We use the RX interrupt and a circular buffer of 1024 bytes so that we can capture a full stream of
//data even at 115200bps
//Does not exit until Ctrl+z (ASCII 26) is received
//Returns 0 on error
//Returns 1 on success
uint8_t append_file(char* file_name)
{
//44051
//This is the size of the receive buffer. The bigger it is, the less likely we will overflow the buffer while doing a record to SD.
//But we have limited amounts of RAM (~1100 bytes)
#define BUFF_LEN 250 //50 works well. Too few and we will call file.write A LOT. Too many and we run out of RAM.
//#define BUFF_LEN 400 //Fails horribly for some reason. Oh right, readSpot only goes to 255.
//#define BUFF_LEN 100 //Works well.
char inputBuffer[BUFF_LEN];
char escape_chars_received = 0;
byte readSpot = 0; //Limited to 255
byte incomingByte;
// O_CREAT - create the file if it does not exist
// O_APPEND - seek to the end of the file prior to each write
// O_WRITE - open for write
if (!file.open(currentDirectory, file_name, O_CREAT | O_APPEND | O_WRITE)) error("open1");
#if DEBUG
PgmPrintln("File open");
PgmPrintln("Recording");
#endif
Serial.print('<'); //give a different prompt to indicate no echoing
digitalWrite(statled1, HIGH); //Turn on indicator LED
//Clear out the serial buffer
Serial.flush();
//Start recording incoming characters
//HardwareSerial.cpp has a buffer tied to the interrupt. We increased this buffer to 512 bytes
//As characters come in, we read them in and record them to FAT.
while(1){
uint16_t timeout_counter = 0;
#if BOOTTIME_TESTING
boottime = millis(); //Get the time from power on to ready to receive
PgmPrint("Time until ready to recieve (ms): ");
Serial.println(boottime);
#endif
#if RAM_TESTING
PgmPrint("Free RAM receive ready: ");
Serial.println(FreeRam());
#endif
//Testing to try to get rid of long delay after the first synch
//This forces OpenLog to scan the fat table and get the pointers ready before the wave of data starts coming in
//currentDirectory.sync();
//file.write("123", 3);
//file.sync();
//file.close();
//if (!file.open(currentDirectory, file_name, O_CREAT | O_APPEND | O_WRITE)) error("open1");
while(!Serial.available()){ //Wait for characters to come in
if(timeout_counter++ > 1200){ //If we haven't seen a character for about 3 seconds, then record the buffer, sync the SD, and shutdown
timeout_counter = 0;
if(readSpot != 0){ //There is unrecorded stuff sitting in the buffer
//Record the buffer
if(file.write((byte*)inputBuffer, readSpot) != readSpot)
PgmPrintln("error writing to file");
}
file.sync(); //Push these new file.writes to the SD card
Serial.flush(); //Clear out the current serial buffer. This is needed if the buffer gets overrun. OpenLog will fail to read the escape character if
//the buffer gets borked.
//Reset the points so that we don't record these freshly recorded characters a 2nd time, when the unit receives more characters
readSpot = 0;
//Now power down until new characters to arrive
while(!Serial.available()){
digitalWrite(statled1, LOW); //Turn off stat LED to save power
sleep_mode(); //Stop everything and go to sleep. Wake up if serial character received
}
}
delay(1); //Hang out for a ms
}
incomingByte = Serial.read(); //Grab new character from hardwareserial.cpp buffer (could be 512 bytes)
//Scan for escape character
if(incomingByte == setting_escape_character){
#if DEBUG
Serial.print("!");
#endif
if(++escape_chars_received == setting_max_escape_character) break;
}
else
escape_chars_received = 0;
inputBuffer[readSpot++] = incomingByte; //Record character to the local buffer
if(readSpot == BUFF_LEN){ //If we've filled the local small buffer, pass it to the sd write function.
//Record the buffer
if(file.write((byte*)inputBuffer, BUFF_LEN) != BUFF_LEN){
PgmPrintln("error writing to file");
break;
}
readSpot = 0; //Wrap the buffer
}
STAT1_PORT ^= (1<<STAT1); //Toggle the STAT1 LED each time we receive a character
} //End while - escape character received or error
//Upon receiving the escape character, we may still have stuff left in the buffer, record the last of the buffer to memory
if(readSpot != BUFF_LEN){
//Record the buffer
if(file.write((byte*)inputBuffer, readSpot) != readSpot)
PgmPrintln("error writing to file");
}
file.sync();
file.close(); //Done recording, close out the file
digitalWrite(statled1, LOW); //Turn off indicator LED
#if DEBUG
PgmPrintln("Done!");
#endif
PgmPrint("~"); //Indicate a successful record
return(1); //Success!
}
Its core:
while(!Serial.available()){ //Wait for characters to come in
if(timeout_counter++ > 1200){ //If we haven't seen a character for about 3 seconds, then record the buffer, sync the SD, and shutdown
timeout_counter = 0;
if(readSpot != 0){ //There is unrecorded stuff sitting in the buffer
//Record the buffer
if(file.write((byte*)inputBuffer, readSpot) != readSpot)
PgmPrintln("error writing to file");
}
file.sync(); //Push these new file.writes to the SD card
Serial.flush(); //Clear out the current serial buffer. This is needed if the buffer gets overrun. OpenLog will fail to read the escape character if
//the buffer gets borked.
//Reset the points so that we don't record these freshly recorded characters a 2nd time, when the unit receives more characters
readSpot = 0;
//Now power down until new characters to arrive
while(!Serial.available()){
digitalWrite(statled1, LOW); //Turn off stat LED to save power
sleep_mode(); //Stop everything and go to sleep. Wake up if serial character received
}
}
delay(1); //Hang out for a ms
}
incomingByte = Serial.read(); //Grab new character from hardwareserial.cpp buffer (could be 512 bytes)
//Scan for escape character
if(incomingByte == setting_escape_character){
#if DEBUG
Serial.print("!");
#endif
if(++escape_chars_received == setting_max_escape_character) break;
}
else
escape_chars_received = 0;
I should change first line of the "core" to make it sensitive to a switch rather than serial input, so logging will stop upon turning on or off or pressing the switch: this will prevent data loss and file corruption w.r.t. just unplugging the device.
Then I'll have to change this line to properly read sensors and write data:
if(file.write((byte*)inputBuffer, readSpot) != readSpot)