2017-07-20 01:52 PM
Hello everyone,
I recently got myself a little nucleo compatible
http://www.waveshare.com/w/upload/3/3a/Accessory-Shield-Schematic.pdf
that comes with at I2C Temperature sensorhttp://www.nxp.com/docs/en/data-sheet/LM75B.pdf
. After carefully reading the datasheet I felt confident that I could get a working code quick enough. As a first test I decided to try to do a read of the temperature sensor using the pointer. I found some example online that I modified for my needs that look something like that :I2C_HandleTypeDef hi2c1;
volatile uint8_t buffer[5];
volatile uint16_t rawTemp;int16_t Temp;void TempMeasurement(void){
buffer[0] = 0x00; //Pointer to the Temp. Register HAL_I2C_Master_Transmit(&hi2c1,0x48<<1,buffer,1,100); //Send pointer for Temperature Register HAL_Delay(10); HAL_I2C_Master_Receive(&hi2c1,0x48<<1,buffer,2,100); //Buffer[0] : MSB //Buffer[1] : LSB printf('Buffer After %d\r\n',buffer[0]); rawTemp = buffer[0]<<5 | buffer[1]; //combine 2 MSB and LSB in one 10 bit number}I use the cube to generate the basic code for the I2C Bus. I also know that the sensor is working because I ran the provided mbed code as a check to verify that the electric part of the 'project' is working. If you could help with the code that would be great. On the other hand what I am interested in is ways that I can use HAL librairies to inspect where and how the code is breaking?
I tried to dig into the code and found various values like TIMEOUT and ERROR. Could I use these to check how my bus is failing?
Thank you in advance.
Solved! Go to Solution.
2017-07-20 06:09 PM
one command looks more complex than the three you're doing? i'm simply adding sanity checks anyone should be doing. making sure the bus is ready. making sure the device is ready. otherwise, i've actually replaced two commands and a delay, with one. and done some error checking.
regardless, the point im trying to make is look at the definition of the function you're trying to use and meet it's demands. the HAL wants a pointer to a buffer's address. you're not giving it that. that may be one of your problems with your code.
your code:
HAL_I2C_Master_Transmit(&hi2c1,0x48<<1,buffer,1,100); //Send pointer for Temperature Register
HAL_Delay(10); HAL_I2C_Master_Receive(&hi2c1,0x48<<1,buffer,2,100);this is the definition for Master_Transmit
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
it returns the status of the command
it wants a pointer to the address of the handle
it wants the device's i2c address, as a 16 bit integer left-aligned
it wants a pointer to the address of the variable containing the data
it wants the size of the data in numbers of bytes
it wants to know how long to wait in ms before the timeout
your code:
attempt to transmit
wait for 10 ms
attempt to receive
try:
is device ready
if yes, transmit to device
if no, handle it
is transmit finished
if yes, receive response
if no, handle it
2017-07-20 03:04 PM
Hello!
In your code you use hi2c1 without initialize it
Is it an external handle initialised somewere else?
extern I2C_HandleTypeDef hi2c1;
2017-07-20 04:17 PM
to read a register use I2C_MemRead();
while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY) {}
while (HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(0x48<<1), 3, 100) != HAL_OK) {}
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Mem_Read(&hi2c1, // i2c handle
(uint16_t)(0x48<<1), // i2c address, left aligned (uint16_t)register_addr, // register address I2C_MEMADD_SIZE_8BIT, // device uses 8-bit register addresses (uint8_t*)(&buffer), // variable to put returned value 2, // return two bytes 100); // timeout in msif(status != HAL_OK)
{switch(status)
{
case HAL_ERROR: do error stuff; break;
case HAL_BUSY: do busy stuff; break;
case HAL_TIMEOUT: do timeout stuff; break;
}
}
as far as troubleshooting without a scope goes, you probably have a debugger in your tool chain, and a person can go pretty far with an LED and a few printf() statements
2017-07-20 06:09 PM
one command looks more complex than the three you're doing? i'm simply adding sanity checks anyone should be doing. making sure the bus is ready. making sure the device is ready. otherwise, i've actually replaced two commands and a delay, with one. and done some error checking.
regardless, the point im trying to make is look at the definition of the function you're trying to use and meet it's demands. the HAL wants a pointer to a buffer's address. you're not giving it that. that may be one of your problems with your code.
your code:
HAL_I2C_Master_Transmit(&hi2c1,0x48<<1,buffer,1,100); //Send pointer for Temperature Register
HAL_Delay(10); HAL_I2C_Master_Receive(&hi2c1,0x48<<1,buffer,2,100);this is the definition for Master_Transmit
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
it returns the status of the command
it wants a pointer to the address of the handle
it wants the device's i2c address, as a 16 bit integer left-aligned
it wants a pointer to the address of the variable containing the data
it wants the size of the data in numbers of bytes
it wants to know how long to wait in ms before the timeout
your code:
attempt to transmit
wait for 10 ms
attempt to receive
try:
is device ready
if yes, transmit to device
if no, handle it
is transmit finished
if yes, receive response
if no, handle it
2017-07-20 07:45 PM
Is there an issue doing a receive the way I chose to? Because the
I2C_MemRead(); method looks a lot more complex and less straight forward?