Подключение дисплея GMG12864-06D на ST7565R

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

andriano пишет:

И еще: для своего дисплея я в свое время (сразу после покупки) нашел следующий скетч: *****

Правда, здесь понятие верха и низа противоположно библиотеке u8g, но зато достаточно экономично по памяти:

Скетч использует 2352 байт (7%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 1033 байт (50%) динамической памяти, оставляя 1015 байт для локальных переменных. Максимум: 2048 байт.

Спасибо! Забрал на анализ и опыты!

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

wdrakula пишет:

Я не против спорта, но не для достижения реального результата. Если это не тиражируемое, а единичное изделие, то на фоне времени разработки стоимость контроллера равна нолю, так почему не взять побольше.

Если можно 3 вольта - СТМ32, если нужна связь - ЕСП32, если нужны 5В - Мега. А Уно/нано - для совсем мелочей. Ну а Тиньки - это святое, это уже только для души! ;))) (ну или если нужно 8 ног)

По-мойму все что делает на Ардуино все для спорта! А если реально что-то нужно, то можно просто купить готовое.

По поводу почему не мега или есп32? Дык я даже не задумывался об этом. Просто на столе есть дисплей (сабжевый), в тумбе есть Уно, ... и выбор очевиден)

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

lilik пишет:

А вот это не такой (только дешевле)? Получается много внешне одинаковых, а чипы разные? Пиксель имеет не квадратную форму? По картинке явно пропорции не 2:1. Графика будет искажаться? Просто тоже за кампанию захотелось :-)

Мой дешевле на 50 руб))

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

khusamov пишет:

А дисплей-то мой дешевле. И покрасивше на вид. 

Не буду спорить ни с тем, ни с другим: я брал такие дисплейчики в начале 2017 - в запас. И так ими и не воспользовался. Ну а прогресс за 4 с половиной года никто не отменял.

Цитата:

Тоже из ОЗУ осталось 600 байт.

Ну, во-первых, Вы так и не привели никаких соображений за то, что этой памяти для Тетриса мало.

А во-вторых, я ведь привел пример скетча с почти таким же дисплеем, где остается более 1000 байт. Кто мешает им воспользоваться?

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

andriano пишет:

Ну, во-первых, Вы так и не привели никаких соображений за то, что этой памяти для Тетриса мало.

А во-вторых, я ведь привел пример скетча с почти таким же дисплеем, где остается более 1000 байт. Кто мешает им воспользоваться?

Тетрис это лишь пример.

Я выше написал, что взял код на анализ)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

wdrakula пишет:

Я не против спорта, но не для достижения реального результата. Если это не тиражируемое, а единичное изделие, то на фоне времени разработки стоимость контроллера равна нолю, так почему не взять побольше.

Вот получается интересная ситуация: ты вроде как ратуешь за "побольше", а пользуешься в основном Атмегой328, а я вроде бы тебе возражаю, а на деле совсем погряз в stm32f407...

Цитата:

Если можно 3 вольта - СТМ32, если нужна связь - ЕСП32, если нужны 5В - Мега. А Уно/нано - для совсем мелочей.

Вот Тетрис - та самая мелочь и есть.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

khusamov пишет:

Просто на столе есть дисплей (сабжевый), в тумбе есть Уно, ... и выбор очевиден)

khusamov пишет:

Тетрис это лишь пример.

Ну, вообще-то принята следующая последовательность действий:

1. Формулировка задачи.

2. Оценка требуемых ресурсов для ее решения.

3. Выбор комплектующих.

Ну а так - да, обычно берешь то, что лежит в "тумбочке". Главное, чтобы эта "тумбочка" была достаточно вместительной. И тогда Уно/Мега/Дуэ/ЕСП/СТМ - это уже безразлично.

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

andriano пишет:

Ну, вообще-то принята следующая последовательность действий:

1. Формулировка задачи.

2. Оценка требуемых ресурсов для ее решения.

3. Выбор комплектующих.

Это я на работе так буду делать.

А с ардуино я отдыхаю. Заместо рыбалки. 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

andriano пишет:

Вот получается интересная ситуация: ты вроде как ратуешь за "побольше", а пользуешься в основном Атмегой328, а я вроде бы тебе возражаю, а на деле совсем погряз в stm32f407...

Не... вот сейчас я медленно и печально доделываю контроллер отопителя в автобус. Так специально мегу на мелкой плате заказал. Так что скорее так: я просто очень хорошо знаю 8ми битные АВР. И мне быстрее думается в их парадигме. Поэтому чаще выбираю их.

А так да 328 очень удобный контроллер для много чего. Только без графики и без веба ;))).

lilik
Offline
Зарегистрирован: 19.10.2017

khusamov пишет:

lilik пишет:

А вот это не такой (только дешевле)? Получается много внешне одинаковых, а чипы разные? Пиксель имеет не квадратную форму? По картинке явно пропорции не 2:1. Графика будет искажаться? Просто тоже за кампанию захотелось :-)

Мой дешевле на 50 руб))

А ссылку на продавца этого такого-не такого экрана можно?... да и скетч на вывод полноэкранной картинки :-)

Гулять так гулять !

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

lilik пишет:

А ссылку на продавца этого такого-не такого экрана можно?... да и скетч на вывод полноэкранной картинки :-)

Гулять так гулять !

Вообще-то ссылки я уже давал. Вот дублирую:

https://aliexpress.ru/item/1005001621784395.html

https://aliexpress.ru/item/32800995659.html

А скетчи все тут:

https://github.com/olikraus/u8g2

lilik
Offline
Зарегистрирован: 19.10.2017

Спасибо, как то упустил из вида.

lilik
Offline
Зарегистрирован: 19.10.2017

Глянул по 2 ссылке в отзывы. Он и цветной?

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

lilik пишет:

Глянул по 2 ссылке в отзывы. Он и цветной?

Где-то я видел цветной. Ну как цветной, разделенный на 2-3 полоски. В каждой полосе свой цвет пиксела. Типа можно статусную строку сверху сделать отличающимся цветом.

Но тот, что я купил, он не цветной. Обычный монохромный. Хотя... у меня их две штуки. От разных продавцов. Один я уже опробировал, он точно монохромный, а вот второй не пробовал... Позже попробую -расскажу)

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

andriano пишет:

khusamov пишет:

В следующий раз я вместо тетриса буду запрашивать дум.

Тогда Вам скажут, что с Uno там однозначно делать нечего.

Кстати, а дум можно уместить в 2 килобайта. Вот уже сделали его, правда на 2.5 кб:

https://community.arduboy.com/t/dark-under-a-dungeon-crawler/4637

lilik
Offline
Зарегистрирован: 19.10.2017

https://www.youtube.com/watch?v=wJG04DSo7Xw&t=82s

Стрелялка по типу "вольфенштейн" только на ssd1306.

А вообще такому экрану мне кажется больше подходит вот это:

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

khusamov пишет:

Кстати, а дум можно уместить в 2 килобайта. Вот уже сделали его, правда на 2.5 кб:

https://community.arduboy.com/t/dark-under-a-dungeon-crawler/4637

А кто Вам сказал, что это - Дум? Это даже не Вольфенштейн.

Кстати, думаю, что Вольфенштейна уже можно сделать на Ардуино.

 

На всякий случай:

1. Данный движок: пол и потолок плоские в одном уровне. Карта представляет собой набор квадратных ячеек. Игрок может находиться только в центре ячейки и быть повернутым на угол кратный 90 градусам. Движок не использует FPU.

2. Вольфенштейн: пол и потолок плоские в одном уровне. Карта представляет собой набор квадратных ячеек. Игрок может находиться в произвольной точке уровня и быть повернутым на произвольный угол. Движок не использует FPU.

3. Дум: уровень пола и высота потолка может изменяться, в частности, возможны ступеньки. Карта может состоять из произвольных полигонов. Но стены всегда перпендикулярны потолку и полу, а потолок и пол - единственные в данной точке карты, т.е. туннели и мосты невозможны. Игрок может находиться в произвольной точке уровня и быть повернутым на произвольный угол. Движок использует FPU.

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

andriano пишет:

1. Данный движок: пол и потолок плоские в одном уровне. Карта представляет собой набор квадратных ячеек. Игрок может находиться только в центре ячейки и быть повернутым на угол кратный 90 градусам. Движок не использует FPU.

2. Вольфенштейн: пол и потолок плоские в одном уровне. Карта представляет собой набор квадратных ячеек. Игрок может находиться в произвольной точке уровня и быть повернутым на произвольный угол. Движок не использует FPU.

3. Дум: уровень пола и высота потолка может изменяться, в частности, возможны ступеньки. Карта может состоять из произвольных полигонов. Но стены всегда перпендикулярны потолку и полу, а потолок и пол - единственные в данной точке карты, т.е. туннели и мосты невозможны. Игрок может находиться в произвольной точке уровня и быть повернутым на произвольный угол. Движок использует FPU.

Да вы специалист по думам)))

Для меня все что в лабиринте и с пистолетом посередине экрана все ДУМ!

 

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

lilik пишет:

Глянул по 2 ссылке в отзывы. Он и цветной?

Проверил второй дисплей. Который был куплен с этой карточки, где такая странная фотография.

Нет, он не цветной.

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

В общем все работает как надо. ОЗУ остается 1500 байта. 

В библиотеке есть три режима. Первые два как раз позволяют сильно экономить ОЗУ за счет скорости вывода. Скорость упала заметно, но не критично.

Всем кто помогал СПАСИБО!

lilik
Offline
Зарегистрирован: 19.10.2017

khusamov пишет:

lilik пишет:

Глянул по 2 ссылке в отзывы. Он и цветной?

Проверил второй дисплей. Который был куплен с этой карточки, где такая странная фотография.

Нет, он не цветной.

Ясно, кому как повезёт :-)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Сварганил небольшой пример на том дисплейчике, что у меня есть (JLX12864G-086) - он очень похож на сабжевый.

файл JLX12864G-086.ino

/*
JLX12864G-086 (Graphic LCD 128x64)
LEDA : +3.3V
VDD : +3.3V
VSS: GND
*/

#include <SPI.h>
#include "ASM12864.h"

//const int  csPIN  = 10;  // CS
//const int rstPIN  = 8;    // RST
//const int  rsPIN  = 9;    // RS
//const int sckPIN = 13;  // SCK
//const int sdaPIN = 11;  // SDA

const byte PROGMEM graphic1[1028]={
  128, 64, 0xff, 1,
0xf0, 0xf8, 0x6c, 0x6c, 0x6c, 0x78, 0x70, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xf0, 0xf8, 0x6c, 
0x6c, 0x6c, 0x78, 0x70, 0x00, 0x00, 0xf0, 0xf8, 0x0c, 0x0c, 0x9c, 0x98, 0x00, 0x0c, 0xfe, 0xff, 
0x0c, 0x0c, 0x00, 0xf0, 0xf8, 0x9c, 0x0c, 0x9c, 0xf8, 0xf0, 0x00, 0x00, 0xf0, 0xf8, 0x9c, 0x0c, 
0x98, 0xff, 0xff, 0x00, 0x00, 0x88, 0xcc, 0x6c, 0x2c, 0xfc, 0xf8, 0x00, 0x0c, 0xfc, 0xf0, 0x00, 
0xf0, 0xfc, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 
0xe0, 0x30, 0x10, 0x08, 0x0c, 0x04, 0x04, 0x02, 0x06, 0x03, 0x11, 0x41, 0x01, 0x01, 0x01, 0x07, 
0x11, 0x21, 0x41, 0x41, 0x81, 0x81, 0x01, 0x02, 0x82, 0x80, 0x44, 0x1c, 0x08, 0x90, 0x60, 0x20, 
0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01, 0x03, 
0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x01, 0x03, 
0x03, 0x03, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 
0x01, 0x03, 0x03, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x01, 0x03, 0x02, 0x00, 0x10, 0x1f, 0x1f, 
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xb8, 0x8c, 0x83, 0x00, 
0x00, 0x03, 0x04, 0x00, 0x88, 0x48, 0x08, 0x28, 0x28, 0x08, 0x04, 0x42, 0x41, 0x80, 0x00, 0x00, 
0xf8, 0x04, 0x02, 0x02, 0x02, 0x02, 0x04, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x81, 0x86, 0x88, 
0x88, 0x90, 0x13, 0x14, 0x18, 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

0xfc, 0x04, 0x04, 0x04, 0x04, 0x04, 0xfc, 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, 
0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 
0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x9f, 0x01, 0x00, 0x00, 0x00, 0x81, 
0x22, 0x20, 0x80, 0x8f, 0x70, 0x20, 0x20, 0x20, 0xe0, 0x10, 0x10, 0x10, 0x10, 0x79, 0x92, 0x00, 
0x08, 0x11, 0x13, 0xd2, 0x12, 0x10, 0x12, 0xe2, 0x21, 0x00, 0x1e, 0x11, 0xe0, 0x20, 0x10, 0x10, 
0x10, 0x00, 0x00, 0x8a, 0x98, 0x70, 0x10, 0x01, 0xe5, 0x06, 0x0c, 0xf0, 0x00, 0x00, 0x00, 0x00, 

0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
0x08, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x01, 0xf1, 0x11, 0x01, 0x82, 0x44, 0x38, 0x00, 0x00, 
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xd0, 0x21, 0xe1, 0xf1, 0x0c, 0x86, 
0x83, 0x09, 0x10, 0x21, 0x22, 0x44, 0x48, 0x08, 0xf0, 0x91, 0x0c, 0x04, 0x04, 0x04, 0x03, 0x02, 
0x02, 0x02, 0x83, 0xc3, 0x82, 0x82, 0x03, 0x02, 0x00, 0x04, 0x02, 0x19, 0x78, 0x48, 0x44, 0x44, 
0xd2, 0x32, 0x71, 0x71, 0x38, 0x38, 0x1c, 0x12, 0x09, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 
0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x7f, 0x7f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x44, 0xc4, 0xc5, 0x05, 
0x9e, 0x3e, 0xee, 0x27, 0x46, 0xf7, 0xff, 0xf6, 0xf3, 0x08, 0x00, 0x04, 0x7e, 0xff, 0xe7, 0xfe, 
0xfd, 0x97, 0x83, 0x83, 0xfe, 0xfc, 0xff, 0xfb, 0xff, 0x03, 0x01, 0x01, 0x07, 0x1f, 0x32, 0x8c, 
0x06, 0xfe, 0x27, 0x03, 0x68, 0x1c, 0xcc, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0xfe, 0x80, 0x00, 0x84, 0xc2, 0xa2, 
0x92, 0x8c, 0x00, 0x6c, 0x92, 0x92, 0x92, 0x6c, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 0x00, 0x78, 
0x94, 0x92, 0x92, 0x60, 0x00, 0x30, 0x28, 0x24, 0xfe, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x47, 0x5e, 0x24, 0xc8, 0x89, 0x9e, 
0x38, 0x01, 0xc7, 0x2e, 0x60, 0xe1, 0xe7, 0x3c, 0x07, 0x00, 0xc0, 0xf0, 0xb8, 0xfc, 0xfc, 0x0c, 
0x0d, 0xfd, 0xf9, 0xe1, 0x81, 0x81, 0x7c, 0x2c, 0x46, 0x46, 0x76, 0x7c, 0x78, 0x80, 0x80, 0x00, 
0x0f, 0xe0, 0x40, 0xdf, 0x0e, 0x00, 0x33, 0x1c, 0xc4, 0x74, 0x3a, 0x0e, 0x86, 0xc2, 0xc2, 0x80, 

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x60, 0xf0, 0xf8, 0x60, 0x60, 0x00, 
0x80, 0xc0, 0x60, 0x60, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x60, 0xe0, 0xc0, 0x00, 
0x00, 0xf8, 0xf8, 0xc0, 0x60, 0x60, 0xe0, 0xc0, 0x00, 0x00, 0xc0, 0xe0, 0x60, 0x60, 0x60, 0x40, 
0x00, 0x60, 0xf0, 0xf8, 0x60, 0x60, 0x00, 0x80, 0xc0, 0x60, 0x60, 0x60, 0xc0, 0x80, 0x00, 0x00, 
0xe0, 0xe0, 0xc0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x02, 0x03, 0x01, 0x01, 0x7f, 0xdd, 0xed, 0x6d, 
0x67, 0xe7, 0x67, 0x93, 0x0e, 0x7f, 0x80, 0x00, 0x00, 0x80, 0x9f, 0xff, 0xcd, 0xc3, 0xff, 0x60, 
0xf0, 0xff, 0xd7, 0xff, 0xf8, 0x81, 0xc3, 0x61, 0x64, 0x65, 0xad, 0x2d, 0x6f, 0xc5, 0x80, 0x60, 
0x18, 0x8f, 0xbe, 0x7d, 0x4c, 0x4e, 0x4f, 0x4f, 0xd9, 0xf1, 0x3e, 0x01, 0x00, 0x00, 0x00, 0x00, 

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x1f, 0x18, 0x18, 0x00, 
0x07, 0x0f, 0x1b, 0x1b, 0x1b, 0x1b, 0x0b, 0x00, 0x00, 0x07, 0x0f, 0x18, 0x18, 0x1c, 0x0c, 0x00, 
0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x09, 0x1b, 0x1b, 0x1b, 0x1f, 0x0e, 
0x00, 0x00, 0x0f, 0x1f, 0x18, 0x18, 0x00, 0x07, 0x0f, 0x1b, 0x1b, 0x1b, 0x1b, 0x0b, 0x00, 0x00, 
0xff, 0xff, 0x0c, 0x18, 0x1c, 0x0f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x16, 
0x22, 0x22, 0x02, 0x41, 0x61, 0x61, 0x24, 0x85, 0xf3, 0x9b, 0xa0, 0x81, 0x82, 0x9b, 0x8d, 0x84, 
0xb4, 0xd4, 0x80, 0x88, 0xb0, 0xb3, 0xb2, 0x88, 0x1d, 0x0c, 0x4c, 0x54, 0x44, 0x45, 0x47, 0x40, 
0x42, 0x42, 0x03, 0x22, 0x24, 0x24, 0x13, 0x16, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

const byte PROGMEM Logo_BMP[36] = {
  0x10, 0x10, 0xff, 0x01,
  B00000000,  B00000001,  B00000001,  B00000011,  B11110011,  B11111110,  B01111110,  B00110011,
  B00011111,  B00001101,  B00011011,  B00111111,  B00111111,  B01111100,  B01110000,  B00000000,
  B11000000,  B11000000,  B11000000,  B11100000,  B11100000,  B11111000,  B11111111,  B10011111,
  B11111100,  B01110000,  B10100000,  B11100000,  B11110000,  B11110000,  B01110000,  B00110000 };

byte Logo_BMP_M[36] = {
  0x10, 0x10, 0xff, 0x01,
  B00000000,  B00000001,  B00000001,  B00000011,  B11110011,  B11111110,  B01111110,  B00110011,
  B00011111,  B00001101,  B00011011,  B00111111,  B00111111,  B01111100,  B01110000,  B00000000,
  B11000000,  B11000000,  B11000000,  B11100000,  B11100000,  B11111000,  B11111111,  B10011111,
  B11111100,  B01110000,  B10100000,  B11100000,  B11110000,  B11110000,  B01110000,  B00110000 };

const byte PROGMEM pacman[184] = {
  0x14, 0x18, 0xff, 0x03,
0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3E, 0x1C,   // 0x0010 (16) pixels
0x0C, 0x00, 0x00, 0x00, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9,   // 0x0020 (32) pixels
0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F,   // 0x0030 (48) pixels
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x03, 0x00, 0x00, 0x00, 

0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x7C,   // 0x0010 (16) pixels
0x7C, 0x38, 0x20, 0x00, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9,   // 0x0020 (32) pixels
0xF9, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F,   // 0x0030 (48) pixels
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x03, 0x01, 0x00, 0x00, 

0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFC,   // 0x0010 (16) pixels
0xF8, 0xF0, 0xE0, 0x80, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0020 (32) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xF9, 0x79, 0x19, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F,   // 0x0030 (48) pixels
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 
};   

const byte PROGMEM pacman_clear[10] = {
  0x03, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

const byte PROGMEM pill[9] = {
  0x05, 0x08, 0x00, 0x01,
0x0E, 0x1F, 0x1F, 0x1F, 0x0E, 
};

byte pill_0[] ={
  0x05, 0x08, 0x00, 0x01,
0x0E, 0x1F, 0x1F, 0x1F, 0x0E, 
};

void funA(char * c) {
  Serial.print("Char  ");
  Serial.println((byte)c[0]);
}

void funA(PGM_VOID_P c){ //(__FlashStringHelper * c) {
  Serial.print("__FlashStringHelper ");
  Serial.println(pgm_read_byte(c));
}
 
#define LCD_C LOW
#define LCD_D HIGH

#define LCD_X 128
#define LCD_Y 64
#define LCD_CMD 0

int a = 0;

void DisplayGraphic1();
//void clear_screen();

void setup() {
  Serial.begin(115200);
  Serial.println("Start JLX12864G-086");
  funA(pill);
  funA(pill_0);
  funA(Logo_BMP);
  funA(pacman);
  Serial.print("pacman: ");  Serial.println((uint16_t)pacman);
  LD.init();
  LD.clearDisplay();
  delay(10);
}

inline void putPixel(uint8_t x, uint8_t y) { // ~4us
//  graphic1[128*(y >> 3) + x + 4] |= 1 << (y & 7);
}

void loop() {
  uint32_t t0 = micros();
  for(byte i = 0; i < 64; i++) putPixel(i,i);
  for(byte i = 0; i < 64; i++) putPixel(64+i,63-i);
  for(byte i = 0; i < 64; i++) putPixel(i,63-i);
  for(byte i = 0; i < 64; i++) putPixel(64+i,i);
  uint32_t t1 = micros();
  Serial.print("128 putPixel:  ");  Serial.println(t1-t0);

  t0 = micros();
  LD.printString(F("0123456789!\"#$%&'()*+"), 0, 0);
  LD.printString(F(",-./:;<=>?@[\\]^_`{|}~"), 0, 1);
  LD.printString(F("ABCDEFGHIJKLMNOPQRSTU"), 0, 2);
  LD.printString(F("VWXYZabcdefghijklmnop"),0, 3);
  LD.printString(F("qrstuvwxyzАБВГДЕЁЖЗИЙ"), 0, 4);
  LD.printString(F("КЛМНОПРСТУФХЦЧШЩЪЫЬЭЮ"), 0, 5);
  LD.printString(F("Яабвгдеёжзийклмнопрст"), 0, 6);
  LD.printString(F("уфхцчшщъыьэюяЇїЎў§°±µ"), 0, 7);
  t1 = micros();
  Serial.print("Draw Text:     ");  Serial.println(t1-t0);
  delay(2000);

  LD.SetInverseText();

  t0 = micros();
  LD.printString(F("0123456789!\"#$%&'()*+"), 0, 0);
  LD.printString(F(",-./:;<=>?@[\\]^_`{|}~"), 0, 1);
  LD.printString(F("ABCDEFGHIJKLMNOPQRSTU"), 0, 2);
  LD.printString(F("VWXYZabcdefghijklmnop"),0, 3);
  LD.printString(F("qrstuvwxyzАБВГДЕЁЖЗИЙ"), 0, 4);
  LD.printString(F("КЛМНОПРСТУФХЦЧШЩЪЫЬЭЮ"), 0, 5);
  LD.printString(F("Яабвгдеёжзийклмнопрст"), 0, 6);
  LD.printString(F("уфхцчшщъыьэюяЇїЎў§°±µ"), 0, 7);
  t1 = micros();
  Serial.print("Draw Text:     ");  Serial.println(t1-t0);
  delay(2000);

  t0 = micros();
  LD.drawBitmap(graphic1, 0, 0); // X - in 1 pixel, Y - in 8 pixels
  t1 = micros();
  Serial.print(" BMP   :       ");  Serial.println(t1-t0);
  delay(2000);
  
  t0 = micros();
  for (int i = 0; i < 128; i++){
    int j = (int)(sin(i*0.09 + 0.2)*35) + 45;
    LD.VertBar(i, j, 0, 90);
  }
  t1 = micros();
  Serial.print(" VertBar :     ");  Serial.println(t1-t0);
  delay(2000);
  
  int n0 = 123;
  int n1 = -321;
  float d0 = 456.789;
  float d1 = -0.00789;
  t0 = micros();
  LD.printNumber((long)n0, 0, 0);  // 123
  LD.printNumber((long)n1, 0, 2); // -321
  LD.SetInverseText();
  LD.printNumber(d0, 6, 60, 2);     // 456.789
  LD.SetNormalText();
  LD.printNumber(-d0, 6, 48, 0);   // -456.789
  LD.printNumber(d1, 8, 0, 6);     // 0.00789
  LD.printNumber((long)10, 28, 4);        // 10
  LD.printString("3"); //, 0, 4);  // ^3
  LD.printString("="); //, 0, 4); // =
  LD.printNumber((long)1000); //, 0, 4);  // 1000
  t1 = micros();
  Serial.print(" Numbers :     ");  Serial.println(t1-t0);
  delay(2000);
  t0 = micros();
  LD.clearDisplay();
  t1 = micros();
  Serial.print("FillScreen:    ");  Serial.println(t1-t0);
//  t0 = micros();
  for(byte i = 0; i < 5; i++)
    LD.drawBitmap(pill,  26 + i*24, 1); //, 5, 8);
    
  t0 = micros();
  LD.drawBitmap(Logo_BMP, 100, 5); //, 16,16); //, 16, 2);
  t1 = micros();
  Serial.print("BMP 16*16 PGM: ");  Serial.println(t1-t0);
  
  t0 = micros();
  LD.drawBitmap(Logo_BMP_M, 50, 5); //, 16,16); //, 16, 2);
  t1 = micros();
  Serial.print("BMP 16*16 RAM: ");  Serial.println(t1-t0);
  
  for(byte i = 3; i < 108; i++) {
    byte phase = i & 3;
    if (phase == 3) phase = 1;
    LD.drawBitmap(pacman_clear,    i-3, 0,  2, 24);
    LD.drawBitmap(&pacman[phase*60], i, 0, 20, 24);
    delay(60);
  }      
  delay(2000);
}



файл ASM12864.h

/*
  ASM12864.h - JLX12864G-086 128x64 SPI Driver Library
  ver. 0.1

  2021 Copyright (c) Sergey Andrianov

  Please, do not distribute this library. 
  It is not ready yet. Work is not complete. 
  It is a preliminary variant exceptionally for testing.
*/

#include <SPI.h>

#ifndef ASM12864_data_H
#define ASM12864_data_H

#include <Arduino.h>

#define ASM12864_Max_X				128	//128 Pixels
#define ASM12864_Max_Y				64	//64  Pixels

class ASM12864 {

public:
  void init();
  void printString(const char *String, byte X=255, byte Y=255);  // font 6x8, switch CurrFont to Font_6x8
  void printString(const __FlashStringHelper *ifsh, byte X=255, byte Y=255);  // font 6x8, switch CurrFont to Font_6x8 - text in PROGMEM

  byte printNumber(long n, byte X=255, byte Y=255); // current font
  byte printNumber(float float_num, byte prec=6, byte Y=255, byte numChar=255); // current font
  void drawBitmap(byte *bitmaparray, byte X, byte Y, byte width=255, byte height=255); // X - in 1 pixel, Y - in 8 pixels
  void drawBitmap(const byte *bitmaparray, byte X, byte Y, byte width=255, byte height=255); // X - in 1 pixel, Y - in 8 pixels unit
  void VertBar(int Num, int Val, int MinVal, int MaxVal); // draw vertical line from bottom, h ~ (Val - MinVal)/(MaxVal - MinVal)
  void clearDisplay();
	
  void setCursorXY(byte Column, byte Row); // X * 1 pixels, Y * 8 pixels
  byte GetCurrentX();  // get current X position in 1-pixel unit (from 9 to 127)
  byte GetCurrentY();  // get current Y position in 8-pixel unit (from 0 to 7)

  void SetInverseText(); // next string will draw inverse
  void SetNormalText(); // next string will draw normal
  void sendCommand(byte command);

private:
  void sendData(byte Data);

  void printChar(char c);

  char NumberString[16]; // 4 print numbers
  byte LenString = 0;   // current length of NumberString
  byte CurrX = 0;   // current position
  byte CurrY = 0;
  byte textMode = 0; // 0 for normal text? 0xff for inverse text
};

extern ASM12864 LD;  // ASM12864 object 

#endif

файл ASM12864.cpp

#include "ASM12864.h"
#include <avr/pgmspace.h>
#include "a_Small_Rus.c"

#define  csPIN  10  // CS   POTRB  0x04
#define rstPIN   8  // RST  POTRB  0x01
#define  rsPIN   9  // RS   POTRB  0x02
#define sckPIN  13  // SCK  POTRB  0x20
#define sdaPIN  11  // SDA  POTRB  0x08

#define LCD_CMD 0
//#define LCD_D HIGH

inline void CS_ON()   {  PORTB &= 0xfb; } //digitalWrite(csPIN, LOW);     }
inline void CS_OFF()  {  PORTB |= 0x04; } //digitalWrite(csPIN, HIGH);    }
inline void CMD_ON()  {  PORTB &= 0xfd; } //digitalWrite(rsPIN, LCD_CMD); }
inline void DATA_ON() {  PORTB |= 0x02; } //digitalWrite(rsPIN, LCD_D);   }

void LcdWrite(byte dc, byte data)
{
  digitalWrite(rsPIN, dc);
  CS_ON();
  SPI.transfer(data);
  CS_OFF();
}


//==========================================================

unsigned char ASA_utf8_preliminary_byte = 0;

inline void ASM12864::sendData(byte data){
  SPI.transfer(data);
}

unsigned char RecodeUTF_ASA(unsigned char c)
{
	switch (c)
	{
	case (unsigned char)0xD0:
		ASA_utf8_preliminary_byte = c; // wait second byte
		return 255;
	case (unsigned char)0xD1:
		ASA_utf8_preliminary_byte = c; // wait second byte
		return 255;
  case (unsigned char)0xD2:
    ASA_utf8_preliminary_byte = c; // wait second byte
    return 255;
  case (unsigned char)0xC2:
    ASA_utf8_preliminary_byte = c; // wait second byte
    return 255;
	default:
		if(ASA_utf8_preliminary_byte == 0) // first half of ASCII table or nonsupported symbol
		{
			if((c >= ' ') && (c <= '~')) {
				return c;
			}else{
				return '*';
			}
		}
		else if(ASA_utf8_preliminary_byte == 0xD0) //
		{
			ASA_utf8_preliminary_byte = 0;
			if((c >= 144) && (c <= 191))	{
				return c - 17;
			} else if (c == 129) { // Ё
				return 191;
      } else if (c == 131) { // Ѓ
        return 193;
      } else if (c == 132) { // Є
        return 195;
      } else if (c == 134) { // І
        return 197;
      } else if (c == 135) { // Ї
        return 199;
      } else if (c == 142) { // Ў
        return 201;
			} else {
				return '*';
			}
		}
		else if(ASA_utf8_preliminary_byte == 0xD1) //
		{
			ASA_utf8_preliminary_byte = 0;
			if((c >= 128) && (c <= 143)){
				return c + 47;
			} else if (c == 145) { // ё
				return 192;
      } else if (c == 147) { // ѓ
        return 194;
      } else if (c == 148) { // є
        return 196;
      } else if (c == 150) { // і
        return 198;
      } else if (c == 151) { // ї
        return 200;
      } else if (c == 158) { // ў
        return 202;
			} else {
				return '*';
			}
		}
    else if(ASA_utf8_preliminary_byte == 0xD2) //
    {
      ASA_utf8_preliminary_byte = 0;
      if (c == 144) { // Ґ
        return 203;
      } else if (c == 145) { // ґ
        return 204;
      } else {
        return '*';
      }
    }
    else if(ASA_utf8_preliminary_byte == 0xC2) //
    {
      ASA_utf8_preliminary_byte = 0;
      if (c == 167) { // §
        return 205;
      } else if (c == 176) { // °
        return 206;
      } else if (c == 177) { // ±
        return 207;
      } else if (c == 181) { // µ
        return 208;
      } else {
        return '*';
      }
    }
		else {
			return '*';
		}
	}
}

// ====================== LOW LEVEL =========================

void ASM12864::printChar(char C){ // write to temp string for numbers
  NumberString[LenString++] = C;
  NumberString[LenString] = 0;
}

void ASM12864::printString(const char *String, byte X, byte Y){
  CS_ON();
  setCursorXY(X, Y);
	while(*String){
		unsigned char c = RecodeUTF_ASA(*String++);
		if (c != 255) {                   //			printChar6(c);
      SPI.transfer(textMode);
      for(byte i=0; i<5; i++)
        SPI.transfer(pgm_read_byte(&SmallFont[(c-32)*(int)5 + i + 4])^textMode);
      CurrX += 6;
		}
	}
  CS_OFF();
}

void ASM12864::printString(const __FlashStringHelper *ifsh, byte X, byte Y){
  PGM_P p = reinterpret_cast<PGM_P>(ifsh);
  CS_ON();
  setCursorXY(X, Y);
  while(pgm_read_byte(p)){
    unsigned char c = RecodeUTF_ASA(pgm_read_byte(p++));
    if (c != 255) {                   //      printChar6(c);
      SPI.transfer(textMode);
      for(byte i=0; i<5; i++)
        SPI.transfer(pgm_read_byte(&SmallFont[(c-32)*(int)5 + i + 4])^textMode);
      CurrX += 6;
    }
  }
  CS_OFF();
}

byte ASM12864::printNumber(long long_num, byte X, byte Y){
  LenString = 0;
  CS_ON();
	setCursorXY(X, Y);
	byte char_buffer[10] = "";
	byte i = 0;
	byte f = 0; // number of characters
	if (long_num < 0) {
		f++;
		printChar('-');
		long_num = -long_num;
	} 
	else if (long_num == 0) {
		f++;
		printChar('0');
    printString(&NumberString[0]); //, X, Y);
    CS_OFF();
		return f;
	} 
	while (long_num > 0) {
		char_buffer[i++] = long_num % 10;
		long_num /= 10;
	}
	f += i;
	for(; i > 0; i--) 
		printChar('0'+ char_buffer[i - 1]);
  printString(&NumberString[0]); //, X, Y);
  CS_OFF();
	return f;
}

byte ASM12864::printNumber(float float_num, byte prec, byte X, byte Y){
  LenString = 0;
  CS_ON();
	setCursorXY(X, Y);
// prec - 6 maximum
	byte num_int = 0;
	byte num_frac = 0;
	byte num_extra = 0;
	long d = float_num; // get the integer part
	float f = float_num - d; // get the fractional part
	if (d == 0 && f < 0.0){
		printChar('-');
		num_extra++;
		printChar('0');
		num_extra++;
		f *= -1;
    printString(&NumberString[0]);
    LenString = 0;
	}
	else if (d < 0 && f < 0.0){
		num_int = printNumber(d);  // count how many digits in integer part
    LenString = 0;
		f *= -1;
	}
	else{
		num_int = printNumber(d);  // count how many digits in integer part
    LenString = 0;
	}
	// only when fractional part > 0, we show decimal point
	if (f > 0.0){
		printChar('.');
		num_extra++;
    printString(&NumberString[0]); //, X, Y);
    LenString = 0;
		if (num_int + prec > 8) 
			prec = 8 - num_int;
    for (byte j=0; j<prec; j++){
      f *= 10.0;
      byte dd = f;
      printChar('0' + dd);
      f -= dd;
    }
    printString(&NumberString[0]);
    num_frac = prec;
	}
  CS_OFF();
	return num_int + num_frac + num_extra;
}

void ASM12864::drawBitmap(byte *bitmaparray, byte X, byte Y, byte width=255, byte height=255){
  if(height == 255){
    width  = bitmaparray[0];
    height = bitmaparray[1];
  }
  height /= 8;
//  Serial.print("RAM.w: "); Serial.print(width); Serial.print(", h: "); Serial.println(height);
  unsigned char *address; //pointer
  address=&bitmaparray[4]; //data pointer:point to "graphic[]",one-dimension array
  CS_ON();
  for(byte j = 0; j < height; j++)
  {
    setCursorXY(X, Y + j);
    for(byte i = 0; i < width; i++) {
      SPI.transfer(bitmaparray[i + 4 + j*width]);
//      SPI.transfer(*address);
//      address++;
    }
  }
  CS_OFF();
}

//void ASM12864::drawBitmap(PGM_VOID_P bitmaparray, byte X, byte Y){
void ASM12864::drawBitmap(const byte * bitmaparray, byte X, byte Y, byte width = 255, byte height = 255){
  if(height == 255){
    width  = pgm_read_byte(bitmaparray);
    height = pgm_read_byte(bitmaparray + 1);
  }
  height /= 8;
//  Serial.print("Fl.w: "); Serial.print(width); Serial.print(", h: "); Serial.print(height); 
//  Serial.print(", addr: "); Serial.println((uint16_t)bitmaparray);
  CS_ON();
  for (byte j = 0; j <  height; j++) {
    setCursorXY(X, Y + j);
    for (byte i = 0; i < width; i++)    {
      SPI.transfer(pgm_read_byte(bitmaparray + i + 4 + j*width));
    }
  }
  CS_OFF();
}

void ASM12864::VertBar(int Num, int Val, int MinVal, int MaxVal)
{
	if (Val < MinVal) Val = MinVal;            // consider that Val already scaled
	if (Val > MaxVal) Val = MaxVal;
	Val -= MinVal;
  CS_ON();
  for (int i = 0; i < 8; i++) {             // go from high levels to low ones
		setCursorXY(Num, i);
    int b;                                   // will calc this value for each columns (bars)
		int UpB = (MaxVal - MinVal)*(8-i)/8;
    if (Val <= UpB) {                         // top boundary
			int DownB = (MaxVal - MinVal)*(7-i)/8;
      if (Val >= DownB) {                     // bottom boundary
				int j = (Val - DownB)*8/(UpB - DownB);
				int k = 0xFF00;
				b = (k >> j) & 0xFF;
			} else {
				b = 0;
			}
		} else {
			b = 0xFF;
		}
		sendData(b);
	}
  setCursorXY(0, 0);
  CS_OFF();
}

// =================== High Level ===========================

void ASM12864::init(){
  pinMode(csPIN,  OUTPUT);
  pinMode(rstPIN, OUTPUT);
  pinMode(rsPIN,  OUTPUT);
  pinMode(sdaPIN, OUTPUT);
  pinMode(sckPIN, OUTPUT);
  SPI.begin();
  SPI.beginTransaction (SPISettings(8000000, MSBFIRST, SPI_MODE0));
  digitalWrite(rstPIN, LOW);
  delay(50);
  digitalWrite(rstPIN, HIGH);
  delay(50);
  LcdWrite(LCD_CMD, 0xe2); // Soft Reset
  LcdWrite(LCD_CMD, 0x2c); // Boost 1
  LcdWrite(LCD_CMD, 0x2e); // Boost 2
  LcdWrite(LCD_CMD, 0x2f); // Boost 3
  LcdWrite(LCD_CMD, 0x23); // Coarse Contrast, setting range is from 20 to 27
  LcdWrite(LCD_CMD, 0x81); // Trim Contrast
  LcdWrite(LCD_CMD, 0x28); // Trim Contrast value range can be set from 0 to 63
  LcdWrite(LCD_CMD, 0xa2); // 1/9 bias ratio
  LcdWrite(LCD_CMD, 0xc8); // Line scan sequence : from top to bottom
  LcdWrite(LCD_CMD, 0xa0); // Column scanning order : from left to right
  LcdWrite(LCD_CMD, 0xaf); // Open the display
  CurrX = -1;
  CurrY = -1;
}

void ASM12864::setCursorXY(byte X, byte Y){
// Y - 1 unit = 1 page (8 pixel rows)
// X - 1 unit = 1 pixel columns
  if (X < 128)
    if ((X != CurrX) || (Y != CurrY)){
      CMD_ON();
      SPI.transfer(0xb0+Y);
      SPI.transfer(0x10+((X>>4)&0x0f));
      SPI.transfer(0x00+(X&0x0f));
      DATA_ON();
      CurrX = X;
      CurrY = Y;
    }
}

void ASM12864::clearDisplay()	{
  unsigned int i,j;
  CS_ON();
  for(i=0;i<8;i++)
  {
    CMD_ON();
    SPI.transfer(0xb0+i);
    SPI.transfer(0x10);
    SPI.transfer(0x00);
    DATA_ON();
    for(j=0;j<132;j++)
    {
      SPI.transfer(0x00);
    }
  }
  CS_OFF();
}
  

/*=========================================*/


void ASM12864::SetInverseText() // next string will draw inverse
{
  textMode = 0xff;  
}

void ASM12864::SetNormalText() // next string will draw normal
{
  textMode = 0;  
}

ASM12864 LD;  // Preinstantiate Objects

Все написано для Uno/Nano/Mini. 

Пока это черновой вариант.

И, кстати, дисплейчик не подходит для динамичных игрушек - слишком медленно переключаются кристаллы - за 60 мс явно не успевает.

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

andriano пишет:

И, кстати, дисплейчик не подходит для динамичных игрушек - слишком медленно переключаются кристаллы - за 60 мс явно не успевает.

Однако игры на нем идут))) И вполне играбельно. Вот я подключил дисплей и загрузил игрушку:

https://www.youtube.com/watch?v=hZoALSgG3qo

Кстати, а есть более быстрые дисплеи до 350 рублей?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Заметно "мажет". Особенно заметно при движении горизонтального отрезка (расплываются края) и окружности по горизонтали (фрагменты перпендикулярные движению почти полностью исчезают).

На всякий случай видео с тем скетчем, что я выложил: https://youtu.be/VZiHPJZfkls

Там единственная подвижная сцена - пакман. Особенно заметно, что смазывается движение челюстями.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Добавил 3 подвижных окружности: 15fps, 30fps и 60fps. Вторая - еле видна, а третью вообще практически не видно.

Видео: https://youtu.be/6_Olwjy3jEM

Скетч:

//    JLX12864G-086 (Graphic LCD 128x64)
//   LEDA : +3.3V,  VDD : +3.3V,  VSS: GND

#include <SPI.h>
#include "ASM12864.h"

//const int  csPIN  = 10; // CS
//const int rstPIN  = 8;  // RST
//const int  rsPIN  = 9;  // RS
//const int sckPIN = 13;  // SCK
//const int sdaPIN = 11;  // SDA

const byte PROGMEM graphic1[1028]={
  128, 64, 0xff, 1,
0xf0, 0xf8, 0x6c, 0x6c, 0x6c, 0x78, 0x70, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xf0, 0xf8, 0x6c, 
0x6c, 0x6c, 0x78, 0x70, 0x00, 0x00, 0xf0, 0xf8, 0x0c, 0x0c, 0x9c, 0x98, 0x00, 0x0c, 0xfe, 0xff, 
0x0c, 0x0c, 0x00, 0xf0, 0xf8, 0x9c, 0x0c, 0x9c, 0xf8, 0xf0, 0x00, 0x00, 0xf0, 0xf8, 0x9c, 0x0c, 
0x98, 0xff, 0xff, 0x00, 0x00, 0x88, 0xcc, 0x6c, 0x2c, 0xfc, 0xf8, 0x00, 0x0c, 0xfc, 0xf0, 0x00, 
0xf0, 0xfc, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 
0xe0, 0x30, 0x10, 0x08, 0x0c, 0x04, 0x04, 0x02, 0x06, 0x03, 0x11, 0x41, 0x01, 0x01, 0x01, 0x07, 
0x11, 0x21, 0x41, 0x41, 0x81, 0x81, 0x01, 0x02, 0x82, 0x80, 0x44, 0x1c, 0x08, 0x90, 0x60, 0x20, 
0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01, 0x03, 
0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x01, 0x03, 
0x03, 0x03, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 
0x01, 0x03, 0x03, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x01, 0x03, 0x02, 0x00, 0x10, 0x1f, 0x1f, 
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xb8, 0x8c, 0x83, 0x00, 
0x00, 0x03, 0x04, 0x00, 0x88, 0x48, 0x08, 0x28, 0x28, 0x08, 0x04, 0x42, 0x41, 0x80, 0x00, 0x00, 
0xf8, 0x04, 0x02, 0x02, 0x02, 0x02, 0x04, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x81, 0x86, 0x88, 
0x88, 0x90, 0x13, 0x14, 0x18, 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

0xfc, 0x04, 0x04, 0x04, 0x04, 0x04, 0xfc, 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, 
0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 
0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x9f, 0x01, 0x00, 0x00, 0x00, 0x81, 
0x22, 0x20, 0x80, 0x8f, 0x70, 0x20, 0x20, 0x20, 0xe0, 0x10, 0x10, 0x10, 0x10, 0x79, 0x92, 0x00, 
0x08, 0x11, 0x13, 0xd2, 0x12, 0x10, 0x12, 0xe2, 0x21, 0x00, 0x1e, 0x11, 0xe0, 0x20, 0x10, 0x10, 
0x10, 0x00, 0x00, 0x8a, 0x98, 0x70, 0x10, 0x01, 0xe5, 0x06, 0x0c, 0xf0, 0x00, 0x00, 0x00, 0x00, 

0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
0x08, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x01, 0xf1, 0x11, 0x01, 0x82, 0x44, 0x38, 0x00, 0x00, 
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xd0, 0x21, 0xe1, 0xf1, 0x0c, 0x86, 
0x83, 0x09, 0x10, 0x21, 0x22, 0x44, 0x48, 0x08, 0xf0, 0x91, 0x0c, 0x04, 0x04, 0x04, 0x03, 0x02, 
0x02, 0x02, 0x83, 0xc3, 0x82, 0x82, 0x03, 0x02, 0x00, 0x04, 0x02, 0x19, 0x78, 0x48, 0x44, 0x44, 
0xd2, 0x32, 0x71, 0x71, 0x38, 0x38, 0x1c, 0x12, 0x09, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 
0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x7f, 0x7f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x44, 0xc4, 0xc5, 0x05, 
0x9e, 0x3e, 0xee, 0x27, 0x46, 0xf7, 0xff, 0xf6, 0xf3, 0x08, 0x00, 0x04, 0x7e, 0xff, 0xe7, 0xfe, 
0xfd, 0x97, 0x83, 0x83, 0xfe, 0xfc, 0xff, 0xfb, 0xff, 0x03, 0x01, 0x01, 0x07, 0x1f, 0x32, 0x8c, 
0x06, 0xfe, 0x27, 0x03, 0x68, 0x1c, 0xcc, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0xfe, 0x80, 0x00, 0x84, 0xc2, 0xa2, 
0x92, 0x8c, 0x00, 0x6c, 0x92, 0x92, 0x92, 0x6c, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 0x00, 0x78, 
0x94, 0x92, 0x92, 0x60, 0x00, 0x30, 0x28, 0x24, 0xfe, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x47, 0x5e, 0x24, 0xc8, 0x89, 0x9e, 
0x38, 0x01, 0xc7, 0x2e, 0x60, 0xe1, 0xe7, 0x3c, 0x07, 0x00, 0xc0, 0xf0, 0xb8, 0xfc, 0xfc, 0x0c, 
0x0d, 0xfd, 0xf9, 0xe1, 0x81, 0x81, 0x7c, 0x2c, 0x46, 0x46, 0x76, 0x7c, 0x78, 0x80, 0x80, 0x00, 
0x0f, 0xe0, 0x40, 0xdf, 0x0e, 0x00, 0x33, 0x1c, 0xc4, 0x74, 0x3a, 0x0e, 0x86, 0xc2, 0xc2, 0x80, 

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x60, 0xf0, 0xf8, 0x60, 0x60, 0x00, 
0x80, 0xc0, 0x60, 0x60, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x60, 0xe0, 0xc0, 0x00, 
0x00, 0xf8, 0xf8, 0xc0, 0x60, 0x60, 0xe0, 0xc0, 0x00, 0x00, 0xc0, 0xe0, 0x60, 0x60, 0x60, 0x40, 
0x00, 0x60, 0xf0, 0xf8, 0x60, 0x60, 0x00, 0x80, 0xc0, 0x60, 0x60, 0x60, 0xc0, 0x80, 0x00, 0x00, 
0xe0, 0xe0, 0xc0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x02, 0x03, 0x01, 0x01, 0x7f, 0xdd, 0xed, 0x6d, 
0x67, 0xe7, 0x67, 0x93, 0x0e, 0x7f, 0x80, 0x00, 0x00, 0x80, 0x9f, 0xff, 0xcd, 0xc3, 0xff, 0x60, 
0xf0, 0xff, 0xd7, 0xff, 0xf8, 0x81, 0xc3, 0x61, 0x64, 0x65, 0xad, 0x2d, 0x6f, 0xc5, 0x80, 0x60, 
0x18, 0x8f, 0xbe, 0x7d, 0x4c, 0x4e, 0x4f, 0x4f, 0xd9, 0xf1, 0x3e, 0x01, 0x00, 0x00, 0x00, 0x00, 

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x1f, 0x18, 0x18, 0x00, 
0x07, 0x0f, 0x1b, 0x1b, 0x1b, 0x1b, 0x0b, 0x00, 0x00, 0x07, 0x0f, 0x18, 0x18, 0x1c, 0x0c, 0x00, 
0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x09, 0x1b, 0x1b, 0x1b, 0x1f, 0x0e, 
0x00, 0x00, 0x0f, 0x1f, 0x18, 0x18, 0x00, 0x07, 0x0f, 0x1b, 0x1b, 0x1b, 0x1b, 0x0b, 0x00, 0x00, 
0xff, 0xff, 0x0c, 0x18, 0x1c, 0x0f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x16, 
0x22, 0x22, 0x02, 0x41, 0x61, 0x61, 0x24, 0x85, 0xf3, 0x9b, 0xa0, 0x81, 0x82, 0x9b, 0x8d, 0x84, 
0xb4, 0xd4, 0x80, 0x88, 0xb0, 0xb3, 0xb2, 0x88, 0x1d, 0x0c, 0x4c, 0x54, 0x44, 0x45, 0x47, 0x40, 
0x42, 0x42, 0x03, 0x22, 0x24, 0x24, 0x13, 0x16, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

const byte PROGMEM Logo_BMP[36] = {
  0x10, 0x10, 0xff, 0x01,
  B00000000,  B00000001,  B00000001,  B00000011,  B11110011,  B11111110,  B01111110,  B00110011,
  B00011111,  B00001101,  B00011011,  B00111111,  B00111111,  B01111100,  B01110000,  B00000000,
  B11000000,  B11000000,  B11000000,  B11100000,  B11100000,  B11111000,  B11111111,  B10011111,
  B11111100,  B01110000,  B10100000,  B11100000,  B11110000,  B11110000,  B01110000,  B00110000 };

byte Logo_BMP_M[36] = {
  0x10, 0x10, 0xff, 0x01,
  B00000000,  B00000001,  B00000001,  B00000011,  B11110011,  B11111110,  B01111110,  B00110011,
  B00011111,  B00001101,  B00011011,  B00111111,  B00111111,  B01111100,  B01110000,  B00000000,
  B11000000,  B11000000,  B11000000,  B11100000,  B11100000,  B11111000,  B11111111,  B10011111,
  B11111100,  B01110000,  B10100000,  B11100000,  B11110000,  B11110000,  B01110000,  B00110000 };

const byte PROGMEM pacman[184] = {
  0x14, 0x18, 0xff, 0x03,
0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3E, 0x1C,   // 0x0010 (16) pixels
0x0C, 0x00, 0x00, 0x00, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9,   // 0x0020 (32) pixels
0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F,   // 0x0030 (48) pixels
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x03, 0x00, 0x00, 0x00, 

0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x7C,   // 0x0010 (16) pixels
0x7C, 0x38, 0x20, 0x00, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9,   // 0x0020 (32) pixels
0xF9, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F,   // 0x0030 (48) pixels
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x03, 0x01, 0x00, 0x00, 

0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFC,   // 0x0010 (16) pixels
0xF8, 0xF0, 0xE0, 0x80, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0020 (32) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xF9, 0x79, 0x19, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F,   // 0x0030 (48) pixels
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 
};   

const byte PROGMEM pacman_clear[10] = {
  0x03, 0x18, 0x00, 0x01,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

const byte PROGMEM pill[9] = {
  0x05, 0x08, 0x00, 0x01,      0x0E, 0x1F, 0x1F, 0x1F, 0x0E};

byte pill_0[] ={
  0x05, 0x08, 0x00, 0x01,      0x0E, 0x1F, 0x1F, 0x1F, 0x0E};

const byte PROGMEM circle[20] = {
  0x10, 0x08, 0x00, 0x01,      0,0,0,0,0x1c,0x22, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, 0, 0, 0, 0};

void setup() {
  Serial.begin(115200);
  Serial.println("Start JLX12864G-086");
  LD.init();
  LD.clearDisplay();
  delay(10);
}

inline void putPixel(uint8_t x, uint8_t y) { // ~4us
//  graphic1[128*(y >> 3) + x + 4] |= 1 << (y & 7);
}

void loop() {
  uint32_t t0 = micros();
  for(byte i = 0; i < 64; i++) putPixel(i,i);
  for(byte i = 0; i < 64; i++) putPixel(64+i,63-i);
  for(byte i = 0; i < 64; i++) putPixel(i,63-i);
  for(byte i = 0; i < 64; i++) putPixel(64+i,i);
  uint32_t t1 = micros();
  Serial.print("128 putPixel:  ");  Serial.println(t1-t0);

  t0 = micros();
  LD.printString(F("0123456789!\"#$%&'()*+"), 0, 0);
  LD.printString(F(",-./:;<=>?@[\\]^_`{|}~"), 0, 1);
  LD.printString(F("ABCDEFGHIJKLMNOPQRSTU"), 0, 2);
  LD.printString(F("VWXYZabcdefghijklmnop"),0, 3);
  LD.printString(F("qrstuvwxyzАБВГДЕЁЖЗИЙ"), 0, 4);
  LD.printString(F("КЛМНОПРСТУФХЦЧШЩЪЫЬЭЮ"), 0, 5);
  LD.printString(F("Яабвгдеёжзийклмнопрст"), 0, 6);
  LD.printString(F("уфхцчшщъыьэюяЇїЎў§°±µ"), 0, 7);
  t1 = micros();
  Serial.print("Draw Text:     ");  Serial.println(t1-t0);
  delay(2000);

  LD.SetInverseText();

  t0 = micros();
  LD.printString(F("0123456789!\"#$%&'()*+"), 0, 0);
  LD.printString(F(",-./:;<=>?@[\\]^_`{|}~"), 0, 1);
  LD.printString(F("ABCDEFGHIJKLMNOPQRSTU"), 0, 2);
  LD.printString(F("VWXYZabcdefghijklmnop"),0, 3);
  LD.printString(F("qrstuvwxyzАБВГДЕЁЖЗИЙ"), 0, 4);
  LD.printString(F("КЛМНОПРСТУФХЦЧШЩЪЫЬЭЮ"), 0, 5);
  LD.printString(F("Яабвгдеёжзийклмнопрст"), 0, 6);
  LD.printString(F("уфхцчшщъыьэюяЇїЎў§°±µ"), 0, 7);
  t1 = micros();
  Serial.print("Draw Text:     ");  Serial.println(t1-t0);
  delay(2000);

  t0 = micros();
  LD.drawBitmap(graphic1, 0, 0); // X - in 1 pixel, Y - in 8 pixels
  t1 = micros();
  Serial.print(" BMP   :       ");  Serial.println(t1-t0);
  delay(2000);
  
  t0 = micros();
  for (int i = 0; i < 128; i++){
    int j = (int)(sin(i*0.09 + 0.2)*35) + 45;
    LD.VertBar(i, j, 0, 90);
  }
  t1 = micros();
  Serial.print(" VertBar :     ");  Serial.println(t1-t0);
  delay(2000);
  
  int n0 = 123;
  int n1 = -321;
  float d0 = 456.789;
  float d1 = -0.00789;
  t0 = micros();
  LD.printNumber((long)n0, 0, 0);  // 123
  LD.printNumber((long)n1, 0, 2); // -321
  LD.SetInverseText();
  LD.printNumber(d0, 6, 60, 2);     // 456.789
  LD.SetNormalText();
  LD.printNumber(-d0, 6, 48, 0);   // -456.789
  LD.printNumber(d1, 8, 0, 6);     // 0.00789
  LD.printNumber((long)10, 28, 4);        // 10
  LD.printString("3"); //, 0, 4);  // ^3
  LD.printString("="); //, 0, 4); // =
  LD.printNumber((long)1000); //, 0, 4);  // 1000
  t1 = micros();
  Serial.print(" Numbers :     ");  Serial.println(t1-t0);
  delay(2000);
  t0 = micros();
  LD.clearDisplay();
  t1 = micros();
  Serial.print("FillScreen:    ");  Serial.println(t1-t0);
  for(byte i = 0; i < 5; i++)
    LD.drawBitmap(pill,  26 + i*24, 1); //, 5, 8);
    
  t0 = micros();
  LD.drawBitmap(Logo_BMP, 100, 6); //, 16,16); //, 16, 2);
  t1 = micros();
  Serial.print("BMP 16*16 PGM: ");  Serial.println(t1-t0);
  
  t0 = micros();
  LD.drawBitmap(Logo_BMP_M, 50, 6); //, 16,16); //, 16, 2);
  t1 = micros();
  Serial.print("BMP 16*16 RAM: ");  Serial.println(t1-t0);

  int xc1 = 0, xc2 = 0, xc4 = 0;
  int dxc1 = 1, dxc2 = 1, dxc4 = 1;
  for(byte i = 3; i < 108; i++) {
    byte phase = i & 3;
    if (phase == 3) phase = 1;
    LD.drawBitmap(pacman_clear,    i-3, 0,  2, 24);
    LD.drawBitmap(&pacman[phase*60], i, 0, 20, 24);
    LD.drawBitmap(circle, xc1, 3);
    xc1 += dxc1;
    if(xc1 > 112) { xc1 = 112; dxc1 = -dxc1; }
    if(xc1 < 0)   { xc1 = 0;   dxc1 = -dxc1; }
    LD.drawBitmap(circle, xc2, 4);
    xc2 += dxc2;
    if(xc2 > 112) { xc2 = 112; dxc2 = -dxc2; }
    if(xc2 < 0)   { xc2 = 0;   dxc2 = -dxc2; }
    LD.drawBitmap(circle, xc4, 5);
    xc4 += dxc4;
    if(xc4 > 112) { xc4 = 112; dxc4 = -dxc4; }
    if(xc4 < 0)   { xc4 = 0;   dxc4 = -dxc4; }
    delay(15);

    LD.drawBitmap(circle, xc4, 5);
    xc4 += dxc4;
    if(xc4 > 112) { xc4 = 112; dxc4 = -dxc4; }
    if(xc4 < 0)   { xc4 = 0;   dxc4 = -dxc4; }
    delay(15);

    LD.drawBitmap(circle, xc2, 4);
    xc2 += dxc2;
    if(xc2 > 112) { xc2 = 112; dxc2 = -dxc2; }
    if(xc2 < 0)   { xc2 = 0;   dxc2 = -dxc2; }
    LD.drawBitmap(circle, xc4, 5);
    xc4 += dxc4;
    if(xc4 > 112) { xc4 = 112; dxc4 = -dxc4; }
    if(xc4 < 0)   { xc4 = 0;   dxc4 = -dxc4; }
    delay(15);

    LD.drawBitmap(circle, xc4, 5);
    xc4 += dxc4;
    if(xc4 > 112) { xc4 = 112; dxc4 = -dxc4; }
    if(xc4 < 0)   { xc4 = 0;   dxc4 = -dxc4; }
    delay(15);

  }      
  delay(2000);
}

 

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

andriano пишет:

Добавил 3 подвижных окружности: 15fps, 30fps и 60fps. Вторая - еле видна, а третью вообще практически не видно.

А в чем проблема? Все равно лучше нету за такую цену.

Вы что предлагаете?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Что я предлагаю?

Лично я брал эти дисплейчики для использования в качестве вспомогательных. Т.е. не составляющих основную функцию прибора. Фактически, для вывода текста. 

lilik
Offline
Зарегистрирован: 19.10.2017

Интересно, а шкалы со стрелками - потянет имитацию движений экран такой (всё никак не решусь метнуть 350 Р в пробы)?

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

lilik пишет:

Интересно, а шкалы со стрелками - потянет имитацию движений экран такой (всё никак не решусь метнуть 350 Р в пробы)?

Мое видео смотрели?

Вполне видно будет. Можно сделать след (аналог следа в Windows) для большей видимости стрелок.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Что-то везде указано, что дисплей 3.3-вольтовый, а подключают его, я смотрю, к 5-вольтовым AVR.

Это через конвертеры уровня или напрямую?

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

andriano пишет:

Что-то везде указано, что дисплей 3.3-вольтовый, а подключают его, я смотрю, к 5-вольтовым AVR.

Это через конвертеры уровня или напрямую?

Написано же четко:

>> Напряжение: 3,3 V

https://aliexpress.ru/item/1005001621784395.html

Я подключал к 3.3 вольтовому пину Ардуинки. И нигде не видел, чтобы к пяти подключали.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А остальные выводы (CS, RS, RST, SDA, SCK)? На них ведь тоже 5В.

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

andriano пишет:

А остальные выводы (CS, RS, RST, SDA, SCK)? На них ведь тоже 5В.

На канале Ардуино Лаборатория ведущий сказал что они толерантны к обоим напряжениям. А вот питание только 3.3 вольта.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

khusamov пишет:

andriano пишет:

А остальные выводы (CS, RS, RST, SDA, SCK)? На них ведь тоже 5В.

На канале Ардуино Лаборатория ведущий сказал что они толерантны к обоим напряжениям.

А можно ссылочку?

Что-то в дэйташите я такого не обнаружил.

Нашел видео от arduinoLab https://www.youtube.com/watch?v=YwYkXSt6HfA , но там человек явно указывает, что питать от более чем 3.3В вероятнее всего приведет к выгоранию. По поводу толерантности входов - ничего, хотя экспериментирует с Nano, у которой как раз 5В.

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

andriano пишет:

А можно ссылочку?

Что-то в дэйташите я такого не обнаружил.

Нашел видео от arduinoLab https://www.youtube.com/watch?v=YwYkXSt6HfA , но там человек явно указывает, что питать от более чем 3.3В вероятнее всего приведет к выгоранию. По поводу толерантности входов - ничего, хотя экспериментирует с Nano, у которой как раз 5В.

Вы и сами нашли ссылку. 

Там используется нано у которой 5 вольт. Так что можно подавать 5 вольт?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Я не рискнул. Запустил от stm32, у которого везде по 3.3В.

khusamov
khusamov аватар
Offline
Зарегистрирован: 25.09.2013

andriano пишет:

Я не рискнул. Запустил от stm32, у которого везде по 3.3В.

Вот что пишут на просторах интернета:

Из особенностей дисплея следует отметить, что контроллер ST7735R работает с напряжением 3.3V, включая логику, но в жизни у всех прекрасно работает и на 5V без дополнительных резисторов. 

Думаю ST7735R почти такой как в сабже.

alek4613
Offline
Зарегистрирован: 04.09.2021

Здравствуйте. Друзья, помогите Христа ради подключить дисплей WO12864D3-TGK# к микроконтроллеру Atmega 328 на контроллере st7565p (?).  Если это возможно, могли бы вы набросать схему подключения? У меня есть рукописная схема подключения этого дисплея и обвязка к кассовому аппарату. Но там подключается к другому контроллеру (LPC1768FBD100). Какие нужны уточнения? Возможно ли на этом сайте загрузить изображение или скинуть на Email? Я не программист, готовлю материал в помощь для дальнейшей работы с программистом.

i?r=AzEPZsRbOZEKgBhR0XGMT1Rk2SO6oT4_7Z-Z

alek4613
Offline
Зарегистрирован: 04.09.2021

Жаль... Так никто и не отозвался.

Logik
Offline
Зарегистрирован: 05.08.2014

А на что ты рассчитывал? Картинку выложил так, что ниче не видно, дисплей не интересный никому, старый ч/б  128*64. Вон смотри что в тренде http://arduino.ru/forum/apparatnye-voprosy/lcd-ew24da3fly , там отзывы есть. А ковыряться в мертвечине не интересно. 

alek4613
Offline
Зарегистрирован: 04.09.2021

Уважаемый Logik, картинку тут лучшего качества не выложишь, это понятно. Во время конкретного диалога можно фото дать и получше. А насчёт мертвечины это вы зря. Зачем обидели железяку, она ещё может поработать?!  Я хотел с товарищем сделать 2-х канальный термометр на МК с применением датчиков DS18B20 на ЖК дисплее. Перепробовал несколько схем.  Вот эту например: автора : Vnnink (Виктора)   https://www.kt818.ru/index.php/proekty/izmeritelnaya-tekhnika/termometry/1-dvukhkanalnyj-termometr-na-pic16f628-i-lcd-nokia  Работает схема уже третий год без нареканий.  К сожалению автор этой конструкции по ряду причин отошёл от дел, а я хотел развить эту тему немного далее. Хочу сделать на более крупном индикаторе - WO12864D3-TGK от кассового аппарата MINI-T 400 МЕ и с применением специализированных модулей датчиков давления  BMP280 и часов DS3231 (только для календаря) и немного другим дизайном и желательно на AVR.  Почему именно этот индикатор, Цветные дисплеи это конечно хорошо и красиво. Ничего не скажешь. Дело в том, что у меня лежат несколько WO12864D3-TGK и ждут своего часа. (или места) И у меня нет особого смысла покупать дорогой дисплей.  Кстати, автор дал мне исходники своей программы. Только в данном случае они вряд ли пригодятся. Беда в том, что я совершенно не программист и постигать эту науку поздно — давно на пенсии. А теперь хочу термометр немного модернизировать. Товарищ похоже не потянул тему. И вот приходится искать  любителя-программиста, интересующегося подобной темой, который помог бы мне с программой в реализации подобной конструкции. Сама идея состоит сделать некое подобие настольной метеостанции с календарём на немного более крупном экране. В подарок даю дисплей, датчики часов, давления и температуры. Рисунок желаемого эскиза дисплея по желанию скину. Это суть в двух словах. А вот с предложением купить термометр в магазине просьба не обращаться.

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

alek4613, к слову, нет ничего сложного выложить сюда картинку нормального качества. То. что для вас это непосильная задача - просто показывает что вы не умеете искать информацию

Что касается задуманного проекта - если это хобби, такие вещи надо самому осваивать, а не дядю просить. Это, кстати, еще и полезно в пожилом возрасте. Если же кто-то это делает за вас - то смысл полностью теряется, тогда и правда проще в магазине купить

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

alek4613 пишет:
Сама идея состоит сделать некое подобие настольной метеостанции с календарём на немного более крупном экране. В подарок даю дисплей, датчики часов, давления и температуры. Рисунок желаемого эскиза дисплея по желанию скину. Это суть в двух словах. А вот с предложением купить термометр в магазине просьба не обращаться.

Можешь написать мне на elf-basic@yandex.ru  чотыхош.  Если немного, я тебе свою метеостанцию на этот экран переделаю. 

alek4613
Offline
Зарегистрирован: 04.09.2021

Вы меня весьма заинтриговали. Очень хотелось бы посмотреть как вы в семьдесят лет будете осваивать с нуля программирование. Я понимаю, что программа тут основное, но, далеко ещё не всё. Поэтому смысл не потеряется. Насчёт картинки согласен. Каюсь. :)) Сайт только нашёл, не изучал его.  Заметил, почти на всех сайтах попадаются сердитые люди, которых хлебом не корми, дай кого-то жизни поучить. Желаю вам дожить до моих лет и заниматься радиолюбительством. Анекдот есть на эту тему. Проходит мужик медпрофосмотр. Осталось терапевта пройти. Заходит, а там врач бабушка - божий одуванчик лет так за восемьдесят и спрашивает: что беспокоит?  Я ей говорю: - ничего, планирую прожить ещё лет 100 - 150. А она отвечает: - Вы, молодой человек, оптимист! Если проживёте столько лет, я вам первая пожму руку!  :) 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

alek4613 пишет:

Цветные дисплеи это конечно хорошо и красиво. Ничего не скажешь. Дело в том, что у меня лежат несколько WO12864D3-TGK и ждут своего часа. (или места) И у меня нет особого смысла покупать дорогой дисплей. 

Это, смотря в чем искать смысл.

Если хотите подешевле - смысл есть. Ибо самый дорогой дисплей, под который есть софт, окажется дешевле, чем бесплатный дисплей + работа программиста.

alek4613
Offline
Зарегистрирован: 04.09.2021

Ребята! Да я со всеми вашими доводами согласен. Не захочет никто помочь, ну, что ж... закрою проект. Я предложил, люди отказались. К чему нервничать, минуса ставить? В своё время было и бесплатно приходилось телевизоры ремонтировать. У нас это очень ценилось. Само собой ставить знак равенства между программированием и ремонтом телевизора нельзя, но любая помощь совершённая в нужный момент вещь ценная. Думаю, дискуссию нужно прекращать. 

sadman41
Offline
Зарегистрирован: 19.10.2016

Такое впечатление, что в России всех пенсионеров обязывают изучать программирование. Я вот тоже много чего хочу сделать, но если не по силам - не мучаюсь.

Чего вы вечно обиженных из себя строите? Можно подумать, что кому-то хочется глаза портить для постройки очередной метеостанции для удовлетворения любопытства абсолютно незнакомого человека. Или нужно целыми днями колотить по кнопками заради того, чтоб хорошим прослыть? Дурака работа любит... Я тоже дохрена бесплатно делал. Только кончалось это тем, что оказывалось не нужным даже заказчику - сил довести до готового устройства у него не хватало, а бросить то, что ничего не стоило - проще простого. Потом он загорался другой идеей, для которой опять нужна была помощь...

alek4613
Offline
Зарегистрирован: 04.09.2021

sadman41 пишет:
Я тоже дохрена бесплатно делал. Только кончалось это тем, что оказывалось не нужным даже заказчику
Вам просто везло на неблагодарных людей. И ко всему прочему я не обижаюсь. Это в вас говорит обиженный жизнью человек. Тем более вы сами об этом написали.   Надо же, какую тему животрепещущую затронул! Даже не ожидал. Мне говорили что программисты к своей работе слишком трепетно относятся, но не ожидал, что настолько.  :))

lilik
Offline
Зарегистрирован: 19.10.2017

https://www.radiokot.ru/forum/viewtopic.php?f=61&t=93990

Вот похожий, наверное экранчик обсуждается, в конце есть ссылки на архивы. Человек обратился к производителю вроде как.

alek4613
Offline
Зарегистрирован: 04.09.2021

Спасибо, закинул себе в архивы.