Variable changes when it shouldn't when debugging Arduino Uno R3 with avr-debugger

I’m working on a library to control an 8x8 dot LED matrix with two 8bit shift registers (74hc595). I installed the avr-debugger library and configured my project by following the instructions on pg. 88 of the debugger documentation.

So I start the debug, the board resets a couple of times before the debug actually starts and the debugger goes through the delay function. When I don’t have any breakpoints all works as expected.

The problem - when I put a breakpoint in the lightSingle function I’m testing, the col variable changes and gets assigned some weird value on line 37. I’m guessing it’s something to do with the bitwise operator (the row variable was also changing when I had a similar bitwise shift on line 36).

This is what’s going on with the breakpoints. The code doesn’t recover from then on, the LEDs light up incorrectly until I reset the board:

https://i.imgur.com/OOrEBz6.png
https://i.imgur.com/ERAhMNk.png

Would appreciate if someone has an explanation of what’s going on here.

Here’s the loop and function code:

void loop()
{
    for (int i = 1; i <= 8; i++)
    {
        for (int j = 1; j <= 8; j++)
        {
            ledMatrix->lightSingle(i, j);
            delay(500);
        }
    }
}

const int activeRowValue[] = {254, 253, 251, 247, 239, 223, 191, 127};

void LedMatrix::lightSingle(int row, int col)
{
    if (row < 1 || row > 8 || col < 1 || col > 8)
    {
        return;
    }


    int activeRow = activeRowValue[row - 1];
    int activeCols = (1 << (col - 1));


    shiftOut(_rowSer, _rowSrclk, MSBFIRST, activeRow);
    shiftOut(_colSer, _colSrclk, MSBFIRST, activeCols);


    digitalWrite(_rowRclk, HIGH);
    digitalWrite(_colRclk, HIGH);
    digitalWrite(_rowRclk, LOW);
    digitalWrite(_colRclk, LOW);
}

platformio.ini

[env:uno]
platform = atmelavr
board = uno
framework = arduino

lib_deps = jdolinay/avr-debugger@^1.5

; added for avr-debugger
build_type = debug
debug_tool = avr-stub
debug_port = COM3

debug_build_flags =
    -Og
    -g2
    -DDEBUG
    -DAVR8_BREAKPOINT_MODE=1

Is it the same when you use -O0 instead of -Og?

I know it’s not VSCode in my reply, but, I have my Arduino IDE set to “optimize for debugging” even for the Arduino UNO which doesn’t have a hardware debugger that the IDE can use. For details on setting this up, see Debug optimization incorrectly set to -Os should be -O0 · Issue #554 · arduino/ArduinoCore-avr · GitHub.

However, the optimisation flags for that debugging are -o=O0 -g and this definitely works for me with the IDE and my Simulavr simulator/debugger whihc I’m using for some Assembly code debugging.

Maybe those flags would help?

Cheers,
Norm.

Bit of an update.

I changed the optimization level to -O0 as suggested. The col variable doesn’t randomly change anymore.

However, the original issue I had was that the LEDs light incorrectly - due to the random change of the col variable I incorrectly thought that all the columns were lit, actually the whole column is being lit (so all the rows at once).

I changed the lightSingle function a bit:

void LedMatrix::lightSingle(int row, int col)
{
    if (row < 1 || row > 8 || col < 1 || col > 8)
    {
        return;
    }

    int activeRow = ~(1 << (row - 1));
    int activeCols = (1 << (col - 1));

    shiftOut(_colSer, _colSrclk, MSBFIRST, activeCols);
    digitalWrite(_colRclk, HIGH);
    digitalWrite(_colRclk, LOW);

    shiftOut(_rowSer, _rowSrclk, MSBFIRST, activeRow);
    digitalWrite(_rowRclk, HIGH);
    digitalWrite(_rowRclk, LOW);
}

For some reason all the pins of the row shift register are set to low and continue to be low even while the column is changing until I reset the board. I checked the SER pin of the shift register while stepping over the code in the shiftOut function and it all appeared to be correct (didn’t monitor the clock pins though). For example, for lighting the 1st row I sent 254 with shiftOut and I saw seven highs followed by a low as it should be. And still when I enabled the latch pin all the rows lit up.

Here is an example where a dot on row 6 is lit and only the column should change but all the rows become low

I have some spare shift registers, tried swapping them but got the same thing. Anyway the fact that I get this problem only when hitting a breakpoint while debugging makes me think this is not a component issue.

Check your shift register connections. There are a couple of pins that are active low and should be tied high (or vice versa) if not in use.

I have a batch of 10 and 5 work fine without the pull ups, the others don’t work without them.

Sorry, on my phone, away from docs and notes.

EDIT. /OE and /SRCLR are the pins to tie to VCC. A 10K redistor should do it.

HTH

Cheers,
Norm.

I wonder if your toggling of the clock pin is necessary? Here’s the code for shiftOut():

void shiftOut(uint8_t dataPin,
              uint8_t clockPin,
              uint8_t bitOrder,
              uint8_t val)
{
    uint8_t i;

    for (i = 0; i < 8; i++) {
        if (bitOrder == LSBFIRST) {
            digitalWrite(dataPin, val & 1);
            val >>= 1;
        } else {
            digitalWrite(dataPin, (val & 128) != 0);
            val <<= 1;
       }
       digitalWrite(clockPin, HIGH);
       digitalWrite(clockPin, LOW);
    }
}

You can see that the entire 8 bits are clocked out to the data pin and then the clock pin is toggled for you, there should be no need to do this in your own code, ! suspect.

Also, I assume your two shift registers are not cascaded together?

Cheers,
Norm.

Yeah you could be right about the SRCLR pin, I definitely need to monitor all the pins. I’ll post an update when I get the time.

I’m toggling the latch pin though, different pin than the one shiftOut is toggling.
Yes, the shift registers use separate GPIO pins.

1 Like

Sorry, my mistake, I read your pin name as a clock pin, not a latch. :slightly_frowning_face:

From your logic analyser image, I suspect the /SRCLR pin is floating and is somehow going low when you toggle the latch pin…

Cheers,
Norm.