Hi all.
Newbie warning in effect. Be nice OK. Apologies for the long post.
I am trying to learn OOP and on the surface of it, it makes sense. But implementing it I get lost.
As a learning aid to write a library for Arduino, I'm using an old (circa 1989) unit that uses shift registers (2x 4015's and a 4017) to drive a 10x10 LED matrix. It works fine using straight C.
I can make it work with OOP but ran into the following problem:
There is a function that is responsible to get the data into a buffer (that in turn is written to the LED matrix with another f() ). In this function I use a pointer to the buffer.
In the .h file the variables are declared such:
private:
uint16_t _buffer[2][10];
uint16_t *_buffPtr;
In the .cpp file the function is:
void SFRI100LED::loadBuffer(uint8_t buffNo, uint8_t selectedCharOffset, uint8_t fontDimentions){
//Uses a reference to font.h.
//Comes in as a 8x8 character from program memory
//loads iinto SFRI100LED:_buffer[buffNo]
//uint8_t selectedCharpoints to the char to be loaded offset within the font array
//e.g. if selectedCharOffset = 'A' it can be used as *cp437_font[selectedCharOffset]
//fontDimentions is typically 8, i.e. a 8x8 pixel font
uint8_t loop;
uint8_t value;
*_buffPtr = _buffer[buffNo];//THIS SEEMS TO LOAD _buffPtr ONCE only
sprintf (_checkbuffer, "add of \"buff[buffNo][0]\" in ram = 0x%02x\n\n", &(*_buffPtr));
Serial.print(_checkbuffer);
for (loop = 0; loop < fontDimentions; loop++){
//Serial.print(pgm_read_byte(&(cp437_font[tableOffset][loop])));
//Serial.print(" ");
//value = mirrorBits(pgm_read_byte(&(cp437_font[tableOffset][loop])));
value = pgm_read_byte(&(cp437_font[selectedCharOffset][loop]));//Since data is stored in program memory must us the pgm_read_byte macro
/* THIS DOES NOT WORK */
//*(_buffPtr) = (value) & 0x3FF;
// _buffPtr++;
/* END OF NON WORKING CODE */
/* THIS WORKS*/
*(_buffPtr+loop) = (value) & 0x3FF;
/* END OF WORKING CODE */
}
SFRI100LED::printArr(&(_buffer[buffNo][0]));
}
So, at the start of the function I load the pointer with the start address of the buffer. I then use the pointer to step through the values loaded from the font (which is stored in program memory).
The problem is that it seems the pointer is loaded only once (the first time the function is called). So, incrementing the pointer (as opposed to adding an offset to the pointer) causes the pointer to be pointing at the wrong address the next time the function is called (to load the next character). The debug (serial print) output for the working and non working:
In the non working output you'll notice the address of the buffer changes and you can see the second character added to the end of the buffer. Eventually something important is overwritten and the whole thing crashes. Where as, the working output shows the buffer address remains the same (as it should) and a new character is loaded into it with every iteration.
For the sake of completion the font look up table looks like this (at least a small portion).
const uint8_t cp437_font [256] [8] PROGMEM = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x00
{ 0x7E, 0x81, 0x95, 0xB1, 0xB1, 0x95, 0x81, 0x7E }, // 0x01
{ 0x7E, 0xFF, 0xEB, 0xCF, 0xCF, 0xEB, 0xFF, 0x7E }, // 0x02
{ 0x0E, 0x1F, 0x3F, 0x7E, 0x3F, 0x1F, 0x0E, 0x00 }, // 0x03
{ 0x08, 0x1C, 0x3E, 0x7F, 0x3E, 0x1C, 0x08, 0x00 }, // 0x04
{ 0x18, 0xBA, 0xFF, 0xFF, 0xFF, 0xBA, 0x18, 0x00 }, // 0x05
The relevant section as per the output:
{ 0x7C, 0x7E, 0x13, 0x13, 0x7E, 0x7C, 0x00, 0x00 }, // 'A'
{ 0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00 }, // 'B'
{ 0x1C, 0x3E, 0x63, 0x41, 0x41, 0x63, 0x22, 0x00 }, // 'C'
{ 0x41, 0x7F, 0x7F, 0x41, 0x63, 0x3E, 0x1C, 0x00 }, // 'D'
{ 0x41, 0x7F, 0x7F, 0x49, 0x5D, 0x41, 0x63, 0x00 }, // 'E'
{ 0x41, 0x7F, 0x7F, 0x49, 0x1D, 0x01, 0x03, 0x00 }, // 'F'
{ 0x1C, 0x3E, 0x63, 0x41, 0x51, 0x73, 0x72, 0x00 }, // 'G'
{ 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00 }, // 'H'
So, to the question: Why (and I'm sure it's glaringly obvious) is the pointer not reset when I call the function repeatedly:
*_buffPtr = _buffer[buffNo];//THIS SEEMS TO LOAD _buffPtr ONCE only