cancel
Showing results for 
Search instead for 
Did you mean: 

A problem with I2C and ADS1115

LMI2
Lead

I get always zeros from my code. Is there something you see immediately.

This is what TI tells me to do (I have ADS1115).

For example, to write to the configuration register to set the ADS111x to continuous-conversion mode and then

read the conversion result, send the following bytes in this order:

1. Write to Config register:

– First byte: 0b10010000 (first 7-bit I2C address followed by a low R/W bit)

– Second byte: 0b00000001 (points to Config register)

– Third byte: 0b10000100 (MSB of the Config register to be written)

– Fourth byte: 0b10000011 (LSB of the Config register to be written)

2. Write to Address Pointer register:

– First byte: 0b10010000 (first 7-bit I2C address followed by a low R/W bit)

– Second byte: 0b00000000 (points to Conversion register)

3. Read Conversion register:

– First byte: 0b10010001 (first 7-bit I2C address followed by a high R/W bit)

– Second byte: the ADS111x response with the MSB of the Conversion register

– Third byte: the ADS111x response with the LSB of the Conversion register

And this is my code to do it

unsigned char txBuffer[25];
unsigned char rxBuffer[25];
char msg[80];
int lamp1,lamp2;
...
...
...	
txBuffer[0]=0b00000001 ;//
	txBuffer[1]=0b10000100 ;
	txBuffer[2] =0b10000011;
 
 HAL_I2C_Master_Transmit (&hi2c1,(uint8_t)0b10010000,(uint8_t*)txBuffer, 3, 1000);
 
	txBuffer[0]=0b00000000;//
 
 HAL_I2C_Master_Transmit (&hi2c1, (uint8_t)0b10010000, (uint8_t*)txBuffer,1, 1000);
 HAL_Delay(500);
 
	txBuffer[0]=0b10010001 ;//
	txBuffer[1]=0b00000001 ;//
	txBuffer[2] =0b10000100;
	txBuffer[2] =0b10000011;
	HAL_I2C_Master_Receive (&hi2c1, (uint8_t)0b10010001, (uint8_t*)rxBuffer, 2, 1000);
 
	lamp1=rxBuffer[0]*256;
	lamp1=lamp1+(rxBuffer[1]);
 
	sprintf(msg ,"01 06 21 adcanssi %d \r\n",lamp1);
	HAL_UART_Transmit(&huart3, (uint8_t*)msg, strlen(msg), 1000);

1 ACCEPTED SOLUTION

Accepted Solutions

// Step1

{

 uint8_t Value[] = { 0x84,0x83 };

 HAL_StatusTypeDef status = HAL_I2C_Mem_Write(&I2CHandle, 0x90, 1, I2C_MEMADD_SIZE_8BIT, &Value[0], sizeof(Value), 1000);

}

// Step 2 and 3

{

 uint8_t Value[2];

 HAL_StatusTypeDef status = HAL_I2C_Mem_Read(&I2CHandle, 0x90, 0, I2C_MEMADD_SIZE_8BIT, &Value[0], sizeof(Value), 1000);

lamp1=(rxBuffer[0]*256)+rxBuffer[1];

}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

9 REPLIES 9
raptorhal2
Lead

The code does not match your description of what TI tells you to do.

Data sheet 9.1 "Data can be read at any time and always reflect the most recent completed conversion"

There is no delay to wait for first completed conversion, or a read of the conversion ready pin.

Cheers, Hal

// Step1

{

 uint8_t Value[] = { 0x84,0x83 };

 HAL_StatusTypeDef status = HAL_I2C_Mem_Write(&I2CHandle, 0x90, 1, I2C_MEMADD_SIZE_8BIT, &Value[0], sizeof(Value), 1000);

}

// Step 2 and 3

{

 uint8_t Value[2];

 HAL_StatusTypeDef status = HAL_I2C_Mem_Read(&I2CHandle, 0x90, 0, I2C_MEMADD_SIZE_8BIT, &Value[0], sizeof(Value), 1000);

lamp1=(rxBuffer[0]*256)+rxBuffer[1];

}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
TDK
Guru

What are the return values from HAL_I2C_Master_Transmit? Does HAL_I2C_IsDeviceReady see the device?

If you feel a post has answered your question, please click "Accept as Solution".

0693W00000BaDTlQAN.png0693W00000BaDTgQAN.pngI get HAL_error from I2C calls. I have not tried HAL_I2C_IsDeviceReady. (I also noticed that breakpoints do no work with CubeIde and stm32h750vbt6, and then I read that some CPU had that problem.)

I get good square wave from SCL and SDA pins, I can't tell you more now, I have only single channel scope here. Pictures show CPU/CubeMX settings, I cannot anything special in them.

TDK
Guru

> I get HAL_error from I2C calls.

If they return HAL_ERROR, it would indicate your device does not ACK when the address is sent.

> I have not tried HAL_I2C_IsDeviceReady.

So try it. This should be the first step in debugging an I2C problem. If you don't get HAL_OK, the device isn't wired up properly, or doesn't have the slave address you think it does.

If you feel a post has answered your question, please click "Accept as Solution".
LMI2
Lead

HAL_I2C_IsDeviceReady returns error at every address except at 00h. I think I must check my ADC.

DOCon.1
Senior

Hi - I'm using this ADC on STM32 as well. Let's assume the HAL code for I2C operation is correct. Here's the general idea. (Your OP code looked right; not sure what I missed). This is coded in Rust, but the concept is the same. Note that the `cmd` argument is the string of bytes used to set in the cfg register, ie choosing the channel, voltage range etc. Also note that the reading taken here isn't necessarily the one from the commanded version; you'd have to use an interrupt, or block for that etc. I think that's what your delay is for? A better approach would be to poll the cfg register until it shows the conversion has stopped. (if blocking is OK)

const CFG_REG: u8 = 0x1;
const CONV_REG: u8 = 0x0;
 
/// Take a measurement from an external ADC, using the I2C connection.
fn take_reading<I2C, E>(addr: u8, cmd: u16, i2c: &mut I2C) -> i16
where
    I2C: Write<Error = E> + WriteRead<Error = E>,
{
    let mut result_buf: [u8; 2] = [0, 0];
 
    // Set up the cfg, and command a one-shot reading. Note that we
    // pass the 16-bit i2c command as 2 bytes.
    i2c.write(addr, &[CFG_REG, (cmd >> 8) as u8, cmd as u8])
        .ok();
 
    // Note: The measurements we're taking isn't necessarily the one
    // commanded by the above conversion.
 
    // Request the measurement.
    i2c.write_read(addr, &[CONV_REG], &mut result_buf).ok();
 
    i16::from_be_bytes([result_buf[0], result_buf[1]])
}

LMI2
Lead

I got some life to the device. It has now I2C address 0x96/0x97, and not 0x90 like the data sheet says it has when ADDR is grounded. The chip uses 0x96 address when ADDR is connected to the SCL. And I am sure ADDR is grounded.

I got some response with my code, but Clives Tesla makes more sense.

This is probably the answer, but chip behaves in odd way.