Не спорю. Что за дисплей? Какой контроллер? Как графику выводите?
Дисплей ST7565R, плата уно, графика - фоновая картинка, отрезки, окружность, числа, буквы
///////////////// часы с мелодией версия 1
#include <Arduino.h>
#include <U8g2lib.h>
#include <SPI.h>
U8G2_ST7565_ERC12864_2_4W_SW_SPI u8g2(U8G2_R0, /* scl=*/ 13, /* si=*/ 11, /* cs=*/ 10, /* rs=*/ 9, /* rse=*/ 8);
#include <iarduino_RTC.h>
iarduino_RTC time(RTC_DS3231);
extern const unsigned char schkala_C[];
///////////////////////////
// НОВОГОДНЯЯ МЕЛОДИЯ фрагмент
int tonePin = 7;
const struct sound{
int freq, duration, dly;
} sounds[] PROGMEM = {
{293, 225, 250}, {493, 225, 250}, {440, 225, 250}, {391, 225, 250}, {293, 450, 750},
{293, 225, 250}, {293, 225, 250}, {493, 225, 250}, {440, 225, 250}, {391, 225, 250},
{329, 450, 750}, {329, 225, 250}, {329, 225, 250}, {523, 225, 250}, {493, 225, 250},
{440, 225, 250}, {587, 450, 750}, {587, 225, 250}, {659, 225, 250}, {587, 225, 250},
{523, 225, 250}, {440, 225, 250}, {493, 675, 750}
};
const uint8_t melodieLength = sizeof(sounds) / sizeof(sound);
sound SoundSRAM;
///////////////////////////////
int t=222;// пауза между считываниями данных
float minuti = 0.00; //пременные хранения углов
float tcshasi = 0.00; //
float sekundi = 0.00; //
int dlina_1 = 57;//задаём геометрию-форму стрелок часов
int dlina_2 = 28;
bool fl=false;//"флаг по условию" переключает режимы часы-календарь
void setup()
{
u8g2.begin();
u8g2.setContrast (20);
time.begin();
//u8g2.sendF("c", 0xA7);//инвертировать цвета на экране
u8g2.enableUTF8Print();
u8g2.setFont(u8g2_font_cu12_t_cyrillic);
}
void loop()
{
if((time.minutes==0&&time.seconds<10)||(time.minutes==30&&time.seconds<10)){midi();}// играем мелодию в начале каждого получаса
vremia_A();
delay(t);
}
////////////////////////////////////////
void vremia_A (){
time.gettime();//
sekundi=time.seconds*2*PI/60.0;//
minuti=time.minutes*2*PI/60.0;//
tcshasi=time.hours*2*PI/12.0+minuti/12.0 ;//
///////////////
//выставляем на экран календарь с 45 по 50 секунды каждой минуты
if(time.seconds==45){fl=true;}
if(time.seconds==50){fl=false;}
///////////////
// u8g2.clearBuffer();//очистка экрана
u8g2.firstPage();
do {
if(fl==true){//КАЛЕНДАРЬ на экране виден 5 сек. каждую минуту
///////////////
u8g2.setFont(u8g2_font_logisoso22_tr);//меняем шрифт
u8g2.setCursor(50,24);u8g2.print(time.day);// число месяца пишем
u8g2.setFont(u8g2_font_cu12_t_cyrillic);//возвращаем шрифт
u8g2.setCursor(30,37);
if( time.month==1){u8g2.print("ЯНВАРЯ");}// название месяца пишем
if( time.month==2){u8g2.print("ФЕВРАЛЯ");}
if( time.month==3){u8g2.print("МАРТА");}
if( time.month==4){u8g2.print("АПРЕЛЯ");}
if( time.month==5){u8g2.print("МАЯ");}
if( time.month==6){u8g2.print("ИЮНЯ");}
if( time.month==7){u8g2.print("ИЮЛЯ");}
if( time.month==8){u8g2.print("АВГУСТА");}
if( time.month==9){u8g2.print("СЕНТЯБРЯ");}
if( time.month==10){u8g2.print("ОКТЯБРЯ");}
if( time.month==11){u8g2.print("НОЯБРЯ");}
if( time.month==12){u8g2.print("ДЕКАБРЯ");}
u8g2.setCursor(52,50);
u8g2.print("20");//год пишем
u8g2.setCursor(67,50);
u8g2.print(time.year);
u8g2.setCursor(30,60);
if(time.weekday==1){u8g2.print("понедельник");}//день недели пишем
if(time.weekday==2){u8g2.print("вторник");}//
if(time.weekday==3){u8g2.print("среда");}//
if(time.weekday==4){u8g2.print("четверг");}//
if(time.weekday==5){u8g2.print("пятница");}//
if(time.weekday==6){u8g2.print("суббота");}//
if(time.weekday==0){u8g2.print("воскресенье");}//
//////////////
}
else{//ЧАСЫ на эране видны 55 сек. каждую минуту
u8g2.drawXBMP(0, 0, 128, 64,schkala_C);// рисование контура часов по рисунку
u8g2.drawLine(63,32,63 + cos(sekundi - PI / 2) * (dlina_1), 32 + sin(sekundi - PI / 2)* (dlina_2));//секундная стрелка рисуется
u8g2.drawLine(63 + cos(minuti-0.5 - PI / 2) * (dlina_1*0.15), 32 + sin(minuti-0.5 - PI / 2) * (dlina_2*0.15) , 63 + cos(minuti - PI / 2) * (dlina_1*1.1), 32 + sin(minuti - PI / 2) * (dlina_2*1.1)); //минутная стрелка рисуется
u8g2.drawLine(63 + cos(minuti+0.5 - PI / 2) * (dlina_1*0.15), 32 + sin(minuti+0.5 - PI / 2) * (dlina_2*0.15) , 63 + cos(minuti - PI / 2) * (dlina_1), 32 + sin(minuti - PI / 2) * (dlina_2)); //минутная стрелка рисуется
u8g2.drawLine(63 + cos(tcshasi-0.5 - PI / 2) * (dlina_1*0.15), 32 + sin(tcshasi-0.5 - PI / 2) * (dlina_2*0.15) , 63 + cos(tcshasi - PI / 2) * (dlina_1*0.5), 32 + sin(tcshasi - PI / 2) * (dlina_2*0.5)); //часовая стрелка рисуется
u8g2.drawLine(63 + cos(tcshasi+0.5 - PI / 2) * (dlina_1*0.15), 32 + sin(tcshasi+0.5 - PI / 2) * (dlina_2*0.15) , 63 + cos(tcshasi - PI / 2) * (dlina_1*0.5), 32 + sin(tcshasi - PI / 2) * (dlina_2*0.5)); //часовая стрелка рисуется
u8g2.drawCircle( 63, 32, 4);//точка крепления стрелки
}
} while ( u8g2.nextPage() );
// u8g2.sendBuffer();
}
///////////////////////////////////////
void midi() {
for (uint8_t i = 0; i < melodieLength; i++) {
memcpy_P( &SoundSRAM, &sounds[i], sizeof(sound));
tone(tonePin, SoundSRAM.freq, SoundSRAM.duration);
vremia_A();//не забываем двигать стрелки часов во время исполнения мелодии
delay(SoundSRAM.dly-150);
}
}
/////////////////////////////////////////
Фоновая картинка отдельным файлом с расширением с.
#include <avr/pgmspace.h>
const unsigned char schkala_C[]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,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X30,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X06,0X00,0X00,0X00,
0X00,0X00,0X00,0X60,0X00,0X00,0X80,0X9F,0X7F,0X00,0X00,0X00,0X07,0X00,0X00,0X00,
0X00,0X00,0X00,0XC0,0X00,0X00,0X80,0XDF,0XF1,0X00,0X00,0X80,0X01,0X00,0X00,0X00,
0X00,0X00,0X00,0X80,0X03,0X00,0X00,0XDC,0XF1,0X00,0X00,0XE0,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X07,0X00,0X00,0X1C,0X70,0X00,0X00,0X70,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X0E,0X00,0X00,0X1C,0X38,0X00,0X00,0X38,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X1C,0X00,0X00,0X1C,0X0E,0X00,0X00,0X1C,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X30,0X00,0X00,0X1C,0XC3,0X00,0X00,0X06,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X60,0X00,0X80,0XDF,0XFF,0X00,0X80,0X03,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0XC0,0X01,0X80,0XFF,0X7F,0X00,0XC0,0X01,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X80,0X07,0X00,0X00,0X00,0X00,0XF0,0X00,0X00,0X00,0X00,0X00,
0X08,0X00,0X00,0X00,0X00,0X07,0X00,0X00,0X00,0X00,0X70,0X00,0X00,0X00,0X00,0X1C,
0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X80,0X1F,
0XF8,0X07,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XF0,0X0F,
0XC0,0X7F,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0X01,
0X00,0XFE,0X03,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XE0,0X3F,0X00,
0X00,0XF0,0X3F,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFE,0X07,0X00,
0X00,0X00,0XFF,0X01,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XE0,0X7F,0X00,0X00,
0X00,0X00,0XB8,0X07,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XF0,0X0F,0X00,0X00,
0X00,0X00,0X80,0X07,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XB0,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X80,0X07,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XF8,0X01,
0XC0,0X1D,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X9C,0X03,
0XE0,0X38,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1E,0X07,
0X70,0X38,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0C,0X07,
0X70,0X78,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X80,0X03,
0X70,0X78,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XF0,0X01,
0XE0,0X7F,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X90,0X03,
0XC0,0X7B,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X07,
0X00,0X38,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X06,0X0F,
0XE0,0X38,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0E,0X07,
0XE0,0X1C,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X8E,0X07,
0XC0,0X07,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFC,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,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X80,0X07,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X38,0X00,0X00,0X00,
0X00,0X00,0XF0,0X07,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XF8,0X17,0X00,0X00,
0X00,0XC0,0X7F,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X80,0XFF,0X01,0X00,
0X00,0XF8,0X0F,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XF8,0X1F,0X00,
0X80,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XC0,0XFF,0X00,
0XF0,0X1F,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFC,0X0F,
0XF8,0X01,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XC0,0X1F,
0X38,0X00,0X00,0X00,0X00,0X06,0X00,0X00,0X00,0X00,0X30,0X00,0X00,0X00,0X00,0X1C,
0X00,0X00,0X00,0X00,0X00,0X07,0X00,0X00,0X00,0X00,0X70,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X80,0X07,0X00,0X80,0X03,0X00,0XF0,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0XE0,0X01,0X00,0XE0,0X0F,0X00,0XC0,0X03,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X70,0X00,0X00,0X38,0X0E,0X00,0X00,0X07,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X38,0X00,0X00,0X38,0X00,0X00,0X00,0X0E,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X1C,0X00,0X00,0XFC,0X0F,0X00,0X00,0X1C,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X06,0X00,0X00,0X3C,0X1E,0X00,0X00,0X30,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X80,0X03,0X00,0X00,0X1C,0X1C,0X00,0X00,0XE0,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0XC0,0X01,0X00,0X00,0X38,0X1C,0X00,0X00,0XC0,0X01,0X00,0X00,0X00,
0X00,0X00,0X00,0XE0,0X00,0X00,0X00,0X38,0X0E,0X00,0X00,0X80,0X03,0X00,0X00,0X00,
0X00,0X00,0X00,0X30,0X00,0X00,0X00,0XE0,0X03,0X00,0X00,0X00,0X06,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00
};
Спасибо большое. Я опробую этот код, как приедут дисплеи.
Злюсь уже на свою тупость - никак не могу понять как по даташитам управлять железками. Все же написано - бери да действуй. А вот никак (( Тупой, старый дед.
@lilik , чем init _1_
отличается от _2_
?
Ой, смутно помню, есть вроде 3 опции - буфер полного кадра (буква F) и дольные 1 или 2. Для динамичных смен-отрисовок лучше f, но ОЗУ много берёт как и положено.
Ну вот я и помню, что в несколько проходов оно там рисуется, но не помню, насколько 1 экономней 2 и экономней ли. Не нашёл в документации 2 , поэтому и поинтересовался.
А вот это напрасно.
Чтобы работать с дэйташитом нужен вполне определенный опыт.
Точнее даже так: нужно иметь (хотя бы в голове) схему, по которой составляется класс (если угодно - библиотека) для работы с тем или иным устройством. А из дэйташита этот (по сути уже имеющийся) класс просто набивается конкретикой.
copy/paste примеров из инета, потом в них разбираться/изменять - самый простой путь.
Штото я разучился хелпы читать что-ли…
вот тут токо про F и 1
Да я тоже читал там только про это. Видимо из прошлого тянется и история умалчивает. (
Я пробовал и с F, и с 2, и с 1.
Заметил различия ?
Да, по секундной стрелке видно какой режим быстрее в отрисовке.
Так не томи - какие результаты то? Субъективные тоже подойдут
Да всё ожидаемо:при режиме F буфер полного экрана выводится быстро, при режиме 2 - четверть экрана буфер, соответственно 4 раза формируется и опорожняется на экран (медленно отрисовка идёт). При режиме 1 - 8 раз процедура происходит, там как на механических рекламных щитах
Собссна, читать нада. И чем больше - тем лучче. Все написано какие различия 1, 2 и F.
- U8G2_ST7565_ERC12864_ALT_1_4W_SW_SPI(rotation, clock, data, cs, dc [, reset]) [page buffer, size = 128 bytes]
- U8G2_ST7565_ERC12864_ALT_2_4W_SW_SPI(rotation, clock, data, cs, dc [, reset]) [page buffer, size = 256 bytes]
- U8G2_ST7565_ERC12864_ALT_F_4W_SW_SPI(rotation, clock, data, cs, dc [, reset]) [full framebuffer, size = 1024 bytes]
- U8G2_ST7565_ERC12864_ALT_1_4W_HW_SPI(rotation, cs, dc [, reset]) [page buffer, size = 128 bytes]
- U8G2_ST7565_ERC12864_ALT_2_4W_HW_SPI(rotation, cs, dc [, reset]) [page buffer, size = 256 bytes]
- U8G2_ST7565_ERC12864_ALT_F_4W_HW_SPI(rotation, cs, dc [, reset]) [full framebuffer, size = 1024 bytes]
Получается, что если в “окончательном варианте кода” будет байт 400-500 свободно ОЗУ, то можно с 1 на 2 переключиться и будет вывод по быстрее, но при этом не 1,5кб ОЗУ будет дисплей отъедать а гораздо-гораздо меньше.
Ну то потом видно будет, ничего “динамичного” я не планировал выводить…
Народ день добрый!
Как правильно использовать PROGMEM с этой библиотекой, и выводить определенную строку из массива?
Делаю так…
const char* const messages[] PROGMEM = {
"first",
"second",
"three"
};
strcpy_P(lcd_buf, messages[0]);
u8g2_DrawUTF8(&u8g2, 2, 7, lcd_buf);
Или
strcpy_P(lcd_buf, (const char*)pgm_read_word(&messages[0]));
u8g2_DrawUTF8(&u8g2, 2, 7, lcd_buf);
Ни то ни другое не пошло на дисплей.
/*
PROGMEM string demo
How to store a table of strings in program memory (flash),
and retrieve them.
Information summarized from:
http://www.nongnu.org/avr-libc/user-manual/pgmspace.html
Setting up a table (array) of strings in program memory is slightly complicated, but
here is a good template to follow.
Setting up the strings is a two-step process. First, define the strings.
*/
#include <avr/pgmspace.h>
const char string_0[] PROGMEM = "String 0"; // "String 0" etc are strings to store - change to suit.
const char string_1[] PROGMEM = "String 1";
const char string_2[] PROGMEM = "String 2";
const char string_3[] PROGMEM = "String 3";
const char string_4[] PROGMEM = "String 4";
const char string_5[] PROGMEM = "String 5";
// Then set up a table to refer to your strings.
const char *const string_table[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5};
char buffer[30]; // make sure this is large enough for the largest string it must hold
void setup() {
Serial.begin(9600);
while (!Serial); // wait for serial port to connect. Needed for native USB
Serial.println("OK");
}
void loop() {
/* Using the string table in program memory requires the use of special functions to retrieve the data.
The strcpy_P function copies a string from program space to a string in RAM ("buffer").
Make sure your receiving string in RAM is large enough to hold whatever
you are retrieving from program space. */
for (int i = 0; i < 6; i++) {
strcpy_P(buffer, (char *)pgm_read_word(&(string_table[i]))); // Necessary casts and dereferencing, just copy.
Serial.println(buffer);
delay(500);
}
}