Умные Часы-Метеостанция на 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. Код приведён ниже (нашёл его на этом же форуме). НО, если вдруг вы не хотите делать адаптивной подсветку, я сделал в проекте функцию управления подсветкой через пульт ДУ !

int PhCount = analogRead(7);
  PhCount = PhCount/4;
  if(PhCount > 255){
    analogWrite(led, 255); 
  } else {
    if(PhCount < 40){ //минимальный уровень подсветки 40
      analogWrite(led, 40);
    } else {
      analogWrite(led, PhCount);
    } 
  }

Видеоролики, где продемонстрировал работу метеостанции на 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:

#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme;

#include "IRremote.h"
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x3F,16,2);
//ИК приемник
IRrecv irrecv(A0); // указываем пин, к которому подключен IR приемник
decode_results results;



byte LT[8] = 
{
  B00111,
  B01111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111
};
byte UB[8] =
{
  B11111,
  B11111,
  B11111,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000
};
byte RT[8] =
{

  B11100,
  B11110,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111
};
byte LL[8] =
{


  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B01111,
  B00111
};
byte LB[8] =
{
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B11111,
  B11111,
  B11111
};
byte LR[8] =
{


  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11110,
  B11100
};
byte MB[8] =
{
  B11111,
  B11111,
  B11111,
  B00000,
  B00000,
  B00000,
  B11111,
  B11111
};
byte block[8] =
{
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111
};


// loop counter
int count = 0;

int flag=0;
int piezoPin = 12;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

int regim   =1;
int regim_1 =1;
int regim_2 =1;

int led = 6;   

#define BTN 2




unsigned long timing;

void setup() {
   pinMode(led, OUTPUT);
   pinMode(BTN, INPUT);
   pinMode(piezoPin, OUTPUT);
   pinMode(A0, INPUT); //логика ик приемника
   pinMode(11, OUTPUT); //питание ик приемника
   digitalWrite(11, HIGH); 
   rtc.begin();
   lcd.init();                      // initialize the lcd 
   lcd.backlight();
   lcd.home();
   analogWrite(led, 254); 
   Serial.begin(9600); // подключаем монитор порта
   Wire.begin();
   irrecv.enableIRIn(); // запускаем прием инфракрасного сигнала
   bme.begin(0x76); // запускаем приём ифнормации с датчика через i2c
  

   lcd.createChar(0,LT);
   lcd.createChar(1,UB);
   lcd.createChar(2,RT);
   lcd.createChar(3,LL);
   lcd.createChar(4,LB);
   lcd.createChar(5,LR);
   lcd.createChar(6,MB);
   lcd.createChar(7,block);
    
   
   // sets the LCD's rows and colums:
   lcd.clear();

   if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    //rtc.adjust(DateTime(__DATE__, __TIME__));
  }
}

void custom0(int x)
{ // uses segments to build the number 0

  lcd.setCursor(x,0); // set cursor to column 0, line 0 (first row)
  lcd.write(0);  // call each segment to create
  lcd.write(1);  // top half of the number
  lcd.write(2);
  lcd.setCursor(x, 1); // set cursor to colum 0, line 1 (second row)
  lcd.write(3);  // call each segment to create
  lcd.write(4);  // bottom half of the number
  lcd.write(5);
}

void custom1(int x)
{
  lcd.setCursor(x,0);
  lcd.write(1);
  lcd.write(2);
  lcd.print(" ");
  lcd.setCursor(x,1);
  lcd.write(4);
  lcd.write(7);
  lcd.write(4);
}

void custom2(int x)
{
  lcd.setCursor(x,0);
  lcd.write(6);
  lcd.write(6);
  lcd.write(2);
  lcd.setCursor(x, 1);
  lcd.write(3);
  lcd.write(4);
  lcd.write(4);
}

void custom3(int x)
{
  lcd.setCursor(x,0);
  lcd.write(6);
  lcd.write(6);
  lcd.write(2);
  lcd.setCursor(x, 1);
  lcd.write(4);
  lcd.write(4);
  lcd.write(5); 
}

