[SOLVED] Writing to the wrong elements of an array

Hello all,

I am challenging myself to make a LED marquee from scratch, including the code.

So far, I have been able to sort out every problem that has popped up without having to bother the forums.

However, something has gone wrong with this line of code:

buffer[mtxRow][mtxWidth+ col] = 1;

(The rest of my code is at the bottom of this post)

What this line is supposed to do is to write a 1 or 0 to a specific spot in an array.
However, it writes TWO ones to the array. I have no idea what is going on here. Did I set the array up incorrectly? Am I writing something other than a single "1" to the array?

Super puzzled.

o_O

The rest of my code:

String msg = "abcdef"; //there is a null at the end of this string.

const byte charWidth = 5; // no semicolon required. it will mess things up.
const byte mtxWidth = 8; //matrix width
const byte mtxHeight = 8;

// pin[xx] on led matrix connected to nn on Arduino (99 is dummy to make array start at pos 1)
byte pins[17]= {99, 15, 16, 17, 18, 19, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
// col[xx] of leds = pin yy on led matrix
byte LEDcol[8] = {pins[1], pins[2], pins[3], pins[4], pins[5], pins[6], pins[7], pins[8]};
// row[xx] of leds = pin yy on led matrix
byte LEDrow[8] = {pins[16], pins[15], pins[14], pins[13], pins[12], pins[11], pins[10], pins[9]};

byte buffer[mtxWidth + charWidth][mtxHeight];
byte msgLength = msg.length();
byte currentChar = msgLength;
int toLoad; // byte overflows at 255

static byte chars[] =
{
	0x00, 0x00, 0x00, 0x00, 0x00,// (space) ACSCII VALUE 32
	0x00, 0x00, 0x5F, 0x00, 0x00,// !
	0x00, 0x07, 0x00, 0x07, 0x00,// "
	0x14, 0x7F, 0x14, 0x7F, 0x14,// #
	0x24, 0x2A, 0x7F, 0x2A, 0x12,// $
	0x23, 0x13, 0x08, 0x64, 0x62,// %
	0x36, 0x49, 0x55, 0x22, 0x50,// &
	0x00, 0x05, 0x03, 0x00, 0x00,// '
	0x00, 0x1C, 0x22, 0x41, 0x00,// (
	0x00, 0x41, 0x22, 0x1C, 0x00,// )
	0x08, 0x2A, 0x1C, 0x2A, 0x08,// *
	0x08, 0x08, 0x3E, 0x08, 0x08,// +
	0x00, 0x50, 0x30, 0x00, 0x00,// ,
	0x08, 0x08, 0x08, 0x08, 0x08,// -
	0x00, 0x60, 0x60, 0x00, 0x00,// .
	0x20, 0x10, 0x08, 0x04, 0x02,// /
	0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
	0x00, 0x42, 0x7F, 0x40, 0x00,// 1
	0x42, 0x61, 0x51, 0x49, 0x46,// 2
	0x21, 0x41, 0x45, 0x4B, 0x31,// 3
	0x18, 0x14, 0x12, 0x7F, 0x10,// 4
	0x27, 0x45, 0x45, 0x45, 0x39,// 5
	0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
	0x01, 0x71, 0x09, 0x05, 0x03,// 7
	0x36, 0x49, 0x49, 0x49, 0x36,// 8
	0x06, 0x49, 0x49, 0x29, 0x1E,// 9
	0x00, 0x36, 0x36, 0x00, 0x00,// :
	0x00, 0x56, 0x36, 0x00, 0x00,// ;
	0x00, 0x08, 0x14, 0x22, 0x41,// <
	0x14, 0x14, 0x14, 0x14, 0x14,// =
	0x41, 0x22, 0x14, 0x08, 0x00,// >
	0x02, 0x01, 0x51, 0x09, 0x06,// ?
	0x32, 0x49, 0x79, 0x41, 0x3E,// @
	0x7E, 0x11, 0x11, 0x11, 0x7E,// A
	0x7F, 0x49, 0x49, 0x49, 0x36,// B
	0x3E, 0x41, 0x41, 0x41, 0x22,// C
	0x7F, 0x41, 0x41, 0x22, 0x1C,// D
	0x7F, 0x49, 0x49, 0x49, 0x41,// E
	0x7F, 0x09, 0x09, 0x01, 0x01,// F
	0x3E, 0x41, 0x41, 0x51, 0x32,// G
	0x7F, 0x08, 0x08, 0x08, 0x7F,// H
	0x00, 0x41, 0x7F, 0x41, 0x00,// I
	0x20, 0x40, 0x41, 0x3F, 0x01,// J
	0x7F, 0x08, 0x14, 0x22, 0x41,// K
	0x7F, 0x40, 0x40, 0x40, 0x40,// L
	0x7F, 0x02, 0x04, 0x02, 0x7F,// M
	0x7F, 0x04, 0x08, 0x10, 0x7F,// N
	0x3E, 0x41, 0x41, 0x41, 0x3E,// O
	0x7F, 0x09, 0x09, 0x09, 0x06,// P
	0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
	0x7F, 0x09, 0x19, 0x29, 0x46,// R
	0x46, 0x49, 0x49, 0x49, 0x31,// S
	0x01, 0x01, 0x7F, 0x01, 0x01,// T
	0x3F, 0x40, 0x40, 0x40, 0x3F,// U
	0x1F, 0x20, 0x40, 0x20, 0x1F,// V
	0x7F, 0x20, 0x18, 0x20, 0x7F,// W
	0x63, 0x14, 0x08, 0x14, 0x63,// X
	0x03, 0x04, 0x78, 0x04, 0x03,// Y
	0x61, 0x51, 0x49, 0x45, 0x43,// Z
	0x00, 0x00, 0x7F, 0x41, 0x41,// [
	0x02, 0x04, 0x08, 0x10, 0x20,// "\"
	0x41, 0x41, 0x7F, 0x00, 0x00,// ]
	0x04, 0x02, 0x01, 0x02, 0x04,// ^
	0x40, 0x40, 0x40, 0x40, 0x40,// _
	0x00, 0x01, 0x02, 0x04, 0x00,// `
	0x20, 0x54, 0x54, 0x54, 0x78,// a
	0x7F, 0x48, 0x44, 0x44, 0x38,// b
	0x38, 0x44, 0x44, 0x44, 0x20,// c
	0x38, 0x44, 0x44, 0x48, 0x7F,// d
	0x38, 0x54, 0x54, 0x54, 0x18,// e
	0x08, 0x7E, 0x09, 0x01, 0x02,// f
	0x08, 0x14, 0x54, 0x54, 0x3C,// g
	0x7F, 0x08, 0x04, 0x04, 0x78,// h
	0x00, 0x44, 0x7D, 0x40, 0x00,// i
	0x20, 0x40, 0x44, 0x3D, 0x00,// j
	0x00, 0x7F, 0x10, 0x28, 0x44,// k
	0x00, 0x41, 0x7F, 0x40, 0x00,// l
	0x7C, 0x04, 0x18, 0x04, 0x78,// m
	0x7C, 0x08, 0x04, 0x04, 0x78,// n
	0x38, 0x44, 0x44, 0x44, 0x38,// o
	0x7C, 0x14, 0x14, 0x14, 0x08,// p
	0x08, 0x14, 0x14, 0x18, 0x7C,// q
	0x7C, 0x08, 0x04, 0x04, 0x08,// r
	0x48, 0x54, 0x54, 0x54, 0x20,// s
	0x04, 0x3F, 0x44, 0x40, 0x20,// t
	0x3C, 0x40, 0x40, 0x20, 0x7C,// u
	0x1C, 0x20, 0x40, 0x20, 0x1C,// v
	0x3C, 0x40, 0x30, 0x40, 0x3C,// w
	0x44, 0x28, 0x10, 0x28, 0x44,// x
	0x0C, 0x50, 0x50, 0x50, 0x3C,// y
	0x44, 0x64, 0x54, 0x4C, 0x44,// z
	0x00, 0x08, 0x36, 0x41, 0x00,// {
	0x00, 0x00, 0x7F, 0x00, 0x00,// |
	0x00, 0x41, 0x36, 0x08, 0x00,// }
	0x08, 0x08, 0x2A, 0x1C, 0x08,// ->
	0x08, 0x1C, 0x2A, 0x08, 0x08 // <-
};

void setup()
{
  Serial.begin(9600);
  
  matrixSetup();

  loadNext();
//  Serial.println();

  prtBuff();
}

void loop()
{
}

void loadNext()
{
  if (currentChar + 1 > msgLength - 1) // next char, or wrap around. 
  //The "-1" stops the null from appearing.
  {
    currentChar =0;
  }
  else
  {currentChar++;}

  
  toLoad = (msg[currentChar] - 32) * 5; //toLoad will be the number in chars[] that the char starts with
  
  for (byte col = 0; col<charWidth; col++) // select the first column of the char
  {
    byte mtxRow =0;
    byte charOneCol = chars[toLoad + col]; //YAY
//    Serial.println();
//    Serial.println(col);
    for (byte mask = 00000001; mask > 0; mask <<=1) //select the bits in teh column //YAY
    {
//      Serial.println(mask);
      if (charOneCol & mask) // bitmask
      {
        buffer[mtxRow][mtxWidth+ col] = 1;
        prtBuff();
        Serial.print("y");
        Serial.print(mtxRow);
        Serial.print(mtxWidth+col);
        Serial.println(buffer[mtxRow][mtxWidth+ col]);
      }
      else
      {
        buffer[mtxRow][mtxWidth+ col] = 0;
        Serial.print("n");
        Serial.print(mtxRow);
        Serial.print(mtxWidth+col);
        Serial.println(buffer[mtxRow][mtxWidth+ col]);
      }
      mtxRow++;
    }
  }
}


void matrixSetup()
{
  //matrix pins are all set to outputs
  for (int i = 1; i <= 16; i++) {
    pinMode(pins[i], OUTPUT);
  }

  // set up LEDcol and LEDrow to be pulled down
  for (int i = 1; i <= 8; i++) {
    digitalWrite(LEDcol[i - 1], LOW);
  }

  for (int i = 1; i <= 8; i++) {
    digitalWrite(LEDrow[i - 1], LOW);
  }
}

  

void lightUp() // scans rows. Input via shiftreg on cols
{
  for (byte y = 0; y < mtxHeight; y++)
  {
    digitalWrite(LEDrow[y-1], HIGH); // turn off previous row
    digitalWrite(LEDrow[y], LOW); // turn on current row
    for (byte x = 0; x < mtxWidth; x++)
    {
      if (buffer [y][x])
      {
        digitalWrite(LEDcol[x], LOW); // turn LED on
      }
      else
      {
        digitalWrite(LEDcol[x], HIGH); // turn LED off
      }
    }
  }
}

void shiftBuff()
{
  for (byte x = 0; x < mtxWidth + charWidth - 1; x++) // the -1 means that we don't try to access past the buffer
  {
    for (byte y = 0; y < mtxHeight; y++)
    {
      buffer[y][x] = buffer[y][x+1];
    }
  }
}

void prtBuff()
{
  for (byte y =0; y<mtxHeight; y++)
  {

    for (byte x =0; x < mtxWidth + charWidth; x++)
    {

      Serial.print(buffer[y][x]);

    }
    Serial.println("");
  }
}

'buffer's second dimension is set to 8 ( mtxHeight ) so the range of valid indices are [ 0 to 7 ]

const byte mtxWidth = 8; //matrix width
const byte mtxHeight = 8;

byte buffer[mtxWidth + charWidth][mtxHeight];

You access it at index 8 and above:

buffer[mtxRow][mtxWidth+ col] = 1;

The multiple 1's may be a result of runtime corruption. Fix your indexing errors then check again.

Hi pYro,

If you stick a Serial.print(mtxRow); before each write to the array, you will see that mtxRow does increase to 8, but is reset to 0 before it is called again.

Thanks!

thebestnoobcake:
If you stick a Serial.print(mtxRow); before each write to the array, you will see that mtxRow does increase to 8, but is reset to 0 before it is called again.

Not talking about that variable :wink:

buffer[mtxRow][mtxWidth+ col] = 1;

...

const byte mtxWidth = 8;

thebestnoobcake:

buffer[mtxRow][mtxWidth+ col] = 1;

What this line is supposed to do is to write a 1 or 0 to a specific spot in an array.
However, it writes TWO ones to the array

First rule of debugging - don't waste time trying to figure out why something impossible is happening.

There are NO circumstances in which that line of code can write a 1 into two different array locations.

Hence the problem MUST be something/somewhere else.

If strange things are happening with data in arrays the first thing to check is that it is being indexed correctly. Writing data beyond an array will also corrupt other variables with very strange symptoms.

...R

const byte charWidth = 5; // no semicolon required. it will mess things up.

So, why did you use one?

Hi Paul,

That was a typo. I switched from using #define to const, and forgot to change the comment.

Okay.

I am such an idiot. I initialised buffer as buffer[width][height] instead of buffer[height][width].

Too many years of writing coordinates as [x][y]

It's amazing what a fresh pair of eyes will do for you.

Many thanks for the help everyone!