ARMmbed / mbed-os

Arm Mbed OS is a platform operating system designed for the internet of things
https://mbed.com
Other
4.67k stars 2.98k forks source link

Reading temperature from mlx90614 Sensor attached to Nucleo F091RC #4362

Closed sandeepmvd closed 7 years ago

sandeepmvd commented 7 years ago

Question

I am trying to read some data from the mlx90614 temperature sensor attached to a NUCLEO-F091RC. so far, not successful.

There are many posts on this topic but the issue remains unresolved everywhere.

Following is the code I am trying with.

I2C i2c(I2C_SDA , I2C_SCL);

const int addr7bit = 0x5A;    // 7 bit I2C address
const int addr8bit = 0x5A << 1; // 8bit I2C address, 0x90

int main() {
    char cmd[2];
    while (1) {
        cmd[0] = 0x01;
        cmd[1] = 0x00;
        i2c.write(addr8bit, cmd, 2);

        wait(0.5);

        cmd[0] = 0x07;
        i2c.write(addr8bit, cmd, 1);
        i2c.read( addr8bit, cmd, 2);

//      uint8_t pec = i2c.read(addr8bit);

        pc.printf("cmd[0] = %d cmd[1] = %d\n", cmd[0], cmd[1]);

        float tmp = cmd[0] + ((cmd[1] & 0x007F) << 8) ;
        tmp = (tmp * 0.02) - 0.01;
        float celcius = tmp - 273.15;
        pc.printf("Temp = %.2f degrees celcius\n", celcius);
    }
}

The raw data is always 255. both cmd[0] and [cmd[1]

The above code, I wrote based is based on the working code on Arduino Uno board (github), I2c mbed API's and referring to the sensor's datasheet:

Registers to read from sensor:

image

Here is the pseudo code from the datasheet

image

Toolchain: GCC_ARM

Is there any limitation wrt using I2c on nucleo?

Output:

Raw data from Arduino board (not mbed code. (Arduino library code) )

cmd[0] 120
cmd[1] 58
cmd[0] 124
cmd[1] 58
cmd[0] 118
cmd[1] 58
cmd[0] 118
cmd[1] 58
cmd[0] 125
cmd[1] 58

With the code I posted above, the data is as follows

cmd[0] 255 cmd[1] 255 cmd[0] 255 cmd[1] 255 cmd[0] 255 cmd[1] 255 cmd[0] 255 cmd[1] 255 cmd[0] 255 cmd[1] 255

0xc0170 commented 7 years ago

cc @bcostm @adustm @LMESTM @jeromecoutant

@andcor02

LMESTM commented 7 years ago

@binary-nerd Hello there are weekly non-regression tests in MBED of reading I2C temperature sensors with all NUCLEO boards, so there is no limitation.

Here is a working example of a temperature driver: https://developer.mbed.org/users/neilt6/code/LM75B/file/7ac462ba84ac/LM75B.cpp I think many sensors work the same so you could re-use part of the code for the mlx90614.

I think that your code is missing the "STEP4: Send Repeated Start" In the library that shared this repeated start is sent with passing true as the last parameter to m_I2C_write. ` unsigned short LM75B::read16(char reg) { //Create a temporary buffer char buff[2];

//Select the register
m_I2C.write(m_ADDR, &reg, 1, true);

//Read the 16-bit register
m_I2C.read(m_ADDR, buff, 2);

//Return the combined 16-bit value
return (buff[0] << 8) | buff[1];

} `

I think that you need to add this "true" parameter in your code: ` cmd[0] = 0x07;

i2c.write(addr8bit, cmd, 1, true);

i2c.read( addr8bit, cmd, 2); `

ohagendorf commented 7 years ago

This sensor is a bit tricky. It can be used in two different configuration: i2c or pwm mode. We had to enable the i2c mode everytime we started the system. We used a NUCLEO_F411RE.

The lm75 is much more easier.

sandeepmvd commented 7 years ago

@LMESTM Thank you very much. setting repeated start to true works. I am now getting sensible sensor data.

I get varying temperature data and the values look nice.

The temperature sensor data on nucleo is as follows :

cmd[0] = 94   cmd[1] = 58
cmd[0] = 96   cmd[1] = 58
cmd[0] = 97   cmd[1] = 58
cmd[0] = 96   cmd[1] = 58
cmd[0] = 94   cmd[1] = 58
cmd[0] = 97   cmd[1] = 58
cmd[0] = 96   cmd[1] = 58
cmd[0] = 97   cmd[1] = 58
cmd[0] = 96   cmd[1] = 58
cmd[0] = 146   cmd[1] = 58
cmd[0] = 136   cmd[1] = 58
cmd[0] = 142   cmd[1] = 58
cmd[0] = 140   cmd[1] = 58
cmd[0] = 146   cmd[1] = 58
cmd[0] = 96   cmd[1] = 58

@ohagendorf I am not explicitly setting its mode. With the change suggested by @LMESTM it starts to work. I checked the datasheet to see how to change the mode from I2c to PWM and vice-versa. Cannot find any relevant stuff. Could you please explain here how you are explicitly setting its mode to I2c and PWM?

LMESTM commented 7 years ago

@binary-nerd glad to hear this works fine now - I'll let you close the issue when you think it's ok. You can continue discussion about the sensor even if issue is closed ;-)

sandeepmvd commented 7 years ago

Ok. I will close the issue. :) I will be waiting for reply from @ohagendorf