Умные Часы-Метеостанция на lcd1602 и lcd nokia 5110. Адаптивная подсветка. От чайника для чайников.

alexey.st0
alexey.st0 аватар
Offline
Зарегистрирован: 06.06.2020

Привет всем форумчанинам! Хочу рассказать о своём мега полезном изобретении умные часы-метеостанция. Небольшая лирическая вставка: это мой первый пост на форуме arduino.ru и это мой первый реальный проект с микроконтроллером Arduino, создавая который я осваивал самые азы техчасти и программирования этой платформы. Если где и накосячил, предварительно я вас ввёл в курс дела. Текста будет достаточно.

При необходимости откройте изображение и рассмотрите.

Теперь о самом проекте. Основный функции – отображение текущего времени, числа, месяца, дня недели, считывание и отображение информации с метеодатчика BME280 (температура и влажность воздуха, атмосферное давление, высота над уровнем моря), и самое интересное, полное ДУ с пульта. Второстепенные функции – таймер, будильник, "ежечасовой звон" (прямо как в старых часах :) ). Из полезных фишек реализована адаптивная подсветка lcd через фоторезистор. Я не стал метеостанцию консервировать в корпус, оставил в "сыром виде", поскольку хочу ещё доработать и что-то реализовать. Код представлю в самом конце поста.

Комплектующие. Arduino Nano, rtc ds1307, bme280 5v (но питаю от 3.3v, диапазон позволяет от 2v до 5v), фоторезистор, сенсорная кнопка tt223, IR приёмник, IR пульт, пьезопищалка, 6 резисторов 1кОм. В моём случае lcd 1602 и lcd nokia 5110 (используется только один из них, или один, или второй, поскольку не хватает памяти arduino nano или моего опыта, тут уж не знаю :-) )

Подключение. Всё подключается довольно просто. LCD 1602, BME280 и RTC работают посредством шины I2C (SDL и SDA подключены к A4 и A5). Нюанс, мой lcd nokia подключается VCC к 3.3v, а LIGH и GND к массе. Почему так, я не знаю, но иначе не работает. Остальные 5 пинов подключаем к цифровым пинам arduino через резисторы 1кОм (чтобы lcd прожил больше, используйте 10кОм).

Касательно кнопки. Если хотите, можно использовать традиционную кнопку заместо сенсорной, код останется таким же, но необходимо будет активировать встроенный в микроконтроллер резистор 20кОм через функцию INPUT_PULLUP. Схем в интернете море, выбирайте любую, какая подойдёт. 

Ардуино питается от 5v через шилд блока питания (YwRobot 545043), который устанавливается на макетную плату и может выдавать 5v и 3.3v (управляется перемычками, на фото выше видно). От него же питаются датчики и модули, которые требуют 5v или 3.3v.

Немного об адаптивной подсветке. Сам долго реализовывал данную функцию из-за незнания, поэтому расскажу что к чему. Сначала подключаем фоторезистор к аналоговому входу арудино по схеме ниже. Далее подключаем подсветку lcd 1602 к любому (в моём случае кроме 9го и 10го, шим сигнал почему не выдавал) цифровому пину с ШИМом. Ардуино будет считывать сигнал с фоторезистора в диапазоне от 0 до 1024, делить полученный результат на 4, а посылать сигнал на цифровой пин через analogWrite в диапазоне от 0 до 255. Выше значение, ярче подсветка lcd. Код приведён ниже (нашёл его на этом же форуме). НО, если вдруг вы не хотите делать адаптивной подсветку, я сделал в проекте функцию управления подсветкой через пульт ДУ !

01int PhCount = analogRead(7);
02  PhCount = PhCount/4;
03  if(PhCount > 255){
04    analogWrite(led, 255);
05  } else {
06    if(PhCount < 40){ //минимальный уровень подсветки 40
07      analogWrite(led, 40);
08    } else {
09      analogWrite(led, PhCount);
10    }
11  }

Видеоролики, где продемонстрировал работу метеостанции на lcd1602:

Переключение трёх главных экранов посредством сенсорной кнопки. Реагирует даже на пинцет :)

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

Управление станцией с пульта и демонстрация будильника. Будильник настраивается только через код, для меня оптимально. Можно запрограммировать несколько пультов, даже с телефона можно управлять, если есть ИК порт. Функции пульта следующие: полная перезагрузка ардуино (также выполняется автоматически каждый день в 0:00, можно отключить в коде), вкл/выкл подсветки одной кнопкой, циклическое переключение экранов. Я нажимал vol- и vol+. Эти кнопки регулируют степень яркости подсветки в ручном режиме. Всего 4 степени яркости. Не работало, поскольку в моём случае адаптивная подсветка. Опять таки, можно настроить в коде (старался всё комментировать).  Кнопка 1 и 2 включают готовый таймер на 20сек и 5сек. 

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

Также реализовал автоматическое переключение на главный циферблат, если на каком-то и зкранов застрял более чем на 30сек. Все экраны постарался проработать до мелочей. Однако недочёты есть, из буду по возможности исправлять. Забыл заснять момент ежечасового звона... он такой же как и будильник, но воспроизводится каждый час... Мне нравится, я и сделал.

Демонстрация работы на LCD nokia 5110 (84x48)

