Issues with images declared PROGMEM

Hello,

This is my first topic as I'm pretty new to Arduino.

I tried to display several images (64x64 bits). I started with 16 images all declare with PROGMEM. When I try to display them one at at time, everything is ok : images are displayed correctly. But when I tried to display all of them ... The first three images are not the good ones and the fourth image is not displayed correctly.

I also tried to create a class to manage those images with an array of pointer but it was worse : I had compilation error.

I really don't understand what's wrong. I spent a lot of time but it still doesn't work. I didn't find anything on this forum or google. I'm a little bit hopeless ;-(. So If you have explanation or advice ... I will be really grateful

First try :

#include <UTFTGLUE.h>
UTFTGLUE myGLCD(0,A2,A1,A3,A4,A0);

#include "sun_64x64.c"
#include "cloudy_64x64.c"
#include "rain_n_hail_64x64.c"
#include "rain_n_hail_n_thunderstorm_64x64.c"
#include "cloudy_thunderstorm_64x64.c"
#include "thunderstorm_64x64.c"
#include "maybe_rainy_64x64.c"
#include "rain_64x64.c"
#include "haze_64x64.c"
#include "only_haze_64x64.c"
#include "rain_n_snow_64x64.c"

void setup() {
  myGLCD.InitLCD();
}

void loop() {
   myGLCD.drawRGBBitmap(0, 0, cloudy_64x64, 64, 64);
   myGLCD.drawRGBBitmap(64, 0, rain_n_hail_64x64, 64, 64);
   myGLCD.drawRGBBitmap(128, 0, rain_n_hail_n_thunderstorm_64x64, 64, 64);
   myGLCD.drawRGBBitmap(192, 0, sun_64x64, 64, 64);
   myGLCD.drawRGBBitmap(256, 0, cloudy_thunderstorm_64x64, 64, 64);
   myGLCD.drawRGBBitmap(0, 64, thunderstorm_64x64, 64, 64);
   myGLCD.drawRGBBitmap(64, 64, maybe_rainy_64x64, 64, 64);
   myGLCD.drawRGBBitmap(128, 64, rain_64x64, 64, 64);
   myGLCD.drawRGBBitmap(192, 64, haze_64x64, 64, 64);
   myGLCD.drawRGBBitmap(256, 64, only_haze_64x64, 64, 64);
   myGLCD.drawRGBBitmap(0, 128, rain_n_snow_64x64, 64, 64);

   delay(2000);
}

All images are declared the same way :

#if defined(__AVR__)
    #include <avr/pgmspace.h>
#elif defined(__PIC32MX__)
    #define PROGMEM
#elif defined(__arm__)
    #define PROGMEM
#endif

const uint16_t cloudy_64x64[4096] PROGMEM={
0xFFFF, 0xABCD, 0x0000, 0x1234, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0010 (16) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0020 (32) pixels
......
}

Second try with same image files, but a class to manage images in a array of pointer:

#include "Arduino.h"

#include "Weather.hpp"

Weather weather;

void setup() {
    // Initialisation of main Serial communication port
    Serial.begin(9600);

    // Wait for Serial port to be opened
    while (!Serial) {}
}

void loop() {
    delay(3000);
}
#ifndef __WEATHER_H__
#define __WEATHER_H__

#include "cloudy_64x64.c"
#include "rain_n_hail_64x64.c"
#include "rain_n_hail_n_thunderstorm_64x64.c"
#include "sun_64x64.c"
#include "cloudy_thunderstorm_64x64.c"
#include "thunderstorm_64x64.c"
#include "maybe_rainy_64x64.c"
#include "rain_64x64.c"
#include "haze_64x64.c"
#include "only_haze_64x64.c"
#include "rain_n_snow_64x64.c"

class Weather {
	public:
		Weather();
		~Weather();
		
		const uint16_t *weather[16] = {
            cloudy_64x64,
            rain_n_hail_64x64,
            rain_n_hail_64x64,
            rain_n_hail_n_thunderstorm_64x64,
            sun_64x64,
            cloudy_thunderstorm_64x64,
            thunderstorm_64x64,
            thunderstorm_64x64,
            cloudy_64x64,
            maybe_rainy_64x64,
            rain_64x64,
            thunderstorm_64x64,
            haze_64x64,
            only_haze_64x64,
            rain_n_snow_64x64,
            rain_n_snow_64x64
        };
};

#endif

Here the weather array in not in PROGMEM (I don't even know if it could solve my problem) because I was thinking to make it updatable from touchscreen, at least the order of images;

And here the error :frowning: :

/tmp/cciuRioI.s: Assembler messages:
/tmp/cciuRioI.s:747: Error: value of 81920 too large for field of 2 bytes at 0
/tmp/cciuRioI.s:748: Error: value of 73728 too large for field of 2 bytes at 2
/tmp/cciuRioI.s:749: Error: value of 73728 too large for field of 2 bytes at 4
/tmp/cciuRioI.s:750: Error: value of 65536 too large for field of 2 bytes at 6
/tmp/cciuRioI.s:755: Error: value of 81920 too large for field of 2 bytes at 16
lto-wrapper: fatal error: /mnt/disk1/Downloads/arduino-1.8.13/hardware/tools/avr/bin/avr-gcc returned 1 exit status
compilation terminated.
/mnt/disk1/Downloads/arduino-1.8.13/hardware/tools/avr/bin/../lib/gcc/avr/7.3.0/../../../../avr/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino Mega or Mega 2560.

81920 too large for field of 2 bytes at 0

an uint16_t can go up to 216-1, that is 65535 so 81920 won't fit

Yes i know, but I only create an array with 16 pointers. Where does this value comes from ?
And if I change the size of the array to 17 (instead of 16) it compiles.

Do you have a file by the name of cciuRioI --> go have a look at line 747, 748, etc

you array of 16 pointers should not be part of the instance variables

you are using 16 arrays of 8kB - that's 128KB of data - you are in the far pointers probably of PROGMEM (16 bits can only address 64KB)

The file is deleted before I can get it

forget the file, it's probably far pointer stuff.

have a look at this

Thank you I'll have a look immediatly :slight_smile:

You will need to tell the compiler to store those arrays in the upper portion of flash memory, otherwise you may be displacing other progmem data that relies on bring stored within the bottom 64k.

Yes, like the pin to port table.

How can I do that ?

Thank you all for your help.