This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ADS112U04: Decreased sampling rate when reading on multiple single ended channels

Part Number: ADS112U04

Hello everyone,

First of all I'm sorry if this topic has already been solved but I haven't found anything similar for this ADC model.

I interface an ADS112U04 with an ESP8266EX and I need to read 1000 SPS on one channel and 200 SPS on another channel.

The conversion on one channel works perfectly, but when I add more channels, many read errors occur, and the reading stalls.

At a sampling rate of 20 SPS, it works fine, but the higher I go, the more errors there are. Baudrate is 115200.

I proceed as follows (I don't know if this is the right way):

In setup :
- RESET by hardware
- acStartup(); //function provided by TI code

In loop :

uint8_t data_adc[12];
  
  registerWrite(0x00, REG0_AIN0);
  registerWrite(0x01, REG1);
  registerWrite(0x02, REG2);
  registerWrite(0x03, REG3);
  registerWrite(0x04, REG4);

  for (int i = 0; i < 10; i += 2) {
    // Wait for GPIO2/DRDY to transition low
    while (digitalRead(GPIO_DRDY_PIN) == HIGH) {};
    sendCommand_ADC(0x10);
    while (!Serial.available());
    uint16_t dataLowByte = Serial.read();
    while (!Serial.available());
    uint16_t dataHighByte = Serial.read();
    data_adc[i] = static_cast<uint8_t>(dataLowByte);
    data_adc[i + 1] = static_cast<uint8_t>(dataHighByte);
  }

  registerWrite(0x00, REG0_AIN2);
  registerWrite(0x01, REG1);
  registerWrite(0x02, REG2);
  registerWrite(0x03, REG3);
  registerWrite(0x04, REG4);

  for (int i = 10; i < 12; i += 2) {
    while (digitalRead(GPIO_DRDY_PIN) == HIGH) {};
    sendCommand_ADC(0x10);
    while (!Serial.available());
    uint16_t dataLowByte = Serial.read();
    while (!Serial.available());
    uint16_t dataHighByte = Serial.read();
    data_adc[i] = static_cast<uint8_t>(dataLowByte);
    data_adc[i + 1] = static_cast<uint8_t>(dataHighByte);
  }

sendCommand_ADC function:

void sendCommand_ADC(uint8_t command) {
  Serial.write(SYNC_WORD);
  Serial.write(command);
}

Register correspondence:

#define REG0_AIN0       (CONFIG0_MUX_AIN0_AVSS | CONFIG0_GAIN_1 | CONFIG0_PGA_BYPASS_NO)
#define REG0_AIN2       (CONFIG0_MUX_AIN2_AVSS | CONFIG0_GAIN_1 | CONFIG0_PGA_BYPASS_NO)
#define REG1            (CONFIG1_DR_600_SPS | CONFIG1_MODE_TURBO | CONFIG1_CM_CONTINUOUS | CONFIG1_VREF_EXT | CONFIG1_TS_DISABLED)
#define REG2            (CONFIG2_DRDY_OLD | CONFIG2_DCNT_DISABLED | CONFIG2_CRC_DISABLED | CONFIG2_BCS_DISABLED | CONFIG2_IDAC_OFF)
#define REG3            (CONFIG3_I1MUX_DISABLED | CONFIG3_I2MUX_DISABLED | CONFIG3_AUTO_MANUAL)
#define REG4            (CONFIG4_GPIO2DIR_OUT | CONFIG4_GPIO1DIR_IN | CONFIG4_GPIO0DIR_IN | CONFIG4_GPIO2SEL_DRDY | CONFIG4_GPIO2DAT_LO | CONFIG4_GPIO1DAT_LO | CONFIG4_GPIO0DAT_LO)

Thanks to all

  • Hi Edwin,

    Welcome to the E2E forum!  One thing I would recommend and that is not to send register writes if the configuration stays the same.  For example, if the only thing you change is the mux, don't rewrite the configuration for REGISTER1-4.

    Also, make absolutely sure that you are not sending and receiving data at the same time.  You can verify this with and oscilloscope or logic analyzer on the UART TX and RX pins.  A logic analyzer is best as it will have a protocol analyzer for UART communication.  The system locking up is most often due to cross communication.

    I don't see any code where you are running at 20sps.  REG1 condition is showing 600sps in turbo mode (1200sps).

    Another possible issue is your timing is off.  Instead of running in continuous mode, use single-shot mode first.  It may be possible that DRDY is changing state before you read out the data.  The end goal is to make sure that the data are read before the next conversion completes.

    Best regards,

    Bob B

  • Hi Bob,

    Thanks for your reply.

    I have removed the redundant register writes and added a condition to verify that the UART port is available and the system no longer hangs.

    Condition added :

    if (Serial.available()) {
        registerWrite(0x00, REG0_AIN0);
      }


    However, I realized that the values I obtained when I changed the configuration of the registers were not correct because in reality, the condition does not allow to modify the values of the registers but keeps the same ones.

    I've tried this:

    while (!Serial.available());
    registerWrite(0x00, REG0_AIN0);

    But the system is locking up.

    Do you think this is due to a hardware limitation? Is it possible to remedy this via the software?

    Just a clarification, I've posted here the code I use to get 1000 SPS + 200 SPS as I explained in my first post and not 20 SPS.

    Many thanks

  • Hi Edwin,

    There is example C code available to demonstrate how you should communicate to the ADS112U04.  Code with respect to each individual microcontroller peripheral can be tricky.  You need to fully understand what each function statement is actually doing.

    Each register write command must start with the synchronization byte of 0x55.  The only way to fully verify that you code is working as expected is to use a logic analyzer with a UART protocol analyzer function.  This logic analyzer data is what I need to see to really help you further.

    If you want to change the mux you need to send a register write to REGISTER 0, if you want to change the mux and the data rate, then you need to send two commands with one to REGISTER 0 and the second to REGISTER 1.  

    In the end, just stepping through code shows you very little.  As you are communicating to an external device through a peripheral that usually operates independently of your code flow, you need to monitor the communication to ensure that you are truly doing what you think you are doing and the timing fits all requirements.  The most valuable tool in my toolbox is the logic analyzer.

    Best regards,

    Bob B