ad7124-8 code problem

good morning,

I am currently talking to a Featherwing 3.5" and the CN0391 evaluation board at the same time over a teensy3.6 with an encoder menu over the same SPI line.

the encoder menu works fine and writing values to the display and outputs from the teensy works fine to.

however if I try to run an example, lets say for instance AD7124,full test, continious, thermometer or others

i get kinda rubbish information back, i greatly lack the understanding what the chip is doing. i got the comprehension that the library ad7124 was more written for the CN0381 instead of the CN0391. i tried writing the community from github as well, but they all turned dead.

I would like to do the following for 4 thermocouple signals. four RTC signals also.

measure the cold junction in degrees and substract the thermocouple Temperature. to get the actual temperature from 4 Channels/thermocouples.

so bare with me. I tried to use the CN0391 library but there is to much calling the SSpin that totaly disrupts my communication with the TFT screen.

so Ill start by asking the basic question and would like to know if I am doing it correctly.

please correct me.

this is the thermocouple method from the AD7124-8 I would like to know if I have done it correctly.

Reset the ADC. 2.Select the power mode.

adc.begin (ssPin);

Set the CHANNEL_0 register analog input to AIN0/AIN1.

adc.setConfig (0, RefIn1, Pga16, true);

Assign Setup 0 to this channel.

adc.setChannel (0, 1, AIN1Input, AIN0Input);

Configure Setup 0 to have a gain of 128 and select the internal reference.

adc.setConfig (0, RefIn1, Pga128, true);

Select the filter type and set the output data rate.

adc.setConfigFilter (0, Sinc4Filter, 384);

3.Enable VBIAS on AIN0.

adc.enableChannel(0,true); is this correct?

(where do I set the VBIAS on AIN0?`) is this a reference RefIn1?

4.Set the CHANNEL_1 register analog input to AIN12/AIN13. Assign Setup 1 to this channel. Configure Setup 1 to have a gain of 1 and select the external reference REFIN2(± ). Selectth e filter type and set the output data rate.

adc.setChannel (1, 0, AIN12Input, AIN13Input);

adc.setConfig (1, RefIn2, Pga1, true); is this correct=?

5.Enable the excitation current (IOUTx) and select a suitable value. Output this current to the AIN4 pin.

 adc.setChannel(0,0,AIN4Input,AIN0Input); //shall I put this on AIN0Input? is this correct?
    adc.setCurrentSource (0, IoutCh0, Current500uA); // or should this be IoutCH4?

6.Enable the AIN0/AIN1 channel. Wait until RDY goes low. Read the conversion.

adc.enableChannel(0,true);is this correct?

where do I check if the RDY goes low? is it just the SSpin ?

7.Continue to read nine further conversions from the AIN0/AIN1 channel.

value = adc.read (0); is this correct?

8.Disable CHANNEL_0 and enable CHANNEL_1.

adc.enableChannel(0,false), adc.enableChannel(1,true);

9.Wait until RDY goes low. Read one conversion.

what do I do here?

10.Repeat Step 5 to Step 8.

some for loop?

how do I implement the correction of the thermocouple values?

/*
  CN-0381 Thermometer (AD7124)
  Completely Integrated 4-Wire RTD Measurement System Using a AD7124
  See http://www.analog.com/media/en/reference-design-documentation/reference-designs/CN0381.pdf

  Prints out the RTD temperature and resistor measured at pins AIN2(+)/AIN3(-)
  for schematic see Figure 1., p.2 of CN-0381, e.g. :
  CN-0381 RTD Thermometer
  23.143,108.910
  23.143,108.910


  For more on AD7124, see
  http://www.analog.com/media/en/technical-documentation/data-sheets/AD7124-4.pdf

  The circuit:
  - AD7124 connected on the MOSI, MISO, SCK and /SS pins (pin 10)
  - LED active in low state connected to pin 9.

  created 2018
  by epsilonrt https://github.com/epsilonrt

  This example code is in the public domain.

  https://github.com/epsilonrt/ad7124/tree/master/examples
*/
#include <ad7124.h>

using namespace Ad7124;

/* constants ================================================================ */
const int ledPin = LED_BUILTIN;
const int ssPin = 10;

// Mathematical constants
const double Gain = 16;
const double Rf = 5.11E3;
const long Zero = 1L << 23;
const long FullScale = 1L << 24;

/* public variables ========================================================= */
Ad7124Chip adc;

/* internal public functions ================================================ */

// -----------------------------------------------------------------------------
void setup() {
  int ret;
  long value;

  pinMode (ledPin, OUTPUT);
  digitalWrite (ledPin, 1); // clear the LED

  //Initialize serial and wait for port to open:
  Serial.begin (38400);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // prints title with ending line break
  Serial.println ("RTD Thermometer");

  // Initializes the AD7124 device, the pin /CS is pin 10 (/SS)
  adc.begin (ssPin);

  // Setting the configuration 0:
  // - use of the REFIN1(+)/REFIN1(-) reference
  // - gain of 16 for a bipolar measurement
  // - digital filter Sync4 FS=384
  adc.setConfig (0, RefIn1, Pga128, true);
  adc.setConfigFilter (0, Sinc4Filter, 384);

  // Setting channel 0 with config 0 using pins AIN2(+)/AIN3(-)
  adc.setChannel (0, 1, AIN12Input, AIN13Input);
  
  // Configuring ADC in Full Power Mode (Fastest)
  ret = adc.setAdcControl (StandbyMode, FullPower, true);
  if (ret < 0) {

    Serial.println ("Unable to setting up ADC");
  }
}

// -----------------------------------------------------------------------------
void loop() {
  long value;

  // detect an open wire circuit (no RTD connected) or a short-circuit
  adc.setConfig (0, RefInternal, Pga1, true, Burnout4uA);
  value = adc.read (0);

  if (value >= (FullScale - 10))  {

    // A near full-scale reading can mean that the front-end sensor is open circuit.
    adc.setConfig (0, RefInternal, Pga1, true, BurnoutOff);
    Serial.println ("OPENED");
  }
  else {

    // Setting the configuration 0 for measuring
    adc.setConfig (0, RefIn1, Pga16, true); //programming the RTD for 500uA x
    // Program the excitation currents to 500 μA and output the currents on the AIN0
    adc.setChannel(0,0,AIN0Input,AIN3Input);
    adc.setCurrentSource (0, IoutCh0, Current500uA);
    
    // Measuring on Channel 0 in Single Conversion Mode
    digitalWrite (ledPin, 0);
    value = adc.read (0);
    digitalWrite (ledPin, 1);

    // Program the excitation currents to Off
    adc.setCurrentSource (0, IoutCh0, CurrentOff);

    if (value >= 0) {
      double r, t = 0;

      // See Equation (1), p.4 of CN-0381
      r = ((value - Zero) * Rf) / (Zero * Gain);

      // See Equation (2), p.4 of CN-0381
      t = (r - 100.0) / 0.385;

      // Print results
      Serial.print (t, 3);
      Serial.print (",");
      Serial.println (r, 3);
    }
    else {

      Serial.println ("FAIL");
    }
  }
}
/* ========================================================================== */

best regards

Bastiaan

  • Complete Code for Thermocouple Measurement.... still doesnt work, I followed the scripture on the page 73 the best I could. any advice?

    Best

    Bastiaan

    /*
     * AD7124-8 Six channel continuous sampling example
     * June 2019 - WizardTim
     * 
     * Prints voltages measured at differential pin pairs 2&3 to 12&13, sample rate is controlled by the limitations of the filterWord.
     * 
     * For more on AD7124-8, see
     * http://www.analog.com/media/en/technical-documentation/data-sheets/AD7124-8.pdf
     * 
     * The circuit:
     * - Arduino MCU (tested on Arduino Pro Micro aka LilyPad Arduino USB)
     * - AD7124-8 connected to MISO. MOSI. SCK amd /SS pins (pin 10) 
     */
     
    #include <ad7124.h>
    
    Ad7124Chip strainADC;
    
    // Physical Pins
    const int ssPin = 10;
    const double Gain = 16;
    const double Rf = 5.11E3;
    const long Zero = 1L << 23;
    const long FullScale = 1L << 24;
    
    
    long SBraw[7];
    double SBvolt[7];
    long dataWord;
    byte statusWord;
    byte ch;
    
    // Sample Speed Setting (Full Power Sinc3 Filter Mode)
    //  FW  |  SPS  |  SPS/Ch
    //  600 |    6  |     1
    //  100 |   60  |    10
    //   40 |  156  |    26
    //   20 |  300  |    50
    int filterWord = 100;
    
    void setup() 
    {
     pinMode(LED_BUILTIN, OUTPUT);
      digitalWrite(LED_BUILTIN, 1);
    
      Serial.begin (9600);
      while (!Serial) {
        ; // wait for serial port to connect.
      }
    
      // Loop until ADC responds
      int state = strainADC.begin(ssPin);
      while (state < 0) {
        Serial.println(state);
        Serial.println ("Failed");
        delay(100);
        state = strainADC.begin(ssPin);
    }
    
    //thermocouple Code: example Try: Page 73 from 94.
    /*
     * Reset the ADC. 
     * 2.Select the power mode. Set the CHANNEL_0 register analog input to AIN0/AIN1. Assign Setup 0 to this channel. Configure Setup 0 to have a gain of 128 and select the internal reference. Select the filter type and set the output data rate.
     * 3.Enable VBIAS on AIN0. 
     * 4.Set the CHANNEL_1 register analog input to AIN12/AIN13. Assign Setup 1 to this channel. Configure Setup 1 to have a gain of 1 and select the external reference REFIN2(± ). Selectth e filter type and set the output data rate.
     * 5.Enable the excitation current (IOUTx) and select a suitable value. Output this current to the AIN4 pin. 
     * 6.Enable the AIN0/AIN1 channel. Wait until RDY goes low. Read the conversion.   
     * 7.Continue to read nine further conversions from the AIN0/AIN1 channel. 
     * 8.Disable CHANNEL_0 and enable CHANNEL_1. 
     * 9.Wait until RDY goes low. Read one conversion.
     * 10.Repeat Step 5 to Step 8.
     * 
     * 
     * 
     * 
     * 
     * 
     */
    
     strainADC.setAdcControl(Ad7124::ContinuousMode, Ad7124::FullPower, true);
      
      strainADC.setMode(Ad7124::ContinuousMode);// put your main code here, to run repeatedly:
    
       // Configure Channel 0
      strainADC.setChannel(0,0,Ad7124::AIN1Input,Ad7124::AIN0Input);
      strainADC.setConfig(0, Ad7124::RefInternal, Ad7124::Pga128, true);
      strainADC.setConfigFilter(0, Ad7124::Sinc3Filter, filterWord);
      strainADC.setBiasPins(Ad7124::AIN0Input);
      
      //configure Channel 1
      strainADC.setConfig(1, Ad7124::RefIn2, Ad7124::Pga1, true);
      strainADC.setConfigFilter(1, Ad7124::Sinc3Filter, filterWord);
      strainADC.setChannel(1, 1, Ad7124::AIN12Input, Ad7124::AIN13Input, true);
      //
      strainADC.setChannel(0,0,Ad7124::AIN12Input,Ad7124::AIN13Input);
      strainADC.setCurrentSource(0, Ad7124::IoutCh4, Ad7124::Current500uA);
      strainADC.enableChannel(0,true);
        strainADC.enableChannel(1,false);
     
      strainADC.setCurrentSource (0, Ad7124::IoutCh4, Ad7124::CurrentOff);
      strainADC.enableChannel(0,false);
      strainADC.enableChannel(1,true);
      
      }
    
    void loop() 
    {
       long value;
    
    
      for (int i = 1; i <= 6; i++) {
        strainADC.waitEndOfConversion(500);
        dataWord = strainADC.getData();
        ch = strainADC.currentChannel();
      
        // check RDY bit
        if (ch >= 0) {
          SBraw[ch + 1] = dataWord;
          SBvolt[ch] = Ad7124Chip::toVoltage(SBraw[ch], 1, 2.5, true); 
        }
      }
      Serial.print("$");
      for (int i = 1; i <= 6; i++) {
        Serial.print(",");
        Serial.println(SBvolt[i]);
      }
    
    }

  • 0
    •  Analog Employees 
    on Aug 17, 2020 5:31 AM 3 months ago in reply to BP2015-MDC

    Hi,

    I would suggest to move or post this question to Reference Circuits Community as they may have better understanding how CN-0391 works.

    However, in terms of the steps process I would recommend to double check the analog inputs and the correct settings. Looking at the CN0391, the configuration settings above is incorrect for CN-0391. From the figure, TC are configured single ended, so AIN0 is the positive input and GND is your negative input, since the TC is single ended so you can enable Vbias at positive input, which is AIN0. IOUT is also coming from AIN1 for the first cold junction and this CJC is measured across AIN1 and AIN8 again based on the figure.

    So, I would recommend to clarify or understand first how the circuit works so you can configure the ADC correctly. You can refer to the Reference Circuit community above.   

    In terms of the RDY, you can monitor the RDY using the shared /DRDY pin and also by reading the RDY bit in the status register.

    Thanks,

    Jellenie

  • Hi thanks for the reply. maybe i am lacking understanding of this library.

    i wrote my own sketch to make sure the AD7124-8 is working properly. on page 39. the Register to start with is 0x00. but I am not getting any values on the 0x00, 0x01 only the value jumps from 10000 on the AD7124_Error, IOControl1 and IOControl2 are also showing 10000 as a binary value.

    do I have to use each time during accessing of a register AD7124_CS LOW , and then 10ms during this CS LOW, to HIGH and visa versa?

    ok

    const int ledPin = LED_BUILTIN;
    const int ssPin = 10;
    
    #include <SPI.h>
    //#include <ad7124.h>
    
    #include "Adafruit_GFX.h"
    #include "HX8357_t3n.h"
    #include <FlickerFreePrint.h>     // library to draw w/o flicker
    #include <Bounce.h>
    #include <ADC.h>
    #include <Encoder.h>
    #include <PID_v1.h>
    
    //SPI defines
    #define TFT_DC  9
    #define TFT_CS 10
    #define TFT_RST -1
    #define AD7124_CS 8
    #define AD7124_SPEED 5000000 // 2mhz?
    
    
    
    SPISettings settingsAD7124(5000000, MSBFIRST, SPI_MODE3); //Page 38-94 SPI_MODE3 CS LOW
    
    byte AD7124_Comms,AD7124_Status,AD7124_AdcControl,AD7124_Data,AD7124_IOControl1,AD7124_IOControl2,
    AD7124_ID,
    AD7124_Error,
    AD7124_Error_EN,
    AD7124_MCLKCount,
    AD7124_Ch0,
    AD7124_Ch1,
    AD7124_Ch2;
    
    
    void setup() 
    {
     pinMode(AD7124_CS, OUTPUT);
      pinMode(TFT_CS, OUTPUT);
    
       SPI.begin();
    
         //Initialize serial and wait for port to open:
      Serial.begin (38400);
      while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB port only
      }
    
      // prints title with ending line break
    SPI.beginTransaction(settingsAD7124);
    digitalWrite(AD7124_CS,LOW);
    delay(10); //setting delay 5*10^-6*64clkbits = Reset, a bit more to make sure.
    digitalWrite(AD7124_CS,HIGH);
    delay(1);
    digitalWrite(AD7124_CS,LOW);
    
    
    digitalWrite(AD7124_CS,HIGH);
    SPI.endTransaction();
    }
    void loop() {
    //i am guessing this is the starting Register where it writes to. I cant make this up from the PDF
    SPI.beginTransaction(settingsAD7124);
    digitalWrite(AD7124_CS,HIGH);
    delay(10);
    digitalWrite(AD7124_CS,LOW);
    //this will be properly 16 bit register. Bits15:8=11110011 what are bit 6,5,4? 
    //what do they Set?, there is also no information about this, page 68- box B? and what does Box B do? what does it set exactly?
    //Bit 3 and 2 are 00; Bit 1 and 0 is AINP(4:3) setting the Differential or pseudo differential inputs ;
    //AINP[2:0] and AINM[4:0]
    // so in total i write 0b11110011,11111111, if all inputs are being used in differential input mode.
    
    SPI.transfer(0b10000000);
    AD7124_Comms=SPI.transfer(0x00);// Bit7:1 =Write Enable, Bit6=R/Wnot, bit5=0, bit4=0, bit3=0, bit2=0, bit1=0, bit0=0;
    AD7124_Status=SPI.transfer(0x00); //just read out the register
    SPI.transfer(0b00011011);
    AD7124_AdcControl=SPI.transfer(0x01); //0b00011111
    AD7124_Data=SPI.transfer(0x02);
    AD7124_IOControl1=SPI.transfer(0x03);
    AD7124_IOControl2=SPI.transfer(0x04);
    AD7124_ID=SPI.transfer(0x05);
    AD7124_Error=SPI.transfer(0x06);
    AD7124_Error_EN=SPI.transfer(0x07);
    AD7124_MCLKCount=SPI.transfer(0x08);
    AD7124_Ch0=SPI.transfer(0x09);
    AD7124_Ch1=SPI.transfer(0x10);
    AD7124_Ch2=SPI.transfer(0x11);
    
    Serial.print(" = readout Register 0x00 Comms = ");
    Serial.println(AD7124_Comms,BIN);
    Serial.print(" = readout Register 0x00 Comms = ");
    Serial.println(AD7124_Status,BIN);
    Serial.print(" = readout Register 0x01 ADC_Control = ");
    Serial.println(AD7124_AdcControl,BIN);
    
    Serial.print(" = readout Register 0x02 Data = ");
    Serial.println(AD7124_Data,BIN);
    Serial.print(" = readout Register 0x03 IOControl1 = ");
    Serial.println(AD7124_IOControl1,BIN);
    Serial.print(" = readout Register 0x04 IOControl2 = ");
    Serial.println(AD7124_IOControl2,BIN);
    Serial.print(" = readout Register 0x05 ID = ");
    Serial.println(AD7124_ID,BIN);
    Serial.print(" = readout Register 0x06 Error = ");
    Serial.println(AD7124_Error,BIN);
    Serial.print("= readout Register 0x07 Error_EN = ");
    Serial.println(AD7124_Error_EN,BIN);
    Serial.print("= readout Register 0x08 MCLKCount = ");
    Serial.println(AD7124_MCLKCount,BIN);
    Serial.print("= readout Register 0x09 CH0 = ");
    Serial.println(AD7124_Ch0,BIN);
    Serial.print("= readout Register 0x10 Ch1 = ");
    Serial.println(AD7124_Ch1,BIN);
    Serial.print("= readout Register 0x11 Ch2 = ");
    Serial.println(AD7124_Ch2,BIN);
    
    
    delay(1000);
      // put your main code here, to run repeatedly:
    
    }

    Serial Monitor:

    = readout Register 0x00 Comms = 0
    
     = readout Register 0x00 Comms = 0
    
     = readout Register 0x01 ADC_Control = 100000
    
     = readout Register 0x02 Data = 0
    
     = readout Register 0x03 IOControl1 = 0
    
     = readout Register 0x04 IOControl2 = 0
    
     = readout Register 0x05 ID = 0
    
     = readout Register 0x06 Error = 1000000
    
    = readout Register 0x07 Error_EN = 0
    
    = readout Register 0x08 MCLKCount = 0
    
    = readout Register 0x09 CH0 = 0
    
    = readout Register 0x10 Ch1 = 0
    
    = readout Register 0x11 Ch2 = 0
    
    

    please help.

  • 0
    •  Analog Employees 
    on Aug 18, 2020 1:45 AM 3 months ago in reply to BP2015-MDC

    Hi,

    I'm sorry, I do not understand the follow up question. Are questions somehow related to the available code which you downloaded from CN-0391 website? If this is a code reference to CN-0391 like I suggested please go to  Reference Circuits Community as they are the one who have much better understanding how the driver works. However, my recommendation is to start with a very basic code, like reading the ID register, just to confirm that your digital interface is working before attempting to configure any other registers and performing measurements. You can also probe your digital interface to check if your MCU/Processor is really writing or attempting to read from the device.  

    We have a lot of available resources that you can also use as a reference/starting point. https://wiki.analog.com/resources/tools-software/product-support-software/sigma-delta_adc_temperature-ble_demo?rev=1591600357

    https://wiki.analog.com/resources/tools-software/product-support-software/ad7124_mbed_support

    https://wiki.analog.com/resources/tools-software/product-support-software/ad7124-stm32

    If you have questions related to these codes, I can direct you with our software support group.

    Thanks,

    Jellenie

  • ok, what I was trying to do is: write directly to the SPI.transfer(0x00); and sending the SPI.transfer(0b10000000); in the void loop. However this is quite Rudimentary. I havent hard coded like that. so I base my experience solemnly on the information I read from the Analog Devices forum.

    #include <SPI.h>
    
    //SPI defines
    #define TFT_DC  9
    #define TFT_CS 10
    #define TFT_RST -1
    #define AD7124_CS 8
    #define AD7124_SPEED 5000000 //max speed
    
    
    SPISettings settingsAD7124(5000000, MSBFIRST, SPI_MODE3); //Page 38-94 SPI_MODE3 CS LOW
    unsigned char reg;
    unsigned char reg0=0x00&0x3f;
    unsigned char data;
    unsigned char val;
    
    
    void setup() 
    {
     pinMode(AD7124_CS, OUTPUT);
      pinMode(TFT_CS, OUTPUT);
    
       SPI.begin();
    
         //Initialize serial and wait for port to open:
      Serial.begin (38400);
      while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB port only
      }
    
    }
    void loop() 
    {
    AD7124_Write(reg0,data);
    unsigned char val=AD7124_Read(reg);
    Serial.println("val from AD7124");
    Serial.println(val);
    }
    
    void AD7124_Write(unsigned char reg0, unsigned char data)
    {
    digitalWrite(AD7124_CS,LOW);
      SPI.beginTransaction(settingsAD7124);
    
      // Add WEN and R/W bits to register number
      SPI.transfer(0x05&11110000); // select register to write to
      SPI.transfer(data);
      SPI.endTransaction();
      digitalWrite(AD7124_CS,HIGH);
    
    
    
    }
    
    unsigned char AD7124_Read(unsigned char reg)
    {
      unsigned char data;
      
      digitalWrite(AD7124_CS,LOW);
      SPI.beginTransaction(settingsAD7124);
    
      SPI.transfer(0x05&11110000); // select register to read from
      data = SPI.transfer(0xff);
      SPI.endTransaction();
      digitalWrite(AD7124_CS,HIGH);
      delay(1000); //   optional delay for between transaction spacing
      return data;
    }

    I tried this as well by looking at other forums PJRC and so on. however both cases Hardcoding in the previous message dont show any value back on the Serial monitor. I am quite annoyed by this. it looked straightforward also the postings on the forums. I am missing something, please forward this to the Programming department.

    Important:

    I would like to apply the IMXRT1062 ARM7 Teensy4.1 in coding. the reason why I am stepping over from Arduino uno to the Teensy is the amount of memory and other things I can do during reading SPI. but one of the problem is here->

    The Voltages from the Thermocouple T, K, J, etc are not comparable to the Voltage given by the Calibrator CL3512A from Omega that is hooked up to the CN0391. how do I write the Progmem from the Arduino into a normal file?

    Mircea Caprioru also told me for that the ADuCM360 needs to be rewritten for the IMXRT1062 Teensy4.1 rewriting the Communication.cpp page 71, 93 and 151.

    so I started with the piece of code above to see any results by just sending information to the 0x00 register. still to no avail.

    I also checked the RTD Poly coefficients and Thermocouple Coefficients do some of them need to be 1.0f, why do they need to be 1.0 why not 0? does it matter for the polynomial in the thermocouple.h and RTD.h equation?

    best regards,

    Bastiaan