void custom4(int x)
{
  lcd.setCursor(x,0);
  lcd.write(3);
  lcd.write(4);
  lcd.write(7);
  lcd.setCursor(x, 1);
  lcd.print(" ");
  lcd.print(" ");
  lcd.write(7);
}

void custom5(int x)
{
  lcd.setCursor(x,0);
  lcd.write(3);
  lcd.write(6);
  lcd.write(6);
  lcd.setCursor(x, 1);
  lcd.write(4);
  lcd.write(4);
  lcd.write(5);
}

void custom6(int x)
{
  lcd.setCursor(x,0);
  lcd.write(0);
  lcd.write(6);
  lcd.write(6);
  lcd.setCursor(x, 1);
  lcd.write(3);
  lcd.write(4);
  lcd.write(5);
}

void custom7(int x)
{
  lcd.setCursor(x,0);
  lcd.write(1);
  lcd.write(1);
  lcd.write(2);
  lcd.setCursor(x, 1);
  lcd.print(" ");
  lcd.print(" ");
  lcd.write(7);
}

void custom8(int x)
{
  lcd.setCursor(x,0);
  lcd.write(0);
  lcd.write(6);
  lcd.write(2);
  lcd.setCursor(x, 1);
  lcd.write(3);
  lcd.write(4);
  lcd.write(5);
}

void custom9(int x)
{
  lcd.setCursor(x,0);
  lcd.write(0);
  lcd.write(6);
  lcd.write(2);
  lcd.setCursor(x, 1);
  lcd.print(" ");
  lcd.print(" ");
  lcd.write(7);

}

void clearnumber(int x)
{ //clears the area the custom number is displayed in 
  lcd.setCursor(x,0);
  lcd.print("   ");
  lcd.setCursor(x,1); 
  lcd.print("   ");
}

void(* resetFunc) (void) = 0; //функция перезагрузки arduino


