This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F5529: Problem in interfacing with DHT11 sensor

Part Number: MSP430F5529

I am trying to perform successive readings of the DHT11 humidity and temperature sensor and actually it is reading, but only once. When I put a while (1) after the line lcd_wr_byte (RXBUF5), it is noted that in the first reading there is no problem. As you can see, the RXBUF5 (checksum) is giving the sum of RXBUF1 (humidity integer), RXBUF2(humidity decimal), RXBUF3(temperature integer) and RXBUF4 (temperature decimal), and as a test I am simply writing the RXBUF5 on the LCD. But when I take out the while (1), the idea was for the sensor to perform successive readings with an interval of about 3 seconds (represented by the delays), but it only reads the first time, because when it leaves for the second reading it simply stop in the do{ cont1++; } while((P3IN & BIT4) == BIT4) line, that is, it is as if the sensor pulls the line down (so far so good), then pull the line up (alright too), but it does not pull the line down again to get started the transmission of the bits. For those who are not yet aware of the DHT11 protocol (1-wire protocol), the following is an illustration:

Code:

int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer

    config_timerA0(); //Time for LCD
    config_I2C(); //LCD Comunication
    lcdInic(); //LCD Inicialization
    lcdBacklightON(); //LCD
    lcd_RS_rw(); //LCD
    port_out(); //P3.4 = OUT
    config_timerA1(); //Timer to keep the line down for 20 ms

    while(1){

        P3OUT &= ~BIT4; //Start signal
        TA1R = 0;
        while((TA1CCTL0 & CCIFG) == 0); //20 ms?
        P3OUT |= BIT4;
        port_in(); //P3.4 = IN
        while((P3IN & BIT4) == 1);

        //DHT11 replied

        do {
            cont1++;
        } while ((P3IN & BIT4)==0);
        if(cont1 <= 10){ //<= 80 us?
            cont1 = 0;
            do {
                cont1++;
            } while ((P3IN & BIT4) == BIT4); //Here is the problem at the second reading, always stop here
            if(cont1 <= 10){ //<= 80 us?
                humidity_integer(); //writes on RXBUF1
                humidity_decimal(); //writes on RXBUF2
                temperature_integer(); //writes on RXBUF3
                temperature_decimal(); //writes on RXBUF4
                checksum(); //writes on RXBUF5

                if((RXBUF5) == (RXBUF1 + RXBUF2 + RXBUF3 + RXBUF4)){
                    lcd_wr_byte(RXBUF5); //Testing on LCD
                    
                    //while(1);
                }

                RXBUF1 = 0;
                RXBUF2 = 0;
                RXBUF3 = 0;
                RXBUF4 = 0;
                RXBUF5 = 0;

            }
        }
        
         //I don't think these delays would be the problem, cause I already tried using timers and it didn't work.

         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
         delay(20000);
port_out(); } return 0; }


void port_out(){

P3DIR |= BIT4;

  }

void port_in(){
P3DIR &= ~BIT4;
P3REN |= BIT4;
P3OUT |= BIT4;
}

Can anyone help me please?

  • Sorry, I forgot this picuture to prove that the first reading is working:

  • You seem to have caught all the other occurrences, but

    > while((P3IN & BIT4) == 1);

    This condition is always false. Try:

    > while((P3IN & BIT4) == BIT4);
  • Thanks for your reply.

    When I change while((P3IN & BIT4) == 1) to while((P3IN & BIT4) == BIT4), the problem persists, but now it stops right on this line.

    When I put both as while((P3IN & BIT4) == 1), the sensor reads successively, but it reads only zero.
  • The form I recommended is the correct one. If you compare against ==1, you've effectively deleted the loop.

    One other thing I noticed:
    > while((TA1CCTL0 & CCIFG) == 0); //20 ms?
    you need to clear the CCIFG once you've detected it, or it will still be on the second time around the big loop. This fits with your "stops the second time around" symptom. Just add:
    > TA1CCTL0 &= ~CCIFG; // Clear stale status
    Do this before the while(), since the timer has probably cycled (a number of times) since the last (big) loop.
  • Thanks bro! That was really the problem, I just forgot to do it. But now I have new problems, it correctly reads the first time, but then it stops entering in the first if condition (except the first reading), and as a result it stops reading.

    I removed the if conditions and I noticed that it correctly reads the first time, but then reads only zero. I tried stop cleaning the RXBUF, but it reads the same value always, and not zero anymore. It seems that from the second reading forward it stops entering in my reading functions.

    Maybe that sensor doesn't like me.
  • I see a few paths where cont1 isn't reset to 0, and thus may continue to accumulate. The result would be that <= tests would fail even if the measurement were correct. I suggest you set it to 0 (in every case) before you start counting something.

    Also, cont1 appears to be global. Is it used by e.g. humidity_integer() as well?

    Are you using an external pullup? The internal pullups aren't very strong, which would (at least) slow down rise times.
  • Solved!

    Your question made me pay more attention to the counters in my program. Actually it wasn't cont1, it was another variable that I was using inside the reading functions to count the number of bits that already have been read, and I wasn't cleaning that counter. So that's why it was reading only in the first time.

    Thanks a lot!

**Attention** This is a public forum