Oled 128x64 Помогите разобраться как рисовать иконки и значки

fastudio4
Offline
Зарегистрирован: 30.07.2015

Здравствуйте. Помогите разобраться с отрисовкой иконок и прочей графики на oled дисплее. 
Я использую библиотеку U8glib.h, и дисплейчик у меня SPIный. Не могу понять принцип построения иконки - 
 

const uint8_t rook_bitmap[] U8G_PROGMEM = {
  0x00,         // 00000000 
  0x55,         // 01010101
  0x7f,          // 01111111
  0x3e,         // 00111110
  0x3e,         // 00111110 
  0x3e,         // 00111110
  0x3e,         // 00111110 
  0x7f           // 01111111
};

u8g.drawBitmapP( 0, 0, 1, 8, rook_bitmap);

Что означает "1" и "8"???

Я попробовал свой рисунок через пограмму Img2Lcd

const uint8_t gImage_ph[] U8G_PROGMEM = { /* 0X11,0X81,0X00,0X1E,0X00,0X18, */
0XC7,0X00,0XC1,0XFF,0XC1,0XF8,0X00,0XC1,0XFF,0XC1,0XF8,0X01,0XC1,0XFF,0XC1,0XFC,
0X01,0XC1,0XFF,0XC1,0XFC,0X01,0XC1,0XE0,0X1C,0X01,0XC1,0XFF,0XC1,0XFC,0X01,0XC1,
0XFF,0XC1,0XFC,0X01,0XC1,0XFF,0XC1,0XFC,0X01,0XC1,0XFF,0XC1,0XFC,0X01,0XC1,0XFF,
0XC1,0XFC,0X01,0XC1,0XFF,0XC1,0XFC,0X01,0XC1,0XFF,0XC1,0XFC,0X0F,0XC1,0XE0,0X7C,
0X3F,0XC1,0XE0,0X3C,0X3F,0XC0,0X1C,0X3F,0X80,0X0C,0X3F,0X80,0X0C,0X3F,0X80,0X0C,
0X3F,0X80,0X0C,0X3F,0XC0,0X1C,0X3F,0XC1,0XE0,0X3C,0X0F,0XC1,0XF0,0X7C,0X03,0XC1,
0XFF,0XC1,0XFC,0X01,0XC1,0XFF,0XC1,0XFC,0X00,0XC1,0XFF,0XC1,0XF8,0X00,0XC1,0XFF,
0XC1,0XF8,0X00,0X7F,0XC1,0XF0,0XC3,0X00,};

Но не знаю как считать всю эту лабуду. Есть куча примеров с изображением различных иконок но мне нужны свои поставить, а они у меня выглядят как рябь.
Может есть нормальная программа для создания иконок на таких дисплеях?

 

Radjah
Offline
Зарегистрирован: 06.08.2014

Посмотреть в код бибилиотеки вероисповедние не позволяет?

https://code.google.com/p/u8glib/source/browse/cppsrc/U8glib.h#153

fastudio4
Offline
Зарегистрирован: 30.07.2015

Ответ впечатляет! А можно детально, для чайников? 
Ту часть библиотеки что вы указали для моего понимания не совсем ясна. 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Может это поможет, вроде бы достаточно разжевано http://nnm.me/blogs/pencraft/arduino-i-graficheskiy-displey-128x64-s-kontrollerom-st7920/

Я не помогу, не юзал.

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

fastudio4 пишет:

Ответ впечатляет! А можно детально, для чайников? 
Ту часть библиотеки что вы указали для моего понимания не совсем ясна. 

Можно и детальнее.

Если бы Вы не поленились посмотреть в код библиотеки, то Вы бы увидели, что функция drawBitmapP описана как

void drawBitmapP(u8g_uint_t x, u8g_uint_t y, u8g_uint_t cnt, u8g_uint_t h, const u8g_pgm_uint8_t *bitmap)

Кстати, ещё проще это узнать из документации на библиотеку - https://code.google.com/p/u8glib/wiki/userreference#drawBitmapP

Отсюда ответ на Ваш вопрос очевиден - 1 - количество байтов в строке, 8 - количество строк в битмапе.

Что писать в Вашем случае знаете только Вы, т.к. никто, кроме Вас, не знает сколько строк и столбцов в том битампе, который Вы закодировали в массиве gImage_ph[].

fastudio4
Offline
Зарегистрирован: 30.07.2015

kisoft пишет:

Может это поможет, вроде бы достаточно разжевано http://nnm.me/blogs/pencraft/arduino-i-graficheskiy-displey-128x64-s-kontrollerom-st7920/

Я не помогу, не юзал.

 

Спасибо большое! Большего мне и не нужно было!

taratik
Offline
Зарегистрирован: 18.07.2018

Здесь http://tehnopage.ru/vyvod-kartinki-na-displey-128x64 все разжовано и приведен пример по выводу картинки на такой дисплей.

Bayrn
Offline
Зарегистрирован: 14.06.2019

У меня тоже вопрос иммется, по поводу вывода картинк на дисплей.

Дисплей: SSD1306_128X32 I2C

Библиотека: U8glib.h

