Помогите в личном проекте будильника, не могу записать время на семисегментный дисплей

Я пытаюсь сделать тип будильника Arduino, который, когда время, которое я ввел, равно текущему времени, сервопривод включит мой свет. Он в основном состоит из клавиатуры, RTC DS1307 и семисегментного дисплея TM1637. Основная идея заключается в том, что модуль RTC будет выводить время на дисплей до тех пор, пока я не решу написать что-то на клавиатуре, что очистит время на дисплее, чтобы я мог записать сигнал тревоги. Моя проблема в том, что дисплею удается одновременно показывать время на дисплее и записывать на дисплей, но это работает только с отдельным кодом, а не вместе.

Клавиатура имеет символы " * "и"#", когда я решаю написать время, когда я хочу, чтобы свет включился, после его написания я нажимаю символ"*", чтобы сохранить это время, а затем идея состояла бы в том, чтобы сравнить написанное время и настоящее время, если бы я нажмите "#", затем все будет отменено, и модуль RTC продолжит показывать время на дисплее. (мне не удалось продвинуться так далеко из-за моей ошибки в том, что я не смог очистить дисплей, когда хочу писать на клавиатуре)

#include "Arduino.h"

// КЛАВИАТУРА
#include "Keypad.h"

const byte ROWS = 4; //четыре строки
const byte COLS = 3; //три столбца

//определить символы на кнопках клавиатур
char hexaKeys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};

char customKey;

byte rowPins[ROWS] = {12, 11, 10, 9}; //подключите к строке распиновки клавиатуры
byte colPins[COLS] = {8, 7, 6}; //подключение к колонке распиновки клавиатуры

//инициализировать экземпляр класса NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);


// ДИСПЛЕЙ
#include "SevenSegmentTM1637.h"
#include "SevenSegmentExtended.h"

const byte PIN_CLK = 4;   // определить вывод CLK (любой цифровой вывод)
const byte PIN_DIO = 5;   // определить вывод DIO (любой цифровой вывод)
SevenSegmentExtended      display(PIN_CLK, PIN_DIO);

// РТК

#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>

void setup(){
    Serial.begin(9600);         // инициализирует последовательное соединение при 9600 бод
    display.init();
    display.setBacklight(100);  // установите яркость на 10 %
    display.print("ON");      // display INIT on the display
    delay(1000);                // wait 1000 ms
    display.clear();
}

// OTROS

#define digit 4

byte data_count = 0;
char Data[digit];

void loop(){

    tmElements_t tm; // ЧАСЫ

    display.setColonOn(true);
    customKey = customKeypad.getKey();

    if (RTC.read(tm)) {       
        display.printTime(tm.Hour, tm.Minute, true);
    }


    if (customKey) { // АКТИВИРОВАТЬ КЛАВИАТУРУ

        display.clear();

        if (customKey == '*') { // IF *
            display.blink();

            if (Data[data_count] < 3) {
                error();
            }

        } else if (customKey == '#') { // IF #
            display.blink();
            display.setColonOn(false);
            display.clear();
            clearData();
        } else { // ЗАПИСЬ НА ДИСПЛЕЕ

            Data[data_count] = customKey;
            display.setCursor(0,data_count);
            display.print(Data[data_count]);

            if (data_count < 4) {
                data_count++;
            } else {
                error();
            }       
        } // КОНЕЦ ЗАПИСИ ДИСПЛЕЯ

    } // КОНЕЧНАЯ КЛАВИАТУРА, ЕСЛИ

} // КОНЕЧНЫЙ ЦИКЛ


void error() { // ОТОБРАЗИТЬ ОШИБКУ И УДАЛИТЬ ДАННЫЕ
    display.clear();
    display.setColonOn(false);
    display.print("ERR");
    delay(1000);
    display.clear();
    clearData();
}

void clearData() { // ОЧИСТИТЬ ДАННЫЕ
    while (data_count != 0) {
        Data[data_count--] = 0;
    }
}

Это библиотеки, которые я использую, если это поможет: https://github.com/bremme/arduino-tm1637, https://github.com/PaulStoffregen/DS1307RTC и в Библиотека клавиатуры из Arduino library manager

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

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

, 👍1


1 ответ


Лучший ответ:

2

Я думаю, что ваша проблема здесь:

if (RTC.read(tm)) {       
    display.printTime(tm.Hour, tm.Minute, true);
}

Этот код отображает текущее время и выполняется на каждой итерации цикла. Это явно не то, чего вы хотите. Ваш проект должен иметь по крайней мере два различных режима работы: “отображение текущего времени” и “разрешение пользователю вводить данные”. Вам нужна переменная, чтобы запомнить, какой режим является текущим, например:

enum { MODE_DISPLAY_TIME, MODE_DATA_INPUT } mode;

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

if (mode == MODE_DISPLAY_TIME) {
    if (RTC.read(tm)) {       
        display.printTime(tm.Hour, tm.Minute, true);
    }
} else if (mode == MODE_DATA_INPUT) {
    // Обрабатывать пользовательский ввод.
}

Этот общий подход называется “конечным автоматом”. Подробнее об этом вы можете прочитать в этой статье блога Majenko.

,