Создание массива структур, в которых хранятся растровые изображения для работы с u8glib.

Я пробовал читать документацию и впадаю в отчаяние, потому что ничего не могу найти.

Мне нужно создать массив структур, содержащий растровое изображение, хранящееся в пространстве PROGMEM (из-за проблем с использованием памяти).

Растровые изображения создаются следующим образом:

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

Тогда мне нужно создать такую структуру:

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

chars allChars[1];

но компилятору это почему-то не нравится, и он выплеснул кучу неверных преобразований из const в char, так что стало ясно, что я не могу это использовать! Моей следующей попыткой было создать указатель на шаблон следующим образом:

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

chars allChars[1];

На этот раз он снова выдал предупреждения о недопустимом преобразовании, но, по крайней мере, скомпилировался! Затем я попытался написать весь код и запустить его:

#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);
}

первая строка, где я использовал шаблон непосредственно в функции рисования, работает отлично, но вторая строка, которая получает значение из указателя, рисует какую-то странную форму шума (я предполагаю, что это дамп памяти адреса или что-то в этом роде). )!

Можно ли вообще создать структуру, в которой одна из переменных будет просто указателем на константы, которые я определил ранее? Я почти уверен, что делаю что-то очень неправильно, поскольку я не знаком с использованием указателей, адресов и прочего, поэтому было бы здорово, если бы кто-нибудь помог с этими проблемами!

, 👍1

Обсуждение

Попробуйте «allChars[0].bitmap = pat;», @Mikael Patel


2 ответа


0

Вы слишком сильно к себе относитесь.

Все, что вам нужно, это один двумерный массив данных в 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 },
};

Каждая строка представляет собой растровое изображение, а строк 10, то есть 10 растровых изображений (на данный момент они у меня все одинаковые).

Затем вы просто указываете номер интересующего вас фрагмента:

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

Примечание. Я это не проверял.

,

1

Это все равно не решит проблему со структурой! Кажется, я обнаружил ошибку в компиляторе GCC: если вы определяете свою структуру в динамической памяти, а не в PROGMEM, даже если вы используете буфер и извлекаете данные с помощью memcpy_P, она вернет правильное значение во время печати, но когда вы его скопируете снова в allChars[0].bitmap копируется неправильное значение! проблему решило добавление PROGMEM в структуру, как показано ниже:

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

Я еще не встречал компиляторов, которые были бы настолько специфичными и даже не позволяли бы корректно перемещаться между пространствами памяти. (Не говоря уже о других проблемах с компоновщиком GCC, о которых упомянул Дэвид из eevblog, таких как переполнение стека без предупреждения и т. д.). Им действительно необходимо решать подобные проблемы, поскольку этот компилятор является одним из наиболее часто используемых на разных платформах.

В любом случае, вот окончательный код, если он кому-нибудь покажется полезным (возможно, позже я сделаю об этом видео на YouTube):

#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() );
}
,