Closed yanxiang-wang closed 2 years ago
Thanks for the issue You should be aware that your sketch does also use time to print the value and check if the sensor is ready.
To show this effect change the baudrate of serial to 500.000 or 9600.
High speed will be improved by setting the I2C clock speed e.g to 400K or higher. Best performance is in continuous mode see examples. Then read a sample by checking micros()
Thanks, RobTillaart. I changed the baud rate to 9600 as you suggested. At the same time, I add a timer to print the data count per second.
#include "ADS1X15.h"
#include <MsTimer2.h>
int count = 0;
void check_fq()
{
Serial.print("count:");
Serial.print(count);
Serial.println("");
count = 0;
}
// choose you sensor
// ADS1013 ADS(0x48);
// ADS1014 ADS(0x48);
ADS1015 ADS(0x48);
// ADS1113 ADS(0x48);
// ADS1114 ADS(0x48);
// ADS1115 ADS(0x48);
void setup()
{
Serial.begin(9600);
ADS.begin();
ADS.setGain(1); // 6.144 volt
ADS.setDataRate(0);
ADS.readADC(0);
MsTimer2::set(1000, check_fq);
MsTimer2::start();
}
void loop()
{
// Serial.println(ADS.getValue());
{
int16_t data = ADS.getValue();
count += 1;
}
}
And the serial output is as follows:
count:1783
count:1784
count:1784
count:1785
count:1784
count:1785
count:1784
count:1784
count:1785
count:1784
So you see the time the Serial printing takes affects the performance. At lower baud rates you just have less time to read the ADC. Now give it a try with 500000 baud, what is the count then?
Note: I updated your post by adding cpp to the code block to get syntax highlighting.
Yes, the println
function will affect the speed. The strange point is that I set the data rate to 250 by ADS.setGain(1);
. So, the count should be 250, am I right?
Also, I change the baud by Serial.begin(500000);
, the result is the same as above:
count:1783
count:1784
count:1784
count:1784
count:1785
count:1784
count:1784
count:1784
count:1785
count:1784
count:1785
count:1784
count:1784
count:1784
count:1785
count:1784
count:1784
count:1784
count:1784
The strange point is that I set the data rate to 250 by ADS.setGain(1);.
The frequency is not set by setGain(), gain is sort of amplification, the voltage range. You should use **setDataRate(1)
#include "ADS1X15.h"
#include <MsTimer2.h>
// VARIABLES
volatile uint32_t count = 0;
ADS1015 ADS(0x48);
uint32_t lastTime = 0;
/////////////////////////////////////
void check_fq()
{
Serial.print("count: ");
Serial.println(count);
count = 0;
}
void setup()
{
// initialize Serial
Serial.begin(500000);
// initialize ADS
ADS.begin();
ADS.setWireClock(400000); // higher depending on what your processor supports.
ADS.setGain(1); // 6.144 volt
ADS.setDataRate(2); // 490, note this is faster than we want to sample
ADS.setMode(0); // continuous mode
ADS.readADC(0);
// initialize timer
MsTimer2::set(1000, check_fq);
MsTimer2::start();
}
void loop()
{
if (micros() - lastTime >= 4000) // every 4 millisecond we want a sample.
{
lastTime = micros();
int16_t data = ADS.getValue();
count++;
}
// other code here
}
Give it a try
Wow, it works. Very grateful for the comments. Initially, I thought micros()
was not accurate. And I need to use the interrupt-based timer for all the functions that run at a fixed period. But your example proves I am wrong—many thanks.
And the result of your code is as follows:
count: 249
count: 250
count: 250
count: 250
count: 250
count: 250
count: 250
count: 250
count: 250
If you do not have too many (short, non blocking) tasks at hand scheduling with micros() or even millis() works very well. Did a project with more than 20 tasks that needed to run at least 10 to 50 times per second and that worked well. Only thing I had adapted was the analogRead() which resulted in => https://github.com/RobTillaart/AsyncAnalog
Note there are two slightly different ways to implement this with different behavior:
if (micros() - lastTime >= threshold)
{
lastTime = micros();
...
}
if (micros() - lastTime >= threshold)
{
lastTime += threshold;
...
}
micros()
takes longer than just an addition.As said, the difference is subtle but can be significant when "the load" of the system is high. So choose with care.
If this solves the issue, and no further related questions remain you may close the issue.
Hi, I just bought an ADS 1015, and I set the data rate to option
1
in the code. However, when I read the serial output with my laptop, the data rate looks lower than the target rate. For instance, it will give me about 160Hz while it is set to 250Hz. So, how do you check if you acquire the correct data rate? Thanks.