Go Down

Topic: Program to log 3 serial ports and 4 analog inputs to an SD card (Read 1 time) previous topic - next topic


Hi there,

my question is how to simultaneously log 3 serial inputs (at 20 kbits/s each) and 4 analog inputs (at ~100Hz) to an SD card using the Arduino Mega?

I already wrote a program that logs binary data from the 3 serial ports to an SD card. This is all based on fat16lib's great work (see program below).

My question is how to add the logging of analog inputs at regular 10 ms intervals? The problem is that the SD write and sync commands all use a few ms. I guess I should buffer the analog data, and then write the buffer to the SD card, but I don't know where to add the commands.

Any help would be greatly appreciated!! And I hope someone may find the attached code useful!
Code: [Select]
//This program logs data from multiple serial ports to an SD card.
//Next step is to extend it with analog logging

#include <SdFat.h>
#include <SdFatUtil.h>  // define FreeRam()
#include <I2cMaster.h>
#include <SerialPort.h>
#define CHIP_SELECT     53  // SD chip select pin
#define LOG_INTERVAL  100  // mills between entries
#define ECHO_TO_SERIAL   1  // echo data to serial port if nonzero

uint8_t buf_1[128]; uint8_t buf_2[128]; uint8_t buf_3[128];
uint32_t DelayTime;

// Maximum time between sync() calls in milliseconds.
const uint32_t MAX_SYNC_TIME_MSEC = 1000;

// file system objects
SdFat sd; SdFat sd2;
SdFile file; SdFile file2; SdFile file3;

//Serialport settings
const uint32_t BAUD_RATE = 9600;
const byte SerialOptions = B100111; //Put B100111 to set 8/E/1 serial protocol
SerialPort<0, 0, 0> NewSerial0; // Create Serialport instance
SerialPort<1, 1024, 0> NewSerial1; // Create Serialport instance
SerialPort<2, 1024, 0> NewSerial2; // Create Serialport instance
SerialPort<3, 1024, 0> NewSerial3; // Create Serialport instance

// Serial print stream
ArduinoOutStream cout(NewSerial0);
// store error strings in flash to save RAM
#define error(s) sd.errorHalt_P(PSTR(s))
// call back for file timestamps
void setup() {
  NewSerial1.begin(BAUD_RATE, SerialOptions);
  NewSerial2.begin(BAUD_RATE, SerialOptions);
  NewSerial3.begin(BAUD_RATE, SerialOptions);

  // pstr stores strings in flash to save RAM
  cout << endl << pstr("FreeRam: ") << FreeRam() << endl;

  // initialize the SD card
  if (!sd.init(SPI_FULL_SPEED, CHIP_SELECT)) sd.initErrorHalt();

  //open files on SD card
  if (!file.open("SERIAL1.BIN", O_WRITE | O_CREAT | O_AT_END)) error("file.open");
  if (!file2.open("SERIAL2.BIN", O_WRITE | O_CREAT | O_AT_END)) error("file2.open");
  if (!file3.open("SERIAL3.BIN", O_WRITE | O_CREAT | O_AT_END)) error("file3.open");

  // make sure first cluster is allocated
  if (file.fileSize() == 0) {file.write((uint8_t)0); file.rewind(); file.sync();}
  if (file2.fileSize() == 0) {file2.write((uint8_t)0); file2.rewind(); file2.sync();}
  if (file3.fileSize() == 0) {file3.write((uint8_t)0); file3.rewind(); file3.sync();}

uint32_t syncTime = 0; uint32_t TimeItTakesToSync = 0;
void loop() {
  //Set loop iteration time
  DelayTime = LOG_INTERVAL - millis() % LOG_INTERVAL; delay(DelayTime);
//  cout << pstr("Delay time added = ") << DelayTime << endl;

  //Read out Serial port buffer
    uint16_t n1 = NewSerial1.read(buf_1, sizeof(buf_1));
    uint16_t n2 = NewSerial2.read(buf_2, sizeof(buf_2)); 
    uint16_t n3 = NewSerial3.read(buf_3, sizeof(buf_3)); 

  //Write to SD card
    if (n1 > 0) {if (file.write(buf_1, n1) != n1) error("write error");};
    if (n2 > 0) {if (file2.write(buf_2, n2) != n2) error("write2 error");};
    if (n3 > 0) {if (file3.write(buf_3, n3) != n3) error("write3 error");};
    DelayTime = (millis() - syncTime);
    if (DelayTime < MAX_SYNC_TIME_MSEC) return;
    //Sync SD card
    if (!file.sync()) error("sync error");
    if (!file2.sync()) error("sync2 error"); 
    if (!file3.sync()) error("sync3 error");

   // Go into endless loop after specified number of ms to stop logging
    syncTime = millis();
    if (syncTime > 5000) {
      while (syncTime>5000) {delay(10);}


Go Up