Very Slow less than 1kHz Sample Rate

cauthon180
Posts: 1
Joined: Thu Apr 11, 2019 4:52 am

Very Slow less than 1kHz Sample Rate

Postby cauthon180 » Thu Apr 11, 2019 5:16 am

Hi all,

I'm pretty novice at both arduino, esp-idf, and programming in general, but I am working on a project to take EMG signals (muscle activity) and send it over WiFi to a computer for analysis. So far, I seem to have gotten it working overall, except for the fact that I cannot get a sample rate faster than 125 Hz! Ideally, I need to reach at least 1000 Hz sample rate to get a good signal.

I have tried interrupts, and rtos for multitasking, but nothing has worked. I have even tried an empty loop simply printing micros() since the last loop, and even that only goes ~600 Hz Everywhere I look online, everyone is able to reach 30k+ Hz sample rate. What am I doing wrong?

I've attached my code that uses interrupts (again, much of this is pasted from resources online). Using the adafruit feather board, wroom-32

Thank you!

Code: Select all

// Include Libraries
#include "Arduino.h"
#include <WiFi.h>
#include <WiFiClient.h>
#include "SparkFunLSM6DS3.h"
#include "Wire.h"
#include "SPI.h"
#include <MadgwickAHRS.h>
#include "esp_wpa2.h" //wpa2 library for connections to Enterprise networks

LSM6DS3 myIMU(SPI_MODE,21); //Default constructor is I2C, addr 0x6B
Madgwick filter;
float EMA_a = 0.3;    //initialization of EMA alpha
uint16_t EMA_S = 0;        //initialization of EMA S

#define EAP_ANONYMOUS_IDENTITY "anonymous@example.com"
#define EAP_IDENTITY "******"
#define EAP_PASSWORD "*******"
const char* ssid = "*****"; // Eduroam SSID
//const char* host = "arduino.php5.sk"; //external server domain for HTTP connection after authentification
uint16_t counter = 0;
bool wifistat = false;
WiFiClient client;

unsigned long microsPerReading, microsPrevious, timer, microfreq, currentaccel, currentemg, currentprint, previousaccel=millis(), previousemg=millis(), previousprint=millis();

//// Set these to your desired credentials.
//const char *ssid = "GGesp32";
//const char *password = "capstone";

WiFiServer server(80);

//Timer Interrupts
hw_timer_t *acceltimer = NULL;
hw_timer_t *emgtimer = NULL;
hw_timer_t *printtimer = NULL;
bool updateEMG = false;
bool updateAccel = false;
bool updatePrint = false;


// Initialize Analog Pins
uint16_t EMGLeftRA_pin = 39; //A3
uint16_t EMGRightRA_pin = 34; //A2
uint16_t EMGLeftOb_pin = 36; //A4
uint16_t EMGRightOb_pin = 33; //33
uint16_t EMGErect_pin = 32; //32

// Initialize EMG Aquisition Variables
uint16_t EMGleftRA=0;
uint16_t EMGrightRA=0;
uint16_t EMGleftob=0;
uint16_t EMGrightob=0;
uint16_t EMGerect=0;

// Initialize Mapping for EMG data
uint16_t Min = 0;
uint16_t Max = 4095;
uint16_t Map_Min= 0;
uint16_t Map_Max= 2200;

//Initialize Accelerometer Data
float AccelX=0;
float AccelY=0;
float AccelZ=0;
float roll, pitch, heading;

//Initialize Gyrometer Data
float GyroX=0;
float GyroY=0;
float GyroZ=0;

/*
 * setup function
 */