Скачал я следующий кодб и подточил под свои нужды, картинку с примера выводит, либо обрезанную либо сжатую (т.к дисплей не 64 а 32), но как в примере.

#include "U8glib.h"
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); //erzeugen des Display Objektes

static unsigned char image[] U8G_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, 0xC0, 0x30, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x38, 
  0x1E, 0x07, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x38, 0x0C, 0x07, 0x00, 0x00, 
  0x00, 0x00, 0xE0, 0x30, 0x1C, 0x07, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x78, 
  0x0C, 0x07, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x38, 0x1C, 0x07, 0x00, 0x00, 
  0x00, 0x00, 0xE0, 0x30, 0x1E, 0x07, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x78, 
  0x0E, 0x07, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x38, 0x1C, 0x07, 0x00, 0x00, 
  0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 
  0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 
  0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xE0, 0x01, 0x00, 
  0x00, 0x00, 0x0E, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x0E, 0x00, 
  0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x70, 0x00, 0x00, 
  0x00, 0x00, 0x0E, 0x00, 0x00, 0x70, 0xC0, 0xFF, 0xFF, 0x03, 0x0E, 0x00, 
  0xF0, 0x7F, 0xF0, 0xFF, 0xFF, 0x0F, 0xFE, 0x0F, 0xF8, 0x7F, 0xF0, 0xFF, 
  0xFF, 0x0F, 0xFE, 0x1F, 0xF8, 0x7F, 0x78, 0x00, 0x00, 0x0E, 0xFE, 0x0F, 
  0x00, 0x70, 0x38, 0x00, 0x00, 0x1C, 0x0E, 0x00, 0x00, 0x70, 0x70, 0x00, 
  0x00, 0x1C, 0x0E, 0x00, 0x00, 0x70, 0x78, 0x00, 0x00, 0x0E, 0x0E, 0x00, 
  0xD0, 0x7B, 0x38, 0x00, 0x00, 0x1C, 0xEE, 0x0D, 0xF8, 0x7F, 0x38, 0x00, 
  0x00, 0x1C, 0xFE, 0x1F, 0xF8, 0x7F, 0x38, 0x00, 0x00, 0x0E, 0xFE, 0x0F, 
  0x40, 0x74, 0x30, 0x00, 0x00, 0x1C, 0x1E, 0x0A, 0x00, 0x70, 0x78, 0x00, 
  0x00, 0x1C, 0x0E, 0x00, 0x00, 0x70, 0x78, 0x00, 0x00, 0x1C, 0x0E, 0x00, 
  0x20, 0x74, 0x30, 0x00, 0x00, 0x1C, 0x1E, 0x06, 0xF8, 0x7F, 0x38, 0x00, 
  0x00, 0x0E, 0xFE, 0x1F, 0xF8, 0x7F, 0x38, 0x00, 0x00, 0x1C, 0xFE, 0x0F, 
  0xD0, 0x7B, 0x38, 0x00, 0x00, 0x1C, 0x5E, 0x0B, 0x00, 0x70, 0x70, 0x00, 
  0x00, 0x0E, 0x0E, 0x00, 0x00, 0x70, 0x38, 0x00, 0x00, 0x1C, 0x0E, 0x00, 
  0x00, 0x70, 0x38, 0x00, 0x00, 0x1C, 0x0E, 0x00, 0xF8, 0x7F, 0x38, 0x00, 
  0x00, 0x0E, 0xFE, 0x1F, 0xF8, 0x7F, 0x78, 0x00, 0x00, 0x1C, 0xFE, 0x0F, 
  0xF0, 0x7F, 0xF0, 0xFF, 0xFF, 0x0F, 0xFE, 0x0F, 0x00, 0x70, 0xF0, 0xFF, 
  0xFF, 0x0F, 0x0E, 0x00, 0x00, 0x70, 0xE0, 0xFF, 0xFF, 0x07, 0x0F, 0x00, 
  0x00, 0x70, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x70, 0x00, 0x00, 
  0x00, 0x80, 0x07, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 
  0x00, 0x70, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 
  0xFF, 0xFF, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 
  0x00, 0xF0, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x38, 
  0x0E, 0x07, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x38, 0x1C, 0x07, 0x00, 0x00, 
  0x00, 0x00, 0xE0, 0x30, 0x0E, 0x07, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x78, 
  0x1C, 0x07, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x38, 0x1C, 0x07, 0x00, 0x00, 
  0x00, 0x00, 0xE0, 0x30, 0x0C, 0x07, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x78, 
  0x1C, 0x07, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x38, 0x0E, 0x07, 0x00, 0x00, 
  0x00, 0x00, 0x80, 0x10, 0x0C, 0x01, 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, };


void draw(void) {
  u8g.drawXBMP( 0, 0, 64, 64, image);
}

void setup(void) {
}

void loop(void) {
  // picture loop
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
  
  // rebuild the picture after some delay
  delay(1000);
}

Очень прилежно слелал иконки в пэинте 1:1 попиксельно к дисплею 128х32, через пару сервисов конвертировал в массив, заливаю, а он мне иконку вертикально посередине делит и 2 половину ставит на первое место а первую на второе. Долго парился, все настройки перепробовал не меняется. Если чётный адрес с нечётным поменять то вроде идёт. в чём может быть проблемма, может кто сталкивался?

К примеру иконка батареи:

#include "U8glib.h"

U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE); // I2C / TWI

static unsigned char image[] U8G_PROGMEM = 
{
0xFF,0xFF,
  0xFF,0xFF,
  0xFF,0xFF,
  0xFC,0x3F,
  0xE0,0x07,
  0xEF,0xF7,
  0xE8,0x17,
  0xE8,0x17,
  0xE8,0x17,
  0xE8,0x17,
  0xE8,0x17,
  0xEF,0xF7,
  0xE8,0x17,
  0xE8,0x17,
  0xE8,0x17,
  0xE8,0x17,
  0xE8,0x17,
  0xEF,0xF7,
  0xE8,0x17,
  0xE8,0x17,
  0xE8,0x17,
  0xE8,0x17,
  0xE8,0x17,
  0xEF,0xF7,
  0xE8,0x17,
  0xE8,0x17,
  0xE8,0x17,
  0xEF,0xF7,
  0xE0,0x07,
  0xFF,0xFF,
  0xFF,0xFF,
  0xFF,0xFF,
  0xFF,0xFF,
  0xFF,0xFF
 };

void draw(void) {
  u8g.drawXBMP( 1, 1, 16, 34, image);
}
void setup(void) {
}
void loop(void) {
  // picture loop
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
  
  // rebuild the picture after some delay
  delay(1000);
}

Заранее спасибо.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Вы же сами на свой вопрос ответили. У вас нумерация байтов слева-направо , а выводятся они справа-налево сверху-вниз. Был бы спрайт шириной в три байта нужно было бы местами поменять каждый первый с каждым третьим.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Да, адресации в дисплее 128*32 отличается, вам или самим придётся разбираться как рисуются картинки или автор библиотеки должен покрутить.
Завтра кусок кода откапаю, выложу, там какой то битовый сдвиг использовал, четные / не чётные биты выводятся.

b707
Offline
Зарегистрирован: 26.05.2017

смотрите исходный код процедуры drawXBMP()

Поменять четный и нечетный ряд очень просто - добавьте к массиву ноль в начале да и все

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

вот откопал функцию, при горизонтальном расположенеии экрана 128*32, сначала выводятся младшие 4 бита, раскиданные по нечетным местам байта, потом старшие 4 бита, аналогично раскиданные по нечетным местам байта.

void printOLEDcharP(unsigned char C, unsigned char* X, unsigned char* Y){
	if ( *X >= (MyOLED_Char_X)) {
        *X = 0; ++*Y;
    }
	if ( *Y >= (MyOLED_Char_Y)) *Y = 0; 
	//Ignore unused ASCII characters. Modified the range to support multilingual characters.
    if(C < 32 || C > 127) C='*'; //star - indicate characters that can't be displayed
#ifndef MyOLED_128x32
    setCursorXY(*X, *Y);
    for(unsigned char i=0; i<8; i++) {
       sendData(BasicFont[C-0x20][i]); //font array starts at 0, ASCII starts at 32. Hence the translation
    }
#else
	unsigned char src_b, b_out, b_tmp;
    setCursorXY(*X, (*Y) * 2);
    for(unsigned char i=0; i<8; i++) {
		src_b = BasicFont[C-0x20][i];
					b_out = (src_b & 0x01) << 1;
					b_tmp = (src_b & 0x02) << 2;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x04) << 3;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x08) << 4;
					b_out |= b_tmp;
       //read unsigned chars from code memory
       sendData(b_out); //font array starts at 0, ASCII starts at 32. Hence the translation
    }
    setCursorXY(*X, (*Y) * 2 + 1);
    for(unsigned char i=0; i<8; i++) {
		src_b = BasicFont[C-0x20][i];
					b_out = (src_b & 0x10) >> 3;
					b_tmp = (src_b & 0x20) >> 2;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x40) >> 1;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x80);
					b_out |= b_tmp;
       //read unsigned chars from code memory
       sendData(b_out); //font array starts at 0, ASCII starts at 32. Hence the translation
    }
#endif
    ++ *X;
}

 

Bayrn
Offline
Зарегистрирован: 14.06.2019

Доброго времени суток.

Большое спасибо за ответы.

"смотрите исходный код процедуры drawXBMP()

Поменять четный и нечетный ряд очень просто - добавьте к массиву ноль в начале да и все"

Нуль помогает, картинка соединяется только немного сдвинута по по оси y. 

Я слишко далеко копать не стал, просто взял пример с другой библиотекой и там всё пошло.  

andycat, спасибо большое, я обязательно попробую.

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Bayrn пишет:

.......

Нуль помогает, картинка соединяется только немного сдвинута по по оси y. 

.........

andycat, спасибо большое, я обязательно попробую.

у вас дисплей как я понял в вертикальной ориентации стоит, соответственно моя перестановка битов вам и не нужна

а сдвинутую картинку легко исправить, начинать рисовать просто раньше/позже, в другом столбце