Привет, сообщество!
С детства меня всегда интересовала электроника, и я был вдохновлен каналом AlexGyver. Теперь, будучи в сознательном возрасте, я решил попробовать реализовать проект по автоматизации жалюзей. Однако я только начинаю изучать эту тему и сталкиваюсь с множеством вопросов и трудностей, что заставляет меня обратиться к вам за помощью.
Вот основные задачи, с которыми я столкнулся:
1.Автоматическое управление мотором: Я хочу, чтобы мотор открывался или закрывался автоматически в соответствии с сохраненным временем в базе данных. Мне нужна помощь в написании функции, которая будет проверять текущее время и инициировать действия открытия или закрытия мотора.
2.Подключение физических кнопок: Я планирую подключить две кнопки с внутренней подтяжкой к пинам 2 и 3. Эти кнопки должны управлять мотором: одна будет открывать, а другая закрывать его. Подскажите, пожалуйста, как лучше подключить кнопки и реализовать обработку их нажатий с учетом дребезга.
3.Дополнительное поле в веб-интерфейсе: У меня уже есть поля для настройки времени открытия и закрытия мотора в веб-интерфейсе. Мне нужно добавить еще одно поле, которое позволит пользователю задавать время работы мотора (например, как долго он должен работать после нажатия кнопки и при сробатывание по таймеру).
Если у кого-то есть идеи или примеры кода для реализации этих функций, буду очень признателен за помощь!
Заранее спасибо!
Забыл удалить ключи лишних данных из базы. В строках 37 и 38 (minw1, minw2) эти ключи больше не нужны, так как, насколько я понял, база данных может сохранять время целиком.
С детства меня всегда интересовала электроника, и я был вдохновлен каналом AlexGyver. Теперь, будучи в сознательном возрасте, я решил попробовать реализовать проект по автоматизации жалюзей. Однако я только начинаю изучать эту тему и сталкиваюсь с множеством вопросов и трудностей, что заставляет меня обратиться к вам за помощью.
Вот основные задачи, с которыми я столкнулся:
1.Автоматическое управление мотором: Я хочу, чтобы мотор открывался или закрывался автоматически в соответствии с сохраненным временем в базе данных. Мне нужна помощь в написании функции, которая будет проверять текущее время и инициировать действия открытия или закрытия мотора.
2.Подключение физических кнопок: Я планирую подключить две кнопки с внутренней подтяжкой к пинам 2 и 3. Эти кнопки должны управлять мотором: одна будет открывать, а другая закрывать его. Подскажите, пожалуйста, как лучше подключить кнопки и реализовать обработку их нажатий с учетом дребезга.
3.Дополнительное поле в веб-интерфейсе: У меня уже есть поля для настройки времени открытия и закрытия мотора в веб-интерфейсе. Мне нужно добавить еще одно поле, которое позволит пользователю задавать время работы мотора (например, как долго он должен работать после нажатия кнопки и при сробатывание по таймеру).
Если у кого-то есть идеи или примеры кода для реализации этих функций, буду очень признателен за помощь!
Заранее спасибо!
C++:
const char* ssid = "Vodafone-946C_plus";
const char* password = "19191919";
#ifdef ESP8266
#include <ESP8266WiFi.h>
#else
#include <WiFi.h>
#endif
#include <LittleFS.h>
#include <GyverDBFile.h>
#include <SettingsGyver.h>
#include <GyverNTP.h>
IPAddress local_IP(192, 168, 0, 125);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(8, 8, 8, 8);
IPAddress secondaryDNS(8, 8, 4, 4);
// ===== Инициализация NTP клиента =====
GyverNTP ntp(1); // Время UTC+1 для зимнего времени Берлина
// База данных для хранения настроек
GyverDBFile db(&LittleFS, "/data.db");
// Указывается заголовок меню, подключается база данных
SettingsGyver sett("ЖАЛЮЗИ", &db);
// Ключи для хранения в базе данных
enum kk : size_t {
lbl1, // часы реал. времени
lbl2,
timew1, // Часы открытия
timew2, // Часы закрытия
minw1, // Минуты открытия
minw2, // Минуты закрытия
datime,
btn1,
btn2,
};
// Пины для управления мотором
const int IN1 = 0; // Замените на нужный пин
const int IN2 = 1; // Замените на нужный пин
unsigned long startTime = 0;
bool timerActive = false;
unsigned long previousMillis = 0; // Для отслеживания времени между циклами
const unsigned long interval = 10; // Интервал задержки (раньше 10 мс в delay)
int i = 0; // Для контроля значений в циклах открытия и закрытия
// Проверка, включено ли летнее время
bool isDST(int day, int month, int hour) {
if (month < 3 || month > 10) return false; // Зима, без летнего времени
if (month > 3 && month < 10) return true; // Лето, с летним временем
int lastSunday;
// Рассчитываем последнее воскресенье марта
if (month == 3) {
lastSunday = 31 - ((5 + (ntp.year() + ntp.year() / 4 + 5) % 7) % 7);
return (day > lastSunday || (day == lastSunday && hour >= 2));
}
// Рассчитываем последнее воскресенье октября
if (month == 10) {
lastSunday = 31 - ((2 + (ntp.year() + ntp.year() / 4 + 5) % 7) % 7);
return !(day > lastSunday || (day == lastSunday && hour < 2));
}
return false;
}
// Открыть мотор
void handleOpenButton() {
Serial.println("open");
digitalWrite(IN1, HIGH); // Направление вперед
i = 0; // Начинаем с 0, чтобы нарастить значение в цикле
startTime = millis();
timerActive = true;
}
// Закрыть мотор
void handleCloseButton() {
Serial.println("close");
digitalWrite(IN1, LOW); // Направление назад
i = 255; // Начинаем с 255, чтобы уменьшить значение в цикле
startTime = millis();
timerActive = true;
}
// Проверка таймера для остановки мотора
void checkTimer() {
if (timerActive) {
unsigned long currentMillis = millis(); // Получаем текущее время
// Если прошло больше 5 секунд, остановить мотор
if (currentMillis - startTime >= 5000) {
digitalWrite(IN1, LOW);
#ifdef ESP8266
ledcWrite(channel, 0); // Используйте ledcWrite для ESP8266
#else
analogWrite(IN2, 0);
#endif
Serial.println("5 seconds passed, stopping motor");
timerActive = false;
}
// Контролируем изменение PWM-сигнала через каждые 10 мс
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (digitalRead(IN1) == HIGH && i <= 255) {
// Увеличиваем значение для открытия
#ifdef ESP8266
ledcWrite(channel, i);
#else
analogWrite(IN2, i);
#endif
i++;
} else if (digitalRead(IN1) == LOW && i >= 0) {
// Уменьшаем значение для закрытия
#ifdef ESP8266
ledcWrite(channel, i);
#else
analogWrite(IN2, i);
#endif
i--;
}
}
}
}
//====== Билдер настроек======//
void build(sets::Builder& b) {
b.Label(kk::lbl1, "Время/Дата");
b.Label(kk::lbl2, "millis()", "", sets::Colors::Red);
if (b.beginGroup("")) {
if (b.beginMenu("таймер")) {
b.Time(kk::timew1, "Открыть в");
b.Time(kk::timew2, "Закрыть в");
b.endMenu();
}
b.endGroup();
}
if (b.beginButtons()) {
if (b.Button(kk::btn1, "Открыть")) {
handleOpenButton();
}
if (b.Button(kk::btn2, "Закрыть", sets::Colors::Blue)) {
handleCloseButton();
}
}
b.endButtons();
}
// ======Апдейтер====== //
void update(sets::Updater& upd) {
upd.update(kk::lbl1, NTP.toString()); // Обновляем lbl1 текущим временем
upd.update(kk::lbl2, millis());
}
// ======Инициализация======//
void setup() {
Serial.begin(115200);
Serial.println();
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
// Инициализация LittleFS
LittleFS.begin();
// Настраивает статический IP-адрес
if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
Serial.println("STA Failed to configure");
}
// ======Инициализация Wi-Fi====== //
// WiFi.mode(WIFI_AP_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500); // здесь задержка допустима, так как это при подключении Wi-Fi
}
Serial.println();
Serial.print("Connected: ");
Serial.println(WiFi.localIP());
NTP.begin(1);
// Инициализация базы данных и настроек
sett.begin();
sett.onBuild(build);
sett.onUpdate(update);
db.begin();
db.init(kk::timew1, 6);
}
void loop() {
checkTimer();
sett.tick();
NTP.tick();
}
Изменено: