ARDUINO Реле автоматической подачи школьного звонка.

Реле автоматической подачи школьного звонка.
Доброй ночи, дорогие форумчане!
Еще 3 недели назад пришла идеальная идея в голову: т.к. я заканчиваю 11 класс, решил подарить школе "умную систему".
В Arduino ничего не соображал, собрал схему на nano и часах реального времени с реле. Начал пробывать писать код, кое в чем разобрался.
Всё заработало! Браво!
Думаю, так можно добавить туда ещё и сокращённое расписание. Поставил тумблер, разобрался в switch case .
И у меня уже работает реле для школы. Зачем время тянуть? На выходных его подсоединил, все в восторге.
Понедельник.. Первый день новых технологий. Первый, второй, третий, четвёртый звонки подавались сами, я был доволен.
(Раньше надо было спускаться на 1ый этаж и нажимать выключатель, чтобы подать звонок)
Хоп! Пятого звонка не прозвенело. Я пулей побежал на первый этаж, подал звонок, отключил и включил на Arduino
o питание и следующие 4 звонка опять прозвенели, а пятого не прозвучало.. Решил убрать switch case (расписание сокращённых уроков удалил). На следующий день проверил, опять такая же ерунда! В общем уже 2 недели я в школе страдаю фигнёй, пытаюсь исправить код, уже просто устал. Что только не пробывал.
Мне написали другой, якобы "лучший код", но он так же не работает.. Дорогие форумчане, я у Вас прошу помощи, что может быть не так?
Мой код, который работает, но ардуино с ним засыпает.:
#include <RTClib.h>
#include <Time.h>
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
int relay = 2;      //выход на реле
#define   switchPin 3
uint8_t   switchPinState;

enum switchProg : uint8_t {
  PROG_ONE = 0,           // Если переключатель в положении GND
  PROG_TWO = 1            // Если переключатель в положении VCC
};
void setup()
{
  Serial.begin(9600);
  pinMode(relay, OUTPUT); //выход на реле
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(switchPin, INPUT);
  digitalWrite(relay, HIGH);
  if (rtc.begin()){
  Serial.println("Couldn't find RTC");

  }}
void loop()
{
    DateTime now = rtc.now();

    Serial.println("Current Date & Time: ");
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
delay(1000);

switchPinState = digitalRead(switchPin);

  switch (switchPinState) {
    case switchProg::PROG_ONE:

digitalWrite(4, HIGH);
digitalWrite(5, LOW);

if (now.hour() == 8 && now.minute() == 30 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (relay, LOW);
}
if (now.hour() == 8 && now.minute() == 30 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (relay, HIGH);
}
if (now.hour() == 9 && now.minute() == 15 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 9 && now.minute() == 15 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 9 && now.minute() == 25 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 9 && now.minute() == 25 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 10 && now.minute() == 10 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 10 && now.minute() == 10 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 10 && now.minute() == 30 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 10 && now.minute() == 30 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 11 && now.minute() == 15 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 11 && now.minute() == 15 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 11 && now.minute() == 35 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 11 && now.minute() == 35 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 12 && now.minute() == 20 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 12 && now.minute() == 20 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 12 && now.minute() == 30 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 12 && now.minute() == 30 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 13 && now.minute() == 15 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 13 && now.minute() == 15 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 13 && now.minute() == 25 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 13 && now.minute() == 25 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 14 && now.minute() == 10 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 14 && now.minute() == 10 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 14 && now.minute() == 20 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 14 && now.minute() == 20 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 15 && now.minute() == 05 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 15 && now.minute() == 05 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 15 && now.minute() == 10 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 15 && now.minute() == 10 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 15 && now.minute() == 55 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 15 && now.minute() == 55 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}

break;

   
case switchProg::PROG_TWO:

digitalWrite(5, HIGH);
digitalWrite(4, LOW);

if (now.hour() == 8 && now.minute() == 30 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (relay, LOW);
}
if (now.hour() == 8 && now.minute() == 30 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (relay, HIGH);
}
if (now.hour() == 9 && now.minute() == 10 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 9 && now.minute() == 10 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 9 && now.minute() == 45 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 9 && now.minute() == 45 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 10 && now.minute() == 00 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 10 && now.minute() == 00 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 10 && now.minute() == 35 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 10 && now.minute() == 35 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 10 && now.minute() == 50 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 10 && now.minute() == 50 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 11 && now.minute() == 25 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 11 && now.minute() == 25 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 11 && now.minute() == 30 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 11 && now.minute() == 30 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 12 && now.minute() == 05 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 12 && now.minute() == 05 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 12 && now.minute() == 10 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 12 && now.minute() == 10 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 12 && now.minute() == 45 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 12 && now.minute() == 45 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 12 && now.minute() == 50 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 12&& now.minute() == 50 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
if (now.hour() == 13 && now.minute() == 25 && now.second() == 00 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, LOW);
}
if (now.hour() == 13 && now.minute() == 25 && now.second() == 07 && (now.dayOfTheWeek() != 6 & now.dayOfTheWeek() != 0))
{
digitalWrite (2, HIGH);
}
      break;
     default:
      break;
  }        }
