How to improve frequency sampling in Teensy 3.5 for saving data with SD card?

Status
Not open for further replies.
Hi, I have previously posted a post asking how to save sensors data (EMG and Encoder) using a built in SD card reader in Teensy 3.5. I'm using this code below

Code:
#include <SoftwareSerial.h>
#include <SdFat.h>
//========================================= inisiasi
#define outputA 5 //untuk encoder
#define outputB 6
#define RawEMG A0
int counter = 0;
int derajat = 0;
int EMG;
int aState;
int aLastState;
long timenow = 0 ;
long timeprev = 0;
//========================================= variable
#define MaxCount 30000
float freqsampling = 1200;                      //Hz
float timesampling = (1/freqsampling)*1000;                             
int encoderPPR = 2048;                       // real ppr*2

SdFatSdio sd;
File file;

void setup() {
  pinMode (outputA, INPUT_PULLUP);
  pinMode (outputB, INPUT_PULLUP);
  Serial.begin(57600);
  if (!sd.begin()) {
    sd.initErrorHalt();
  }

  aLastState = digitalRead(outputA);
}

void doLogging(uint32_t timeStamp, int *data1, int *data2, int *data3, int nb)
{
  //================================================= init
  static uint32_t ifl = 0;
  static uint32_t count = 0;
  char filename[32];

  if (!count)
  {
    //open file
    sprintf(filename, "Data_Ramang_Retake01_06_2020-08(1200Hz)-%03d.csv", ifl); ifl++;
    if (!file.open(filename, O_RDWR | O_CREAT))  sd.errorHalt("open failed");

    // write header to file
    file.println("timeStamp,counter,derajat,EMG");

    // flag open file
    count = 1;
  }

  if (count > 0)
  {
    // write to file
    file.print(timeStamp);
    for (int ii = 0; ii < nb; ii++)
    { file.print(',');
      file.print(data1[ii]);
      file.print(',');
      file.print(data2[ii]);
      file.print(',');
      file.print(data3[ii]);
      
      Serial.print(counter);
      Serial.print(",");
      Serial.print(derajat);
      Serial.print(",");
      Serial.println(EMG);
    }
    file.println();
    count++;
    if (count > MaxCount) count = 0;
  }
  if (!count)
  {
    Serial.println("+++++++++++++++++++++++++SAVING DATA+++++++++++++++++++++++++++++++++++++++++++++++++++");
    file.close();
  }
}

void loop() {
  //========================================= read data
  uint32_t t0 = millis();
  EMG = analogRead (RawEMG);                       //reads EMG sensor
  //float EMG = EMG * (5.0 / 1023.0);
  aState = digitalRead(outputA);                   //reads the 'current' state of the outputA

  //========================================= do ... every "timesampling"
  timenow = millis();
  if (timenow - timeprev > timesampling) {
    timeprev = timenow;
//    Serial.print(counter);
//    Serial.print(",");
//    Serial.print(derajat);
//    Serial.print(",");
//    Serial.println(EMG);
    doLogging(t0, &counter, &derajat, &EMG, 1);    // Save data
  }

  //========================================= counter encoder to degrees
  if (aState != aLastState) {
    if (digitalRead(outputB) != aState) {
      counter ++;
    } else {
      counter --;
    }
    if (counter > encoderPPR or counter < -encoderPPR)
    {
      counter = 0;
    }
  }
  derajat = counter * 360 / encoderPPR;
  aLastState = aState;
}


It was working great since it was able to save the data and it have quite a stable frequency sampling although when I tried 200 Hz (for example), it will actually produce a frequency sampling of 166-ish Hz. I think this decrease of frequency sampling might be link to the Serial.print() function but I had to keep this to keep track if the sensors are reading correctly.

Is there any suggestions on improving the stability of the frequency sampling? I need to have a frequency sampling of 1000 Hz because the of nyquist frequency requirement for EMG.

Thank you
 
Status
Not open for further replies.
Back
Top