raspberry-pi3sensorsi2choneywell

Can't interface Honeywell airflow sensor with Raspberry via I2C bus


I am trying to interface the Honeywell airflow sensor (model HAFBSS0200C4AX3 - which has a I2C 3.3V output) with my Raspberry Pi3 but I can't receive truthful values from the sensor (the values are always too low even if I strongly breath in the sensor..)

Here the sensor datasheet (https://www.mouser.com/ds/2/187/honeywell-sensing-airflow-zephyr-haf-series-digita-740409.pdf).

I tried to run the following script:

#include <stdio.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>

int main (int argc, char *argv[])
 {
        int fd;
        float data;
        wiringPiSetup () ;

        fd=wiringPiI2CSetup (0x49) ;

        if(fd==-1)
        {
                printf("Can't setup the I2C device\n");
                return -1;
        }
        else
        {
                for (;;)
                {
                        data=wiringPiI2CRead(fd);
                        if(data==-1)
                        {
                                printf("No data\n");
                                //return -1;
                                delay(1000);
                        }
                        else
                        {
                                //print data
                                printf("data=%f\n", 200*( 
((data/16383)-0.5)/0.4));
                                delay(1000);
                        }
                }
        }
        return 0;
}

The output are too low values... The datasheet says I should read 2 byte (the first LSB and then the MSB), but I don't know if my script is doing so..(I am not I2C expert)..

Please could you help me? Thanks in advance!!


Solution

  • It is mentioned in the data-sheet that following sensor power-up, each of the first two read sequences will respond with 2 bytes of the unique 4-byte Serial Number.

    The first read after power-up will respond with the two most significant bytes of the Serial Number, while the second read will respond with the two least significant bytes of the Serial Number.

    After the power-up read sequence described above, the sensor will respond to each I2C read request with a 16-bit (2 byte) digital flow reading.


    As mentioned in the data-sheet you are not performing power-up read sequence for the Serial Number. I have personally not user wiring pi but its seems like you are reading only 1 byte while the sensor expects you to read two bytes. You can use Linux I2C driver instead :

    #include <string>
    #include <cerrno>
    #include <error.h>
    #include <fcntl.h>
    #include <cstdlib>
    #include <cstdint>
    #include <cstring>
    #include <iostream>
    #include <unistd.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #ifdef __linux__
    #include <sys/ioctl.h>
    #include <linux/i2c-dev.h>
    
    int                 fd;
    const uint8_t       dataLength = 2;
    uint8_t             data[dataLength], tempCount;
    
    sleep(1);
    
    fd = open("/dev/i2c-1", O_RDWR);
    if(fd < 0)
    {
        string str;
        str = "Error while opening i2c-1 bus. Error : " + string(strerror(errno)) + "\n";
        cout << str;
        return false;
    }
    sleep(0);
    if (ioctl(fd, I2C_SLAVE, 0x49) < 0)         //Set Slave Address
    {
        string str;
        str = "Error while ioctl system call on i2c-1 bus. Error : " + string(strerror(errno)) + "\n";
        cout << str;
        return false;
    }
    sleep(0);
    tempCount = read(fd, data, 2);     //We are to read 2 bytes of serial number
    if(tempCount != 2)
    {
        string str;
        str = "Error while reading data on i2c-1 bus. Error : " + string(strerror(errno)) + "\n";
        cout << str;
        return false;
    }
    sleep(0);
    tempCount = read(fd, data, 2);     //We are to read 2 bytes of serial number
    if(tempCount != 2)
    {
        string str;
        str = "Error while reading data on i2c-1 bus. Error : " + string(strerror(errno)) + "\n";
        cout << str;
        return false;
    }
    sleep(0);
    tempCount = read(fd, data, 2);     //We are to read 2 bytes of enviroment data
    if(tempCount != 2)
    {
        string str;
        str = "Error while reading data on i2c-1 bus. Error : " + string(strerror(errno)) + "\n";
        cout << str;
        return false;
    }
    close(fd);
    
    sleep(1);
    

    Kindly note : I have not tested the program against sensor due to unavailability of the said sensor. However the program should work as I have used similar program with several I2C devices.