How can I increase the sample rate

Hi
Currently I use the accelerometer (Steval-mki015v1) to connect to the Arduino UNO board, and I can collect about 500 data per second using 115200 baud, but I need to increase it to 5000 data per second, how can I do it? I'd very thankful for the answer.

code:

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

void loop() {
  int x = analogRead(A0);
  int y = analogRead(A1);
  int z = analogRead(A2);
  
  //XYZ 類比電壓轉換 // 
  float datax = mapf(x, 200, 470, 0.99, 2.31);
  float datay = mapf(y, 200, 470, 0.99, 2.31);
  float dataz = mapf(z, 200, 476, 0.99, 2.31);

  //範圍偏移 將G值轉換
  float ax = ((datax-1.65)/0.66)*9.8;
  float ay = ((datay-1.65)/0.66)*9.8;
  float az = ((dataz-1.65)/0.66)*9.8;
  

  Serial.print(ax);
  Serial.print("\t");
  Serial.print(ay);
  Serial.print("\t");
  Serial.println( az);
  delayMicroseconds(1);

}

float mapf(float value, float fromLow, float fromHigh, float toLow, float toHigh) {
  float result;
  result = (value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow;
  return result;
}

You can't with integrated ADC of ATMega328p.

Each ADC conversion need a little more than 100uS and you have to do this 3 times plus mapping float values (32 bit) with a small 8 bit MCU.

Thanks for the answer, but how can I get data without using analogRead

Thank you for giving me a lot of advice!

(removed due to ethical concerns)

1 Like

Yes you're right, that's the point but still remain the problem with serial speed.

Sorry I don't know the meaning of Serial connection or serial speed

(removed due to ethical concerns)

(removed due to ethical concerns)

1.2. : Since these data will be applied to the ECG, 5000 sps is required
3. It is to use a normal laptop to read data
4. It takes about 15-20 seconds to read data each time

(removed due to ethical concerns)

Edit: in removed post above OP wrote the sensor is placed 'inside the heart' of an animal. In pm he indicated this was not correct and the sensor is placed on the body.

sorry i was wrong because i'm not familiar with english
The sensor will be placed on the outside of the body where the heart is

Start with the sensor being used. A I2C sensor will give about 400Khz data rate. You cannot get any faster than 400Khz minus code overhead.

On the other hand, with a sensor using the SPI interface your data rate from the sensor goes way up. Now you've got a chance of getting the desired output rate, the rest will be up to the efficiency of the MCU and the coder.

Want it real fast use an ESP32. Put the sensor read chores on one core and the sensor processing on another core. Using the dual core scheme, I've got SPI reading of over a 1000 samples per second.

Want it even faster bypass the Arduino ESP32 core and use the ESP32 SPI API, SPI Master Driver - ESP32 - — ESP-IDF Programming Guide latest documentation (espressif.com) and freeRTOS. freeRTOS is the built in OS of the ESP32. Now to find some who can code for the ESP32 SPI API.

Yeah, but he's using the adc in the 328p. That can go way faster than 1ksps if you do it right. He's sampling an analog signal; 3 in fact.

Thats what I get for answering questions before I had a,

You can increase the ADC sample rate by changing the ADC clock prescaler (128 by default, for 9.6 kHz sample frequency).

There is only a small effect on accuracy until you get to very high speeds, say around 500 kHz sample frequency.

Here is how to do that: http://www.optiloading.be/willem/Arduino/speeding.pdf

For example: set the ADC prescale to 16 to have a clock of 1 MHz and a sample rate of 76.8KHz.

 void setup ( )
{
sbi (ADCSRA, ADPS2) ;
cbi (ADCSRA, ADPS1) ;
cbi (ADCSRA, ADPS0) ;
...

At 5000 samples per second, you have 200 microseconds to report each sample.

If you crank up the ADC to 1 MHz, and crank the baud rate to 2 million baud, and get rid of all of the floating-point math, it takes about 350 microseconds to send three two-digit integers. You need to encode the data in fewer characters.

void setup()
{
  Serial.begin(2000000ul); // Two Million Baud
  delay(200);

  // Set ADC clock prescale to 16 (1 MSPS) instead of the default 128 (125 kSPS)
  ADCSRA |= _BV(ADPS2);
  ADCSRA &= ~_BV(ADPS1);
  ADCSRA &= ~_BV(ADPS0);

  unsigned long startTime = micros();

  for (unsigned long i = 0; i < 1000; i++)
  {
    int ax = analogRead(A0);
    int ay = analogRead(A1);
    int az = analogRead(A2);

    Serial.print(ax);
    Serial.print("\t");
    Serial.print(ay);
    Serial.print("\t");
    Serial.println(az);
  }
  unsigned long elapsedTime = micros() - startTime;

  Serial.println(elapsedTime);
}

void loop() {}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.