Go Down

Topic: Feather M0 adalogger high speed data logger (Read 323 times) previous topic - next topic

AdamM18

Oct 16, 2018, 04:54 pm Last Edit: Oct 19, 2018, 01:50 pm by AdamM18 Reason: Adding prototype code
So I've been working on a project with a few guys and I need to create a voltage data logger that will store 1 data point (minimum 8 bits) per millisecond (I know it's a bit fast). The system needs to create a new file and start logging every time i press a button and stop once pressed again. I have been messing with Arduino IDE and some circuits for a while now but I have little programming experience. I assume I'll need to buffer some data and send blocks of data to the SD card to maintain a minimum 1 kHz log rate. Will someone please help me with some code for this?

I am using the Feather M0 Adalogger, 16GB fat32 micro SDHC card, and a spring loaded button; default off position. (I will most likely use the INA219 Current Sensor Breakout but I need the code done by the time I get a sensor :/ )
*I am now using a temporary current sensor for the purposes of testing*

After a couple days of research this is as far as I've got with my code.
Code: [Select]

#include <SPI.h>
#include <SD.h>

#define chipSelect 4

File logfile;

void setup() {
  while (!Serial) {}

  Serial.begin(9600);
  Serial.println("Press button to start logging");

  if (!SD.begin(chipSelect)) {
    Serial.println("Card init. failed!");
  }
}
uint8_t state = 0;
uint8_t i = 0;
uint8_t ButtonRead;

void loop() {
    if (digitalRead(13) == HIGH) {
    ButtonRead = HIGH;
  }
  else {
    ButtonRead = LOW;
  }
  if (ButtonRead == HIGH) {
    if (state == 0)
    {
      char DataFile[9];
      strcpy(DataFile, "file00.TXT");
      for (uint8_t i = 0; i < 100; i++) {
        DataFile[4] = '0' + i / 10;
        DataFile[5] = '0' + i % 10;
        if (! SD.exists(DataFile)) {
          break;
        }
      }
      logfile = SD.open(DataFile, FILE_WRITE);
      if (!logfile) {
        Serial.println("Could not create file");
        logfile.close();
        ButtonRead = LOW;
        delay(1500);
        return;
      }
      else {
        state = 255;
        Serial.print("Created ");
        Serial.println(DataFile);
      }
    }
    else
    {
      state = 0;
      logfile.close();
      ButtonRead = LOW;
      delay(1500);
      return;
    }
  }
  if (state == 255)
  {
    logfile.print(analogRead(A1));
    logfile.print(" , ");
    logfile.println(millis());
    Serial.print(analogRead(A1));
    Serial.print(" , ");
    Serial.println(millis());
  }
}


Thanks for the help.

PaulS

Code: [Select]
    if (digitalRead(13) == HIGH) {
    ButtonRead = HIGH;
  }
  else {
    ButtonRead = LOW;
  }

Why are you using 6 lines of code, when one will do?
Code: [Select]
  ButtonRead = digitalRead(13);

Your code would be faster if you didn't read the analog pin twice. Your code would be faster if you were not using stone age speeds sending serial data to the serial port/PC.

What speed ARE you able to accomplish now?
The art of getting good answers lies in asking good questions.

AdamM18

The code I have posted is rather old. I updated it and removed anything that has to do with the monitor (which I intended to do before finishing).For some reason when I run the code without any Serial commands, the file created won't open. This is what i have so far;

Code: [Select]
#include <SPI.h>
#include "SdFat.h"
SdFat SD;
#define chipSelect 4
#define gLED 8
#define rLED 13
File logfile;

byte state = 0;
byte i = 0;
uint16_t ButtonRead;

void setup() {
  pinMode(gLED, OUTPUT);
  pinMode(rLED, OUTPUT);
  digitalWrite(rLED, LOW);

}
void loop() {
  ButtonRead = digitalRead(A2);

  if (ButtonRead == HIGH) {
    delay(1500);
    if (state == 0)
    {
      char DataFile[9];
      strcpy(DataFile, "File00.TXT");
      for (byte i = 0; i < 100; i++) {
        DataFile[4] = '0' + i / 10;
        DataFile[5] = '0' + i % 10;
        if (! SD.exists(DataFile)) {
          break;
        }
      }
      logfile = SD.open(DataFile, FILE_WRITE);
      if (!logfile) {
        logfile.close();
        ButtonRead = LOW;
        digitalWrite(rLED, HIGH);
        delay(1000);
        digitalWrite(rLED, LOW);
        return;
      }
      else {
        state = 255;
        digitalWrite(gLED, HIGH);
        delay(500);
        digitalWrite(gLED, LOW);
      }
    }
    else
    {
      state = 0;
      digitalWrite(rLED, HIGH);
      logfile.close();
      ButtonRead = LOW;
      delay(500);
      digitalWrite(rLED, LOW);
      return;
    }
  }
  if (state == 255)
  {
    logfile.print(analogRead(A1));
    logfile.print(",");
    logfile.println(millis());
    delayMicroseconds(100);
  }
}


The data is not as accurate as I would like, did I miss something? Here is some of the data collected with the Serial commands still in the code; (the analog reading on the left will be dealt with later)

1023,16580
1023,16581
1023,16581
1023,16582
1023,16583
1023,16584
1023,16585
1023,16586
1023,16587
1023,16588
1023,16589
1023,16590
1023,16591
1023,16592
1023,16593
1023,16594
1023,16594
1023,16595
1023,16596
1023,16597
1023,16598
1023,16706
1023,16707
1023,16708
1023,16709
1023,16710

PaulS

The SD card reader/writer is an SPI device. Look up what that means in terms of the pins used. You can not use those pins for ANYTHING else.
The art of getting good answers lies in asking good questions.

Go Up