1713123632535.png
Код, который мне написали, но он не работает.:
#include <RTClib.h>       // https://github.com/adafruit/RTClib

#define   relePin   2
#define   ON        LOW
#define   OFF       HIGH
#define   LED       13

#define   SUNDAY    0
#define   SATURDAY  6

RTC_DS3231 rtc;

char daysOfTheWeek[7][10] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

DateTime now = rtc.now();

uint32_t  prevMillis;

void setup() {

  pinMode(relePin, OUTPUT);       // выход на реле
  pinMode(LED, OUTPUT);           // Встроенный светодиод, например на Nano имеется...
 
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  digitalWrite(4, HIGH);

  digitalWrite(relePin, HIGH);
  digitalWrite(LED,     LOW);

  Serial.begin(9600);             // Скорость Serial-порта

  if (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1) {                               // Бесконечный цикл, так как RTC не найден.
      digitalWrite(LED, !digitalRead(LED));   // И мигаем при этом встроенным светодиодом, сообщая о проблеме...
      delay(1000);
    }
  }
  prevMillis = millis();
}

void loop() {

  uint16_t  m_year          = now.year();
  uint8_t   m_month         = now.month();
  uint8_t   m_day           = now.day();
  uint8_t   m_dayOfTheWeek  = now.dayOfTheWeek();
  uint8_t   m_hour          = now.hour();
  uint8_t   m_minute        = now.minute();
  int8_t    m_second        = now.second();

  if (millis() - prevMillis >= 1000) {
    prevMillis = millis();
    Serial.println("Current Date & Time: ");
    Serial.print(m_year,  DEC);
    Serial.print('/');
    Serial.print(m_month,  DEC);
    Serial.print('/');
    Serial.print(m_day,    DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[m_dayOfTheWeek]);
    Serial.print(") ");
    Serial.print(m_hour,   DEC);
    Serial.print(':');
    Serial.print(m_minute, DEC);
    Serial.print(':');
    Serial.print(m_second, DEC);
    Serial.println();
  }
 digitalWrite(5, HIGH);
  if (m_dayOfTheWeek != SUNDAY && m_dayOfTheWeek != SATURDAY) {  // Если сегодня будний день (Пн...Пт), то...
    
    if (m_hour == 8 && m_minute == 30) {
      if (m_second <= 7) {
        digitalWrite (relePin, ON);
      } else {
        digitalWrite (relePin, OFF);
      }
    }

    if (m_hour == 9 && m_minute == 15) {
      if (m_second <= 7) {
        digitalWrite (relePin, ON);
      } else {
        digitalWrite (relePin, OFF);
      }
    }

    if (m_hour == 9 && m_minute == 25) {
      if (m_second <= 7) {
        digitalWrite (relePin, ON);
      } else {
        digitalWrite (relePin, OFF);
      }
    }

    if (m_hour == 10 && m_minute == 10) {
      if (m_second <= 7) {
        digitalWrite (relePin, ON);
      } else {
        digitalWrite (relePin, OFF);
      }
    }

    if (m_hour == 10 && m_minute == 30) {
      if (m_second <= 7) {
        digitalWrite (relePin, ON);
      } else {
        digitalWrite (relePin, OFF);
      }
    }
  }
}
 

Комментарии

Старик Похабыч

★★★★★★★
14 Авг 2019
4,266
1,303
Москва
Я выше писал, прозвенел звонок - делайте софтресет платы, я так понимаю при запросе времени в сетап проблем не было ни разу, значит ресет поможет безопасно обновить время.
Ардуино опаздывает на секунд 30
За какой период ?
 
  • Лойс +1
Реакции: Alexhhhhgf

Старик Похабыч

★★★★★★★
14 Авг 2019
4,266
1,303
Москва
При синхронизации по перегрузке после звонка самый большой перерыв будет ночью, значит надо как то предусмотреть расписание перезагрузок на подобии расписания звонков, может быть за 5 минут до звонка делать перезагрузку, тогда расхождение с реальным временем будет до 2 х секунд.
 

vortigont

★★★★★★✩
24 Апр 2020
1,022
542
Saint-Petersburg, Russia
Сделайте поправку для времени, 30 сек за 2 часа это 1 секунда каждые 4 минуты. Будет у вас пол секунды за 2 часа или около 6 сек в сутки. Уже вполне приемлимо. Можно перегружать раз в сутки с утра.
А вообще перечитайте сообщения похабыча ранее, там написано как инициализировать шину и2ц и выясните как именно перезагруз оживляет часы, тогда и исправите свою проблему в корне.
 

Zuker

★✩✩✩✩✩✩
10 Янв 2024
61
12
Докупайте другие модели контроллеров, модулей. Все пригодится. В вашу распай.коробку много чего влезет: Uno, Mega Pro, Pro Micro, Wemos D1 Mini.
Ну не должно так глючить в нормальных условиях. Где брали библиотеку для часов? Можете залить сюда архив всего содержимого вашей папки с библиотеками (стандартный путь): C:\users\user\Documents\Arduino\libraries\

1. Где покупали контроллер Nano? (ваша версия v3 - ATmega328 ?)
2. Часы точно DS3231? Где покупали?
3. Библиотеку "RTCLib" откуда выкачивали? Даже в примерах библиотек время запрашивается в loop раз в 3 секунды и ничего страшного в этом нет. Пробовали другие библиотеки на чистую папку "libraries"?
 
Изменено:
  • Лойс +1
Реакции: Alexhhhhgf

Zuker

★✩✩✩✩✩✩
10 Янв 2024
61
12
@Alexgggfff, попробуйте использовать старую версию библиотеки для часов: https://cloud.mail.ru/public/jwoh/k2omGS6JP (из метеостанции AlexGyver)
Но перед этим временно уберите все из папки Libraries, кроме библиотеки Time. Затем скопируйте старую библиотеку RTClib (ссылка выше).

Библиотеку microDS3231 пробовали?
 

Alexgggfff

✩✩✩✩✩✩✩
4 Май 2024
2
0
@Zuker, эхх, вроде разобрался с проблемой в коде, а теперь гемор с библиотеками начался.
Выдает ошибку:
Arduino: 1.8.16 (Windows 10), Плата:"Arduino Nano, ATmega328P"

C:\Users\olgal\Documents\Arduino\sketch_may05a\sketch_may05a.ino: In function 'void loop()':

sketch_may05a:116:18: error: 'time_now' was not declared in this scope

     Serial.print(time_now.year(),  DEC);

                  ^~~~~~~~

C:\Users\olgal\Documents\Arduino\sketch_may05a\sketch_may05a.ino:116:18: note: suggested alternative: 'time_t'

     Serial.print(time_now.year(),  DEC);

                  ^~~~~~~~

                  time_t
exit status 1
'time_now' was not declared in this scope

Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
"Показать подробный вывод во время компиляции"
1714943148898.png
Скетч:
#include <RTClib.h>       // https://github.com/adafruit/RTClib
#include <TimeLib.h>      // https://github.com/PaulStoffregen/Time


#define   relePin   2
#define   LED       4
#define   LEDD       5
#define   SWITCH_PIN    3

#define   SUNDAY    0
#define   SATURDAY  6
#define   RING_SECONDS      7

#define   TZ_OFFSET 180   // MSK

#define   HOURS     60

RTC_DS3231 rtc;

bool status_led = false;
bool status_ledd = false;

const char* daysOfTheWeek[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

const uint16_t raspisanie[] = {
    8 * HOURS + 30,
    9 * HOURS + 15,
    9 * HOURS + 25,
    10 * HOURS + 10,
    10 * HOURS + 30,
    11 * HOURS + 15,
    11 * HOURS + 35,
    12 * HOURS + 20,
    12 * HOURS + 30,
    13 * HOURS + 15,
    13 * HOURS + 25,
    14 * HOURS + 10,
    14 * HOURS + 20,
    15 * HOURS + 5,
    15 * HOURS + 10,
    15 * HOURS + 50,
};

const uint16_t raspisanie2[] = {
    8 * HOURS + 30,
    9 * HOURS + 5,
    9 * HOURS + 10,
    9 * HOURS + 45,
    10 * HOURS + 1,
    10 * HOURS + 35,
    10 * HOURS + 50,
    11 * HOURS + 25,
    11 * HOURS + 30,
    12 * HOURS + 5,
    12 * HOURS + 10,
    12 * HOURS + 45,
    12 * HOURS + 50,
    13 * HOURS + 25,
};


void zvonok(DateTime &dt){
    for (int i = 0; i != sizeof(raspisanie)/sizeof(uint16_t); ++i ){
      if ( (dt.hour() * HOURS + dt.minute()) == raspisanie[i] ){
          digitalWrite(relePin, dt.second() < RING_SECONDS ? LOW : HIGH );
          if (dt.second() < RING_SECONDS){
              Serial.print("Raspisanie 1: Ring for ");
              Serial.print(RING_SECONDS - dt.second());
              Serial.println(" seconds more");
          }
      }
    }       
};

void zvonok2(DateTime &dt){
    for (int i = 0; i != sizeof(raspisanie2)/sizeof(uint16_t); ++i ){
      if ( (dt.hour() * HOURS + dt.minute()) == raspisanie2[i] ){
          digitalWrite(relePin, dt.second() < RING_SECONDS ? LOW : HIGH );
          if (dt.second() < RING_SECONDS){
              Serial.print("Raspisanie 2: Ring for ");
              Serial.print(RING_SECONDS - dt.second());
              Serial.println(" seconds more");
          }
      }
    }       
};


void setup() {

  pinMode(relePin, OUTPUT);       // выход на реле
  pinMode(LED, OUTPUT);           // Встроенный светодиод, например на Nano имеется...
 
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);

  digitalWrite(relePin, HIGH);
  Serial.begin(9600);             // Скорость Serial-порта

  while (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    digitalWrite(LED, !digitalRead(LED));   // И мигаем при этом встроенным светодиодом, сообщая о проблеме...
    delay(200);
  }

  DateTime time_now = rtc.now();
  adjustTime(TZ_OFFSET * SECS_PER_MIN);
  setTime(time_now.hour(), time_now.minute(), time_now.second(), time_now.day(), time_now.month(), time_now.year());
}

