Sampling Sensor Data at 1Khz

Hello,
I am trying to sample EMG data from Seeeduino Grove at 1KHz using the code below. However, when I check the collected data, I am able to retrieve about 1000 values in around 10s (which means ~100Hz frequency).
Any idea on what is possibly going wrong?
Thank you

// Grove - EMG Sensor demo code
// This demo will need a Grove - Led Bar to show the motion 
// Grove - EMG Sensor connect to A0
// note: it'll take about serval seconds to detect static analog value
// when you should hold your muscle static. You will see led bar from level 10 turn to 
// level 0, it means static analog value get ok

#include <SoftwareSerial.h>

int static_analog_dta0 = 0;                // static analog data
int static_analog_dta2 = 0;

unsigned long intervalTime = 1; // f = 1/1ms = 1000 Hz
unsigned long lastMeasureTime = 0;
unsigned long currentTime = 0;

SoftwareSerial espSerial(5, 6);

// get analog value
int getAnalog(int pin)
{
    long sum = 0;
    
    for(int i=0; i<32; i++)
    {
        sum += analogRead(pin);
    }
    
    return sum>>5;
}

void setup()
{
    Serial.begin(230400);
    espSerial.begin(230400);
    
    long sum0 = 0;
    long sum2 = 0;

    for(int i=0; i<=10; i++)
    {
        for(int j=0; j<100; j++)
        {
            sum0 += getAnalog(A0);
            sum2 += getAnalog(A2);
            delay(1);
        }
        
        Serial.println(10-i);
    }
    
    sum0 /= 1100;
    sum2 /= 1100;
    
    static_analog_dta0 = sum0;
    static_analog_dta2 = sum2;

    Serial.print("static_analog_dta0 = ");
    Serial.println(static_analog_dta0);
    Serial.print("static_analog_dta2 = ");
    Serial.println(static_analog_dta2);
}

void loop()
{
    currentTime = millis();
    if ( currentTime - lastMeasureTime >= intervalTime )
    {
      int val0 = getAnalog(A0);
      int val2 = getAnalog(A2);                    // get Analog value, to convert to volts: *5/(2^10-1) (range 0-5V)
      Serial.print(val0);
      Serial.print(" ");
      Serial.println(val2);

      espSerial.print(val0);
      espSerial.print(" ");
      espSerial.println(val2);

      lastMeasureTime = currentTime;
     // delay(10);
    }
}

just that takes already 3ms

Okay, any idea how to speed things up if possible? Ideally, I would like to read data from 8 sensors simultaneously so in this case the data acquisition rate will go even way lower (8*3==24ms ~ 30ms per sample or 33 Hz).

If you need to read that analog pin 32 times in a rawwith your arduino, there's nothing to do. It takes that long. Also serial.prints etc take some time...

also I don't think sofwareserial can handle that baudrate...
maybe 57600

But you read the pin value 32 times and then divide it by 32, each time. And this takes time, as Kmin pointed.
Do you really need that? If the value is not so stable you could consider a small capacitor in the pin or something. Maybe averaging, but not 32 times.
I don't know, do the maths, but it doesn't really fit.

Also I don't even see where that pin is defined
Also what is that softwareserial supposed to do there...

// Grove - EMG Sensor demo code
// This demo will need a Grove - Led Bar to show the motion 
// Grove - EMG Sensor connect to A0
// note: it'll take about serval seconds to detect static analog value
// when you should hold your muscle static. You will see led bar from level 10 turn to 
// level 0, it means static analog value get ok

#include <SoftwareSerial.h>

int static_analog_dta0 = 0;                // static analog data
int static_analog_dta2 = 0;

unsigned long intervalTime = 1; // f = 1/1ms = 1000 Hz
unsigned long lastMeasureTime = 0;
unsigned long currentTime = 0;

SoftwareSerial espSerial(5, 6);

// get analog value
int getAnalog(int pin)
{
    long sum = 0;
    
    for(int i=0; i<32; i++)
    {
        sum += analogRead(pin);
    }
    
    return sum>>5;
}

void setup()
{
    Serial.begin(230400);
    espSerial.begin(115200);
    
    long sum0 = 0;
    long sum2 = 0;

    for(int i=0; i<=10; i++)
    {
        for(int j=0; j<100; j++)
        {
            sum0 += getAnalog(A0);
            sum2 += getAnalog(A2);
            delay(1);
        }
        
        Serial.println(10-i);
    }
    
    sum0 /= 1100;
    sum2 /= 1100;
    
    static_analog_dta0 = sum0;
    static_analog_dta2 = sum2;

    Serial.print("static_analog_dta0 = ");
    Serial.println(static_analog_dta0);
    Serial.print("static_analog_dta2 = ");
    Serial.println(static_analog_dta2);
}

void loop()
{
    //currentTime = millis();
    //if ( currentTime - lastMeasureTime >= intervalTime )
    //{
      int val0 = analogRead(A0);
      int val2 = analogRead(A2);                    // get Analog value, to convert to volts: *5/(2^10-1) (range 0-5V)
      Serial.print(val0);
      Serial.print(" ");
      Serial.println(val2);

      /*espSerial.print(val0);
      espSerial.print(" ");
      espSerial.println(val2);*/

      //lastMeasureTime = currentTime;
     // delay(10);
    //}

}

Okay this is my new code, basically got rid of the 32 reads in the loop, I am only using analogRead which is supposed to take about 100us. But still, if I read one sensor I get 200Hz, if I read 2 sensors I get 100Hz.
Software serial is sued to send the data to a nodemcu, which can be disregarded for now.

so remove from your code.
You still don't have that pin defined?

Pin is A0 or A2, defined in the function calls within the loop body

I see, my mistake

Remove that softwareserial
Try to raise serial baudrate
Serial.print all your values in one command (not three lines) as a string...
But first try just with one analog read and serialprint.

I ran your code on an Uno and got 2712 samples/second

With just 1 analog read I get close to 4000 samples /second
What Arduino are you using?
How are you counting samples?


void setup()
{
    Serial.begin(115200);
}

void loop()
{
    Serial.println(analogRead(A0));
}

Okay now I am just using this code, I am getting over 22k samples per 10s (~2khz). I am using Mega, and CoolTerm to log data to a file.

Seems about right but the code from post#8 only gave you 200Hz?

Yes! It's so weird. Also now I added another analog read, the rate dropped to ~1khz.


void setup()
{
    Serial.begin(115200);
}

void loop()
{
    Serial.println((String)analogRead(A0) + " " + analogRead(A2));
}

I get around 2000 with that code.
How are you computing the rate?

number of values/time, no?

The rate will be totally dependant on the serial print. If the numbers are 1 digit then it prints fast. If they are 3 digits then it takes longer and the sample rate goes down.

If you want a consistant sample rate, you can't do a print, you need to save the data to an array.