Electronic – arduino – Can’t modify global variables in interrupt, despite having declared them volatile

arduinoavrc

I can't seem to get my global variables (low, high) to change inside my interrupt, despite having declared them volatile. Below is my code.

I find it strange that I can modify my global variable 'change' but modifications to 'low' and 'high' don't seem to work. I know for sure that my interrupt is being completed, since the text is reprinting to the LCD display, just that the numbers aren't being modified.

I marked out the most relevant locations with "HERE" where I think that the problem is most likely at. I also tested whether it's just because the variable turn is always 0 by adding code at the end of the ISR to see whether the global variables change or not. They don't.

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "lcd.h"
int state;
volatile int low; //HERE
volatile int high;
char scount[5];
char snum[5];
char mode;
volatile char change=0;//HERE
int main()
{
    char b_high;
    char b_low;
    DDRD=0xf0;
    DDRB=0b00000011;
    PORTD |= 0b00001000; 
    PORTC |= (1 << PC1);
    PORTC |= (1 << PC2);
    PORTB |= 0b00100000;
    PCICR=0b00000010;
    PCMSK1=0b00000110;
    sei();
    init_lcd();
    writecommand(0x01);
    moveto(0x80);
    stringout("Low:    ");
    stringout("High:    ");
    moveto(0xc0);
    stringout("Change:high");
    int low=70;
    int high=85;
    moveto(0x84);
    itoa(low, scount, 10);
    stringout(scount);
    moveto(0x8d);
    itoa(high, scount, 10);
    stringout(scount);
    while(1){
        b_high = PIND & 0b00001000; 
        b_low = PINB & 0b00100000;
        if(!b_high)
        {
            moveto(0xc7);
            stringout("high");
            mode=0;
        }
        if(!b_low)
        {
            moveto(0xc7);
            stringout("low ");
            mode=1;
        }
        if(change)//HERE
        {
            if(mode)
            {
                //low+=turn;
                itoa(low, snum, 10);//HERE
                moveto(0x84);
                stringout("   ");
                moveto(0x84);
                stringout(snum);
            }
            else
            {
                //high+=turn;
                itoa(high, snum, 10);//HERE
                moveto(0x8d);
                stringout("   ");
                moveto(0x8d);
                stringout(snum);
            }
            change=0;
        }
    }
    return 1;
}
ISR(PCINT1_vect)
{
    int turn=0;
    int pstate=state;
    int bitA = PINC & 0b00000010;
    int bitB = PINC & 0b00000100;
    bitA=bitA>>1;        
    bitB=bitB>>1;
    state=bitA+bitB;
    if((pstate==0&&state==1)||(pstate==1&&state==3)||(pstate==3&&state==2)||(pstate==2&&state==0))
    {
        turn=1;
    }
    if((state==0&&pstate==1)||(state==1&&pstate==3)||(state==3&&pstate==2)||(state==2&&pstate==0))
    {
        turn =-1;
    }
    if(mode)
    {
        low+=turn;//HERE
    }
    else
    {
        high+=turn;//HERE
    }
    high++;//test code, high is still not modified in the main()
    change=1;//HERE
}

Best Answer

You've re-declared 'low' and 'high' as separate variables in your main function. The global variables won't show up in main() if you do that. Remove the duplicate declarations and try again.