void loop() {
 
    Serial.print("Raspisanie: ");
    Serial.println(digitalRead(SWITCH_PIN) ? 1 : 2 );
    Serial.print("Current Date & Time: ");
    Serial.print(time_now.year(),  DEC);
    Serial.print('/');
    Serial.print(time_now.month(),  DEC);
    Serial.print('/');
    Serial.print(time_now.day(),    DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[time_now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(time_now.hour(),   DEC);
    Serial.print(':');
    Serial.print(time_now.minute(), DEC);
    Serial.print(':');
    Serial.print(time_now.second(), DEC);
    Serial.println();
    
    if (digitalRead(SWITCH_PIN)){
      zvonok(time_now);
      digitalWrite(LED, status_led);
      status_led = !status_led;
      digitalWrite(5, LOW);
  }
    else {
      zvonok2(time_now);
      digitalWrite(LEDD, status_ledd);
      status_ledd = !status_led;
      digitalWrite(4, LOW);
    }
    
   delay(1000);
}
 

Zuker

★✩✩✩✩✩✩
10 Янв 2024
61
12
Исправил. Куда-то девалось объявление переменной DateTime time_now;
У меня все компилируется с двумя библиотеками Time \ RTClib-master (старая)

C++:
#include <RTClib.h>       // https://github.com/adafruit/RTClib
#include <TimeLib.h>      // https://github.com/PaulStoffregen/Time
DateTime time_now;

#define   relePin   2
#define   LED       4
#define   LEDD       5
#define   SWITCH_PIN    3

#define   SUNDAY    0
#define   SATURDAY  6
#define   RING_SECONDS      7

#define   TZ_OFFSET 180   // MSK

#define   HOURS     60

RTC_DS3231 rtc;

bool status_led = false;
bool status_ledd = false;

const char* daysOfTheWeek[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

const uint16_t raspisanie[] = {
    8 * HOURS + 30,
    9 * HOURS + 15,
    9 * HOURS + 25,
    10 * HOURS + 10,
    10 * HOURS + 30,
    11 * HOURS + 15,
    11 * HOURS + 35,
    12 * HOURS + 20,
    12 * HOURS + 30,
    13 * HOURS + 15,
    13 * HOURS + 25,
    14 * HOURS + 10,
    14 * HOURS + 20,
    15 * HOURS + 5,
    15 * HOURS + 10,
    15 * HOURS + 50,
};

const uint16_t raspisanie2[] = {
    8 * HOURS + 30,
    9 * HOURS + 5,
    9 * HOURS + 10,
    9 * HOURS + 45,
    10 * HOURS + 1,
    10 * HOURS + 35,
    10 * HOURS + 50,
    11 * HOURS + 25,
    11 * HOURS + 30,
    12 * HOURS + 5,
    12 * HOURS + 10,
    12 * HOURS + 45,
    12 * HOURS + 50,
    13 * HOURS + 25,
};


void zvonok(DateTime &dt){
    for (int i = 0; i != sizeof(raspisanie)/sizeof(uint16_t); ++i ){
      if ( (dt.hour() * HOURS + dt.minute()) == raspisanie[i] ){
          digitalWrite(relePin, dt.second() < RING_SECONDS ? LOW : HIGH );
          if (dt.second() < RING_SECONDS){
              Serial.print("Raspisanie 1: Ring for ");
              Serial.print(RING_SECONDS - dt.second());
              Serial.println(" seconds more");
          }
      }
    }  
};

void zvonok2(DateTime &dt){
    for (int i = 0; i != sizeof(raspisanie2)/sizeof(uint16_t); ++i ){
      if ( (dt.hour() * HOURS + dt.minute()) == raspisanie2[i] ){
          digitalWrite(relePin, dt.second() < RING_SECONDS ? LOW : HIGH );
          if (dt.second() < RING_SECONDS){
              Serial.print("Raspisanie 2: Ring for ");
              Serial.print(RING_SECONDS - dt.second());
              Serial.println(" seconds more");
          }
      }
    }  
};


void setup() {

  pinMode(relePin, OUTPUT);       // выход на реле
  pinMode(LED, OUTPUT);           // Встроенный светодиод, например на Nano имеется...

  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);

  digitalWrite(relePin, HIGH);
  Serial.begin(9600);             // Скорость Serial-порта

  while (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    digitalWrite(LED, !digitalRead(LED));   // И мигаем при этом встроенным светодиодом, сообщая о проблеме...
    delay(200);
  }

  time_now = rtc.now();
  adjustTime(TZ_OFFSET * SECS_PER_MIN);
  setTime(time_now.hour(), time_now.minute(), time_now.second(), time_now.day(), time_now.month(), time_now.year());
}

void loop() {

    Serial.print("Raspisanie: ");
    Serial.println(digitalRead(SWITCH_PIN) ? 1 : 2 );
    Serial.print("Current Date & Time: ");
    Serial.print(time_now.year(),  DEC);
    Serial.print('/');
    Serial.print(time_now.month(),  DEC);
    Serial.print('/');
    Serial.print(time_now.day(),    DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[time_now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(time_now.hour(),   DEC);
    Serial.print(':');
    Serial.print(time_now.minute(), DEC);
    Serial.print(':');
    Serial.print(time_now.second(), DEC);
    Serial.println();

    if (digitalRead(SWITCH_PIN)){
      zvonok(time_now);
      digitalWrite(LED, status_led);
      status_led = !status_led;
      digitalWrite(5, LOW);
  }
    else {
      zvonok2(time_now);
      digitalWrite(LEDD, status_ledd);
      status_ledd = !status_led;
      digitalWrite(4, LOW);
    }

   delay(1000);
}
 
Изменено:
  • Лойс +1
Реакции: Alexhhhhgf

Alexhhhhgf

✩✩✩✩✩✩✩
14 Апр 2024
42
0
Вроде как всё работает.
Код загружаю для себя.
Скетч "зависал" из-за запроса времени каждую секунду с RTC, а именно в момент выключения реле.
завтра отпишусь, как всё работает.
Кхм:
#include <RTClib.h>       // https://github.com/adafruit/RTClib
#include <TimeLib.h>      // https://github.com/PaulStoffregen/Time
DateTime time_now;

#define   relePin   2
#define   LED       4
#define   LEDD       5
#define   SWITCH_PIN    3

#define   RING_SECONDS      7

#define   TZ_OFFSET 180   // MSK

#define   HOURS     60

RTC_DS3231 rtc;


bool status_led = false;
bool status_ledd = false;

const uint16_t raspisanie[] = {
    8 * HOURS + 30,
    9 * HOURS + 15,
    9 * HOURS + 25,
    10 * HOURS + 10,
    10 * HOURS + 30,
    11 * HOURS + 15,
    11 * HOURS + 35,
    12 * HOURS + 20,
    12 * HOURS + 30,
    13 * HOURS + 15,
    13 * HOURS + 25,
    14 * HOURS + 10,
    14 * HOURS + 20,
    15 * HOURS + 5,
    15 * HOURS + 10,
    15 * HOURS + 50,
};

const uint16_t raspisanie2[] = {
    8 * HOURS + 30,
    9 * HOURS + 5,
    9 * HOURS + 10,
    9 * HOURS + 45,
    10 * HOURS + 1,
    10 * HOURS + 35,
    10 * HOURS + 50,
    11 * HOURS + 25,
    11 * HOURS + 30,
    12 * HOURS + 5,
    12 * HOURS + 10,
    12 * HOURS + 45,
    12 * HOURS + 50,
    13 * HOURS + 25,
};


void zvonok(DateTime &dt){
    for (int i = 0; i != sizeof(raspisanie)/sizeof(uint16_t); ++i ){
      if ( (dt.hour() * HOURS + dt.minute()) == raspisanie[i] ){
          digitalWrite(relePin, dt.second() < RING_SECONDS ? LOW : HIGH );
          if (dt.second() < RING_SECONDS){
              Serial.print("Raspisanie 1: Ring for ");
              Serial.print(RING_SECONDS - dt.second());
              Serial.println(" seconds more");
          }
      }
    }      
};

void zvonok2(DateTime &dt){
    for (int i = 0; i != sizeof(raspisanie2)/sizeof(uint16_t); ++i ){
      if ( (dt.hour() * HOURS + dt.minute()) == raspisanie2[i] ){
          digitalWrite(relePin, dt.second() < RING_SECONDS ? LOW : HIGH );
          if (dt.second() < RING_SECONDS){
              Serial.print("Raspisanie 2: Ring for ");
              Serial.print(RING_SECONDS - dt.second());
              Serial.println(" seconds more");
          }
      }
    }      
};


void setup() {

  pinMode(relePin, OUTPUT);       // выход на реле
  pinMode(LED, OUTPUT);           // Встроенный светодиод, например на Nano имеется...

  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);

  digitalWrite(relePin, HIGH);
  Serial.begin(9600);             // Скорость Serial-порта

  while (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    digitalWrite(LED, !digitalRead(LED));   // И мигаем при этом встроенным светодиодом, сообщая о проблеме...
    delay(200);
  }

  DateTime time_now = rtc.now();
  adjustTime(TZ_OFFSET * SECS_PER_MIN);
  setTime(time_now.hour(), time_now.minute(), time_now.second(), time_now.day(), time_now.month(), time_now.year());
}

void loop() {

    DateTime time_now = now();
    Serial.print("Raspisanie: ");
    Serial.println(digitalRead(SWITCH_PIN) ? 1 : 2 );
    Serial.print("Current Date & Time: ");
    Serial.print(time_now.year(),  DEC);
    Serial.print('/');
    Serial.print(time_now.month(),  DEC);
    Serial.print('/');
    Serial.print(time_now.day(),    DEC);
    Serial.print(" ");
    Serial.print(time_now.hour(),   DEC);
    Serial.print(':');
    Serial.print(time_now.minute(), DEC);
    Serial.print(':');
    Serial.print(time_now.second(), DEC);
    Serial.println();
   
    if (digitalRead(SWITCH_PIN)){
      zvonok(time_now);
      digitalWrite(LED, status_led);
      status_led = !status_led;
      digitalWrite(5, LOW);
     
      if (time_now.minute() == 22 && time_now.second() == 10) {
         DateTime time_now = rtc.now();
          setTime(time_now.hour(), time_now.minute(), time_now.second(), time_now.day(), time_now.month(), time_now.year());
      }
     }
   

    else {
      zvonok2(time_now);
      digitalWrite(LEDD, status_ledd);
      status_ledd = !status_led;
      digitalWrite(4, LOW);
     
       if (time_now.minute() == 22 && time_now.second() == 10) {
         DateTime time_now = rtc.now();
          setTime(time_now.hour(), time_now.minute(), time_now.second(), time_now.day(), time_now.month(), time_now.year());
       }
    }
   
   delay(1000);
}
@Alexhhhhgf, при включении Ардуино реле включается на 0.5 сек, такая же ерунда при открытии монитора порта. Почему такое может быть?
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,266
1,303
Москва
При открытии монитор порта идет перезагрузка ардуины, так что причина одна и та же.
Что бы реле не щелкало перед инициацией пина надо установить его состояние в нужное (в высокий уровень), т.е. 94 строку перенести на 87
 
  • Лойс +1
Реакции: Alexhhhhgf

Alexhhhhgf

✩✩✩✩✩✩✩
14 Апр 2024
42
0
Вчера все звонки звенели.
Сегодня сокращённое расписание, тоже всё работает. В общем, проблема была в том, что в момент срабатывания реле ардуино запрашивало время. Всем огромное спасибо.
 

Alexhhhhgf

✩✩✩✩✩✩✩
14 Апр 2024
42
0
Эхх, наконец-то каникулы. Задрал меня этот звонок... Три дня он нормально поработал и так же зависал. Надо за каникулы что-то придумать, а то директор меня из-под земли найдет
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,266
1,303
Москва
Задачи для мк можно условно разделить на 2 группы: 1) Линейные (однозадачные) и 2) многозадачный.
У тебя задача строго говоря однозадачная, значит писать код можно максимально прямолинейно, даже с delay. Если учесть, что зависание идет из за какого то кривого считывания с модуля времени,, то можно просто перегружать его после срабатывания реле, вот только пин reset не выведен . Или даже все плату перегрузить. Можно попробовать заменить реле на транзисторный ключ.

И еще сам код рабочий, дело точно не в нем, а именно схеме.
 

vortigont

★★★★★★✩
24 Апр 2020
1,022
542
Saint-Petersburg, Russia
@Старик Похабыч, ну зачем вы ему советуете костыли с ребутом, он же так и сделает в итоге :)
Целое лето впереди - вполне достаточно что бы научиться работать с и2ц шиной без блокировок. Определять когда она зависла и переинициализировать её (что и происходит при перезагрузке).
Если виснет модуль часов, то можно его перегружать по питанию через внешний полевик и одну ножку на контроллере. Вариантов масса.
 