Экран здесь всего один, зато на нём помещается всё. Циферблат содержит секунды. Дата, дни недели на русском (здесь тоже свои нюансы, напишу пост об этом позже), и те же значения с датчика bme280, тоже на русском. Конкретно для этого дисплея реализовал предупреждение при повышенной влажности в помещении (более 70%). Для меня это важно, однако, повторюсь, в коде всё описано, можно выключить. Также реализован будильник. НО нет ежечасового звона... Также нет управления с пульта, потому что здесь это не нужно (пока что), и нет адаптивной подсветки, поскольку подсветка и без того тусклая. Есть миниатюры при звуковых сигналах. Опять таки, постарался все мелочи проработать. Ниже фото и видео.

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

Как вы поняли, по итоги в этом проекте две прошивки. Одна для lcd1602, вторая для nokia lcd. Они практически одинаковы, в каждой свои особенности. Сделано это было как для себя, так и для расширения проекта. 

Прошивка для lcd1602:

001#include <Adafruit_Sensor.h>
002#include <Adafruit_BME280.h>
003#define SEALEVELPRESSURE_HPA (1013.25)
004Adafruit_BME280 bme;
005 
006#include "IRremote.h"
007#include <Wire.h>
008#include "RTClib.h"
009#include <LiquidCrystal_I2C.h>
010RTC_DS1307 rtc;
011LiquidCrystal_I2C lcd(0x3F,16,2);
012//ИК приемник
013IRrecv irrecv(A0); // указываем пин, к которому подключен IR приемник
014decode_results results;
015 
016 
017 
018byte LT[8] =
019{
020  B00111,
021  B01111,
022  B11111,
023  B11111,
024  B11111,
025  B11111,
026  B11111,
027  B11111
028};
029byte UB[8] =
030{
031  B11111,
032  B11111,
033  B11111,
034  B00000,
035  B00000,
036  B00000,
037  B00000,
038  B00000
039};
040byte RT[8] =
041{
042 
043  B11100,
044  B11110,
045  B11111,
046  B11111,
047  B11111,
048  B11111,
049  B11111,
050  B11111
051};
052byte LL[8] =
053{
054 
055 
056  B11111,
057  B11111,
058  B11111,
059  B11111,
060  B11111,
061  B11111,
062  B01111,
063  B00111
064};
065byte LB[8] =
066{
067  B00000,
068  B00000,
069  B00000,
070  B00000,
071  B00000,
072  B11111,
073  B11111,
074  B11111
075};
076byte LR[8] =
077{
078 
079 
080  B11111,
081  B11111,
082  B11111,
083  B11111,
084  B11111,
085  B11111,
086  B11110,
087  B11100
088};
089byte MB[8] =
090{
091  B11111,
092  B11111,
093  B11111,
094  B00000,
095  B00000,
096  B00000,
097  B11111,
098  B11111
099};
100byte block[8] =
101{
102  B11111,
103  B11111,
104  B11111,
105  B11111,
106  B11111,
107  B11111,
108  B11111,
109  B11111
110};
111 
112 
113// loop counter
114int count = 0;
115 
116int flag=0;
117int piezoPin = 12;
118char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
119 
120int regim   =1;
121int regim_1 =1;
122int regim_2 =1;
123 
124int led = 6;  
125 
126#define BTN 2
127 
128 
129 
130 
131unsigned long timing;
132 
133void setup() {
134   pinMode(led, OUTPUT);
135   pinMode(BTN, INPUT);
136   pinMode(piezoPin, OUTPUT);
137   pinMode(A0, INPUT); //логика ик приемника
138   pinMode(11, OUTPUT); //питание ик приемника
139   digitalWrite(11, HIGH);
140   rtc.begin();
141   lcd.init();                      // initialize the lcd
142   lcd.backlight();
143   lcd.home();
144   analogWrite(led, 254);
145   Serial.begin(9600); // подключаем монитор порта
146   Wire.begin();
147   irrecv.enableIRIn(); // запускаем прием инфракрасного сигнала
148   bme.begin(0x76); // запускаем приём ифнормации с датчика через i2c
149   
150 
151   lcd.createChar(0,LT);
152   lcd.createChar(1,UB);
153   lcd.createChar(2,RT);
154   lcd.createChar(3,LL);
155   lcd.createChar(4,LB);
156   lcd.createChar(5,LR);
157   lcd.createChar(6,MB);
158   lcd.createChar(7,block);
159     
160    
161   // sets the LCD's rows and colums:
162   lcd.clear();
163 
164   if (! rtc.isrunning()) {
165    Serial.println("RTC is NOT running!");
166    // following line sets the RTC to the date & time this sketch was compiled
167    //rtc.adjust(DateTime(__DATE__, __TIME__));
168  }
169}
170 
171void custom0(int x)
172{ // uses segments to build the number 0
173 
174  lcd.setCursor(x,0); // set cursor to column 0, line 0 (first row)
175  lcd.write(0);  // call each segment to create
176  lcd.write(1);  // top half of the number
177  lcd.write(2);
178  lcd.setCursor(x, 1); // set cursor to colum 0, line 1 (second row)
179  lcd.write(3);  // call each segment to create
180  lcd.write(4);  // bottom half of the number
181  lcd.write(5);
182}
183 
184void custom1(int x)
185{
186  lcd.setCursor(x,0);
187  lcd.write(1);
188  lcd.write(2);
189  lcd.print(" ");
190  lcd.setCursor(x,1);
191  lcd.write(4);
192  lcd.write(7);
193  lcd.write(4);
194}
195 
196void custom2(int x)
197{
198  lcd.setCursor(x,0);
199  lcd.write(6);
200  lcd.write(6);
201  lcd.write(2);
202  lcd.setCursor(x, 1);
203  lcd.write(3);
204  lcd.write(4);
205  lcd.write(4);
206}
207 
208void custom3(int x)
209{
210  lcd.setCursor(x,0);
211  lcd.write(6);
212  lcd.write(6);
213  lcd.write(2);
214  lcd.setCursor(x, 1);
215  lcd.write(4);
216  lcd.write(4);
217  lcd.write(5);
218}
219 
220void custom4(int x)
221{
222  lcd.setCursor(x,0);
223  lcd.write(3);
224  lcd.write(4);
225  lcd.write(7);
226  lcd.setCursor(x, 1);
227  lcd.print(" ");
228  lcd.print(" ");
229  lcd.write(7);
230}
231 
232void custom5(int x)
233{
234  lcd.setCursor(x,0);
235  lcd.write(3);
236  lcd.write(6);
237  lcd.write(6);
238  lcd.setCursor(x, 1);
239  lcd.write(4);
240  lcd.write(4);
241  lcd.write(5);
242}
243 
244void custom6(int x)
245{
246  lcd.setCursor(x,0);
247  lcd.write(0);
248  lcd.write(6);
249  lcd.write(6);
250  lcd.setCursor(x, 1);
251  lcd.write(3);
252  lcd.write(4);
253  lcd.write(5);
254}
255 
256void custom7(int x)
257{
258  lcd.setCursor(x,0);
259  lcd.write(1);
260  lcd.write(1);
261  lcd.write(2);
262  lcd.setCursor(x, 1);
263  lcd.print(" ");
264  lcd.print(" ");
265  lcd.write(7);
266}
267 
268void custom8(int x)
269{
270  lcd.setCursor(x,0);
271  lcd.write(0);
272  lcd.write(6);
273  lcd.write(2);
274  lcd.setCursor(x, 1);
275  lcd.write(3);
276  lcd.write(4);
277  lcd.write(5);
278}
279 
280void custom9(int x)
281{
282  lcd.setCursor(x,0);
283  lcd.write(0);
284  lcd.write(6);
285  lcd.write(2);
286  lcd.setCursor(x, 1);
287  lcd.print(" ");
288  lcd.print(" ");
289  lcd.write(7);
290 
291}
292 
293void clearnumber(int x)
294{ //clears the area the custom number is displayed in
295  lcd.setCursor(x,0);
296  lcd.print("   ");
297  lcd.setCursor(x,1);
298  lcd.print("   ");
299}
300 
301void(* resetFunc) (void) = 0; //функция перезагрузки arduino
302 
303 
304void loop() {
305  
306   
307 
308     
309  //Функция перезагрузки arduino каждый день в 00:00:00
310  DateTime now = rtc.now();
311  if (now.hour() == 0 && now.minute() == 00 && now.second() == 00) {
312      lcd.clear();
313      lcd.setCursor(0,0);
314      lcd.print("Reboot device..");
315      delay(1000);
316      lcd.clear();
317      resetFunc();
318  }
319 
320  int PhCount = analogRead(7);
321  PhCount = PhCount/4;
322  if(PhCount > 255){
323    analogWrite(led, 255);
324  } else {
325    if(PhCount < 40){ //минимальный уровень подсветки 40
326      analogWrite(led, 40);
327    } else {
328      analogWrite(led, PhCount);
329    }
330  }
331 
332  //управление с пульта на ИК приёмник
333  if (irrecv.decode(&results)) { // если данные пришли выполняем команды  
334      Serial.println(results.value); //для вывода в монитор порта значений с ИК приёмника
335 
336      //Переключение экранов с пульта
337      if(results.value == 59415 || results.value == 16769565) {
338        regim++;
339        tone(piezoPin, 200, 50);  
340        lcd.clear();
341          
342        //это нужно для того что бы с каждым нажатием кнопки
343        //происходило только одно действие
344        // плюс защита от "дребезга"  100%
345           
346        if(regim>3)//ограничим количество режимов
347        {
348          regim=1;//так как мы используем только одну кнопку,
349                    // то переключать режимы будем циклично
350        }
351      }
352 
353      //управление степенью якркости подсветки LCD
354      //одна кнопка увеличить яркость, вторая - уменьшить
355      if(results.value == 58395 || results.value == 16748655){ //увеличить
356          regim_2++;
357          if(regim_2>4)//ограничим количество режимов
358          {
359            regim_2=4;
360          
361          if(regim_2==1) {
362            analogWrite(led, 20);
363          }
364          if(regim_2==2) {
365            analogWrite(led, 100);
366          }
367          if(regim_2==3) {
368            analogWrite(led, 200);
369          }
370          if(regim_2==4) {
371            analogWrite(led, 255);
372          }
373      }
374      if(results.value == 43095 || results.value == 16754775){ //уменьшить
375          regim_2--;
376          if(regim_2<1)//ограничим количество режимов
377          {
378            regim_2=1;
379          }
380          if(regim_2==1) {
381            analogWrite(led, 20);
382          }
383          if(regim_2==2) {
384            analogWrite(led, 100);
385          }
386          if(regim_2==3) {
387            analogWrite(led, 200);
388          }
389          if(regim_2==4) {
390            analogWrite(led, 255);
391          }   
392      }
393       
394      //управление подсветкой lcd
395      //При нажатии кнопки на пульте - выкл или вкл подсветку
396      if(results.value == 5355 || results.value == 16736925){ //кнопка1 в формате DEC
397          regim_1++;
398          if(regim_1>2)//ограничим количество режимов
399          {
400            regim_1=1;
401          
402          if(regim_1==1) {  //режим 1 - lcd on
403            lcd.clear();
404            lcd.setCursor(4,0);
405            lcd.print("LCD on");
406            tone(piezoPin, 900, 50);
407            delay(500);
408            tone(piezoPin, 900, 50);
409            lcd.backlight(); //вкл
410            delay(500);
411            lcd.clear();  
412          }
413 
414          if(regim_1==2) { //режим 2 - lcd off
415            lcd.clear();
416            lcd.setCursor(4,0);
417            lcd.print("LCD off");
418            tone(piezoPin, 900, 50);
419            delay(500);
420            tone(piezoPin, 900, 50);
421            lcd.noBacklight(); //выкл
422            delay(500);
423            lcd.clear();
424          }
425                    
426      }
427 
428      //Таймер №1 по нажатию на выбранную кнопку с пульта
429      if(results.value == 4335 || results.value == 16724175) { //выбранная кнопка             
430          lcd.clear();
431          lcd.setCursor(2,0);
432          lcd.print("Timer 20s on");
433          lcd.setCursor(6,1);
434          lcd.print("....");
435          tone(piezoPin, 900, 50);
436          delay(20000); //засекаем таймер
437          lcd.clear();
438          lcd.setCursor(4,0);
439          lcd.print("Time out!"); //время вышло!
440          lcd.setCursor(6,1);
441          lcd.print("....");
442          tone(piezoPin, 900, 100);
443          delay(200);
444          tone(piezoPin, 900, 100);
445          delay(200);
446          tone(piezoPin, 900, 100);
447          delay(200);
448          tone(piezoPin, 900, 100);
449          delay(500);
450          lcd.clear();
451          delay(300);
452          lcd.setCursor(4,0);
453          lcd.print("Time out!");
454          lcd.setCursor(6,1);
455          lcd.print("....");
456          tone(piezoPin, 900, 100);
457          delay(200);
458          tone(piezoPin, 900, 100);
459          delay(200);
460          tone(piezoPin, 900, 100);
461          delay(200);
462          tone(piezoPin, 900, 100);
463          delay(500);
464          lcd.clear();
465          delay(300);
466          lcd.setCursor(4,0);
467          lcd.print("Time out!");
468          lcd.setCursor(6,1);
469          lcd.print("....");
470          tone(piezoPin, 900, 100);
471          delay(200);
472          tone(piezoPin, 900, 100);
473          delay(200);
474          tone(piezoPin, 900, 100);
475          delay(200);
476          tone(piezoPin, 900, 100);
477          delay(500);
478          lcd.clear();
479          delay(300);
480       }
481 
482       //Таймер №2 по нажатию на выбранную кнопку с пульта
483      if(results.value == 36975 || results.value == 16718055) { //выбранная кнопка             
484          lcd.clear();
485          lcd.setCursor(2,0);
486          lcd.print("Timer 5s on");
487          lcd.setCursor(6,1);
488          lcd.print("....");
489          tone(piezoPin, 900, 50);
490          delay(5000); //засекаем таймер
491          lcd.clear();
492          lcd.setCursor(4,0);
493          lcd.print("Time out!"); //время вышло!
494          lcd.setCursor(6,1);
495          lcd.print("....");
496          tone(piezoPin, 900, 100);
497          delay(200);
498          tone(piezoPin, 900, 100);
499          delay(200);
500          tone(piezoPin, 900, 100);
501          delay(200);
502          tone(piezoPin, 900, 100);
503          delay(500);
504          lcd.clear();
505          delay(300);
506          lcd.setCursor(4,0);
507          lcd.print("Time out!");
508          lcd.setCursor(6,1);
509          lcd.print("....");
510          tone(piezoPin, 900, 100);
511          delay(200);
512          tone(piezoPin, 900, 100);
513          delay(200);
514          tone(piezoPin, 900, 100);
515          delay(200);
516          tone(piezoPin, 900, 100);
517          delay(500);
518          lcd.clear();
519          delay(300);
520          lcd.setCursor(4,0);
521          lcd.print("Time out!");
522          lcd.setCursor(6,1);
523          lcd.print("....");
524          tone(piezoPin, 900, 100);
525          delay(200);
526          tone(piezoPin, 900, 100);
527          delay(200);
528          tone(piezoPin, 900, 100);
529          delay(200);
530          tone(piezoPin, 900, 100);
531          delay(500);
532          lcd.clear();
533          delay(300);
534       }
535        
536       //перезагрузка устр-ва по нажатию на кнопку пульта
537       if(results.value == 25755 || results.value == 16753245) {
538          lcd.clear();
539          lcd.setCursor(0,0);
540          lcd.print("Reboot device...");
541          delay(1000);
542          lcd.clear();
543          resetFunc();
544         }
545        
546      irrecv.resume();
547  }
548 
549  if(digitalRead(BTN)==HIGH&&flag==0) {
550      tone(piezoPin, 200, 50);
551  }
552   
553  if(digitalRead(BTN)==HIGH&&flag==0)//если кнопка нажата  
554     // и перемення flag равна 0 , то ...
555     {
556       regim++;  
557       flag=1;
558       lcd.clear();
559          
560        //это нужно для того что бы с каждым нажатием кнопки
561        //происходило только одно действие
562        // плюс защита от "дребезга"  100%
563           
564        if(regim>3)//ограничим количество режимов
565        {
566          regim=1;//так как мы используем только одну кнопку,
567                    // то переключать режимы будем циклично
568        }
569     }
570    
571 
572    
573    if(digitalRead(BTN)==LOW&&flag==1)//если кнопка НЕ нажата
574    //и переменная flag равна - 1 ,то ...
575    {          
576        flag=0;//обнуляем переменную "BTN"        
577    }
578     
579    //Автоматическое переключение на главнй экран с циферблатом, если где-то в меню застрял > 40 секунд
580    if (regim == 1 && millis() - timing > 40000) { //если режим ВТОРОЙ
581          timing = millis();
582          lcd.clear();
583          regim=2;
584    }
585    if (regim == 3 && millis() - timing > 40000) { //если режим ТРЕТИЙ
586          timing = millis();
587          lcd.clear();
588          regim=2;
589    }
590 
591      
592    
593    if(regim==2)//ПЕРВЫЙ режим
594    {
595       digitalClockDisplay();
596       delay(100);
597       //мигание временем каждый час (с 10 до 22, указывается в void digitalClockDisplay())
598       DateTime now = rtc.now();
599       if (now.hour() >= 10 && now.hour() <= 22 && now.minute() == 00 && now.second() >= 00 && now.second() < 10 ) {
600          digitalClockDisplay();
601          delay(600);
602          lcd.clear();
603          delay(600);
604       }
605       //мигание временем во время сигнала будильника (указывается в void digitalClockDisplay())
606       if (now.dayOfTheWeek() >= 1 && now.dayOfTheWeek() <= 7 && now.hour() == 14 && now.minute() == 20 && now.second() >= 00 && now.second() < 15) {
607          digitalClockDisplay();
608          delay(600);
609          lcd.clear();
610          delay(600);
611       }
612        //оставляем точки статическими при ежечасовом звоне и будильнике (при мигании циферблата)
613        if (now.hour() >= 10 && now.hour() <= 22 && now.minute() == 00 && now.second() >= 00 && now.second() < 10 ) {
614                lcd.setCursor(7,0);   //оставляем точки разделители статическими
615                lcd.print(".");       //
616                lcd.setCursor(7,1);   //
617                lcd.print(".");       //
618        }
619        if (now.dayOfTheWeek() >= 1 && now.dayOfTheWeek() <= 7 && now.hour() == 14 && now.minute() == 20 && now.second() >= 00 && now.second() < 15) {
620                lcd.setCursor(7,0);   //оставляем точки разделители статическими
621                lcd.print(".");       //
622                lcd.setCursor(7,1);   //
623                lcd.print(".");       //
624        
625   
626       //мигание двух точек, которые разделяют час и минуты
627       //можно изменить положение на 8 символ
628       //нечётное - точки
629       if(now.second() == 1 ||
630          now.second() == 3 ||
631          now.second() == 5 ||
632          now.second() == 7 ||
633          now.second() == 9 ||
634          now.second() == 11 ||
635          now.second() == 13 ||
636          now.second() == 15 ||
637          now.second() == 17 ||
638          now.second() == 19 ||
639          now.second() == 21 ||
640          now.second() == 23 ||
641          now.second() == 25 ||
642          now.second() == 27 ||
643          now.second() == 29 ||
644          now.second() == 31 ||
645          now.second() == 33 ||
646          now.second() == 35 ||
647          now.second() == 37 ||
648          now.second() == 39 ||
649          now.second() == 41 ||
650          now.second() == 43 ||
651          now.second() == 45 ||
652          now.second() == 47 ||
653          now.second() == 49 ||
654          now.second() == 51 ||
655          now.second() == 53 ||
656          now.second() == 55 ||
657          now.second() == 57 ||
658          now.second() == 59    ) {
659                                  
660          lcd.setCursor(7,0);
661          lcd.print(".");
662          lcd.setCursor(7,1);
663          lcd.print(".");
664       }
665       //четное - пробелы
666       if(now.second() == 2 ||
667          now.second() == 4 ||
668          now.second() == 6 ||
669          now.second() == 8 ||
670          now.second() == 10 ||
671          now.second() == 12 ||
672          now.second() == 14 ||
673          now.second() == 16 ||
674          now.second() == 18 ||
675          now.second() == 20 ||
676          now.second() == 22 ||
677          now.second() == 24 ||
678          now.second() == 26 ||
679          now.second() == 28 ||
680          now.second() == 30 ||
681          now.second() == 32 ||
682          now.second() == 34 ||
683          now.second() == 36 ||
684          now.second() == 38 ||
685          now.second() == 40 ||
686          now.second() == 42 ||
687          now.second() == 44 ||
688          now.second() == 46 ||
689          now.second() == 48 ||
690          now.second() == 50 ||
691          now.second() == 52 ||
692          now.second() == 54 ||
693          now.second() == 56 ||
694          now.second() == 58    ) {
695                                  
696          lcd.setCursor(7,0);
697          lcd.print(" ");
698          lcd.setCursor(7,1);
699          lcd.print(" ");
700       }
701    }
702      
703    if(regim==3)// ВТОРОЙ режим
704    {
705      if(millis()-timing>=500) {
706      DateTime now = rtc.now();
707      //printDigits(now.day(), DEC);         если что
708      //printDigits(now.month(), "digits");
709      lcd.setCursor(5,0);
710      if(now.day() < 10) {
711        lcd.print("0");
712      }
713      lcd.print(now.day());
714      lcd.print(".");
715      if(now.month() < 10) {
716        lcd.print("0");
717      }
718      lcd.print(now.month());
719      //расположение дней недели на экране, пн - вт, чт - вс -- на 4 символе, если ср, то на 3 символе
720      if(now.dayOfTheWeek() == 1 || now.dayOfTheWeek() == 2 || now.dayOfTheWeek() == 4 || now.dayOfTheWeek() == 5 || now.dayOfTheWeek() == 6 || now.dayOfTheWeek() == 7) {
721         lcd.setCursor(4,1);
722         lcd.print(daysOfTheWeek[now.dayOfTheWeek()]);      
723      }
724      if(now.dayOfTheWeek() == 3) {
725         lcd.setCursor(3,1);
726         lcd.print(daysOfTheWeek[now.dayOfTheWeek()]);
727      }
728      timing=millis();
729      }
730    }
731     
732    if(regim==1)//ТРЕЙТИЙ режим
733    {
734      if(millis()-timing>=500) {
735          lcd.setCursor(0, 0);
736          lcd.print(round(bme.readTemperature()));
737          lcd.print("'C"); //определение температуры, вывод ее на экран в градусах Цельсия.
738          lcd.setCursor(6, 0);
739          lcd.print(round(bme.readAltitude(SEALEVELPRESSURE_HPA)));
740          lcd.print("m");
741          lcd.setCursor(13, 0);
742          lcd.print(round(bme.readHumidity()));
743          lcd.print("%");
744          lcd.setCursor(0, 1);
745          lcd.print(round(bme.readPressure()*0.0075));
746          lcd.print(" mm.rt.st."); //определение давления, вывод его на экран
747          timing=millis();
748      }
749    }
750   
751}
752 
753void digitalClockDisplay(){
754  // digital clock display of the time
755  DateTime now = rtc.now();
756   
757  printDigits(now.hour()/10,0);
758  printDigits(now.hour()%10,4);
759 
760  printDigits(now.minute()/10,9);
761  printDigits(now.minute()%10,13);
762   
763 
764  //Будильник №1
765  //День недели начала - день конца/час/минута/секунда начала - секунда конца звона
766  if (now.dayOfTheWeek() >= 1 && now.dayOfTheWeek() <= 7 && now.hour() == 14 && now.minute() == 20 && now.second() >= 00 && now.second() < 15) {
767      tone(piezoPin, 120, 400);
768      delay(800);
769      tone(piezoPin, 300, 400);
770      delay(800);
771      tone(piezoPin, 550, 400);
772      delay(800);
773      tone(piezoPin, 450, 400);
774      delay(800);
775      tone(piezoPin, 300, 400);
776      delay(800);
777      tone(piezoPin, 120, 400);
778       
779  }
780 
781  //ежечасовой звон, час начала - час конца, минута начала, секунда начала и секунда конца
782  if (now.hour() >= 10 && now.hour() <= 22 && now.minute() == 00 && now.second() >= 00 && now.second() < 5 ) {
783      tone(piezoPin, 120, 400);
784      delay(800);
785      tone(piezoPin, 300, 400);
786      delay(800);
787      tone(piezoPin, 550, 400);
788      delay(800);
789      tone(piezoPin, 450, 400);
790      delay(800);
791      tone(piezoPin, 300, 400);
792      delay(800);
793      tone(piezoPin, 120, 400);
794      lcd.setCursor(7,0);   //оставляем точки разделители статическими
795      lcd.print(".");       //
796      lcd.setCursor(7,1);   //
797      lcd.print(".");       //
798  
799   
800 
801  //секунды на главном экране
802  //lcd.setCursor(7, 1);
803  //lcd.print(now.second()/10);
804  //lcd.print(now.second()%10);
805}
806 
807void printDigits(int digits, int x){
808  // utility function for digital clock display: prints preceding colon and leading 0
809 
810  switch (digits) {
811  case 0: 
812    custom0(x);
813    break;
814  case 1: 
815    custom1(x);
816    break;
817  case 2: 
818    custom2(x);
819    break;
820  case 3: 
821    custom3(x);
822    break;
823  case 4: 
824    custom4(x);
825    break;
826  case 5: 
827    custom5(x);
828    break;
829  case 6: 
830    custom6(x);
831    break;
832  case 7: 
833    custom7(x);
834    break;
835  case 8: 
836    custom8(x);
837    break;
838  case 9: 
839    custom9(x);
840    break;
841  }
842}

Прошивка для nokia lcd:

001#include <Adafruit_I2CDevice.h>
002#include <Adafruit_GFX.h>
003#include <Adafruit_PCD8544.h>
004Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 7, 8);
005#include <Wire.h>
006#include "RTClib.h"
007RTC_DS1307 rtc;
008 
009#include <Adafruit_Sensor.h>
010#include <Adafruit_BME280.h>
011#define SEALEVELPRESSURE_HPA (1013.25)
012Adafruit_BME280 bme;
013 
014uint32_t ms, ms1 = 0;
015 
016#define BTN 2
017int piezoPin = 12;
018 
019int regim=1;
020int flag=0;
021 
022const unsigned char PROGMEM smileBmp[] = {
023  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0,
0410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0,
0420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0,
0430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0,
0440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0,
0450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf0,
0460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf0,
0470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf0,
0480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0,
0490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0,
0500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x80,
0510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00,
0520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00,
0530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
071};
072 
073const unsigned char PROGMEM clockBmp[] = {
0740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00,
0890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80,
0900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xc0,
0910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x60,
0920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x60,
0930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x18, 0x30,
0940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x18, 0x30,
0950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x1f, 0xb0,
0960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0f, 0x30,
0970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x30,
0980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x30,
0990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x60,
1000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x60,
1010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xc0,
1020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80,
1030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00,
1040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
122};
123 
124void setup() {
125    pinMode(piezoPin, OUTPUT);
126    pinMode(BTN, INPUT);
127    Serial.begin(9600); // подключаем монитор порта
128    bme.begin(0x76); // запускаем приём ифнормации с датчика через i2c
129    rtc.begin();
130    Wire.begin();
131    display.begin();
132    display.clearDisplay();
133    display.display();
134     
135    display.setContrast(50); // установка контраста
136    delay(1000);
137    display.setTextSize(1);  // установка размера шрифта
138    display.setTextColor(BLACK); // установка цвета текста
139    //rtc.adjust(DateTime(__DATE__, __TIME__));
140 
141}
142 
143void digitalClock() {
144  ms = millis();
145       if ( ( ms - ms1 ) > 1000 || ms < ms1 ) {
146          ms1 = ms;
147          display.display();
148          display.clearDisplay();
149     }
150      DateTime now = rtc.now();
151      display.setTextSize(2);
152      if(now.hour() < 10) {
153        display.setCursor(11, 0);
154        display.println("0");
155        display.setCursor(23,0);    
156        display.println(now.hour());
157      }
158      if(now.hour() >= 10) {
159        display.setCursor(11,0);    
160        display.println(now.hour());
161      }
162      if(now.minute() < 10) {
163        display.setCursor(51,0);
164        display.println("0");
165        display.setCursor(63,0);
166        display.println(now.minute());
167      }
168      if(now.minute() >= 10) {
169        display.setCursor(51,0);
170        display.println(now.minute());
171      }
172       
173      //будильник №1
174      if (now.dayOfTheWeek() >= 1 && now.dayOfTheWeek() <= 7 && now.hour() == 14 && now.minute() == 28 && now.second() >= 00 && now.second() < 20) {
175      display.drawBitmap(0, 0, clockBmp, 84, 44, BLACK);
176      tone(piezoPin, 120, 400);
177      delay(800);
178      tone(piezoPin, 300, 400);
179      delay(800);
180      tone(piezoPin, 550, 400);
181      delay(800);
182      tone(piezoPin, 450, 400);
183      delay(800);
184      tone(piezoPin, 300, 400);
185      delay(800);
186      tone(piezoPin, 120, 400);
187      }
188       
189      
190      display.setCursor(37, 3);
191      display.println("-");
192      display.setTextSize(1);
193      if(now.second() < 10) {
194        display.setCursor(37,0);
195        display.println("0");
196        display.setCursor(43,0);
197        display.println(now.second());
198      }
199      if (now.second() >= 10){
200        display.setCursor(37,0);
201        display.println(now.second());
202      }
203      if (now.day() < 10) {
204        display.setCursor(28, 16);
205        display.println("0");
206        display.setCursor(34, 16);
207        display.println(now.day());
208      }
209      if (now.day() >= 10) {
210        display.setCursor(28, 16);
211        display.println(now.day());
212      }
213       
214      display.setCursor(40, 16);
215      display.println(".");
216      if(now.month() < 10){
217        display.setCursor(46, 16);
218        display.println("0");
219        display.setCursor(52, 16);
220        display.println(now.month());
221      }
222      if(now.month() >= 10) {
223        display.setCursor(46, 16);
224        display.println(now.month());
225      }
226      if(now.dayOfTheWeek() == 1){
227        display.setCursor(11, 23);
228        display.println(utf8rus("Понедельник"));
229      }
230      if(now.dayOfTheWeek() == 2){
231        display.setCursor(22, 23);
232        display.println(utf8rus("Вторник"));
233      }
234      if(now.dayOfTheWeek() == 3){
235        display.setCursor(27, 23);
236        display.println(utf8rus("Среда"));
237      }
238      if(now.dayOfTheWeek() == 4){
239        display.setCursor(21, 23);
240        display.println(utf8rus("Четверг"));
241      }
242      if(now.dayOfTheWeek() == 5){
243        display.setCursor(21, 23);
244        display.println(utf8rus("Пятница"));
245      }
246      if(now.dayOfTheWeek() == 6){
247        display.setCursor(21, 23);
248        display.println(utf8rus("Суббота"));
249      }
250      if(now.dayOfTheWeek() == 7){
251        display.setCursor(11, 23);
252        display.println(utf8rus("Воскресенье"));
253      }
254        display.setCursor(0, 32);
255        display.print(round(bme.readTemperature()));
256        display.println(utf8rus("'C")); //определение температуры, вывод ее на экран в градусах Цельсия.
257        display.setCursor(34, 32);
258        display.print(round(bme.readAltitude(SEALEVELPRESSURE_HPA)));
259        display.println(utf8rus("м"));
260        if(bme.readHumidity() > 70) {
261           tone(piezoPin, 200, 100);
262           delay(200);
263           tone(piezoPin, 200, 100);
264           delay(200);
265           display.setCursor(65, 32);
266           display.print(round(bme.readHumidity()));
267           display.println("%"); 
268           //display.setCursor(72, 15);
269           //display.setTextSize(2);
270           //display.print("!");
271           display.drawBitmap(0, 0, smileBmp, 84, 44, BLACK);
272        }
273        if(bme.readHumidity() < 70) {
274              display.setCursor(65, 32);
275              display.print(round(bme.readHumidity()));
276              display.println("%");
277           }
278        display.setTextSize(1);  
279        display.setCursor(0, 40);
280         display.print(round(bme.readPressure()*0.0075));
281        display.println(utf8rus(" мм.рт.ст.")); //определение давления, вывод его на экран
282      delay(1000);
283}
284 
285void loop() {
286       digitalClock();
287}
288 
289/* Recode russian fonts from UTF-8 to Windows-1251 */
290String utf8rus(String source)
291{
292  int i,k;
293  String target;
294  unsigned char n;
295  char m[2] = { '0', '\0' };
296 
297  k = source.length(); i = 0;
298 
299  while (i < k) {
300    n = source[i]; i++;
301 
302    if (n >= 0xBF){
303      switch (n) {
304        case 0xD0: {
305          n = source[i]; i++;
306          if (n == 0x81) { n = 0xA8; break; }
307          if (n >= 0x90 && n <= 0xBF) n = n + 0x2F;
308          break;
309        }
310        case 0xD1: {
311          n = source[i]; i++;
312          if (n == 0x91) { n = 0xB7; break; }
313          if (n >= 0x80 && n <= 0x8F) n = n + 0x6F;
314          break;
315        }
316      }
317    }
318    m[0] = n; target = target + String(m);
319  }
320return target;
321}

Отдельные кусочки кода были взяты откуда-то или написаны мной. Не претендую на перфекционизм !! :)))

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

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020
158lcd.createChar(7,block);

Это не нужно, такой символ в LCD1602 имеется, его код - 255. Я тоже брал этот код для часов на таком дисплее, но с переделками, шрифт получился чуть красивее. Ну и по результатам критики отрисовку цифр переделал. В использованном вами коде она демонстрационная и, соответственно, слишком раздутая.

Код мигания двоеточия на 70 строк - это жесть ))) Проверка числа на четность делается делением на 2 - если остаток равен нулю, значит четное и наоборот. И код получается примерно таким:

1char dt = ".";
2if(now.second() % 2 > 0)
3  dt = " ";
4lcd.setCursor(7, 0);
5lcd.print(dt);
6lcd.setCursor(7, 1);
7lcd.print(dt);

 

alexey.st0
alexey.st0 аватар
Offline
Зарегистрирован: 06.06.2020

За мигания точек спасибо! В 10 раз меньше, исправлю

Насчёт символа.. Это уже мелочное... Шрифт меня не напрягает, пойдёт  

 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

alexey.st0 пишет:

Насчёт символа.. Это уже мелочное... Шрифт меня не напрягает, пойдёт  

Собственно, дело не в шрифте, а в отрисовке цифр

alexey.st0
alexey.st0 аватар
Offline
Зарегистрирован: 06.06.2020

Заменил код мигания точек на ваш код, выдаёт следующую ошибку в терминал:

