Go Down

Topic: Data Refresh Rate of different sensors and Sample Time (Read 468 times) previous topic - next topic

d0minik96

Hey Guys,

first of all: Sorry for my bad english.

Im new to working with arduino and sensors. For an university project i have to measure vibrations and force of a vibration experiment.

For that i am using a Adafruit MMA8451 Accelerationsensor and a ADS1115 ADC, which gets the voltage from my force sensor.

I have problems understanding the meaning of the Data Refresh Rate of my Chips and the sample Rate. I allready searched for this topic but i cant understand it.

i found out that i should use the blink  blink without delay method to get a constant sample rate. And Serial.print slows the whole programm.

My code for now:
Code: [Select]
//Librarys
#include <Wire.h>
#include <Adafruit_MMA8451.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_MCP4725.h>
#include <Adafruit_ADS1015.h>
#include <arduino.h>
//Variablen
uint32_t vmot = 0;
String cmd;
int16_t adc0, adc1, adc2, adc3;
//Modulobjekte
Adafruit_MMA8451 mma = Adafruit_MMA8451();//Acceleration_Sensor
Adafruit_MCP4725 dac;//Digital_Analog_Converter
Adafruit_ADS1115 ads; //Analog_Digital_Converter
//SamplingRate
#define INTERVAL 1250 //800Hz Sampling Rate
unsigned long lastMicros = 0;
unsigned long Micros;
//Funktionen
void readsensors();
void serialtransmitData();

void setup() {
  Serial.begin(115200);
  /******************************************************************/
  //Setup MMA8451
  Serial.println("Adafruit MMA8451 test!");
  if (! mma.begin()) {
    Serial.println("Couldnt start");
    while (1);
  }
  Serial.println("MMA8451 found!");
  mma.setRange(MMA8451_RANGE_8_G);
  mma.setDataRate(MMA8451_DATARATE_400_HZ);
  Serial.print("Range = "); Serial.print(2 << mma.getRange()); 
  Serial.println("G");
  /******************************************************************/
  /******************************************************************/
  //Setup DAC MCP4725
  Serial.println("Connecting DAC...");
  dac.begin(0x62);
  Serial.println("DAC connected.");
  /******************************************************************/
  /******************************************************************/
  //Setup ADC ADS1115
  //                                                                ADS1015  ADS1115
  //                                                                -------  ------
  ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit =    3mV      0.1875mV (default)
  // ads.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
  // ads.setGain(GAIN_TWO);        // 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV
  // ads.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV
  // ads.setGain(GAIN_EIGHT);      // 8x gain   +/- 0.512V  1 bit = 0.25mV   0.015625mV
  // ads.setGain(GAIN_SIXTEEN);    // 16x gain  +/- 0.256V  1 bit = 0.125mV  0.0078125mV
  Serial.println("Connecting ADS1115");
  ads.begin();
  Serial.println("ADC ADS1115 connected.");
}

void loop() {
  // put your main code here, to run repeatedly:
if (micros() - lastMicros > INTERVAL) {
    lastMicros = micros(); // do this first or your interval is too long!
    readsensors();
    serialtransmitData();
  }
}

void readsensors(){
 mma.read();//Read raw data Acceleration: stored mma.x, mma.y,mma.z
 adc0 = ads.readADC_SingleEnded(0); //Read ADC Pin0
 adc1 = ads.readADC_SingleEnded(1); //Read ADC Pin1
 adc2 = ads.readADC_SingleEnded(2); //Read ADC Pin2
 adc3 = ads.readADC_SingleEnded(3); //Read ADC Pin3
}
void serialtransmitData(){
  //Transmitting Data
  Serial.print("D:");
  Serial.print(mma.x);  Serial.print("/t");
  Serial.print(mma.y);  Serial.print("/t");
  Serial.print(mma.z);  Serial.print("/t");
  Serial.print(adc0);   Serial.print("/t");
  Serial.print(adc2);   Serial.print("/t");
  Serial.print(vmot);   Serial.print("/t");
  Serial.print(lastMicros); Serial.println();
 
}