void loop() {
 
  

    
  //Функция перезагрузки arduino каждый день в 00:00:00 
  DateTime now = rtc.now();
  if (now.hour() == 0 && now.minute() == 00 && now.second() == 00) {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Reboot device..");
      delay(1000);
      lcd.clear();
      resetFunc();
  }

  int PhCount = analogRead(7);
  PhCount = PhCount/4;
  if(PhCount > 255){
    analogWrite(led, 255); 
  } else {
    if(PhCount < 40){ //минимальный уровень подсветки 40
      analogWrite(led, 40);
    } else {
      analogWrite(led, PhCount);
    } 
  }

  //управление с пульта на ИК приёмник
  if (irrecv.decode(&results)) { // если данные пришли выполняем команды   
      Serial.println(results.value); //для вывода в монитор порта значений с ИК приёмника

      //Переключение экранов с пульта
      if(results.value == 59415 || results.value == 16769565) {
        regim++;
        tone(piezoPin, 200, 50);   
        lcd.clear();
         
        //это нужно для того что бы с каждым нажатием кнопки 
        //происходило только одно действие 
        // плюс защита от "дребезга"  100% 
          
        if(regim>3)//ограничим количество режимов 
        { 
          regim=1;//так как мы используем только одну кнопку, 
                    // то переключать режимы будем циклично 
        }
      }

      //управление степенью якркости подсветки LCD
      //одна кнопка увеличить яркость, вторая - уменьшить
      if(results.value == 58395 || results.value == 16748655){ //увеличить
          regim_2++;
          if(regim_2>4)//ограничим количество режимов 
          { 
            regim_2=4;
          }  
          if(regim_2==1) { 
            analogWrite(led, 20);
          }
          if(regim_2==2) { 
            analogWrite(led, 100);
          }
          if(regim_2==3) { 
            analogWrite(led, 200);
          }
          if(regim_2==4) { 
            analogWrite(led, 255);
          }
      }
      if(results.value == 43095 || results.value == 16754775){ //уменьшить
          regim_2--;
          if(regim_2<1)//ограничим количество режимов 
          { 
            regim_2=1;
          }
          if(regim_2==1) { 
            analogWrite(led, 20);
          }
          if(regim_2==2) { 
            analogWrite(led, 100);
          }
          if(regim_2==3) { 
            analogWrite(led, 200);
          }
          if(regim_2==4) { 
            analogWrite(led, 255);
          }    
      }
      
      //управление подсветкой lcd 
      //При нажатии кнопки на пульте - выкл или вкл подсветку
      if(results.value == 5355 || results.value == 16736925){ //кнопка1 в формате DEC
          regim_1++;
          if(regim_1>2)//ограничим количество режимов 
          { 
            regim_1=1;
          }  
          if(regim_1==1) {  //режим 1 - lcd on
            lcd.clear();
            lcd.setCursor(4,0);
            lcd.print("LCD on");
            tone(piezoPin, 900, 50);
            delay(500);
            tone(piezoPin, 900, 50);
            lcd.backlight(); //вкл
            delay(500);
            lcd.clear();   
          }

          if(regim_1==2) { //режим 2 - lcd off
            lcd.clear();
            lcd.setCursor(4,0);
            lcd.print("LCD off");
            tone(piezoPin, 900, 50);
            delay(500);
            tone(piezoPin, 900, 50);
            lcd.noBacklight(); //выкл
            delay(500);
            lcd.clear();
          }
                   
      }

      //Таймер №1 по нажатию на выбранную кнопку с пульта
      if(results.value == 4335 || results.value == 16724175) { //выбранная кнопка              
          lcd.clear();
          lcd.setCursor(2,0);
          lcd.print("Timer 20s on");
          lcd.setCursor(6,1);
          lcd.print("....");
          tone(piezoPin, 900, 50);
          delay(20000); //засекаем таймер 
          lcd.clear();
          lcd.setCursor(4,0);
          lcd.print("Time out!"); //время вышло!
          lcd.setCursor(6,1);
          lcd.print("....");
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(500);
          lcd.clear();
          delay(300);
          lcd.setCursor(4,0);
          lcd.print("Time out!");
          lcd.setCursor(6,1);
          lcd.print("....");
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(500);
          lcd.clear();
          delay(300);
          lcd.setCursor(4,0);
          lcd.print("Time out!");
          lcd.setCursor(6,1);
          lcd.print("....");
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(500);
          lcd.clear();
          delay(300);
       }

       //Таймер №2 по нажатию на выбранную кнопку с пульта
      if(results.value == 36975 || results.value == 16718055) { //выбранная кнопка              
          lcd.clear();
          lcd.setCursor(2,0);
          lcd.print("Timer 5s on");
          lcd.setCursor(6,1);
          lcd.print("....");
          tone(piezoPin, 900, 50);
          delay(5000); //засекаем таймер 
          lcd.clear();
          lcd.setCursor(4,0);
          lcd.print("Time out!"); //время вышло!
          lcd.setCursor(6,1);
          lcd.print("....");
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(500);
          lcd.clear();
          delay(300);
          lcd.setCursor(4,0);
          lcd.print("Time out!");
          lcd.setCursor(6,1);
          lcd.print("....");
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(500);
          lcd.clear();
          delay(300);
          lcd.setCursor(4,0);
          lcd.print("Time out!");
          lcd.setCursor(6,1);
          lcd.print("....");
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(200);
          tone(piezoPin, 900, 100);
          delay(500);
          lcd.clear();
          delay(300);
       }
       
       //перезагрузка устр-ва по нажатию на кнопку пульта 
       if(results.value == 25755 || results.value == 16753245) {
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Reboot device...");
          delay(1000);
          lcd.clear();
          resetFunc();
         }
       
      irrecv.resume();
  }

  if(digitalRead(BTN)==HIGH&&flag==0) {
      tone(piezoPin, 200, 50);
  }
  
  if(digitalRead(BTN)==HIGH&&flag==0)//если кнопка нажата   
     // и перемення flag равна 0 , то ... 
     { 
       regim++;   
       flag=1; 
       lcd.clear();
         
        //это нужно для того что бы с каждым нажатием кнопки 
        //происходило только одно действие 
        // плюс защита от "дребезга"  100% 
          
        if(regim>3)//ограничим количество режимов 
        { 
          regim=1;//так как мы используем только одну кнопку, 
                    // то переключать режимы будем циклично 
        }
     } 
   

   
    if(digitalRead(BTN)==LOW&&flag==1)//если кнопка НЕ нажата 
    //и переменная flag равна - 1 ,то ... 
    {           
        flag=0;//обнуляем переменную "BTN"         
    } 
    
    //Автоматическое переключение на главнй экран с циферблатом, если где-то в меню застрял > 40 секунд
    if (regim == 1 && millis() - timing > 40000) { //если режим ВТОРОЙ
          timing = millis(); 
          lcd.clear();
          regim=2;
    }
    if (regim == 3 && millis() - timing > 40000) { //если режим ТРЕТИЙ
          timing = millis(); 
          lcd.clear();
          regim=2;
    }

     
   
    if(regim==2)//ПЕРВЫЙ режим 
    { 
       digitalClockDisplay();
       delay(100);
       //мигание временем каждый час (с 10 до 22, указывается в void digitalClockDisplay())
       DateTime now = rtc.now();
       if (now.hour() >= 10 && now.hour() <= 22 && now.minute() == 00 && now.second() >= 00 && now.second() < 10 ) {
          digitalClockDisplay();
          delay(600);
          lcd.clear();
          delay(600);
       }
       //мигание временем во время сигнала будильника (указывается в void digitalClockDisplay())
       if (now.dayOfTheWeek() >= 1 && now.dayOfTheWeek() <= 7 && now.hour() == 14 && now.minute() == 20 && now.second() >= 00 && now.second() < 15) {
          digitalClockDisplay();
          delay(600);
          lcd.clear();
          delay(600);
       }
        //оставляем точки статическими при ежечасовом звоне и будильнике (при мигании циферблата)
        if (now.hour() >= 10 && now.hour() <= 22 && now.minute() == 00 && now.second() >= 00 && now.second() < 10 ) {
                lcd.setCursor(7,0);   //оставляем точки разделители статическими
                lcd.print(".");       //
                lcd.setCursor(7,1);   //
                lcd.print(".");       //
        }
        if (now.dayOfTheWeek() >= 1 && now.dayOfTheWeek() <= 7 && now.hour() == 14 && now.minute() == 20 && now.second() >= 00 && now.second() < 15) {
                lcd.setCursor(7,0);   //оставляем точки разделители статическими
                lcd.print(".");       //
                lcd.setCursor(7,1);   //
                lcd.print(".");       //
        }  
  
       //мигание двух точек, которые разделяют час и минуты
       //можно изменить положение на 8 символ
       //нечётное - точки
       if(now.second() == 1 ||
          now.second() == 3 ||
          now.second() == 5 ||
          now.second() == 7 ||
          now.second() == 9 ||
          now.second() == 11 ||
          now.second() == 13 ||
          now.second() == 15 ||
          now.second() == 17 ||
          now.second() == 19 ||
          now.second() == 21 ||
          now.second() == 23 ||
          now.second() == 25 ||
          now.second() == 27 ||
          now.second() == 29 ||
          now.second() == 31 ||
          now.second() == 33 ||
          now.second() == 35 ||
          now.second() == 37 ||
          now.second() == 39 ||
          now.second() == 41 ||
          now.second() == 43 ||
          now.second() == 45 ||
          now.second() == 47 ||
          now.second() == 49 ||
          now.second() == 51 ||
          now.second() == 53 ||
          now.second() == 55 ||
          now.second() == 57 ||
          now.second() == 59    ) {
                                 
          lcd.setCursor(7,0);
          lcd.print(".");
          lcd.setCursor(7,1);
          lcd.print(".");
       }
       //четное - пробелы
       if(now.second() == 2 ||
          now.second() == 4 ||
          now.second() == 6 ||
          now.second() == 8 ||
          now.second() == 10 ||
          now.second() == 12 ||
          now.second() == 14 ||
          now.second() == 16 ||
          now.second() == 18 ||
          now.second() == 20 ||
          now.second() == 22 ||
          now.second() == 24 ||
          now.second() == 26 ||
          now.second() == 28 ||
          now.second() == 30 ||
          now.second() == 32 ||
          now.second() == 34 ||
          now.second() == 36 ||
          now.second() == 38 ||
          now.second() == 40 ||
          now.second() == 42 ||
          now.second() == 44 ||
          now.second() == 46 ||
          now.second() == 48 ||
          now.second() == 50 ||
          now.second() == 52 ||
          now.second() == 54 ||
          now.second() == 56 ||
          now.second() == 58    ) {
                                 
          lcd.setCursor(7,0);
          lcd.print(" ");
          lcd.setCursor(7,1);
          lcd.print(" ");
       }
    } 
     
    if(regim==3)// ВТОРОЙ режим
    { 
      if(millis()-timing>=500) {
      DateTime now = rtc.now(); 
      //printDigits(now.day(), DEC);         если что
      //printDigits(now.month(), "digits");
      lcd.setCursor(5,0);
      if(now.day() < 10) {
        lcd.print("0");
      }
      lcd.print(now.day());
      lcd.print(".");
      if(now.month() < 10) {
        lcd.print("0");
      }
      lcd.print(now.month()); 
      //расположение дней недели на экране, пн - вт, чт - вс -- на 4 символе, если ср, то на 3 символе
      if(now.dayOfTheWeek() == 1 || now.dayOfTheWeek() == 2 || now.dayOfTheWeek() == 4 || now.dayOfTheWeek() == 5 || now.dayOfTheWeek() == 6 || now.dayOfTheWeek() == 7) {
         lcd.setCursor(4,1);
         lcd.print(daysOfTheWeek[now.dayOfTheWeek()]);       
      }
      if(now.dayOfTheWeek() == 3) {
         lcd.setCursor(3,1);
         lcd.print(daysOfTheWeek[now.dayOfTheWeek()]);
      }
      timing=millis();
      }
    } 
    
    if(regim==1)//ТРЕЙТИЙ режим
    { 
      if(millis()-timing>=500) {
          lcd.setCursor(0, 0);
          lcd.print(round(bme.readTemperature()));
          lcd.print("'C"); //определение температуры, вывод ее на экран в градусах Цельсия.
          lcd.setCursor(6, 0);
          lcd.print(round(bme.readAltitude(SEALEVELPRESSURE_HPA)));
          lcd.print("m");
          lcd.setCursor(13, 0);
          lcd.print(round(bme.readHumidity()));
          lcd.print("%");
          lcd.setCursor(0, 1);
          lcd.print(round(bme.readPressure()*0.0075));
          lcd.print(" mm.rt.st."); //определение давления, вывод его на экран
          timing=millis();
      }
    }
  
}

void digitalClockDisplay(){
  // digital clock display of the time
  DateTime now = rtc.now();
  
  printDigits(now.hour()/10,0); 
  printDigits(now.hour()%10,4); 

  printDigits(now.minute()/10,9);
  printDigits(now.minute()%10,13);
  

  //Будильник №1
  //День недели начала - день конца/час/минута/секунда начала - секунда конца звона
  if (now.dayOfTheWeek() >= 1 && now.dayOfTheWeek() <= 7 && now.hour() == 14 && now.minute() == 20 && now.second() >= 00 && now.second() < 15) {
      tone(piezoPin, 120, 400);
      delay(800);
      tone(piezoPin, 300, 400);
      delay(800);
      tone(piezoPin, 550, 400);
      delay(800);
      tone(piezoPin, 450, 400);
      delay(800);
      tone(piezoPin, 300, 400);
      delay(800);
      tone(piezoPin, 120, 400);
      
  }

  //ежечасовой звон, час начала - час конца, минута начала, секунда начала и секунда конца
  if (now.hour() >= 10 && now.hour() <= 22 && now.minute() == 00 && now.second() >= 00 && now.second() < 5 ) {
      tone(piezoPin, 120, 400);
      delay(800);
      tone(piezoPin, 300, 400);
      delay(800);
      tone(piezoPin, 550, 400);
      delay(800);
      tone(piezoPin, 450, 400);
      delay(800);
      tone(piezoPin, 300, 400);
      delay(800);
      tone(piezoPin, 120, 400);
      lcd.setCursor(7,0);   //оставляем точки разделители статическими
      lcd.print(".");       //
      lcd.setCursor(7,1);   //
      lcd.print(".");       //
  }  
  

  //секунды на главном экране
  //lcd.setCursor(7, 1);
  //lcd.print(now.second()/10);
  //lcd.print(now.second()%10);
}

void printDigits(int digits, int x){
  // utility function for digital clock display: prints preceding colon and leading 0

  switch (digits) {
  case 0:  
    custom0(x);
    break;
  case 1:  
    custom1(x);
    break;
  case 2:  
    custom2(x);
    break;
  case 3:  
    custom3(x);
    break;
  case 4:  
    custom4(x);
    break;
  case 5:  
    custom5(x);
    break;
  case 6:  
    custom6(x);
    break;
  case 7:  
    custom7(x);
    break;
  case 8:  
    custom8(x);
    break;
  case 9:  
    custom9(x);
    break;
  }
}

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

#include <Adafruit_I2CDevice.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 7, 8);
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;

#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme;

uint32_t ms, ms1 = 0;

#define BTN 2
int piezoPin = 12;

int regim=1;
int flag=0;

const unsigned char PROGMEM smileBmp[] = {
  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, 
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, 
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, 0x7f, 0xc0, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf0, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf0, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf0, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x80, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 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, 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, 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, 0x00
};

const unsigned char PROGMEM clockBmp[] = {
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, 
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, 
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, 0x3e, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xc0, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x60, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x60, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x18, 0x30, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x18, 0x30, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x1f, 0xb0, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0f, 0x30, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x30, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x30, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x60, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x60, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xc0, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 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, 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, 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, 0x00
};

