delayMicroseconds() doesn't work in ADS1115 library
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- xhr0428
- Posts: 18
- Joined: Thu Aug 14, 2014 7:50 pm
delayMicroseconds() doesn't work in ADS1115 library
I have an ADS1115 board. It works great with arduino with default setting of 128sps and 8ms delay. Now I want it to work with 860sps. The delay time should be around 1.3ms, so I changed the register setting for data rate and used delayMicroseconds() function instead of delay() for delay. But no matter how I changed the delay time in delayMicroseconds(), it gave me all most the same results like the case without delay. How should I set the delay to make it work properly with 860sps? Thanks.
- adafruit_support_bill
- Posts: 87391
- Joined: Sat Feb 07, 2009 10:11 am
Re: delayMicroseconds() doesn't work in ADS1115 library
The conversion delay is built into the library.
- xhr0428
- Posts: 18
- Joined: Thu Aug 14, 2014 7:50 pm
Re: delayMicroseconds() doesn't work in ADS1115 library
Yes, I was changing the settings in the .h and .cpp file. Any hint?adafruit_support_bill wrote:The conversion delay is built into the library.
- adafruit_support_bill
- Posts: 87391
- Joined: Sat Feb 07, 2009 10:11 am
Re: delayMicroseconds() doesn't work in ADS1115 library
Post your test code & we'll take a look.
- xhr0428
- Posts: 18
- Joined: Thu Aug 14, 2014 7:50 pm
Re: delayMicroseconds() doesn't work in ADS1115 library
Here is the arduino sketchadafruit_support_bill wrote:Post your test code & we'll take a look.
Code: Select all
#include <Wire.h>
#include <Adafruit_ADS1015.h>
Adafruit_ADS1115 ads; /* Use this for the 16-bit version */
//Adafruit_ADS1015 ads; /* Use thi for the 12-bit version */
void setup(void)
{
Serial.begin(19200);
Serial.println("Hello!");
Serial.println("Getting single-ended readings from AIN0..3");
Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)");
ads.begin();
}
void loop(void)
{
int16_t adc1;
int n = 0;
while (n<100)
{
adc1 = ads.readADC_SingleEnded(1);
n = n+1;
}
Serial.println(millis());
}
In the .cpp file, I modified uint16_t Adafruit_ADS1015::readADC_SingleEnded(uint8_t channel) function.
ADS1015_REG_CONFIG_DR_1600SPS was changed to ADS1015_REG_CONFIG_DR_3300SPS
delay(m_conversionDelay) was changed to delayMicroseconds(m_conversionDelay)
- adafruit_support_bill
- Posts: 87391
- Joined: Sat Feb 07, 2009 10:11 am
Re: delayMicroseconds() doesn't work in ADS1115 library
That sounds like it should work. There is some overhead in the i2c communication, but it should not be all that much. You can increase the speed of the i2c bus and see if that makes a difference..
The default bus speed is 100KHz and can be increased to 400KHz by editing the library file in your Arduino installation folder. The file can be found in hardware/libraries/wire/utility/twi.h.
Find the line with: "#define TWI_FREQ 100000L"
and change it to "#define TWI_FREQ 400000L"
Or, you can add the following code to your setup() function:
TWBR = ((F_CPU /400000l) - 16) / 2; // Change the i2c clock to 400KHz
The default bus speed is 100KHz and can be increased to 400KHz by editing the library file in your Arduino installation folder. The file can be found in hardware/libraries/wire/utility/twi.h.
Find the line with: "#define TWI_FREQ 100000L"
and change it to "#define TWI_FREQ 400000L"
Or, you can add the following code to your setup() function:
TWBR = ((F_CPU /400000l) - 16) / 2; // Change the i2c clock to 400KHz
- xhr0428
- Posts: 18
- Joined: Thu Aug 14, 2014 7:50 pm
Re: delayMicroseconds() doesn't work in ADS1115 library
I don't have arduino at hand now. I'll try it later and let you know the result.adafruit_support_bill wrote:That sounds like it should work. There is some overhead in the i2c communication, but it should not be all that much. You can increase the speed of the i2c bus and see if that makes a difference..
The default bus speed is 100KHz and can be increased to 400KHz by editing the library file in your Arduino installation folder. The file can be found in hardware/libraries/wire/utility/twi.h.
Find the line with: "#define TWI_FREQ 100000L"
and change it to "#define TWI_FREQ 400000L"
Or, you can add the following code to your setup() function:
TWBR = ((F_CPU /400000l) - 16) / 2; // Change the i2c clock to 400KHz
One more strange thing I want to mention is I changed the delay variable between 1300 and 5000 for a few times, all the cases took about 100~120 ms to finish the 100 sampling. It seems that delayMicroseconds() didn't work at all.
- xhr0428
- Posts: 18
- Joined: Thu Aug 14, 2014 7:50 pm
Re: delayMicroseconds() doesn't work in ADS1115 library
Hi Bill, I just tested your advice in the post. Changing the speed of i2c decreased the time interval between two sampling batches, but it didn't solve the delayMicroseconds problem. FYI, the time reported to take 100 samples is 40ms now though I set the delay to be 1300us for each sample.adafruit_support_bill wrote:That sounds like it should work. There is some overhead in the i2c communication, but it should not be all that much. You can increase the speed of the i2c bus and see if that makes a difference..
The default bus speed is 100KHz and can be increased to 400KHz by editing the library file in your Arduino installation folder. The file can be found in hardware/libraries/wire/utility/twi.h.
Find the line with: "#define TWI_FREQ 100000L"
and change it to "#define TWI_FREQ 400000L"
Or, you can add the following code to your setup() function:
TWBR = ((F_CPU /400000l) - 16) / 2; // Change the i2c clock to 400KHz
- adafruit_support_bill
- Posts: 87391
- Joined: Sat Feb 07, 2009 10:11 am
Re: delayMicroseconds() doesn't work in ADS1115 library
No idea. If you post your modified library code (.h and .cp), we might be able to spot the problem.
- xhr0428
- Posts: 18
- Joined: Thu Aug 14, 2014 7:50 pm
Re: delayMicroseconds() doesn't work in ADS1115 library
in the .h file, this is the only place I changedadafruit_support_bill wrote:No idea. If you post your modified library code (.h and .cp), we might be able to spot the problem.
Code: Select all
/*=========================================================================
CONVERSION DELAY (in mS)
-----------------------------------------------------------------------*/
#define ADS1015_CONVERSIONDELAY (1)
#define ADS1115_CONVERSIONDELAY (1300)
/*=========================================================================*/
1. ADS1015_REG_CONFIG_DR_1600SPS to ADS1015_REG_CONFIG_DR_3300SPS
2. delay(m_conversionDelay) to delayMicroseconds(m_conversionDelay)
Code: Select all
/*!
@brief Gets a single-ended ADC reading from the specified channel
*/
/**************************************************************************/
uint16_t Adafruit_ADS1015::readADC_SingleEnded(uint8_t channel) {
if (channel > 3)
{
return 0;
}
// Start with default values
uint16_t config = ADS1015_REG_CONFIG_CQUE_NONE | // Disable the comparator (default val)
ADS1015_REG_CONFIG_CLAT_NONLAT | // Non-latching (default val)
ADS1015_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val)
ADS1015_REG_CONFIG_CMODE_TRAD | // Traditional comparator (default val)
ADS1015_REG_CONFIG_DR_3300SPS | // 1600 samples per second (default)
ADS1015_REG_CONFIG_MODE_SINGLE; // Single-shot mode (default)
// Set PGA/voltage range
config |= m_gain;
// Set single-ended input channel
switch (channel)
{
case (0):
config |= ADS1015_REG_CONFIG_MUX_SINGLE_0;
break;
case (1):
config |= ADS1015_REG_CONFIG_MUX_SINGLE_1;
break;
case (2):
config |= ADS1015_REG_CONFIG_MUX_SINGLE_2;
break;
case (3):
config |= ADS1015_REG_CONFIG_MUX_SINGLE_3;
break;
}
// Set 'start single-conversion' bit
config |= ADS1015_REG_CONFIG_OS_SINGLE;
// Write config register to the ADC
writeRegister(m_i2cAddress, ADS1015_REG_POINTER_CONFIG, config);
// Wait for the conversion to complete
//delay(m_conversionDelay);
delayMicroseconds(m_conversionDelay);
// Read the conversion results
// Shift 12-bit results right 4 bits for the ADS1015
return readRegister(m_i2cAddress, ADS1015_REG_POINTER_CONVERT) >> m_bitShift;
}
- adafruit_support_bill
- Posts: 87391
- Joined: Sat Feb 07, 2009 10:11 am
Re: delayMicroseconds() doesn't work in ADS1115 library
You need to change the ADS1115 version of this function.uint16_t Adafruit_ADS1015::readADC_SingleEnded(uint8_t channel) {
- xhr0428
- Posts: 18
- Joined: Thu Aug 14, 2014 7:50 pm
Re: delayMicroseconds() doesn't work in ADS1115 library
But this is the only readADC_SingleEnded function in the .cpp file. Doesn't class Adafruit_ADS1115 inherit those functions from class Adafruit_ADS1015?adafruit_support_bill wrote:You need to change the ADS1115 version of this function.uint16_t Adafruit_ADS1015::readADC_SingleEnded(uint8_t channel) {
- adafruit_support_bill
- Posts: 87391
- Joined: Sat Feb 07, 2009 10:11 am
Re: delayMicroseconds() doesn't work in ADS1115 library
Yes, it appears that it does. So I guess we are back to 'no idea'.
Just out of curiosity - what happens if you increase the ADS1015 conversion delay (it is currently at '1')? In theory at least, the constructor of the base class should be called first. But when things are behaving strangely, sometimes it is best to confirm the theories.
Just out of curiosity - what happens if you increase the ADS1015 conversion delay (it is currently at '1')? In theory at least, the constructor of the base class should be called first. But when things are behaving strangely, sometimes it is best to confirm the theories.
- xhr0428
- Posts: 18
- Joined: Thu Aug 14, 2014 7:50 pm
Re: delayMicroseconds() doesn't work in ADS1115 library
I changed ADS1015 conversion delay to the same value of ADS1115 conversion delay, the issue remained.adafruit_support_bill wrote:Yes, it appears that it does. So I guess we are back to 'no idea'.
Just out of curiosity - what happens if you increase the ADS1015 conversion delay (it is currently at '1')? In theory at least, the constructor of the base class should be called first. But when things are behaving strangely, sometimes it is best to confirm the theories.
Now I set the delay to 3300 us and used millis() to record moments of samples (though it is not accurate). I printed out the recorded time points after 100 samples, the result showed there were two samples in 1 ms, while I should see 1 sample every 3 or 4 ms in theory. When it is 1300 us, I got 2 or 3 samples in 1 ms.
- adafruit_support_bill
- Posts: 87391
- Joined: Sat Feb 07, 2009 10:11 am
Re: delayMicroseconds() doesn't work in ADS1115 library
Not sure what is going on there. I'll run it by some of the other engineers. If I get some time later this week I can try to reproduce it here.
Please be positive and constructive with your questions and comments.