poty

★★★★★★✩
19 Фев 2020
3,237
942
@vortigont, а чем это отличается от ресета Ардуино? Есть часы на ГРИ, где масса мест, которые могут давать помехи, однако там RTC работают годами без всякой суеты (с заменой первой буквы). А значит у ТС либо что-то с модулями, либо с питанием, либо с монтажом. Использование того, что находится под рукой и "монтаж" на проволочках - путь как раз к таким ошибкам. Как там собрано реально не знает никто. И будет думать он долго...
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,266
1,303
Москва
@vortigont, Только за одним - это самый простой способ сделать рабочий вариант для проверки. И не такой уж плохой. Есть такая платка esp8266, так вот она для выхода из глубокого сна должна получить сигнал на ресет, там вообще цикл loop можно не использовать.
 

vortigont

★★★★★★✩
24 Апр 2020
1,022
542
Saint-Petersburg, Russia
а чем это отличается от ресета Ардуино?
тем что неизвестно когда нужно перегружать ардуино, т.к. сам момент "зависания" не отлавливается. Это просто на "авось" раз ребутнулись значит какое-то время оно будет работаеть. Что лишь снижает вероятность возникновения проблемы. Ну конечно если математически расчитать период ребутов с заданным значением вероятности зависания "раз в n месяцев" то вполне рабочий вариант. Но что-то мне кажется что такой расчет сделать будет сложнее чем выявить причину зависания и метод её устранения без перезагрузки всего контроллера.
Как по мне так достаточно будет опросить шину на наличие устройства часов перед посыланием туда запроса. Или сменить библиотеку работы с часами на ту, которая делает это сама и не блокируется насмерть а возвращает каку-то вразумительную ошибку.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,266
1,303
Москва
@vortigont, автор написал, что зависание происходит в момент чтения данных с одновременной работой реле. Я бы предположил, что реле вызывает зависание, так что перегруз нужно делать после завершения звонка , для этого времени вагон. Т.е. я бы делал так: когда время пришло, то включил звонок, задержка на 7 секунд, выключил звонок, пауза , ресет.
 
  • Лойс +1
Реакции: Alexhhhhgf

vortigont

★★★★★★✩
24 Апр 2020
1,022
542
Saint-Petersburg, Russia
зависание происходит в момент чтения данных с одновременной работой реле
этого не может быть, иначе у него бы звонок начинал звенеть и звенел бесконечно пока не обесточат реле. А у него звонки вообще пропадают, значит "зависает" еще до подачи звонка.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,266
1,303
Москва
Зависать может в момент выключения и одновременного считывания. Тогда все выключится и дальше будет фигня. Но детально автор не исследовал, данные в монитор не выводил.
 

vortigont

★★★★★★✩
24 Апр 2020
1,022
542
Saint-Petersburg, Russia
Зависать может в момент выключения и одновременного считывания
на однопоточном уно я как-то с трудом себе такую ситуацию представляю. Да и по тому коду что тут был явно видно что сначала читалось время, а потом дергалось реле.

Но детально автор не исследовал
да вот в этом-то и беда... :) за пару месяцев у него не нашлось времени дома на стенде отсоединить дата и/или клок проводок от модуля часов и посмотреть заблочится его код на чтении данных или нет )
 

Max965

✩✩✩✩✩✩✩
28 Окт 2023
16
2
Коллеги, у меня возникла та же мысль, что у автора, но идею использования реле я отверг сразу, так как звонки имеют свою индуктивность и искра на контактах реле неизбежна (помехи могут влиять на устройство), поэтому поставил твердотельное реле. Скетч писал с нуля, так как мой аппарат включает в себя помимо реле ещё индикатор TM1637 и часовой модуль DS3231 (кроме звонков блок ещё является первичными часами для сети). Как ни странно, в таком варианте все звонки идут по расписанию, и не звучат тоже по нему (праздники, выходные, каникулы).
Может, кому пригодится идея, но просьба сильно не кидаться камнями, т.к. я писал чисто для себя (упрощать можно, но не хочется).
C++:
#include <GyverTM1637.h>
#include <microDS3231.h>

