简体   繁体   中英

Weird variable behaviour - Arduino Uno rev 3

I have got very weird problem with a int variable. There is a code:

#include <EEPROM.h>
#define dht_dpin 14

byte bGlobalErr;
byte dht_dat[4];

int a;

void setup(){
    pinMode(13, OUTPUT);
    a = 0;
    InitDHT();
    Serial.begin(9600);
    delay(300);
    Serial.println("Humidity and temperature\n\n");
    delay(700);
} //end "setup()"

void loop()
{
    digitalWrite(13, HIGH);
    delay(300);
    digitalWrite(13, LOW);
    Serial.println(a);

    ReadDHT();

    switch (bGlobalErr) 
        {
            case 0:
                Serial.print("humdity = ");
                Serial.print(dht_dat[0], DEC);
                Serial.print(".");
                Serial.print(dht_dat[1], DEC);
                Serial.print("%  ");
                Serial.print("temperature = ");
                Serial.print(dht_dat[2], DEC);
                Serial.print(".");
                Serial.print(dht_dat[3], DEC);
                Serial.println("C  ");
                EEPROM.write(a, dht_dat[0]);
                EEPROM.write(a + 1, dht_dat[2]);

                break;
            case 1:
                Serial.println("Error 1: DHT start condition 1 not met.");
                break;
            case 2:
                Serial.println("Error 2: DHT start condition 2 not met.");
                break;
            case 3:
                Serial.println("Error 3: DHT checksum error.");
                break;
            default:
                Serial.println("Error: Unrecognized code encountered.");
                break;


    } //end "switch"

        a = a + 2;
        delay(10000);

} // end loop()

void InitDHT(){
    pinMode(dht_dpin,OUTPUT);
    digitalWrite(dht_dpin,HIGH);
} //end InitDHT

void ReadDHT(){
    bGlobalErr=0;
    byte dht_in;
    byte i;
    digitalWrite(dht_dpin,LOW);
    delay(18);
    delayMicroseconds(600);
    digitalWrite(dht_dpin,HIGH); 
    delayMicroseconds(40);
    pinMode(dht_dpin,INPUT);
    delayMicroseconds(40);

    dht_in=digitalRead(dht_dpin);

    if(dht_in) {
        bGlobalErr=1;
        return;
    } //end "if..."
    delayMicroseconds(80);

    dht_in=digitalRead(dht_dpin); //Was: dht_in = PINC & _BV(dht_PIN);

    if(!dht_in) {
        bGlobalErr=2;
        return;
    } //end "if..."

    delayMicroseconds(70);
    for (i=0; i<5; i++)
        dht_dat[i] = read_dht_dat();

    pinMode(dht_dpin,OUTPUT); //Was: DDRC |= _BV(dht_PIN);
    digitalWrite(dht_dpin,HIGH); //Was: PORTC |= _BV(dht_PIN);
    byte dht_check_sum =
            dht_dat[0]+dht_dat[1]+dht_dat[2]+dht_dat[3];
    if(dht_dat[4]!= dht_check_sum)
    {bGlobalErr=3; }
}; //end ReadDHT()

byte read_dht_dat(){
    byte i = 0;
    byte result=0;
    for(i=0; i< 8; i++) {
        while(digitalRead(dht_dpin)==LOW) ;
        delayMicroseconds(30);
        if (digitalRead(dht_dpin)==HIGH)
            result |=(1<<(7-i));
        while (digitalRead(dht_dpin)==HIGH) ;
    } //end of "for.."
    return result;
} //end of "read_dht_dat()"

Output is:

Humidity and temperature

0
humdity = 49.0%  temperature = 22.0C  
73
humdity = 49.0%  temperature = 22.0C  
73
humdity = 49.0%  temperature = 22.0C  
73
humdity = 49.0%  temperature = 22.0C

Variable "a" is set to "0" at the beginning and then somehow it has value of 71 inside the switch section, sometimes but very rare 70 or 72 which is even more weird. I have done different combinations with places where a is set to 0 and incremented. I added variable "b" next to "a" and "b" was behaving as it should. Then I changed variable "a" in two "EEPROM.write..." commands on variable "b" and program was running well. When I deleted variable "a", variable "b" started behaving exactly the same as variable "a".

Any ideas guys?

Thanks

That has all the signs of a buffer overflow on the variable declared just before a , specifically byte dht_dat[4] . Try for a start to extend that to byte dht_dat[8] and see if your problem doesn't go away. Then start looking for the spot where you write more than 4 bytes to dht_dat .

Also, the lines

byte dht_check_sum =
        dht_dat[0]+dht_dat[1]+dht_dat[2]+dht_dat[3];
if(dht_dat[4]!= dht_check_sum)

should be reviewed... You're explicitly referencing beyond the bounds of dht_dat here.

Cheers,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM