WiFi, Hostname, OTA, Button, Relay, Status, config
This commit is contained in:
commit
805e492fe9
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.pio
|
||||
8
platformio.ini
Normal file
8
platformio.ini
Normal file
@ -0,0 +1,8 @@
|
||||
[env:Sonoff4ChPro]
|
||||
platform = espressif8266
|
||||
board = esp8285
|
||||
framework = arduino
|
||||
upload_speed = 921600
|
||||
upload_port = 10.0.0.178
|
||||
monitor_speed = 115200
|
||||
build.filesystem = littlefs
|
||||
74
src/Button.h
Normal file
74
src/Button.h
Normal file
@ -0,0 +1,74 @@
|
||||
#ifndef BUTTON_H
|
||||
#define BUTTON_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
enum ButtonEvent {
|
||||
BUTTON_PRESSED,
|
||||
BUTTON_PRESSED_LONG,
|
||||
BUTTON_RELEASED,
|
||||
BUTTON_RELEASED_SHORT,
|
||||
BUTTON_RELEASED_LONG,
|
||||
};
|
||||
|
||||
class Button {
|
||||
|
||||
public:
|
||||
|
||||
typedef void (*callback_t)(ButtonEvent event);
|
||||
|
||||
private:
|
||||
|
||||
const uint8_t pin;
|
||||
|
||||
const bool pullup;
|
||||
|
||||
const bool inverted;
|
||||
|
||||
const callback_t callback;
|
||||
|
||||
bool lastState = false;
|
||||
|
||||
bool pressedLong = false;
|
||||
|
||||
unsigned long lastMillis = 0;
|
||||
|
||||
public:
|
||||
|
||||
explicit Button(const uint8_t pin, const bool pullup, const bool inverted, const callback_t callback) : pin(pin), pullup(pullup), inverted(inverted), callback(callback) {
|
||||
//
|
||||
}
|
||||
|
||||
void setup() {
|
||||
pinMode(pin, pullup ? INPUT_PULLUP : INPUT);
|
||||
lastMillis = millis();
|
||||
lastState = (digitalRead(pin) == HIGH) ^ inverted;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
const auto currentMillis = millis();
|
||||
const auto currentState = digitalRead(pin) == LOW;
|
||||
const auto duration = currentMillis - lastMillis;
|
||||
if (lastState != currentState && duration >= 200) {
|
||||
if (currentState) {
|
||||
callback(BUTTON_PRESSED);
|
||||
} else {
|
||||
callback(BUTTON_RELEASED);
|
||||
if (pressedLong) {
|
||||
callback(BUTTON_RELEASED_LONG);
|
||||
} else {
|
||||
callback(BUTTON_RELEASED_SHORT);
|
||||
}
|
||||
pressedLong = false;
|
||||
}
|
||||
lastState = currentState;
|
||||
lastMillis = currentMillis;
|
||||
} else if (lastState && duration >= 3000 && !pressedLong) {
|
||||
pressedLong = true;
|
||||
callback(BUTTON_PRESSED_LONG);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
47
src/Output.h
Normal file
47
src/Output.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef OUTPUT_H
|
||||
#define OUTPUT_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
class Output {
|
||||
|
||||
const char *name;
|
||||
|
||||
const uint8_t pin;
|
||||
|
||||
const bool inverted;
|
||||
|
||||
const bool logState;
|
||||
|
||||
public:
|
||||
|
||||
Output(const char *name, const uint8_t pin, const bool inverted, const bool logState): name(name), pin(pin), inverted(inverted), logState(logState) {
|
||||
//
|
||||
}
|
||||
|
||||
void setup() const {
|
||||
pinMode(pin, OUTPUT);
|
||||
}
|
||||
|
||||
void set(const bool state) const {
|
||||
if (logState && state != get()) {
|
||||
Serial.printf("%s: %s\n", name, state ? "ON" : "OFF");
|
||||
}
|
||||
digitalWrite(pin, state ^ inverted ? HIGH : LOW);
|
||||
}
|
||||
|
||||
bool get() const {
|
||||
return (digitalRead(pin) == HIGH) ^ inverted;
|
||||
}
|
||||
|
||||
void toggle() const {
|
||||
set(!get());
|
||||
}
|
||||
|
||||
void loop() const {
|
||||
// TODO auto off etc
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
35
src/config.cpp
Normal file
35
src/config.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <LittleFS.h>
|
||||
|
||||
void configSetup() {
|
||||
LittleFS.begin();
|
||||
}
|
||||
|
||||
File configOpen(const char *name, const char *mode) {
|
||||
char path[64];
|
||||
snprintf(path, sizeof(path), "/%s", name);
|
||||
return LittleFS.open(path, mode);
|
||||
}
|
||||
|
||||
String configReadString(const char *name, const char *fallback) {
|
||||
if (auto file = configOpen(name, "r")) {
|
||||
const auto content = file.readString();
|
||||
file.close();
|
||||
return content;
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
bool configWriteString(const char *name, const char *fallback, const String &value) {
|
||||
if (configReadString(name, fallback) == value) {
|
||||
return false;
|
||||
}
|
||||
Serial.printf("\"%s\" = \"%s\"", name, value.c_str());
|
||||
if (auto file = configOpen(name, "w")) {
|
||||
file.write(value.c_str(), value.length());
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
12
src/config.h
Normal file
12
src/config.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include <WString.h>
|
||||
|
||||
void configSetup();
|
||||
|
||||
String configReadString(const char *name, const char *fallback);
|
||||
|
||||
bool configWriteString(const char *name, const char *fallback, const String &value);
|
||||
|
||||
#endif
|
||||
7
src/io.cpp
Normal file
7
src/io.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include "io.h"
|
||||
|
||||
void buttonCallback(const Output &output, const ButtonEvent event) {
|
||||
if (event == BUTTON_PRESSED) {
|
||||
output.toggle();
|
||||
}
|
||||
}
|
||||
55
src/io.h
Normal file
55
src/io.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef IO_H
|
||||
#define IO_H
|
||||
|
||||
#include "Button.h"
|
||||
#include "Output.h"
|
||||
|
||||
void buttonCallback(const Output &output, ButtonEvent event);
|
||||
|
||||
inline Output relay1("RELAY #1", 12, false, true);
|
||||
|
||||
inline Output relay2("RELAY #2", 5, false, true);
|
||||
|
||||
inline Output relay3("RELAY #3", 4, false, true);
|
||||
|
||||
inline Output relay4("RELAY #4", 15, false, true);
|
||||
|
||||
inline Output status("Status", 13, true, false);
|
||||
|
||||
inline Button button1(0, true, true, [](const ButtonEvent event) { buttonCallback(relay1, event); });
|
||||
|
||||
inline Button button2(9, true, true, [](const ButtonEvent event) { buttonCallback(relay2, event); });
|
||||
|
||||
inline Button button3(10, true, true, [](const ButtonEvent event) { buttonCallback(relay3, event); });
|
||||
|
||||
inline Button button4(14, true, true, [](const ButtonEvent event) { buttonCallback(relay4, event); });
|
||||
|
||||
inline void ioSetup() {
|
||||
button1.setup();
|
||||
button2.setup();
|
||||
button3.setup();
|
||||
button4.setup();
|
||||
|
||||
status.setup();
|
||||
|
||||
relay1.setup();
|
||||
relay2.setup();
|
||||
relay3.setup();
|
||||
relay4.setup();
|
||||
}
|
||||
|
||||
inline void ioLoop() {
|
||||
button1.loop();
|
||||
button2.loop();
|
||||
button3.loop();
|
||||
button4.loop();
|
||||
|
||||
status.loop();
|
||||
|
||||
relay1.loop();
|
||||
relay2.loop();
|
||||
relay3.loop();
|
||||
relay4.loop();
|
||||
}
|
||||
|
||||
#endif
|
||||
20
src/main.cpp
Normal file
20
src/main.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include <ArduinoOTA.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "io.h"
|
||||
#include "wifi.h"
|
||||
|
||||
void setup() {
|
||||
delay(500);
|
||||
Serial.begin(115200);
|
||||
Serial.print("\n\n\nStartup!\n");
|
||||
|
||||
configSetup();
|
||||
ioSetup();
|
||||
wifiSetup();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
ioLoop();
|
||||
ArduinoOTA.handle();
|
||||
}
|
||||
63
src/wifi.cpp
Normal file
63
src/wifi.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
#include "wifi.h"
|
||||
|
||||
#include <ArduinoOTA.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "io.h"
|
||||
|
||||
#define DEFAULT_HOSTNAME "PatrixSonoff4ChPro"
|
||||
#define DEFAULT_WIFI_SSID "HappyNet"
|
||||
#define DEFAULT_WIFI_PASS "1Grausame!Sackratte7"
|
||||
|
||||
void wifiChangeHostname(const char *hostname) {
|
||||
if (configWriteString("hostname", DEFAULT_HOSTNAME, hostname)) {
|
||||
WiFi.setHostname(hostname);
|
||||
Serial.printf("Changed hostname to: %s\n", hostname);
|
||||
}
|
||||
}
|
||||
|
||||
void wifiChangeSSID(const char *ssid) {
|
||||
if (configWriteString("wifiSSID", DEFAULT_WIFI_SSID, ssid)) {
|
||||
Serial.printf("Changed SSID to: %s\n", ssid);
|
||||
}
|
||||
}
|
||||
|
||||
void wifiChangePassword(const char *password) {
|
||||
configWriteString("wifiPass", DEFAULT_WIFI_PASS, password);
|
||||
Serial.printf("Changed password\n");
|
||||
}
|
||||
|
||||
void wifiSetup() {
|
||||
const auto hostname = configReadString("hostname", DEFAULT_HOSTNAME);
|
||||
const auto wifiSSID = configReadString("wifiSSID", DEFAULT_WIFI_SSID);
|
||||
const auto wifiPass = configReadString("wifiPass", DEFAULT_WIFI_PASS);
|
||||
WiFi.hostname(hostname);
|
||||
WiFi.begin(wifiSSID, wifiPass);
|
||||
while (WiFi.localIP() == 0UL) {
|
||||
delay(500);
|
||||
status.toggle();
|
||||
}
|
||||
|
||||
yield();
|
||||
status.set(false);
|
||||
Serial.printf("Connected as \"%s\" (%s)\n", WiFi.hostname().c_str(), WiFi.localIP().toString().c_str());
|
||||
|
||||
ArduinoOTA.onStart([] {
|
||||
Serial.println("OTA begin...");
|
||||
status.set(true);
|
||||
});
|
||||
ArduinoOTA.onProgress([](const unsigned progress, const unsigned total) {
|
||||
Serial.printf("OTA: %3d%%\r", 100 * progress / total);
|
||||
status.toggle();
|
||||
});
|
||||
ArduinoOTA.onEnd([] {
|
||||
Serial.println("\nOTA success!");
|
||||
status.set(true);
|
||||
});
|
||||
ArduinoOTA.onError([](const ota_error_t error) {
|
||||
Serial.printf("\nOTA error %u\n", error);
|
||||
status.set(false);
|
||||
});
|
||||
ArduinoOTA.begin();
|
||||
delay(1000);
|
||||
}
|
||||
12
src/wifi.h
Normal file
12
src/wifi.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef WIFI_H
|
||||
#define WIFI_H
|
||||
|
||||
void wifiChangeHostname(const char *hostname);
|
||||
|
||||
void wifiChangeSSID(const char *ssid);
|
||||
|
||||
void wifiChangePassword(const char *password);
|
||||
|
||||
void wifiSetup();
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user