void setup() {
    pinMode(piezoPin, OUTPUT);
    pinMode(BTN, INPUT);
    Serial.begin(9600); // подключаем монитор порта
    bme.begin(0x76); // запускаем приём ифнормации с датчика через i2c
    rtc.begin();
    Wire.begin();
    display.begin();
    display.clearDisplay();
    display.display();
    
    display.setContrast(50); // установка контраста
    delay(1000);
    display.setTextSize(1);  // установка размера шрифта
    display.setTextColor(BLACK); // установка цвета текста
    //rtc.adjust(DateTime(__DATE__, __TIME__));

}

void digitalClock() {
  ms = millis();
       if ( ( ms - ms1 ) > 1000 || ms < ms1 ) {
          ms1 = ms;
          display.display();
          display.clearDisplay();
     }
      DateTime now = rtc.now();
      display.setTextSize(2);
      if(now.hour() < 10) {
        display.setCursor(11, 0);
        display.println("0");
        display.setCursor(23,0);     
        display.println(now.hour());
      }
      if(now.hour() >= 10) {
        display.setCursor(11,0);     
        display.println(now.hour());
      }
      if(now.minute() < 10) {
        display.setCursor(51,0);
        display.println("0");
        display.setCursor(63,0);
        display.println(now.minute());
      }
      if(now.minute() >= 10) {
        display.setCursor(51,0);
        display.println(now.minute());
      }
      
      //будильник №1
      if (now.dayOfTheWeek() >= 1 && now.dayOfTheWeek() <= 7 && now.hour() == 14 && now.minute() == 28 && now.second() >= 00 && now.second() < 20) {
      display.drawBitmap(0, 0, clockBmp, 84, 44, BLACK);
      tone(piezoPin, 120, 400);
      delay(800);
      tone(piezoPin, 300, 400);
      delay(800);
      tone(piezoPin, 550, 400);
      delay(800);
      tone(piezoPin, 450, 400);
      delay(800);
      tone(piezoPin, 300, 400);
      delay(800);
      tone(piezoPin, 120, 400);
      } 
      
     
      display.setCursor(37, 3);
      display.println("-");
      display.setTextSize(1);
      if(now.second() < 10) {
        display.setCursor(37,0);
        display.println("0");
        display.setCursor(43,0);
        display.println(now.second());
      }
      if (now.second() >= 10){
        display.setCursor(37,0);
        display.println(now.second());
      }
      if (now.day() < 10) {
        display.setCursor(28, 16);
        display.println("0");
        display.setCursor(34, 16);
        display.println(now.day());
      }
      if (now.day() >= 10) {
        display.setCursor(28, 16);
        display.println(now.day());
      }
      
      display.setCursor(40, 16);
      display.println(".");
      if(now.month() < 10){
        display.setCursor(46, 16);
        display.println("0");
        display.setCursor(52, 16);
        display.println(now.month());
      }
      if(now.month() >= 10) {
        display.setCursor(46, 16);
        display.println(now.month());
      }
      if(now.dayOfTheWeek() == 1){
        display.setCursor(11, 23);
        display.println(utf8rus("Понедельник"));
      }
      if(now.dayOfTheWeek() == 2){
        display.setCursor(22, 23);
        display.println(utf8rus("Вторник"));
      }
      if(now.dayOfTheWeek() == 3){
        display.setCursor(27, 23);
        display.println(utf8rus("Среда"));
      }
      if(now.dayOfTheWeek() == 4){
        display.setCursor(21, 23);
        display.println(utf8rus("Четверг"));
      }
      if(now.dayOfTheWeek() == 5){
        display.setCursor(21, 23);
        display.println(utf8rus("Пятница"));
      }
      if(now.dayOfTheWeek() == 6){
        display.setCursor(21, 23);
        display.println(utf8rus("Суббота"));
      }
      if(now.dayOfTheWeek() == 7){
        display.setCursor(11, 23);
        display.println(utf8rus("Воскресенье"));
      }
        display.setCursor(0, 32);
        display.print(round(bme.readTemperature()));
        display.println(utf8rus("'C")); //определение температуры, вывод ее на экран в градусах Цельсия.
        display.setCursor(34, 32);
        display.print(round(bme.readAltitude(SEALEVELPRESSURE_HPA)));
        display.println(utf8rus("м"));
        if(bme.readHumidity() > 70) {
           tone(piezoPin, 200, 100);
           delay(200);
           tone(piezoPin, 200, 100);
           delay(200);
           display.setCursor(65, 32);
           display.print(round(bme.readHumidity()));
           display.println("%");  
           //display.setCursor(72, 15);
           //display.setTextSize(2);
           //display.print("!");
           display.drawBitmap(0, 0, smileBmp, 84, 44, BLACK);
        }
        if(bme.readHumidity() < 70) {
              display.setCursor(65, 32);
              display.print(round(bme.readHumidity()));
              display.println("%");
           }
        display.setTextSize(1);   
        display.setCursor(0, 40);
         display.print(round(bme.readPressure()*0.0075));
        display.println(utf8rus(" мм.рт.ст.")); //определение давления, вывод его на экран
      delay(1000);
}

void loop() {
       digitalClock();
}

/* Recode russian fonts from UTF-8 to Windows-1251 */
String utf8rus(String source)
{
  int i,k;
  String target;
  unsigned char n;
  char m[2] = { '0', '\0' };

  k = source.length(); i = 0;

  while (i < k) {
    n = source[i]; i++;

    if (n >= 0xBF){
      switch (n) {
        case 0xD0: {
          n = source[i]; i++;
          if (n == 0x81) { n = 0xA8; break; }
          if (n >= 0x90 && n <= 0xBF) n = n + 0x2F;
          break;
        }
        case 0xD1: {
          n = source[i]; i++;
          if (n == 0x91) { n = 0xB7; break; }
          if (n >= 0x80 && n <= 0x8F) n = n + 0x6F;
          break;
        }
      }
    }
    m[0] = n; target = target + String(m);
  }
return target;
}

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

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

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

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

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

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

 

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

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

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

 

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

alexey.st0 пишет:

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

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

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

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

 warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

           dot = " ";

 

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()

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

 

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

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

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

char dot = '.';
if(now.second() % 2 > 0) {
dot = ' ';
}
          
lcd.setCursor(7, 0);
lcd.print(dot);
lcd.setCursor(7, 1);
lcd.print(dot);

 

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

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

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


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

 

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

DetSimen пишет:

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


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

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

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

v258 пишет:

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

Чойта?

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

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

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

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