Is this Code working with my sample rate of 800Hz ?
I can adjust the Datarefreshrate of my MMA8451 chip ( 800Hz-1,56Hz). What is the actuall meaning of the Datafrefreshrate and how does it affect my Data ?  
The ADS1115 has different RefreshRates (860-8Hz).
I think i just need a higher Data RefreshRate than my Sample Rate, right?

In order to transmit my data to Matlab: 
Is there a better option for seperating my data than "Serial.print("/t")?
And do i need to save my Data in a Array and transmit it after the Measurement is done ? Or does my method work?

I'm pretty confused at the moment. I hope these arent too many questions  :o :smiley-confuse:
Dominik

pylon

Data refresh rate and sample rate are the same. I got the impression that you confuse the sample rate with the read out rate. As you failed to tell us what model of Arduino you're using I cannot tell if a read out rate of 800Hz is even feasible.
Anyway transferring the read data serially to the PC at 115200 baud limits the maximum rate you get at the PC to about 230Hz, given that the sensor read out is fast enough.

d0minik96

Thanks for your reply,

im using an Arduino Uno. I testet the time my loop takes to read the Data:
Just reading my Accelerometer Data, micros() and sending the value of MIcros() takes me 2,7 ms.
Reading out the ADC Value of the ADS1115 in the same manner takes 18 ms.
So for know i am trying to use the integrated ADC of my Arduino to get the Value from my Force Sensors.

In order to get my 800Hz Sample rate, i will try to speed up the I2C Connection. I found a manual to change the twi.h File for that. Hopefully this will boost up the speed of my Accelerometer Reading a littlle bit.


If my Data Transfer rate is really that slow, how can i improve my code there ? If my Sample rate is about 800HZ and my transfer Data Rate ios about 230Hz my Serial buffer will be full after some time and the whole loop waits for the Buffer to clear or ?

Is it possible to save the Measurement data local and transmit it after or is the Storage in my Arduino uno to small ?


Idahowalker

#3
Sep 20, 2019, 01:36 pm Last Edit: Sep 20, 2019, 01:37 pm by Idahowalker
The https://www.nxp.com/docs/en/data-sheet/MMA8451Q.pdf can do a data ready interrupt. By using the dataready interrupt you can program so that when the device has data you can read the device and do the thing instead of trying to get data and hoping there is data read for you to read.


wildbill

You can try running the uno at a higher baud rate. IIRC, people have had success running it at 300000 baud, but that's still not enough for 800Hz because yes, once the serial output buffer is full your code will block.

I doubt that you can store results in RAM, unless the period you're running this test for is incredibly short - the Uno just doesn't have the memory for it. Other Arduino like devices have a lot more though.

You might try using an SD card, store the data locally and then send it to Matlab at your leisure afterwards.

d0minik96

so should i buy something like this ?
https://learn.adafruit.com/adafruit-data-logger-shield/overview

Is a data logger shield even written faster than the serial communication ?
Or are there any other options transmitting the data quickly to the PC ?

Edit:
If i run the measurement for about 30sec for each motor frequenz is there enough buffer ?
Atm i only have 370 Hz running.
I could just measure 30 sec and than wait until the buffer is empty. Does this work ?

pylon

Quote
Is a data logger shield even written faster than the serial communication ?
No.

Are your force sensors fast enough to provide new values at 800Hz? If not it might be a good idea only read them at a speed they provide new data.

Quote
I found a manual to change the twi.h File for that.
There an official method for that:

Wire.setClock()

400000 should work for the UNO.

It might be a good idea to change to an ARM based Arduino if you need more speed. As you still failed to provide links to the used hardware (not the chips, the actual breakout boards or  better their schematics) it's up to you to check if they are compatible.

jremington

#7
Sep 20, 2019, 08:47 pm Last Edit: Sep 20, 2019, 08:48 pm by jremington
As always, we strongly advise to get your project working once piece at a time.

The MMA8451 accelerometer is digital and has a maximum data rate of 800 Hz. There should be no problem to transmit the data at that rate to a PC over the serial port. Start with that alone, and learn how to use it properly.

Then get the mysterious "force sensor" working separately, before combining the projects. Why are you using a separate ADC? That just adds to the complexity.

d0minik96

The mysterious force sensor is not important for my question.
Its a very good force sensor from a small german company. The Force Sensor is working.

I already work without the extra ADC because the ads1115 slows thinks down and getting the data fromk 2 different pins takes about 18ms, way too long.

I'm now using the internal adc from the arduino uno board.

The Adafruit MMA8451 is working with 800Hz aswell as the force sensor. Im just trying to get the 800 Hz Sample Rate and to send my informations via serial.

@pylon: thank you for the method. I didnt know that.

For my experiment i need to send atleast these informations to Matlab: voltage motor(int), z acceleration , 2x voltage from analog input pins from my arduino and the micros() for the time of the data.
At the moment i have a sample rate of 400 Hz. I hope updating the I2C clock will speed up the time my arduino takes to get the acceleration data to 800 Hz. I dont know if my serial buffer will get full or not.

Can somebody tell me if this works or not ?
Changing the Arduino to a faster model like the Arduino due will not speed up my serial speed. So this is the only breaking point in my experiment.

Idahowalker


jremington

#10
Sep 21, 2019, 04:51 pm Last Edit: Sep 21, 2019, 04:51 pm by jremington
Quote
I dont know if my serial buffer will get full or not.
The beauty of Arduino is that you can try things and see what works.

However, a little thought goes a long, long way.

Your program currently sets the serial Baud rate to 115200, which means you can transmit 11520 characters per second.

If you break that into 800 packets per second, each packet can have 14 characters, counting possible line feed/carriage returns/commas etc.

Can you guess where I'm going with this?

d0minik96





Is their a SPI device you can use?
I would like to go with the Acceleration Sensor i got. It should work. If not, i can give a SPI Chip a try.

The beauty of Arduino is that you can try things and see what works.

However, a little thought goes a long, long way.

Your program currently sets the serial Baud rate to 115200, which means you can transmit 11520 characters per second.

If you break that into 800 packets per second, each packet can have 14 characters, counting possible line feed/carriage returns/commas etc.

Can you guess where I'm going with this?
14 characters = 14 Byte a 8 Bit.
Micros() is a var of unsigned Long = 4 Byte
2 X Analog Read() = 2x 2 Byte = 4 Byte
Acceleration MMA8451 Raw Data = 14 bits -> 2 Byte
Voltage Mot = int = 2 Byte
New Line in case of a Serial.println() = 1 Byte
In total = 13 Byte
Than i am missing 3 Byte for a comma. So this is not working....
Is there an option to seperate the data without kommas ?
 

jremington

#12
Sep 21, 2019, 09:43 pm Last Edit: Sep 21, 2019, 09:45 pm by jremington
If you are sending binary data  through the serial port, there is no point in using newline, commas or other separators, as the records are all the same size. At 115200 Baud, you can send 14 byte records of raw data at 800 Hz.

Double the serial port data rate to get twice the data transmission rate, so 28 byte records at 800 Hz.

However, the accelerometer has 3 axes, so 6 bytes are required to transmit the X, Y and Z axis data at 14 bit resolution.


d0minik96

If you are sending binary data  through the serial port, there is no point in using newline, commas or other separators, as the records are all the same size. At 115200 Baud, you can send 14 byte records of raw data at 800 Hz.

Double the serial port data rate to get twice the data transmission rate, so 28 byte records at 800 Hz.

However, the accelerometer has 3 axes, so 6 bytes are required to transmit the X, Y and Z axis data at 14 bit resolution.


I'm just interested in the Z axis. Can i double the Baudrate, where are the limits for my PC and the Arduino Uno?

jremington

Quote
where are the limits for my PC and the Arduino Uno?
Try the various options and let us know.

Go Up