Hello—I am trying to write some CO2 sensor data to an SD card using two peripherals on a Xenon: a UART CO2 sensor (COZIR-LP-5) and a Sparkfun microSD breakout. I’m running deviceOS 1.5.2. The code below does what I want it to (poll the UART CO2 sensor then write result to microSD) roughly ten times but then starts flashing red/SOS. It repeats this cycle indefinitely. I can confirm that data are being written to the microSD card as desired.
The code works properly/indefinitely if I comment out the SdFat parts. It also continues running, but never writes to the SD card, if I comment out just the myFile.close();
call at the end of void loop()
. So by all accounts, it appears to be a problem with my use of SdFat.
At the moment, I’m using the Xenon just as a microcontroller/development module, not for its mesh capabilities (and I’m aware it’s been discontinued) but since this appears to be a firmware issue, not a hardware one, I’d greatly appreciate any suggestions from you all to help me locate the cause of the crash! Thanks!
#include "SdFat.h"
int led = D7; // blink to let us know you're alive
bool led_state = HIGH; // starting state
//------------------COZIR LP UART Configuration Details--------------------------------
int co2 =0;
double multiplier = 1;// 1 for 2% =20000 PPM, 10 for 20% = 200,000 PPM
// Verify multiplication factor for COZIR-LP-5;
// put in COMMAND MODE "K 0" in setup
// Serial1.println("K 0");
// then run in loop()
// Serial1.println(".");
// while(Serial1.available()){
// Serial.print(Serial1.readString());
// }
uint8_t buffer[25];
uint8_t ind =0;
int fill_buffer(); // function prototypes here
int format_output();
//------------------SD SPI Configuration Details--------------------------------
File myFile;
SdFat sd;
const uint8_t chipSelect = SS;
SYSTEM_MODE(MANUAL);
SYSTEM_THREAD(ENABLED);
void setup() {
pinMode(led, OUTPUT);
Serial.begin(9600);
Serial.print("\n\n");
Serial.println(" Ardunio to COZIR CO2 Sensor - Demonstration code 2/14/18\n\n");
Serial1.begin(9600); // Start serial communications with sensor
// COZIR UART
//Serial1.println("K 0"); // Set Command mode
Serial1.println("M 6"); // send Mode for Z and z outputs
// "Z xxxxx z xxxxx" (CO2 filtered and unfiltered)
Serial1.println("K 1"); // set streaming mode
// SD Card
// Uncomment the following four lines for testing
// Serial.println("Type any character to start");
// while (Serial.read() <= 0) {
// SysCall::yield();
// }
// Initialize SdFat or print a detailed error message and halt
// Use half speed like the native library.
// Change to SPI_FULL_SPEED for more performance.
if (!sd.begin(chipSelect)) {
sd.initErrorHalt();
}
delay(3000);
// open the file for write at end like the "Native SD library"
if (!myFile.open("COZIR.txt", O_RDWR | O_CREAT | O_AT_END)) {
sd.errorHalt("opening test.txt for write failed");
}
// if the file opened okay, write to it:
Serial.print("Writing to test.txt...");
// myFile.println("testing 1, 2, 3.");
// myFile.printf("fileSize: %d\n", myFile.fileSize());
// close the file:
myFile.close();
Serial.println("done.");
}
void loop() {
led_state = !led_state; // toggle
digitalWrite(led, led_state); // command LED accordingly
// open the file for write at end
if (!myFile.open("COZIR.txt", O_RDWR | O_CREAT | O_AT_END)) {
sd.errorHalt("opening test.txt for write failed");
}
fill_buffer(); // function call that reads CO2 sensor and fills buffer
// Serial.print("Buffer contains: ");
// for(int j=0; j<ind; j++) Serial.print(buffer[j],HEX);
long unsigned raw_co2 = format_output(0);
// Serial.print(" Raw PPM ");
format_output(8);
// Serial.println(" Filtered PPM\n\n");
// if the file opened OK above, write to it and close file
char data[120];
snprintf(data, sizeof(data), "%lu,%lu",
Time.now(), raw_co2);
Serial.println(data);
myFile.println(data);
myFile.close();
delay(2000);
}
int fill_buffer(void){
// Fill buffer with sensor ascii data
ind = 0;
while(buffer[ind-1] != 0x0A){ // Read sensor and fill buffer up to 0XA = CR
if(Serial1.available()){
buffer[ind] = Serial1.read();
ind++;
}
}
// buffer() now filled with sensor ascii data
// ind contains the number of characters loaded into buffer up to 0xA = CR
ind = ind -2; // decrement buffer to exactly match last numerical character
return ind;
}
long unsigned format_output(uint8_t index){ // read buffer, extract 6 ASCII chars, convert to PPM and print
co2 = buffer[15-index]-0x30;
co2 = co2+((buffer[14-index]-0x30)*10);
co2 +=(buffer[13-index]-0x30)*100;
co2 +=(buffer[12-index]-0x30)*1000;
co2 +=(buffer[11-index]-0x30)*10000;
long unsigned final_co2 = co2*multiplier;
// Serial.print("\n CO2 = ");
// Serial.print(final_co2);
return final_co2;
}