1

I've tried reading the documentations and I'm getting desperate because I can't find anything.

I need to create an array of structures, which contains a bitmap stored in PROGMEM space (because of issues with memory usage).

The bitmaps are created as follows:

const uint8_t pat[] PROGMEM = {
...
};

Then I need to create a structure like this:

typedef struct{
    uint8_t bitmap[8];
} chars;

chars allChars[1];

but the compiler doesn't like that for some reason and spit out a bunch on invalid conversion from const to char so it was clear I couldn't use that! My next attempt was to create a pointer to the pattern like so:

typedef struct{
    const uint8_t *bitmap[8];
} chars;

chars allChars[1];

This time it again gave warnings about invalid conversion but at least compiled! I then tried to write the entire code and run it:

#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);

typedef struct{
    const uint8_t *bitmap[8];
} chars;

chars allChars[1];


const uint8_t pat[] PROGMEM = {
  0xff,
  0x00,
  0xff,
  0x00,
  0xff,
  0x00,
  0xff,
  0x66
};

void draw(void) {
  u8g.drawBitmapP( 37, 28, 1, 8, pat);
  u8g.drawBitmapP( 74, 28, 1, 8, (char*) allChars[0].bitmap);
}

void setup(void) {
  allChars[0]= (chars) {*pat};
}

void loop(void) {
  draw();
  while(true);
}

the first line where I have used the pattern directly in the draw function, works perfectly fine, but the second line which retrieves the value from the pointer draws some weird noise shape (I'm guessing memory dump of an address or something)!

Is it even possible to create a struct with one of the variables being just a pointer to the constants that I have defined earlier? I'm pretty sure I'm doing something very wrong as I'm not familiar with using pointers and addresses and whatnot, so it would be great if someone could help with these issues!

1
  • 1
    Try "allChars[0].bitmap = pat;" Feb 10, 2019 at 21:22

2 Answers 2

1

That still wouldn't solve the issue with struct! I think I have found a glitch in GCC compiler where if you define your struct in dynamic memory rather than PROGMEM, even if you use a buffer and fetch the data using memcpy_P, it will return the correct value while printing, but when you copy it again to allChars[0].bitmap , the wrong value is copied! the thing that solved the issue was adding PROGMEM to the struct like below:

typedef struct {
  unsigned int ascii;
  int size[2];
  const PROGMEM unsigned char *bitmap;
} chars;

I have not yet encountered any compilers that are this specific and don't even allow transfer between memory spaces correctly. (Not to mention other issues with GCC linker that are brought up by david from eevblog like stack overflow without warning, etc). They really need to solve issues like this as this compiler is one of the most frequently used on different platforms.

anyways, here is the final code if anyone finds it useful (I will probably end up making a youtube video about it later):

#include "U8glib.h"
//U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE);
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);

typedef struct {
  unsigned int ascii;
  int size[2];
  const PROGMEM unsigned char *bitmap;
} chars;

chars allChars[1];

const unsigned char pat[] PROGMEM = {
  0x00, 0x00, 0x00,  //..................... 
  0x00, 0x00, 0x00,  //..................... 
  0x00, 0x00, 0x00,  //..................... 
  0x00, 0x00, 0x00,  //..................... 
  0x00, 0x00, 0x00,  //..................... 
  0x00, 0x00, 0x00,  //..................... 
  0x00, 0x00, 0x00,  //..................... 
  0x00, 0x00, 0x00,  //..................... 
  0x00, 0x00, 0x00,  //..................... 
  0x01, 0xfc, 0x00,  //.......%%%%%%%....... 
  0x0f, 0xff, 0x00,  //....%%%%%%%%%%%%..... 
  0x1f, 0xff, 0xc0,  //...%%%%%%%%%%%%%%%... 
  0x3f, 0xff, 0xe0,  //..%%%%%%%%%%%%%%%%%.. 
  0x3f, 0xff, 0xe0,  //..%%%%%%%%%%%%%%%%%.. 
  0x7f, 0xff, 0xf0,  //.%%%%%%%%%%%%%%%%%%%. 
  0x7f, 0xdf, 0xf0,  //.%%%%%%%%%.%%%%%%%%%. 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0xff, 0x8f, 0xf8,  //%%%%%%%%%...%%%%%%%%% 
  0x7f, 0xdf, 0xf0,  //.%%%%%%%%%.%%%%%%%%%. 
  0x7f, 0xff, 0xf0,  //.%%%%%%%%%%%%%%%%%%%. 
  0x3f, 0xff, 0xe0,  //..%%%%%%%%%%%%%%%%%.. 
  0x3f, 0xff, 0xe0,  //..%%%%%%%%%%%%%%%%%.. 
  0x1f, 0xff, 0xc0,  //...%%%%%%%%%%%%%%%... 
  0x0f, 0xff, 0x80,  //....%%%%%%%%%%%%%.... 
  0x01, 0xfc, 0x00,  //.......%%%%%%%....... 
  0x00, 0x00, 0x00,  //..................... 
  0x00, 0x00, 0x00,  //..................... 
  0x00, 0x00, 0x00,  //..................... 
  0x00, 0x00, 0x00,  //..................... 
  0x00, 0x00, 0x00,  //..................... 
};

void charToBitmap(int x, int y, char chr){
  for(unsigned int i=0; i<sizeof(allChars);i++){
    if (allChars[i].ascii=chr){
      u8g.drawBitmapP( x, y, allChars[i].size[0], allChars[i].size[1], allChars[i].bitmap);
      break;
    }
  }
}

void draw(void) {
  charToBitmap(0,0,'0');
}

void setup(void) {
  allChars[0] = (chars) {48,{3,54},pat};
}

void loop(void) {
    u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
}
0

You're making it far too hard on yourself.

All you need is a single 2-dimensional array of data in PROGMEM:

const uint8_t bitmaps[10][8] PROGMEM = {
  { 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x66 },
  { 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x66 },
  { 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x66 },
  { 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x66 },
  { 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x66 },
  { 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x66 },
  { 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x66 },
  { 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x66 },
  { 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x66 },
  { 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x66 },
};

Each row is a bitmap, and there are 10 rows, so 10 bitmaps (I have them all the same at the moment).

Then you just reference the slice number you are interested in:

u8g.drawBitmapP( 100, 30, 1, 8, bitmaps[3]);

Note: I haven't tested this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.