2 years ago

#12861

test-img

Zafer SEN

Losing data bit when reading from GPIO by libgpiod on Linux

I am using Debian (8.3.0-6) on an embedded custom board and working on the dht11 sensor. Briefly, I need to read 40 bits from a GPIO pin and each bit can take a max 70 microseconds. When bit-level is high for max 28us or 70us, it means is logic 0 or 1, respectively. (So I have a timeout controller for each bit and if a bit takes more than 80us, I need to stop the process.). enter image description here enter image description here In my situation, sometimes I can read all 40 bits correctly but sometimes I can't do it and the function of libgpiod gpiod_line_get_value(line); is missing the bit (my code is below). I am trying to figure out that why I cant read and lose a bit, what is the reason for that. But I haven't found a sensible answer yet. So I was wondering What am I missing out?, What is the proper way to GPIO programming?

Here is what I wanted to show you, How do I understand what I am missing a bit? Whenever I catch a bit, I am setting and resetting another GPIO pin at the rising and falling edge of a bit (So I can see which bit missing). Moreover, as far as I see I am always missing the two edges on one bit or one edge on two bits consecutively (rising and falling or falling and rising). In the first picture, you can see which bit I missed, the second is when I read all bits correctly.

enter image description here

enter image description here

Here it is my code:

//********************************************************* Start reading data bit by low level (50us) ***************************
    for (int i = 0; i < DHT_DATA_BYTE_COUNT ; i++) //DHT_DATA_BYTE_COUNT = 5
    {
        for (int J = 7; J > -1; J--)
        {
             GPIO_SetOutPutPin(testPin); //gpiod_line_set_value(testPin, 1);
             int ret;
             start = micros();
             do
             {
                 ret = GPIO_IsInputPinSet(dht11pin);//gpiod_line_get_value(dht11pin);
                 delta = micros() - start;
                 if(ret == -1)
                 {
                     err_step.step = 9;
                    err_step.ret_val = -1;
                    return -1;
                 }
                if(delta > DHT_START_BIT_TIMEOUT_US) //80us
                {
                    err_step.step = 10;
                    err_step.ret_val = -2;
                    err_step.timestamp[is] = delta;
                    err_step.indx[is].i = i;
                    err_step.indx[is++].j = J;
                    GPIO_ResetOutPutPin(testPin);
                    return -2;
                }
             }while(ret == 0);


                GPIO_ResetOutPutPin(testPin);
                err_step.ret_val = 10;


                GPIO_SetOutPutPin(testPin);

            start = micros();
            do
             {
                 ret = GPIO_IsInputPinSet(dht11pin);
                 delta = micros() - start;
                 if(ret == -1)
                 {
                     err_step.step = 11;
                    err_step.ret_val = -1;
                    return -1;
                 }
                 if(delta > DHT_BEGIN_RESPONSE_TIMEOUT_US) //80us
                {
                    err_step.step = 12;
                    err_step.ret_val = -2;
                    err_step.timestamp[is] = delta;
                    err_step.indx[is].i = i;
                    err_step.indx[is++].j = J;
                    return -2;
                }
             }while(ret == 1);

                    err_step.timestamp[is] = delta;
                    err_step.indx[is].i = i;
                    err_step.indx[is++].j = J;
                GPIO_ResetOutPutPin(testPin);
                err_step.ret_val = 10;

            (delta > DHT_BIT_SET_DATA_DETECT_TIME_US) ? bitWrite(dht11_byte[i],J,1) : bitWrite(dht11_byte[i],J,0);
        }
    }

c

embedded-linux

gpio

iio

libgpiod

0 Answers

Your Answer

Accepted video resources