double modifiedMap(double x, double in_min, double in_max, double out_min, double out_max)
{
 return round(((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)*10)/10;
}

void IRAM_ATTR onEMGTimer(){
  updateEMG = true;
}

void IRAM_ATTR onAccelTimer(){
  updateAccel = true;
}

void startTimer(){
  acceltimer = timerBegin(0,80,true);
  emgtimer = timerBegin(3,80,true);
  timerAttachInterrupt(acceltimer,&onAccelTimer,true);
  timerAttachInterrupt(emgtimer,&onEMGTimer,true);
  timerAlarmWrite(acceltimer,1000000/26,true);
  timerAlarmWrite(emgtimer,10000000/1000,true);
  timerAlarmEnable(acceltimer);
  timerAlarmEnable(emgtimer);
}


// Setup the essentials for your circuit to work. It runs first every time your circuit is powered with electricity.
void setup() 
{
  Serial.begin(1000000);
  delay(10);
  Serial.println();
  Serial.print("Connecting to network: ");
  Serial.println(ssid);
  WiFi.disconnect(true);  //disconnect form wifi to set new wifi connection
  WiFi.mode(WIFI_STA); //init wifi mode
 esp_wifi_sta_wpa2_ent_set_identity((uint8_t *)EAP_ANONYMOUS_IDENTITY, strlen(EAP_ANONYMOUS_IDENTITY)); 
  esp_wifi_sta_wpa2_ent_set_username((uint8_t *)EAP_IDENTITY, strlen(EAP_IDENTITY));
  esp_wifi_sta_wpa2_ent_set_password((uint8_t *)EAP_PASSWORD, strlen(EAP_PASSWORD));
  esp_wpa2_config_t config = WPA2_CONFIG_INIT_DEFAULT(); //set config settings to default
  esp_wifi_sta_wpa2_ent_enable(&config); //set config settings to enable function
  WiFi.begin(ssid); //connect to wifi
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    counter++;
    if(counter>=60){ //after 30 seconds timeout - reset board
      ESP.restart();
    }
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address set: "); 
  Serial.println(WiFi.localIP()); //print LAN IP

  myIMU.settings.gyroRange = 125;   //Max deg/s.  Can be: 125, 245, 500, 1000, 2000
  myIMU.settings.gyroSampleRate = 26;   //Hz.  Can be: 13, 26, 52, 104, 208, 416, 833, 1666
  myIMU.settings.gyroBandWidth = 50;  //Hz.  Can be: 50, 100, 200, 400;

  myIMU.settings.accelRange = 2;      //Max G force readable.  Can be: 2, 4, 8, 16
  myIMU.settings.accelSampleRate = 26;  //Hz.  Can be: 13, 26, 52, 104, 208, 416, 833, 1666, 3332, 6664, 13330
  myIMU.settings.accelBandWidth = 50;  //Hz.  Can be: 50, 100, 200, 400;


  myIMU.begin();
  filter.begin(26);

// initialize variables to pace updates to correct rate
  microsPerReading = 1000000 / 26;
  microsPrevious = micros();

// //Start Servers
  server.begin();

// Start Timers
  startTimer();
  
}

// Main logic of your circuit. It defines the interaction between the components you selected. After setup, it runs over and over again, in an eternal loop.
void loop() 
{
  
  if (WiFi.status() == WL_CONNECTED && wifistat == false) { //if we are connected to Eduroam network
    counter = 0; //reset counter
    Serial.println("Wifi is still connected with IP: "); 
    Serial.println(WiFi.localIP());   //inform user about his IP address
    wifistat = true;
  }else if (WiFi.status() != WL_CONNECTED) { //if we lost connection, retry
    WiFi.begin(ssid); 
    wifistat = false;     
  }
  while (WiFi.status() != WL_CONNECTED) { //during lost connection, print dots
    delay(500);
    Serial.print(".");
    counter++;
    if(counter>=60){ //30 seconds timeout - reset board
    ESP.restart();
    }
  }
  client = server.available();
  delay(1);
  if (client) {                             // if you get a client,
    //Serial.println("New Client.");           // print a message out the serial port
    //String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected

      if (updateAccel == true){
        // Defining Positional Data
        AccelX=myIMU.readFloatAccelX(); 
        AccelY=myIMU.readFloatAccelY(); 
        AccelZ=myIMU.readFloatAccelZ();
    
        // Defining Positional Data
        
        GyroX=myIMU.readFloatGyroX();
        GyroY=myIMU.readFloatGyroY(); 
        GyroZ=myIMU.readFloatGyroZ();   
    
        filter.updateIMU(GyroX,GyroY,GyroZ,AccelX,AccelY,AccelZ);
    
        roll = filter.getRoll();
        pitch = filter.getPitch();
        heading = filter.getYaw();
        
        EMA_S = (EMA_a*heading)+((1-EMA_a)*EMA_S);
        heading = heading - EMA_S;
    
        AccelX=heading;
        AccelY=pitch;
        AccelZ=roll;
        
        updateAccel = false;
      }
    

      if (updateEMG ==true){
//      //Method 1 EMG, adding false gain
      EMGleftRA=analogRead(EMGLeftRA_pin);
      EMGrightRA=analogRead(EMGRightRA_pin);
      EMGleftob=analogRead(EMGLeftOb_pin);
      EMGrightob=analogRead(EMGRightOb_pin);
      EMGerect=analogRead(EMGErect_pin);
      
      EMGleftRA = constrain(EMGleftRA*1.814,Min,Max);
      EMGrightRA = constrain(EMGrightRA*1.814,Min,Max);
      EMGleftob = constrain(EMGleftob*2.165,Min,Max);
      EMGrightob = constrain(EMGrightob*2.165,Min,Max);
      EMGerect = constrain(EMGerect*2.268,Min,Max);
      
      // Maping vaues from 0-4095 to 0-2200Mv
      EMGleftRA=modifiedMap(EMGleftRA,Min,Max,Map_Min,Map_Max);
      EMGrightRA=modifiedMap(EMGrightRA,Min,Max,Map_Min,Map_Max);
      EMGleftob=modifiedMap(EMGleftob,Min,Max,Map_Min,Map_Max);
      EMGrightob=modifiedMap(EMGrightob,Min,Max,Map_Min,Map_Max);
      EMGerect=modifiedMap(EMGerect,Min,Max,Map_Min,Map_Max);

    // SENDING RAW EMG DATA TO LABVIEW
    
    // Initialize buffer for the ASCII String
    char a[6]="";
    char b[6]="";
    char c[6]="";
    char d[6]="";
    char e[6]="";

    // Initializing Buffer for ASCII String for Accel Data
    char Ax[6]="";  
    char Ay[6]="";  
    char Az[6]="";

    // Initializing Buffer for ASCII String for Accel Data
    char Gx[6]="";  
    char Gy[6]="";  
    char Gz[6]="";

    // Converting RAW emg data to a string
      String str1= String(EMGleftRA);
      String str2= String(EMGrightRA);
      String str3= String(EMGleftob);
      String str4= String(EMGrightob);
      String str5= String(EMGerect);
  
      // Converting Accel Data to Strings
      String Axstr= String(AccelX);
      String Aystr= String(AccelY);
      String Azstr= String(AccelZ);
  
      // Converting Accel Data to Strings
      String Gyxstr= String(GyroX);
      String Gyystr= String(GyroY);
      String Gyzstr= String(GyroZ);
      
      
      // Converts 5 bytes of data in str to a char array e
      str1.toCharArray(a,5);
      str2.toCharArray(b,5);
      str3.toCharArray(c,5);
      str4.toCharArray(d,5);
      str5.toCharArray(e,5);
  
      // Converting Strings to Char Array
       Axstr.toCharArray(Ax,6);
       Aystr.toCharArray(Ay,6);
       Azstr.toCharArray(Az,6);
  
       // Converting Strings to Char Array
       Gyxstr.toCharArray(Gx,6);
       Gyystr.toCharArray(Gy,6);
       Gyzstr.toCharArray(Gz,6);
  //
  //    //Writing all to server EMG first then Accel then Gyro
      client.write(a);
      Serial.print(a);
      client.write(",");
      Serial.print(",");
      client.write(b);
      Serial.print(b);
      client.write(",");
      Serial.print(",");
      client.write(c);
      Serial.print(c);
      client.write(",");
      Serial.print(",");
      client.write(d);
      Serial.print(d);
      client.write(",");
      Serial.print(",");
      client.write(e);
      Serial.print(e);
      client.write(",");
      Serial.print(",");
      client.write(Ax);
      Serial.print(Ax);
      client.write(",");
      Serial.print(",");
      client.write(Ay);
      Serial.print(Ay);
      client.write(",");
      Serial.print(",");
      client.write(Az);
      Serial.println(Az);

//ENDING DATA TRANSMISSION 
        client.write("\r");
      
    }
    //close the connection
    client.stop();
    Serial.println("Client Disconnected.");
}
}

Who is online

Users browsing this forum: No registered users and 80 guests