Telling function which array to use?

I've been playing with a 16x16RGB matrix and using it to show images and simple animations. The animations are stored in flash using PROGMEM. At the moment I am copying identical routines to show different animation array's, so every time I want a new animation I have having to copy the routine in full.

I would like to have a function that would call the array needed but despite looking I can not find one that works for me. Most guides say about using '&' to point(?) to the array but my current setup give an error when compiling:

"invalid conversion from 'const short unsigned int*' to 'short unsigned int' [-fpermissive]"

here is the code (I am using the Adafruit Graphics library to run the matrix):

void setup() {
  matrix.begin();
  matrix.setBrightness(92);
}



void loop() {
  scrollImage(106, 1, 1000 / 30, 1, picToShow);
  scrollImage(106, 1, 1000 / 30, 1, showThisPic);
}




void scrollImage(byte width, byte pixelScroll, byte fRate, char scrollDir, unsigned short &picture) {
  if (scrollDir == 1) {
    for (byte pos = 1; pos < width - 16; pos += pixelScroll) {
      buttonCheck();
      matrix.drawRGBBitmap(-pos, 0, (const uint16_t *) picture, width, 16);
      showBriLevel();
      matrix.show();
      delay(fRate);
    }
  }
  else {
    for (byte pos = width - 16; pos > 0 ; pos -= pixelScroll) {
      buttonCheck();
      matrix.drawRGBBitmap(-pos, 0, (const uint16_t *) picture, width, 16);
      showBriLevel();
      matrix.show();
      delay(fRate);
    }
  }
}




const unsigned short picToShow[1696] PROGMEM={
0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 
...
...
...
};


const unsigned short showThisPic[1696] PROGMEM={
0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 
...
...
...
};

I have never tried to pass an array name to a function before and reading the tutorials have left me more confused then when I started! I am left wondering if it is because all the tutorials talk about arrays in RAM and not in FLASH?

unsigned short *picture

Thanks for the reply, I changed the decleration of the function to:

void scrollImage(byte width, byte pixelScroll, byte fRate, char scrollDir, unsigned short *picture) {

but still get the error:

invalid conversion from 'const short unsigned int*' to 'short unsigned int*' [-fpermissive]

Then change it to const.

You will have problems if you pass a pointer to your array to .drawRGBbitmap(). Passing an array is how the Adafruit library knows you mean PROGMEM and not RAM.

// Draw a PROGMEM-resident 16-bit image (RGB 5/6/5) at the specified
//   (x,y) position. For 16-bit display devices; no color reduction performed.

void Adafruit_GFX::drawRGBBitmap(int16_t x, int16_t y, 
                                 const uint16_t bitmap[],
                                 int16_t w, int16_t h);

// Draw a RAM-resident 16-bit image (RGB 5/6/5) at the specified (x,y)
// position. For 16-bit display devices; no color reduction performed.
void Adafruit_GFX::drawRGBBitmap(int16_t x, int16_t y, 
                                 uint16_t *bitmap,
                                int16_t w, int16_t h);

I think what you want is:

void scrollImage(byte width, byte pixelScroll, byte fRate, char scrollDir, const uit16_t picture[]) {
  if (scrollDir == 1) {
    for (byte pos = 1; pos < width - 16; pos += pixelScroll) {
      buttonCheck();
      matrix.drawRGBBitmap(-pos, 0, picture, width, 16);
      showBriLevel();
      matrix.show();
      delay(fRate);
    }
  }
  else {
    for (byte pos = width - 16; pos > 0 ; pos -= pixelScroll) {
      buttonCheck();
      matrix.drawRGBBitmap(-pos, 0, picture, width, 16);
      showBriLevel();
      matrix.show();
      delay(fRate);
    }
  }
}
1 Like

johnwasser:
You will have problems if you pass a pointer to your array to .drawRGBbitmap(). Passing an array is how the Adafruit library knows you mean PROGMEM and not RAM.

As a function parameter, uint16_t bitmap[] and uint16_t bitmap*are equivalent.
The difference between the first and the second function is that one takes a const pointer, and the other doesn't.

smartroad:
matrix.drawRGBBitmap(-pos, 0, (const uint16_t *) picture

Never use C-style casts to cast pointers like that. In your original code, picture cannot be cast to a pointer in any meaningful way, yet by adding the C-style cast, you force the compiler to do it anyway, without any warnings.

If you have to cast, use static_cast<>, it is checked by the compiler, so it won't crash your Arduino at runtime.

Pieter

PieterP:
Never use C-style casts to cast pointers like that. In your original code, picture cannot be cast to a pointer in any meaningful way, yet by adding the C-style cast, you force the compiler to do it anyway, without any warnings.

If you have to cast, use static_cast<>, it is checked by the compiler, so it won't crash your Arduino at runtime.

Pieter

That was a direct copy of code from somewhere (not sure where I found it now I started this project ages ago and only just came back to it!)

In order to make this work I have removed it from my code and now have it working correctly.

Thank you to everyone for your help :smiley: It is gratefully received :slight_smile: