mardi 23 avril 2019

Strange behavior of variables inside if statement

I was testing a section of code that was running on an Arduino Uno based platform and ran into a strange issue. The function I'm testing simply reads some bytes from the eeprom into a c-string and displays the result on a 16 x 2 LCD. But before I go into details, here's the complete sketch (minimal extraction from the full program to reproduce the bug):

#include <avr/eeprom.h>
#include "LiquidCrystal.h"

#define LCD_RS    6
#define LCD_E     4
#define LCD_D4    9
#define LCD_D5    10
#define LCD_D6    11
#define LCD_D7    12
#define EE_ENGINE  (uint8_t*)  0x390 // 32 chars message 
#define MSGLEN_FULL  (16*2)

LiquidCrystal lcd (6, 4, 9,10,11,12);
char tempCharArrary[4];
char engineMsg[MSGLEN_FULL + 1]; // 32 + null

char data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ12    ";


void setup() {
    pinMode(LCD_RS, OUTPUT);
    pinMode(LCD_E,  OUTPUT);
    pinMode(LCD_D4, OUTPUT);
    pinMode(LCD_D5, OUTPUT);
    pinMode(LCD_D6, OUTPUT);
    pinMode(LCD_D7, OUTPUT);

    lcd.begin(16, 2);
    lcd.display();

    read_msg(engineMsg, EE_ENGINE, 0);

    lcd.print((unsigned char)tempCharArrary[0]);
    lcd.print(' ');
    lcd.print((unsigned char)tempCharArrary[1]);
    lcd.print(' ');
    lcd.print((unsigned char)tempCharArrary[2]);
    lcd.print(' ');
    lcd.print((unsigned char)tempCharArrary[3]);

    delay(3000);

    printMessage(engineMsg, nullptr);
}

void loop() {

}

boolean read_msg(char * msg, uint8_t* eeprom_addr, const char * msg_default)
{    

  for(byte i = 0; i < 32; i++)
  {
    char c = data[i];//eeprom_read_byte(eeprom_addr++);

    tempCharArrary[0] = i;
    tempCharArrary[1] = c;

    if(c < ' ' || c > 'z') 
    {
      tempCharArrary[2] = i;
      tempCharArrary[3] = c;
      return 0;
    }

    msg[i] = c;
  }
  return 1;             // valid message read
}

void printMessage(char *firstLineText, char *secondLineText)
{
    lcd.clear();

    if(firstLineText)
    {
        lcd.setCursor(0, 0);
   //     lcd.print(firstLineText);

        if(!secondLineText)
        {
            for(int i = 0; i < strlen(firstLineText); i++)
            {
                if(i == 15)
                    lcd.setCursor(0, 1);

                lcd.write(firstLineText[i]);
//                delay(500);
            }
        }
        else
        {
            lcd.print(firstLineText);
        }

    }

    lcd.setCursor(0, 1);
    if(secondLineText)
    {
        lcd.setCursor(0, 1);
        lcd.print(secondLineText);
    }
}

In the read_msg function inside of the for loop is an if statement that checks for characters outside of a valid range. If the condition is true, then there was originally some code which would return a blank c-string (omitted for simplicity). However, the strange thing I'm seeing is that when I read the value of c and i from INSIDE the if statement, I get different values than when I read them from directly above the if-statment.

In the example program, the LCD will print "31 32 0 0" on the screen, followed by the full set of characters that were stored on the EEPROM "ABCDEFGHIJKLMNOPQRSTUVWXYZ12".

But just to eliminate the EEPROM itself as a possible source of issues, I replaced the eeprom_read_byte() function call with an array (data) that contains the same information that the EEPROM had. Even in this case, I get the same result.

I'm guessing there's some sort of weird variable scope thing happening, but so far I'm stumped.

Aucun commentaire:

Enregistrer un commentaire