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.

ADS122C04: Read out external REF and internal temperatur

Part Number: ADS122C04

As an external reference, I applied a 5.0V voltage. I would like to measure voltage in the range of 0-5V with two inputs. In order to calculate internally in the microcontroller I would like to measure the external reference with the ADC, however, I measure everything else but not 5V I measure 3048mV, which is 1V more than the internal reference. But I don't know exactly what I'm doing wrong in register 0 is 0xC1 and in register 1 is 0xBA. In register 2 and 3 there is 0x00. Reading out is the same as with an analog input, I assume. I also read out the internal temperature. However, I fully understand how that can be calculated with MSB = 1, which is the other way around for me than in the data sheet. If I have 25 degrees, MSB 1 is theoretically minus for me but not according to the calculation. For the temperature, register 1 is 0xBB, register 0 has no influence and registers 2 and 3 are 0x00.

func read_REF()
    I2C1_Start();
    I2C1_Write(0x80); //device adress
    I2C1_Write(0x40); //registdr 0
    I2C1_Write(0xC1); //config (V(REFP) – V(REFN)) / 4 monitor (PGA bypassed) gain = 1, bypassed enabled
    I2C1_Stop();
    pause(5);
    I2C1_Start();
    I2C1_Write(0x80); //device adress
    I2C1_Write(0x44); //registdr 1
    I2C1_Write(0xBA); //config temp OFF and Ref extern
    I2C1_Stop();

    pause(5);
    I2C1_Start();
    I2C1_Write(0x80); //device adress
    I2C1_Write(0x10); //read out Register
    I2C1_Stop();
    I2C1_Start();
    I2C1_Write(0x81); //device adress  + read bit
    REFMSB = I2C1_Read();
    I2C1_Ack();
    REFMB = I2C1_Read();
    I2C1_Ack();
    REFLSB = I2C1_Read();
    I2C1_Nack();
    I2C1_Stop();
endfunc


func read_Temp()
    I2C1_Start();
    I2C1_Write(0x80); //device adress
    I2C1_Write(0x44); //registdr 1
    I2C1_Write(0xBB); //config temp ON and Ref extern
    I2C1_Stop();
    pause(5);
    I2C1_Start();
    I2C1_Write(0x80); //device adress
    I2C1_Write(0x10); //read out Register
    I2C1_Stop();
    I2C1_Start();
    I2C1_Write(0x81);   //device adress  + read bit
    TempHigh = (I2C1_Read()<<10);
    I2C1_Ack();
    TempLow = I2C1_Read();
    I2C1_Nack();
    I2C1_Stop();

    TempHigh = TempHigh >>4;
    Temperatur = (TempHigh + TempLow);
endfunc

  • Hi Simon,

    Welcome to the E2E forum! Do you happen to have a logic analyzer (or even oscilloscope shots)?  It would be much more helpful if I can see the actual communication to make sure that there are now transmission errors.

    I don't see anything particularly wrong with the register writes, but once you set the ADS122C04 to continuous conversion mode you must issue the START/SYNC command by writing the command (0x08) to the ADS122C04 to actually start the conversions. 

    If you want to verify your register writes with register reads you need to use the RREG command.  The RREG command is similar to the WREG command in that you can only read one register at at time.  The RREG command for register 0 is 0x20. 

    You are attempting to read the conversion result for the mux setting just made.  As I said earlier you must issue the START/SYNC command to start the conversion after setting to continuous conversion mode.  You must also ensure that the conversion completes before you read back the results by using the RDATA command.  It is not at all clear what 'pause(5)' means with respect to time.  Again it would be helpful for me to see the actual data returned and not a computed value.

    As to the temperature measurement, I will assume that the START/SYNC command has already been issued.  Again, it is not clear what 'pause(5)' means with respect to time.  At 20sps, you must wait a minimum of 50ms after the write command to turn on the temperature sensor prior to reading back the result.

    I don't understand how you are attempting to read and make the temperature conversion result, nor do I understand your method of shifting the data.  Obviously you are short-cycling the result only reading 2 bytes of the 3 byte result.  The result is 14-bit left-justified, so the way I would do this is to use a signed 16-bit (short) integer for the variable 'Tempartur'.  The code segment would look something like as follows:

    short int Temperatur;
    
    I2C1_Start();
    I2C1_Write(0x80); //device adress
    I2C1_Write(0x10); //read out Register
    I2C1_Stop();
    I2C1_Start();
    I2C1_Write(0x81);   //device adress  + read bit
    TempHigh = I2C1_Read();
    I2C1_Ack();
    TempLow = I2C1_Read();
    I2C1_Nack();
    I2C1_Stop();
    
    Temperatur = (TempHigh <<8) + TempLow); // 14-bit left-justified
    Temperatur = Temperatur >> 2;  //Sign-extended 14-bit result

    Best regards,

    Bob B