Создание массива структур, в которых хранятся растровые изображения для работы с 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);
}
первая строка, где я использовал шаблон непосредственно в функции рисования, работает отлично, но вторая строка, которая получает значение из указателя, рисует какую-то странную форму шума (я предполагаю, что это дамп памяти адреса или что-то в этом роде). )!
Можно ли вообще создать структуру, в которой одна из переменных будет просто указателем на константы, которые я определил ранее? Я почти уверен, что делаю что-то очень неправильно, поскольку я не знаком с использованием указателей, адресов и прочего, поэтому было бы здорово, если бы кто-нибудь помог с этими проблемами!
@OM222O, 👍1
Обсуждение2 ответа
Вы слишком сильно к себе относитесь.
Все, что вам нужно, это один двумерный массив данных в 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]);
Примечание. Я это не проверял.
Это все равно не решит проблему со структурой! Кажется, я обнаружил ошибку в компиляторе 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() );
}
- Почему структура переменного размера не компилируется в Arduino IDE?
- Интерпретатор и обработчик сообщений – как сохранить имя функции в структуре?
- Динамическое размещение/указатель на указатель для обновления массива, содержащего параметр
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Ошибка: invalid application of 'sizeof' to incomplete type 'int []' при попытке вычислить размер массива в библиотеке
- Инициализация массива структур
- Объявление и использование массива структур в Arduino
- Как получить размер (sizeof) массива структур
Попробуйте «allChars[0].bitmap = pat;», @Mikael Patel