А как зовут зайку?
Гренка
Согласен.
Смотрел, что не так с Варварой и понял. Перепутаны местами оттенки серого.
Вот исходник:
Вот настройки в конвертере (инверсия цвета нужна иначе чёрное с белым поменяются):
И вот итог на экране - серые тона поменяны:
Что делать и кто виноват?
…Интуитивно кажется -надо инвертировать каждый бит в байте, но как это сделать?
Побитовое НЕ инвертирует состояние каждого бита исходной переменной.
~11001010 => 00110101
x = ~x;
Спасибо. Методом тыка, в том числе и с помощью этого значка редактировал функцию авторов ПО. Не знаю ошибка это у них или ошибка у производителей экрана. Но после этого фотки стали нормальными:
Что ещё
Из обидного: Производители не дают возможности задавать цвет из 4 как аргумент в функциях, оставляя лишь два.
Всё таки недоделки они знатные. Сделали функцию для вывода картинки в оттенках серого в любое место экрана и любого размера (меньше экрана), НО! с забеливанием всего остального экрана. То есть сделать календарь как сменяемый набор мелких 4 цветных картинок не получится ![]()
//Функция редактирована под верное отображение оттенков серого!!!
void Epd::Set_4GrayDisplay(const unsigned char *Image, int x, int y, int w, int l)
{
int i,j,k,m;
int z=0;
unsigned char temp1,temp2,temp3;
/****Color display description****
white gray1 gray2 black
0x10| 01 01 00 00
0x13| 01 00 01 00
*********************************/
//ЗАМЕНА!!!
/****Color display description****
white gray1 gray2 black
0x10| 01 00 01 00
0x13| 01 01 00 00
*********************************/
SendCommand(0x24);
z=0;
x= x/8*8;
for(m = 0; m<EPD_HEIGHT;m++)
for(i=0;i<EPD_WIDTH/8;i++)
{
if(i >= x/8 && i <(x+w)/8 && m >= y && m < y+l){
temp3=0;
for(j=0;j<2;j++)
{
temp1 = ~pgm_read_byte(&Image[z*2+j]);//ЗАМЕНА!!!
for(k=0;k<2;k++)
{
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0)
temp3 |= 0x01;//white
else if(temp2 == 0x00)
temp3 |= 0x00; //black
else if(temp2 == 0x80)
temp3 |= 0x00; //gray1//ЗАМЕНА!!!
else //0x40
temp3 |= 0x01; //gray2//ЗАМЕНА!!!
temp3 <<= 1;
temp1 <<= 2;
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0) //white
temp3 |= 0x01;
else if(temp2 == 0x00) //black
temp3 |= 0x00;
else if(temp2 == 0x80)
temp3 |= 0x00; //gray1//ЗАМЕНА!!!
else //0x40
temp3 |= 0x01; //gray2//ЗАМЕНА!!!
if(j!=1 || k!=1)
temp3 <<= 1;
temp1 <<= 2;
}
}
z++;
SendData(temp3);
}else{
SendData(0xff);
}
}
// new data
SendCommand(0x26);
z=0;
for(m = 0; m<EPD_HEIGHT;m++)
for(i=0;i<EPD_WIDTH/8;i++)
{
if(i >= x/8 && i <(x+w)/8 && m >= y && m < y+l){
temp3=0;
for(j=0;j<2;j++)
{
temp1 = ~pgm_read_byte(&Image[z*2+j]);//ЗАМЕНА!!!
for(k=0;k<2;k++)
{
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0)
temp3 |= 0x01;//white
else if(temp2 == 0x00)
temp3 |= 0x00; //black
else if(temp2 == 0x80)
temp3 |= 0x01; //gray1//ЗАМЕНА!!!
else //0x40
temp3 |= 0x00; //gray2//ЗАМЕНА!!!
temp3 <<= 1;
temp1 <<= 2;
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0) //white
temp3 |= 0x01;
else if(temp2 == 0x00) //black
temp3 |= 0x00;
else if(temp2 == 0x80)
temp3 |= 0x01; //gray1//
else //0x40
temp3 |= 0x00; //gray2//
if(j!=1 || k!=1)
temp3 <<= 1;
temp1 <<= 2;
}
}
z++;
SendData(temp3);
}else {
SendData(0xff);
}
}
TurnOnDisplay_4Gray();
}
Ну, это естественно. Просто подумайте, почему они так сделали. И если Вас не парит их ограничение, то переделайте эту функцию.
Я в смутных сомнениях. Пока догадываюсь - нельзя в принципе менять состояние отдельных пикселей, а только скопом. Переделать с наскоку не вышло. Прокатило только с правильными чередованиями цветов. Просто с чёрно-белым вариантом вроде функции для фрагментов экрана есть. Пробовать двухцветный вариант?
@lilik , а эту самую “бумагу” ляхтронную для часов можно использовать?
Ну может быть не именно эту, а вот которая была черно/бело/красная?
Или очень медленно обновляются данные?
Вот как раз на этом экране быстро по сравнению с красным.
на первом экране имеем фото в Высоком Ключе, зачёт)))
Конечно, там фотка из интернета, явно фотограф делал. А другая ИИ генератор по исходной фотке.
#include <SPI.h>
#include "epd4in2_V2.h"
#include "imagedata.h"
const struct {
const unsigned char *bitmap;
}
arhiv_znaki[12]={znak_1,znak_2,znak_3,znak_4,znak_5,znak_6,znak_7,znak_8,znak_9,znak_10,znak_11,znak_12};//размер значка 96Х96 пикселей
void setup() {
Epd epd;
epd.Init();
epd.Clear();
/////////////////////
for(int i=0;i<12;i++){
epd.Display_Partial_Not_refresh(arhiv_znaki[i].bitmap, 0+(i%4)*96, 0+(i/4)*96, 96+(i%4)*96, 96+(i/4)*96);
if(i==11){epd.Display_Partial(arhiv_znaki[i].bitmap,0+(i%4)*96, 0+(i/4)*96, 96+(i%4)*96, 96+(i/4)*96);}
}
epd.Sleep();
}
void loop() {
// put your main code here, to run repeatedly:
}
Смысл дошёл таки
Особенно : Display_Partial_Not_refresh - отображать частичку, но не обновлять
Сделал графику и вывод её на экран. Могу ссылку на файлы выложить, у кого есть подобный экран - для проверки. Осталось ds3231 как то подключить и запрограммировать, раньше только к уно подключал.
#include <SPI.h>
#include "epd4in2_V2.h"
#include "imagedata.h"
const struct {
const unsigned char *bitmap;
}
arhiv_znaki[12]={znak_1,znak_2,znak_3,znak_4,znak_5,znak_6,znak_7,znak_8,znak_9,znak_10,znak_11,znak_12};//размер значка 96Х96 пикселей
const struct {
const unsigned char *bitmap;
}
arhiv_mes[12]={mes_1,mes_2,mes_3,mes_4,mes_5,mes_6,mes_7,mes_8,mes_9,mes_10,mes_11,mes_12};//размер шильда 56Х248 пикселей
const struct {
const unsigned char *bitmap;
}
arhiv_ned[7]={ned_1,ned_2,ned_3,ned_4,ned_5,ned_6,ned_7};//размер шильда 32Х200 пикселей
const struct {
const unsigned char *bitmap;
}
arhiv_chis[10]={chis_0,chis_1,chis_2,chis_3,chis_4,chis_5,chis_6,chis_7,chis_8,chis_9,};//размер шильда 144X72 пикселей
int CH=3;int M=9;int N=2;int Z=8;//числа данных календаря - число, месяц, день недели, текущий знак гороскопа
void setup() {
Epd epd;
epd.Init();
epd.Clear();
/////////////////////
/*
for(int i=0;i<12;i++){
epd.Display_Partial_Not_refresh(arhiv_znaki[i].bitmap, 0+(i%4)*96, 0+(i/4)*96, 96+(i%4)*96, 96+(i/4)*96);
if(i==11){epd.Display_Partial(arhiv_znaki[i].bitmap,0+(i%4)*96, 0+(i/4)*96, 96+(i%4)*96, 96+(i/4)*96);}
}
*/
//отрисовка листка календаря
epd.Display_Partial_Not_refresh(fon_, 0, 0, 400, 300);
if(CH>9){epd.Display_Partial_Not_refresh(arhiv_chis[CH/10].bitmap, 220, 80, 220+144, 80+72);epd.Display_Partial_Not_refresh(arhiv_chis[CH%10].bitmap, 220, 80+72, 220+144, 80+72+72);}
else{epd.Display_Partial_Not_refresh(arhiv_chis[CH].bitmap, 220, 116, 220+144, 116+72);}
epd.Display_Partial_Not_refresh(arhiv_mes[M-1].bitmap, 180, 26, 180+56, 26+248);
epd.Display_Partial_Not_refresh(arhiv_ned[N-1].bitmap, 140, 40, 140+32, 40+200);
epd.Display_Partial(arhiv_znaki[Z-1].bitmap,40, 100, 96+40, 96+100);
epd.Sleep();
}
void loop() {
// put your main code here, to run repeatedly:
}
Нет никаких проблем, работает нормально ))
я думаю надо сделать как проект в соответствующем разделе
Я видимо пропустил ответ на свой вопрос (или не задал его
):
Если данный дисплей использовать для часов? Пойдет?
Питание от батареек или акб. Спим, раз в минуту ds3231 будит мк, тот получает время и перерисовывает его на экране.
Или в минуту не уложиться?
Ну и сколько во время перерисовки потребляет интересно узнать? В общем больше вопросов пока…
ЗЫ: Оно же без питания «держит» картинку?
Вопрос был задан, ответ пропущен.
Данный дисплей для часов пойдёт. Обновлять раз в минуту. Время обновления - секунды. Но зависит от режимов-функций обновлений. Вот эта отрисовка календаря дольше чем отрисовка фото. Фото вспыхивает быстро, несколько раз моргает и устанавливается. А вывод календаря - моргаем несколько раз чёрным-белым, потом белый экран секунды 4, потом сразу бах и вся картинка появляется…
Картинка на экране будет “вечной” после отключения проводов
Коты несколько месяцев уже стоят.