// 328p часы школьные
MicroDS3231 rtc;
#define CLK 2 //pins definitions for TM1637 and can be changed to other ports
#define DIO 3
GyverTM1637 disp(CLK, DIO);
int val=0, curr_val=0; bool flag=false, flag3=false, bell=false; int curr_sec, block=0, bell_sec=2;
byte troll[4] = {_3, _B, _O, _H};

void setup() {
  pinMode(7, OUTPUT); pinMode(8, OUTPUT); // выход на часы
  pinMode(4, INPUT); // вход 1 Гц
  pinMode(11, INPUT_PULLUP); // кнопка ускор. перевода
  pinMode(10, INPUT_PULLUP); // кнопка коррекции
  pinMode(9, INPUT_PULLUP); // кнопка управления индикатором
  pinMode(12, INPUT_PULLUP); // кнопка внепланового включения звонков
  pinMode(13, OUTPUT); // выход на звонок
  //rtc.setTime(COMPILE_TIME);   // установка времени компьютера
  disp.clear(); disp.brightness(1);  // яркость дисплея: 0 - 7 (минимум - максимум) 
  Serial.begin(9600);
}

void loop() {
  DateTime now = rtc.getTime(); curr_sec=now.second; // получаем значение текущего времени и даты
  Serial.println(rtc.getTimeString()); Serial.println(rtc.getDateString());
  if (digitalRead(11)) {     // нормальный ход часов
    if (now.second==0 && !flag3) {
       if (now.minute %2==0) digitalWrite(7, HIGH); else digitalWrite(8, HIGH);  flag3=true; 
                                        }
    if (now.second>=1)  {flag3=false; digitalWrite(7, LOW); digitalWrite(8, LOW);}     
               }
  else {        // ускоренный перевод часов
      if (now.second %2==0) {digitalWrite(7, HIGH); digitalWrite(8, LOW);}
      else {digitalWrite(8, HIGH); digitalWrite(7, LOW);}     
        }
  // управление звонком
       if (now.day>5 && !bell) delay (1); // исключаем субботу и воскресенье
  else if (now.month==1 && now.date<9 && !bell) delay (1); // исключаем новогодние каникулы
  else if (now.month>5 && now.month<9 && !bell) delay (1); // исключаем летние месяцы
  else if (now.month==2 && now.date==23) delay (1); // исключаем 23 февраля
  else if (now.month==3 && now.date==8) delay (1); // исключаем 8 марта
  else if (now.month==5 && (now.date==1 || now.date==9)) delay (1); // исключаем майские праздники
  else if (now.month==11 && now.date==4) delay (1); // исключаем 4 ноября
  else if (now.second==1) {         // здесь расписание звонков
       if (now.hour==8 && now.minute==29) digitalWrite(13, HIGH), bell_sec=4; // за минуту до начала урока
       if (now.hour==8 && now.minute==30) digitalWrite(13, HIGH), bell_sec=3; // начало урока 1
       if (now.hour==9 && now.minute==15) digitalWrite(13, HIGH), bell_sec=3; // конец урока
       if (now.hour==9 && now.minute==19) digitalWrite(13, HIGH), bell_sec=4; // за минуту до начала урока
       if (now.hour==9 && now.minute==20) digitalWrite(13, HIGH), bell_sec=3; // начало урока 2
       if (now.hour==10 && now.minute==5) digitalWrite(13, HIGH), bell_sec=3; // конец урока
       if (now.hour==10 && now.minute==9) digitalWrite(13, HIGH), bell_sec=4; // за минуту до начала урока
       if (now.hour==10 && now.minute==10) digitalWrite(13, HIGH), bell_sec=3; // начало урока 3
       if (now.hour==10 && now.minute==55) digitalWrite(13, HIGH), bell_sec=3; // конец урока
       if (now.hour==10 && now.minute==59) digitalWrite(13, HIGH), bell_sec=4; // за минуту до начала урока
       if (now.hour==11 && now.minute==00) digitalWrite(13, HIGH), bell_sec=3; // начало урока 4
       if (now.hour==11 && now.minute==45) digitalWrite(13, HIGH), bell_sec=3; // конец урока
       if (now.hour==11 && now.minute==59) digitalWrite(13, HIGH), bell_sec=4; // за минуту до начала урока
       if (now.hour==12 && now.minute==0) digitalWrite(13, HIGH), bell_sec=3; // начало урока 5
       if (now.hour==12 && now.minute==45) digitalWrite(13, HIGH), bell_sec=3; // конец урока
       if (now.hour==12 && now.minute==59) digitalWrite(13, HIGH), bell_sec=4; // за минуту до начала урока
       if (now.hour==13 && now.minute==0) digitalWrite(13, HIGH), bell_sec=3; // начало урока 6
       if (now.hour==13 && now.minute==45) digitalWrite(13, HIGH), bell_sec=3; // конец урока
  }
  if (curr_sec>=bell_sec) digitalWrite(13, LOW);
  if (digitalRead(12)==LOW) {bell=true; val=4;} // включение звонков в неурочный день
  else if (now.hour==0 && bell) bell=false; // в полночь неурочный день окончен 
     
 if (block>0) --block;  // коррекция не повторяется раньше, чем через 20 сек.
  if (digitalRead(10)==LOW && !block) {  // коррекция секунд в ноль
    if (now.second>30) {if (now.minute==59) ++now.hour, now.minute=0; else ++now.minute; }
    now.second=0; block=20;
    rtc.setTime(now);  // загружаем в RTC   
  }
  else if (digitalRead(10)==LOW) Serial.println("correction blocked");
  switch (val) {
  case 1: {disp.displayClock(now.minute, now.second);}  // вывести минуты и секунды
    break;
  case 2: {disp.displayClock(now.date, now.month);}  // вывести день и месяц
    break;
  case 3: {disp.displayInt(now.year);} // вывести год
    break;
  case 4: {disp.displayByte(troll);} // вывести "звон"
    break;   
  default: {disp.displayClock(now.hour, now.minute);}  // вывести часы и минуты   
    break;
}
  if (digitalRead(9)==LOW && !flag) {if (val<3) ++ val; else val=0; flag=true;}
  while (curr_sec==rtc.getSeconds()) delay (1); //ждём следующую секунду
  flag=false; if (val==4) val=0; curr_val=val;         
              
}

void yield() {                               // точки на индикаторе
 if (val==2) disp.point(true); else if (val>2) disp.point(false);
 else {if (digitalRead(4)==LOW) disp.point(true); else disp.point(false);}   
 }
 
  • Лойс +1
Реакции: vortigont