delayMicroseconds() doesn't work in ADS1115 library

Breakout boards, sensors, other Adafruit kits, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
xhr0428
 
Posts: 18
Joined: Thu Aug 14, 2014 7:50 pm

delayMicroseconds() doesn't work in ADS1115 library

Post by xhr0428 »

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.

User avatar
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: delayMicroseconds() doesn't work in ADS1115 library

Post by adafruit_support_bill »

The conversion delay is built into the library.

User avatar
xhr0428
 
Posts: 18
Joined: Thu Aug 14, 2014 7:50 pm

Re: delayMicroseconds() doesn't work in ADS1115 library

Post by xhr0428 »

adafruit_support_bill wrote:The conversion delay is built into the library.
Yes, I was changing the settings in the .h and .cpp file. Any hint?

User avatar
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: delayMicroseconds() doesn't work in ADS1115 library

Post by adafruit_support_bill »

Post your test code & we'll take a look.

User avatar
xhr0428
 
Posts: 18
Joined: Thu Aug 14, 2014 7:50 pm

Re: delayMicroseconds() doesn't work in ADS1115 library

Post by xhr0428 »

adafruit_support_bill wrote:Post your test code & we'll take a look.
Here is the arduino sketch

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 .h file, I changed #define ADS1115_CONVERSIONDELAY (8) to #define ADS1115_CONVERSIONDELAY (1300)
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)

User avatar
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: delayMicroseconds() doesn't work in ADS1115 library

Post by adafruit_support_bill »

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

User avatar
xhr0428
 
Posts: 18
Joined: Thu Aug 14, 2014 7:50 pm

Re: delayMicroseconds() doesn't work in ADS1115 library

Post by xhr0428 »

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
I don't have arduino at hand now. I'll try it later and let you know the result.
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.

User avatar
xhr0428
 
Posts: 18
Joined: Thu Aug 14, 2014 7:50 pm

Re: delayMicroseconds() doesn't work in ADS1115 library

Post by xhr0428 »

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
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.

User avatar
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: delayMicroseconds() doesn't work in ADS1115 library

Post by adafruit_support_bill »

No idea. If you post your modified library code (.h and .cp), we might be able to spot the problem.

User avatar
xhr0428
 
Posts: 18
Joined: Thu Aug 14, 2014 7:50 pm

Re: delayMicroseconds() doesn't work in ADS1115 library

Post by xhr0428 »

adafruit_support_bill wrote:No idea. If you post your modified library code (.h and .cp), we might be able to spot the problem.
in the .h file, this is the only place I changed

Code: Select all

/*=========================================================================
    CONVERSION DELAY (in mS)
    -----------------------------------------------------------------------*/
    #define ADS1015_CONVERSIONDELAY         (1)
    #define ADS1115_CONVERSIONDELAY         (1300)
/*=========================================================================*/
in the .cpp file, I only changed readADC_SingleEnded(uint8_t channel) function. Sorry I don't find a way to highlight the changes in the code. Here are the modifications:
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;  
}

User avatar
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: delayMicroseconds() doesn't work in ADS1115 library

Post by adafruit_support_bill »

uint16_t Adafruit_ADS1015::readADC_SingleEnded(uint8_t channel) {
You need to change the ADS1115 version of this function.

User avatar
xhr0428
 
Posts: 18
Joined: Thu Aug 14, 2014 7:50 pm

Re: delayMicroseconds() doesn't work in ADS1115 library

Post by xhr0428 »

adafruit_support_bill wrote:
uint16_t Adafruit_ADS1015::readADC_SingleEnded(uint8_t channel) {
You need to change the ADS1115 version of this function.
But this is the only readADC_SingleEnded function in the .cpp file. Doesn't class Adafruit_ADS1115 inherit those functions from class Adafruit_ADS1015?

User avatar
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: delayMicroseconds() doesn't work in ADS1115 library

Post by adafruit_support_bill »

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.

User avatar
xhr0428
 
Posts: 18
Joined: Thu Aug 14, 2014 7:50 pm

Re: delayMicroseconds() doesn't work in ADS1115 library

Post by xhr0428 »

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.
I changed ADS1015 conversion delay to the same value of ADS1115 conversion delay, the issue remained.
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.

User avatar
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: delayMicroseconds() doesn't work in ADS1115 library

Post by adafruit_support_bill »

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.

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Products from Adafruit”