arduino ЖК-дисплей помощь

Я пытаюсь создать умные часы с будильником, используя Arduino Uno.

Моя проблема заключается в том, что когда я ставлю будильник, я не могу установить его снова. Каждый раз мне приходится выключать Arduino, а затем снова включать его, чтобы снова установить будильник.

Я использую:
Ардуино Уно
ЖК 16*2
кнопки
зуммер и светодиод
РТК

Мой код работает так: Вначале это позволит вам установить дату и время с помощью кнопок, а также вы можете установить будильник. Когда наступает время будильника, включается мелодия зуммера и загораются светодиоды.

но

Я хочу выключить будильник, чтобы установить другой будильник.

Это мой код:

#include "RTClib.h"
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int alarmState = 0;
int alarmSnooze = 0;
int btnSet = 0;
int btnSel = 0;
int alarmValue = 0;
int alarmCounter = 0;
boolean turnOffAlarm = false;
boolean settingAlarm = false;
int counter = 0;
boolean initialCount = true;
boolean alarmSet = false;
int timeArray[6]; // 0=час, 1=минуты, 2=день, 3=день недели, 4=месяц, 5=год;
int timeCounter = 0;
int alarmArray[2];
char* days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
char* months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
RTC_DS1307 rtc;    // Создаем объект RealTimeClock
DateTime now; // Чтение данных из чипа RTC

///////////////////////////
 ///кнопка определения////
int  b6=6;
int b7=7;
int b8=8;
int b9=9;
/////////////////////




///мелодия///
#include "pitches.h"

const int piezoPin = 13; // пьезо
const int rPin = A0;  //красный светодиод
const int gPin = A1;  //зеленый светодиод
const int bPin = A2;  //синий светодиод
const int pPin = 6;  //нажать кнопку

int ledState = 0;
int ledOn = false;


// примечания
int melody[] = {
  NOTE_F5,NOTE_D5,NOTE_AS4,NOTE_D5,NOTE_F5,NOTE_AS5,NOTE_D6,NOTE_C6,NOTE_AS5,NOTE_D5,NOTE_E5,NOTE_F5,
  NOTE_F5,NOTE_F5,NOTE_D6,NOTE_C6,NOTE_AS5,NOTE_A5,NOTE_G5,NOTE_A5,NOTE_AS5,NOTE_AS5,NOTE_F5,NOTE_D5,NOTE_AS4,
  NOTE_D6,NOTE_D6,NOTE_D6,NOTE_DS6,NOTE_F6,NOTE_F6,NOTE_DS6,NOTE_D6,NOTE_C6,NOTE_D6,NOTE_DS6,NOTE_DS6,
  0,NOTE_DS6,NOTE_D6,NOTE_C6,NOTE_AS5,NOTE_A5,NOTE_G5,NOTE_A5,NOTE_AS5,NOTE_D5,NOTE_E5,NOTE_F5,
  NOTE_F5,NOTE_AS5,NOTE_AS5,NOTE_AS5,NOTE_A5,NOTE_G5,NOTE_G5,NOTE_G5,NOTE_C6,NOTE_DS6,NOTE_D6,NOTE_C6,NOTE_AS5,NOTE_AS5,NOTE_A5,
  NOTE_F5,NOTE_F5,NOTE_AS5,NOTE_C6,NOTE_D6,NOTE_DS6,NOTE_F6,NOTE_AS5,NOTE_C6,NOTE_D6,NOTE_DS6,NOTE_C6,NOTE_AS5
};

// длительности: 2 = половинная нота и 8/3,4,6,8,12. Похоже, что 8/2,9 точнее, чем 8/3.
float noteDurations[] = {
  6,12,4,4,4,2,6,12,4,4,4,2,
  8,8,8/2.9,8,4,2,8,8,4,4,4,4,4,
  6,12,4,4,4,2,8,8,4,4,4,2,
  8,8,8/2.9,8,4,2,8,8,4,4,4,2,
  4,4,4,8,8,4,4,4,4,8,8,8,8,4,4,
  8,8,8/2.9,8,8,8,2,8,8,4,4,4,2
};


// вычисляет количество элементов в массиве мелодии.
int musicLength=sizeof(melody)/sizeof('NOTE_F5');

///////////////////////////






void setup()
{


  pinMode(pPin, INPUT);
  pinMode(rPin, OUTPUT);
  pinMode(gPin, OUTPUT);
  pinMode(bPin, OUTPUT);


  Serial.begin(9600);
  lcd.begin(16, 2);
  pinMode(10, OUTPUT);
  rtc.begin(); // Запускаем код библиотеки RTC
  rtc.adjust(DateTime(0, 0, 0, 0, 0, 0));
}
void loop()

{ alarmState = digitalRead(b9);
  alarmSnooze = digitalRead(b6);
  btnSet = digitalRead(b7);
  btnSel = digitalRead(b8);


  if (timeCounter == 0)
  {
    if(initialCount == true){
      counter=0;
      initialCount = false;
    }
    setHour();
  }
  else if (timeCounter == 1)
  {
    if(initialCount == true){
      counter=0;
      initialCount =false;
    }
    setMinute();
  }
  else if (timeCounter == 2)
  {
    if(initialCount == true){
      counter= 1;
      initialCount=false;
    }
    setDay();
  }
  else if (timeCounter == 3)
  {
    if(initialCount == true){
      counter = 0;
      initialCount =false;
    }
    setDOW();
  }
  else if (timeCounter == 4)
  {
    if(initialCount==true){
      counter=0;
      initialCount=false;
    }
    setMonth();
  }
  else if (timeCounter == 5)
  {
    if(initialCount==true){
      counter=0;
      initialCount=false;
    }
    setYear();
  }
  else if (timeCounter == 6)
  {
    rtc.adjust(DateTime(2000+timeArray[5], timeArray[4], timeArray[2], timeArray[0], timeArray[1], 0));
    timeCounter++;
    delay(200);
  }
  else if (timeCounter > 6){
    if(alarmState == LOW&&settingAlarm==false){
      now = rtc.now();
      digitalClockDisplay();
    }
    else if(alarmState == HIGH||settingAlarm==true)
    {
      settingAlarm = true;
      if(alarmValue==0){
        if(initialCount==true)
        {
          lcd.clear();
          alarmCounter=0;
          initialCount=false;
        }
        setAlarmHour();
      }
      else if(alarmValue==1){
        if(initialCount==true)
        {
          alarmCounter=0;
          initialCount=false;
        }
        setAlarmMinute();
      }
      else if(alarmValue>1){
        alarmSet = true;
        settingAlarm = false;
      }
    }
    if(alarmArray[0]==now.hour()&&alarmArray[1]==now.minute()&&turnOffAlarm==false&&alarmSet==true&&alarmSnooze==LOW){
       for (int thisNote = 0; thisNote < musicLength; thisNote++) {
      // мигаем последовательно тремя светодиодами
      if (thisNote%3==0){    
        digitalWrite(rPin, HIGH);
        digitalWrite(gPin, LOW);
        digitalWrite(bPin, LOW);
      }
      else if (thisNote%3==1){    
        digitalWrite(rPin, LOW);
        digitalWrite(gPin, HIGH);
        digitalWrite(bPin, LOW);
      }
      else if (thisNote%3==2){    
        digitalWrite(rPin, LOW);
        digitalWrite(gPin, LOW);
        digitalWrite(bPin, HIGH);
      }

      // вычисляем длительность ноты. изменить темп, изменив 2000 на другие значения
      int noteDuration = 2000/noteDurations[thisNote];
      tone(piezoPin, melody[thisNote],noteDuration);

      // чтобы различать ноты, установите минимальное время между ними.
      // продолжительность ноты + 30%, кажется, работает хорошо
      float pauseBetweenNotes = noteDuration * 1.30;

      //делим задержку на две части и проверяем
      //нажата ли кнопка для выключения
      // звук и свет
      delay(pauseBetweenNotes/2);
      if(digitalRead(pPin)==HIGH) {
        break;      
      }
      delay(pauseBetweenNotes/2);
      if(digitalRead(pPin)==HIGH) {
        break;      
      }

    }
      digitalWrite(13, HIGH);

    }




    else if(alarmArray[0]==now.hour() && alarmArray[1]==now.minute()&&turnOffAlarm==false&&alarmSet==true&&alarmSnooze==HIGH){
      noTone(13);
      digitalWrite(13, LOW);
      digitalWrite(rPin, LOW);
    digitalWrite(gPin, LOW);
    digitalWrite(bPin, LOW);
      turnOffAlarm = true;
    } 
  }
}

void nextValue(){
  btnSel=LOW;
  // Обновить значение массива со счетчиком
  timeArray[timeCounter] = counter;
  counter=0;
  initialCount = true;
  timeCounter++;
  delay(200);
  lcd.clear();
}
void nextAlarmValue(){
  btnSel=LOW;
  // Обновить значение массива со счетчиком
  alarmArray[alarmValue] = alarmCounter;
  alarmCounter=0;
  initialCount = true;
  alarmValue++;
  delay(200);
  lcd.clear();
}

void setAlarmHour(){
   if(alarmCounter==24){
    alarmCounter=0;
    lcd.clear();
  }
  lcd.setCursor(0,0);
  lcd.print("Set alarm hour");
  lcd.setCursor(7,1);
  lcd.print(alarmCounter);
  if (btnSet==HIGH)
  {
    alarmCounter++;
    delay(200);
  }
 else if(btnSel==HIGH)
 {
  nextAlarmValue();
 }
}

void setAlarmMinute(){
  if(alarmCounter==59){
  alarmCounter=0;
  lcd.clear();
  }
  lcd.setCursor(0,0);
  lcd.print("Set alarm minute");
  lcd.setCursor(7,1);
  lcd.print(alarmCounter);
  if (btnSet==HIGH)
  {
    alarmCounter++;
    delay(200);
  }
 else if(btnSel==HIGH)
 {
  nextAlarmValue();
 }
}

void setDOW(){
  if(counter==7){
    counter=0;
    lcd.clear();
  }
  lcd.setCursor(0,0);
  lcd.print("Set day of week");
  lcd.setCursor(7,1);
  lcd.print(days[counter]);
  if (btnSet==HIGH)
  {
    counter++;
    delay(200);
  }
 else if(btnSel==HIGH)
 {
  nextValue();
 }
}
void setHour()
{
  if(counter==24){
    counter=0;
    lcd.clear();
  }
  lcd.setCursor(0,0);
  lcd.print("Set hour");
  lcd.setCursor(7,1);
  lcd.print(counter);
  if (btnSet==HIGH)
  {
    counter++;
    delay(200);
  }
 else if(btnSel==HIGH)
 {
  nextValue();
 }
}

// Функция для установки минут
void setMinute()
{
  if(counter==60){
    counter=0;
    lcd.clear();
  }
  lcd.setCursor(0,0);
  lcd.print("Set minute");
  lcd.setCursor(7,1);
  lcd.print(counter);
  if (btnSet==HIGH)
  {
    counter++;
    delay(200);
  }
 else if(btnSel==HIGH)
 {
  nextValue();
 }
}

// Функция для установки даты
void setDay()
{
  if(counter==32){
    counter=1;
    lcd.clear();
  }
  lcd.setCursor(0,0);
  lcd.print("Set day");
  lcd.setCursor(7,1);
  lcd.print(counter);
  if (btnSet==HIGH)
  {
    counter++;
    delay(200);
  }
 else if(btnSel==HIGH)
 {
  nextValue();
 }
}

// Функция для установки месяца
void setMonth()
{
  if(counter==12){
    counter=0;
    lcd.clear();
  }
  lcd.setCursor(0,0);
  lcd.print("Set month");
  lcd.setCursor(7,1);
  lcd.print(months[counter]);
  if (btnSet==HIGH)
  {
    counter++;
    delay(200);
  }
 else if(btnSel==HIGH)
 {
  nextValue();
 }
}

// Функция для установки года
void setYear()
{
  lcd.setCursor(0,0);
  lcd.print("Set year");
  lcd.setCursor(7,1);
  lcd.print(counter);
  if (btnSet==HIGH)
  {
    counter++;
    delay(200);
  }
 else if(btnSel==HIGH)
 {
  nextValue();
 }
}

void digitalClockDisplay(){
  // цифровые часы отображающие время
  long hours;
  String amOrPm = "";
  if(now.hour() > 12){
    hours = now.hour() - 12;
    amOrPm = "PM";
  }
  else if(now.hour()==0){
    hours=12;
    amOrPm = "AM";
  }
  else{
    hours = now.hour();
    amOrPm = "AM";
  }
  lcd.setCursor(0,0);
  lcd.print(days[timeArray[3]]);
  lcd.print(" ");
  lcd.print(months[timeArray[4]]);
  lcd.print(" ");
  lcd.print(now.day());
  lcd.print(" ");
  lcd.print(now.year());
  lcd.setCursor(0,1);
  lcd.print(hours);
  printDigits(now.minute());
  printDigits(now.second());
  lcd.print(" ");
  lcd.print(amOrPm);
}

void printDigits(int digits){
  // служебная функция для отображения цифровых часов: печатает предшествующее двоеточие и начальный 0
  lcd.print(":");
  if(digits < 10)
    lcd.print('0');
  lcd.print(digits);
}

, 👍2

Обсуждение

Что вы пытались сделать с помощью sizeof(melody)/sizeof('NOTE_F5')??? В чем конкретно смысл sizeof('NOTE_F5')? Что компилятор сказал вам о 'NOTE_F5'?, @AnT


2 ответа


1

Похоже, вы не сбросили переменную состояния turnOffAlarm после выключения будильника.

,

0

Поскольку вопрос отмечен тегом [code-review]

  1. char* days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
    

    Это должен быть массив const из const char *, а не из char *.

    const char *const days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
    

    То же самое касается месяцев.

  2. int  b6=6;
    ...
    const int piezoPin = 13;
    ...
    

    Почему некоторые из ваших контактов const, а другие нет? Я не вижу никаких попыток или причин изменить значение b6 в коде. Почему это не const?

  3. int melody[] = { ... };
    float noteDurations[] = { ... };
    

    По-видимому, оба должны быть const.

  4. // вычисляет количество элементов в массиве мелодии.
    int musicLength=sizeof(melody)/sizeof('NOTE_F5');
    

    Правда? Что такое 'NOTE_F5'? Что ваш компилятор сказал вам об этом? Вы только что проигнорировали сообщение компилятора?

    Должно быть

    const int musicLength = sizeof melody / sizeof *melody;
    

    Я бы предпочел unsigned или size_t, но не будем открывать эту банку с червями.

  5. В скетче с одним файлом все глобальные переменные (т.е. те, которые действительно должны быть глобальными) должны быть объявлены либо const, либо static (или помещены в анонимном пространстве имен). Для объявления глобальной переменной, которая не является const или static, требуется веская причина.

,