1warning: invalid conversion from 'const char*' to 'char' [-fpermissive]
2 
3          dot = " ";

 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

warning - это не ошибка. Код работает?

alexey.st0
alexey.st0 аватар
Offline
Зарегистрирован: 06.06.2020

Да, но вместо точек непонятные символы

alexey.st0
alexey.st0 аватар
Offline
Зарегистрирован: 06.06.2020

Уже починил. Просто поменял на const char* и переместил в void digitalClockDisplay()

1const char* dot = ".";
2        if(now.second() % 2 > 0) {
3          dot = " ";
4        }
5           
6        lcd.setCursor(7, 0);
7        lcd.print(dot);
8        lcd.setCursor(7, 1);
9        lcd.print(dot);

 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Всегда считал, что константы изменению не подлежат ))

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

1char dot = '.';
2if(now.second() % 2 > 0) {
3dot = ' ';
4}
5           
6lcd.setCursor(7, 0);
7lcd.print(dot);
8lcd.setCursor(7, 1);
9lcd.print(dot);

 

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

v258 пишет:
Код мигания двоеточия на 70 строк - это жесть ))) Проверка числа на четность делается делением на 2 - если остаток равен нулю, значит четное и наоборот. И код получается примерно таким:

Нет, код получается примерно таким: 

1char dt = (now.second() & 0x01) ? '.' : ' ';

 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

DetSimen пишет:

Нет, код получается примерно таким: 

1char dt = (now.second() & 0x01) ? '.' : ' ';

Сходу под дых? ))))

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

v258 пишет:

Сходу под дых? ))))

Чойта?

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Человек с простой арифметикой не сообразил, а ты ему битовыми операциями ))

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

Так пусть учится. Код не смотрел, но судя по стилю изложения, автору лет 15... В этом возрасте еще не поздно узнавать новое :)