@ramisdavletov

Проект Arduino, работа по таймеру?

Код написанный работает некорректно на устройстве. Думаю что проблема в реализации таймера отключения (так как при включении питания лампочка загорается и тухнет сразу без задержки).
Есть ли проблема в ней? Спасибо!)

Логика работы лампы.
void Lamp(int CheckSensInterval, int DelayOFF)
{
  int UpdInterval = CheckSensInterval;
  unsigned long lastUpdate;
  if ((millis() - lastUpdate) > UpdInterval)
  {
    FotoValue = analogRead(FotoResist);
    int PIRvalue = digitalRead(PIRpin);  // считываем значение с датчика

    if (PIRvalue == HIGH && FotoValue < 700)
    { // проверяем, соответствует ли считанное значение HIGH
      digitalWrite(RelayLampPin, HIGH);  // включаем лампу
      if (pirState == LOW)
      {
        lcd.setCursor(0, 0);
        lcd.print("Motion detected!");
        // мы выводим изменение, а не состояние
        pirState = HIGH;
      }
    }
    else
    {
      int TimerOFFLamp = atoi(minute) + DelayOFF;
      while (minute < TimerOFFLamp) {
        digitalWrite(RelayLampPin, HIGH);
      }
      digitalWrite(RelayLampPin, LOW); // выключаем светодиод
      if (pirState == HIGH)
      {
        // мы только что его выключили
        lcd.setCursor(0, 0);
        lcd.print("Motion ended!");
        // мы выводим  изменение, а не состояние
        pirState = LOW;
      }
    }
    lastUpdate = millis();
  }
}

Файл MyClock.h

#ifndef MYCLOCK_H
#define MYCLOCK_H

#include "Arduino.h"
#include <DS3231.h>
DS3231 Clock;
bool Century = false;
bool h12;
bool PM;
byte ADay, AHour, AMinute, ASecond, ABits;
bool ADy, A12h, Apm;
byte year, month, date, hour, minute, second;

void SettingTime(byte H, byte M, byte S)
{
  Clock.setSecond(S);//Set the second
  Clock.setMinute(M);//Set the minute
  Clock.setHour(H); //Set the hour
  Clock.setClockMode(false);// Set 12/24h mode. True is 12-h, false is 24-hour.
}

void SettingDate(byte D, byte M, byte Y)
{
  Clock.setDate(D); //Set the date of the month
  Clock.setMonth(M); //Set the month of the year
  Clock.setYear(Y); //Set the year (Last two digits of the year)
}

void ShowTimeAndDate(int interval)
{
  int updateInterval = interval;
  unsigned long lastUpdate;
  int second, minute, hour, date, month, year;
  if ((millis() - lastUpdate) > updateInterval)
  {
    year = Clock.getYear();
    month = Clock.getMonth(Century);
    date = Clock.getDate();
    hour = Clock.getHour(h12, PM);
    minute = Clock.getMinute();
    second = Clock.getSecond();
    if (date < 10) lcd.print('0');
    lcd.print(date, DEC);
    lcd.print('-');
    if (month < 10) lcd.print('0');
    lcd.print(month, DEC);
    lcd.print('-');
    lcd.print("20");
    lcd.print(year, DEC);
    // set the cursor to column 0, line 1
    // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor(0, 1);
    if (hour < 10) lcd.print('0');
    lcd.print(hour, DEC);
    lcd.print(':');
    if (minute < 10) lcd.print('0');
    lcd.print(minute, DEC);
    lcd.print(':');
    if (second < 10) lcd.print('0');
    lcd.print(second, DEC);
    lcd.print(' ');
    lastUpdate = millis();
  }
}
#endif

Главный файл PartOfGreenhouse

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#include <Wire.h>
#include "TempSens.h"
#include "MyClock.h"

int pirState = LOW;  // начинаем работу программы, предполагая, что движения нет
int PIRvalue = 0;  // переменная для чтения состояния пина
int statusLamp = 0;
unsigned int FotoValue = 0;
int PIRpin = 3;  // инициализируем пин для получения сигнала от пироэлектрического датчика движения
int RelayLampPin = 40;
//Определим какие пины использовать для датчика влажности почвы
int FotoResist = A14; //Фоторезистор
int DelayOFF = 2; //Выдержка для лампы (1 мин)

void setup() {
  Wire.begin();
  Serial.begin(19200);      // Связь по терминалу
  dht.begin();
  lcd.init();
  pinMode(PIRpin, INPUT);
  pinMode(RelayLampPin, OUTPUT); 
  SettingTime(21, 15, 16);
  SettingDate(15, 12, 16);
  tone(4, 2000, 200); 
}

void loop() {
  TempSens();
  ShowTimeAndDate(300);
  Lamp(1000, DelayOFF);
}
  • Вопрос задан
  • 430 просмотров
Решения вопроса 1
Ocelot
@Ocelot
Тут некорректно работает?
int TimerOFFLamp = atoi(minute) + DelayOFF;
      while (minute < TimerOFFLamp) {
        digitalWrite(RelayLampPin, HIGH);
      }


1) Зачем тут atoi()? Это функция преобразования строки в число, ей передаётся указатель char*. А вам достаточно сделать (int)minute.

2) Значение переменной minute не обновляется в течение цикла. Либо цикл будет вечным, либо компилятор соптимизирует и выкинет его совсем, оставив одну итерацию (вероятно, произошло второе)

3) Этот цикл - вообще плохая идея. Он вешает всю программу, пока не дотикает таймер. Функция Lamp() и так вызывается раз в секунду. Сделайте в ней однократную проверку: время вышло - выключаем лампу; не вышло - ничего не делаем, проверим ещё раз в следующую секунду.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы