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