persistent config for ESP8266
This commit is contained in:
parent
05f32f34c7
commit
50db32676c
@ -23,7 +23,7 @@ void configReset() {
|
|||||||
nvs_flash_init();
|
nvs_flash_init();
|
||||||
config.begin("config", false);
|
config.begin("config", false);
|
||||||
config.putString("HOSTNAME", HOSTNAME);
|
config.putString("HOSTNAME", HOSTNAME);
|
||||||
configLoad();
|
configLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
String configGetString(const char *name, const char *fallback, bool allowEmpty) {
|
String configGetString(const char *name, const char *fallback, bool allowEmpty) {
|
||||||
@ -48,34 +48,125 @@ double configGetDouble(const char *name, double fallback) {
|
|||||||
return config.getDouble(name);
|
return config.getDouble(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool configPutDouble(const char *name, double fallback) {
|
bool configPutDouble(const char *name, double value) {
|
||||||
return config.value(name, fallback) == 0;
|
return config.value(name, value) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#include <EEPROM.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
JsonDocument json;
|
||||||
|
|
||||||
|
bool configRead();
|
||||||
|
|
||||||
|
bool configWrite();
|
||||||
|
|
||||||
|
size_t configWriteBytes(int *address, uint8_t *data, size_t size);
|
||||||
|
|
||||||
|
size_t configReadBytes(int *address, uint8_t *data, size_t size);
|
||||||
|
|
||||||
void configSetup() {
|
void configSetup() {
|
||||||
// ESP8266 FAKE
|
configRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
void configReset() {
|
void configReset() {
|
||||||
// ESP8266 FAKE
|
json.clear();
|
||||||
|
json["HOSTNAME"] = HOSTNAME;
|
||||||
|
configWrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
String configGetString(const char *name, const char *fallback, bool allowEmpty) {
|
String configGetString(const char *name, const char *fallback, bool allowEmpty) {
|
||||||
return fallback;
|
if (!json.containsKey(name)) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
String value = json[name];
|
||||||
|
if (!allowEmpty && value.isEmpty()) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool configPutString(const char *name, const char *value) {
|
bool configPutString(const char *name, const char *value) {
|
||||||
return false;
|
json[name] = value;
|
||||||
|
return configWrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
double configGetDouble(const char *name, double fallback) {
|
double configGetDouble(const char *name, double fallback) {
|
||||||
return fallback;
|
if (!json.containsKey(name)) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
return json[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool configPutDouble(const char *name, double fallback) {
|
bool configPutDouble(const char *name, double value) {
|
||||||
|
json[name] = value;
|
||||||
|
return configWrite();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool configRead() {
|
||||||
|
size_t length;
|
||||||
|
char buffer[512];
|
||||||
|
|
||||||
|
bool ok = true;
|
||||||
|
int address = 0;
|
||||||
|
EEPROM.begin(512);
|
||||||
|
ok &= configReadBytes(&address, reinterpret_cast<uint8_t *>(&length), sizeof length);
|
||||||
|
ok &= configReadBytes(&address, reinterpret_cast<uint8_t *>(buffer), length);
|
||||||
|
ok &= EEPROM.end();
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
JsonDocument tmp;
|
||||||
|
deserializeJson(tmp, buffer);
|
||||||
|
if (tmp.is<JsonObject>() && !tmp.isNull() && tmp.containsKey("HOSTNAME")) {
|
||||||
|
info("Config loaded");
|
||||||
|
json = tmp;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
error("Failed to parse config JSON");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error("Failed to load config from EEPROM");
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool configWrite() {
|
||||||
|
char buffer[512];
|
||||||
|
size_t length = serializeJson(json, buffer, sizeof buffer);
|
||||||
|
|
||||||
|
bool ok = true;
|
||||||
|
int address = 0;
|
||||||
|
EEPROM.begin(512);
|
||||||
|
ok &= configWriteBytes(&address, reinterpret_cast<uint8_t *>(&length), sizeof length);
|
||||||
|
ok &= configWriteBytes(&address, reinterpret_cast<uint8_t *>(buffer), length);
|
||||||
|
ok &= EEPROM.end();
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t configWriteBytes(int *address, uint8_t *data, size_t size) {
|
||||||
|
uint8_t *b = data;
|
||||||
|
for (; b < data + size; b++) {
|
||||||
|
EEPROM.write((*address)++, *b);
|
||||||
|
if (*address >= EEPROM.length()) {
|
||||||
|
error("END OF EEPROM!!!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b - data;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t configReadBytes(int *address, uint8_t *data, size_t size) {
|
||||||
|
uint8_t *b = data;
|
||||||
|
for (; b < data + size; b++) {
|
||||||
|
*b = EEPROM.read((*address)++);
|
||||||
|
if (*address >= EEPROM.length()) {
|
||||||
|
error("END OF EEPROM!!!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b - data;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -7,7 +7,7 @@ void configSetup();
|
|||||||
|
|
||||||
void configReset();
|
void configReset();
|
||||||
|
|
||||||
void configLoad();
|
void configLoaded();
|
||||||
|
|
||||||
String configGetString(const char *name, const char *fallback, bool allowEmpty);
|
String configGetString(const char *name, const char *fallback, bool allowEmpty);
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,7 @@ monitor_port = ${COMMON.monitor_port}
|
|||||||
monitor_speed = ${COMMON.monitor_speed}
|
monitor_speed = ${COMMON.monitor_speed}
|
||||||
monitor_filters = ${COMMON.monitor_filters}
|
monitor_filters = ${COMMON.monitor_filters}
|
||||||
lib_deps = ${COMMON.lib_deps}
|
lib_deps = ${COMMON.lib_deps}
|
||||||
build_flags = -D HOSTNAME=\"TEST32\" -D WIFI_SSID=\"${COMMON.WIFI_SSID}\" -D WIFI_PKEY=\"${COMMON.WIFI_PKEY}\" -D OTA_PASSWORD=\"OtaAuthPatrixTEST32\" -D BOOT_DELAY=false -D DEBUG_LOG=false
|
build_flags = -D TEST32 -D HOSTNAME=\"TEST32\" -D WIFI_SSID=\"${COMMON.WIFI_SSID}\" -D WIFI_PKEY=\"${COMMON.WIFI_PKEY}\" -D OTA_PASSWORD=\"OtaAuthPatrixTEST32\" -D BOOT_DELAY=false -D DEBUG_LOG=false
|
||||||
|
|
||||||
[env:TEST8266]
|
[env:TEST8266]
|
||||||
upload_port = 10.0.0.162
|
upload_port = 10.0.0.162
|
||||||
@ -44,7 +44,7 @@ monitor_port = ${COMMON.monitor_port}
|
|||||||
monitor_speed = ${COMMON.monitor_speed}
|
monitor_speed = ${COMMON.monitor_speed}
|
||||||
monitor_filters = esp8266_exception_decoder
|
monitor_filters = esp8266_exception_decoder
|
||||||
lib_deps = ${COMMON.lib_deps}
|
lib_deps = ${COMMON.lib_deps}
|
||||||
build_flags = -D HOSTNAME=\"TEST8266\" -D WIFI_SSID=\"${COMMON.WIFI_SSID}\" -D WIFI_PKEY=\"${COMMON.WIFI_PKEY}\" -D OTA_PASSWORD=\"OtaAuthPatrixTEST8266\" -D BOOT_DELAY=true -D DEBUG_LOG=true
|
build_flags = -D TEST8266 -D HOSTNAME=\"TEST8266\" -D WIFI_SSID=\"${COMMON.WIFI_SSID}\" -D WIFI_PKEY=\"${COMMON.WIFI_PKEY}\" -D OTA_PASSWORD=\"OtaAuthPatrixTEST8266\" -D BOOT_DELAY=true -D DEBUG_LOG=true
|
||||||
|
|
||||||
[env:Fermenter]
|
[env:Fermenter]
|
||||||
upload_port = 10.0.0.164
|
upload_port = 10.0.0.164
|
||||||
@ -59,4 +59,4 @@ monitor_port = ${COMMON.monitor_port}
|
|||||||
monitor_speed = ${COMMON.monitor_speed}
|
monitor_speed = ${COMMON.monitor_speed}
|
||||||
monitor_filters = esp8266_exception_decoder
|
monitor_filters = esp8266_exception_decoder
|
||||||
lib_deps = ${COMMON.lib_deps}
|
lib_deps = ${COMMON.lib_deps}
|
||||||
build_flags = -D HOSTNAME=\"Fermenter\" -D WIFI_SSID=\"${COMMON.WIFI_SSID}\" -D WIFI_PKEY=\"${COMMON.WIFI_PKEY}\" -D OTA_PASSWORD=\"OtaAuthPatrixFermenter\" -D BOOT_DELAY=true -D DEBUG_LOG=true
|
build_flags = -D FERMENTER -D HOSTNAME=\"Fermenter\" -D WIFI_SSID=\"${COMMON.WIFI_SSID}\" -D WIFI_PKEY=\"${COMMON.WIFI_PKEY}\" -D OTA_PASSWORD=\"OtaAuthPatrixFermenter\" -D BOOT_DELAY=true -D DEBUG_LOG=true
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
#if defined(FERMENTER)
|
||||||
|
|
||||||
#include <Patrix.h>
|
#include <Patrix.h>
|
||||||
#include "sensors/Dallas.h"
|
#include "sensors/Dallas.h"
|
||||||
#include "sensors/DallasSensor.h"
|
#include "sensors/DallasSensor.h"
|
||||||
@ -10,31 +12,37 @@
|
|||||||
#define CONTROL_PWM_BITS 10
|
#define CONTROL_PWM_BITS 10
|
||||||
#define CONTROL_PWM_MAX (pow(2, CONTROL_PWM_BITS) - 1)
|
#define CONTROL_PWM_MAX (pow(2, CONTROL_PWM_BITS) - 1)
|
||||||
|
|
||||||
|
#define PID_DEFAULT_P 100
|
||||||
|
#define PID_DEFAULT_I 10
|
||||||
|
#define PID_DEFAULT_D 0
|
||||||
|
#define PID_DEFAULT_TARGET 31
|
||||||
|
#define PID_DEFAULT_OVER 5
|
||||||
|
|
||||||
Dallas dallas(SENSOR_GPIO);
|
Dallas dallas(SENSOR_GPIO);
|
||||||
|
|
||||||
DallasSensor sensor(dallas, 0x3D0417C1D740FF28, "sensor", 0.5, 5, 60);
|
DallasSensor sensor(dallas, 0x3D0417C1D740FF28, "sensor", 0.5, 5, 60);
|
||||||
|
|
||||||
ArduPID pid;
|
ArduPID pid;
|
||||||
|
|
||||||
double temperatureTarget = 31;
|
double proportional = PID_DEFAULT_P;
|
||||||
|
|
||||||
|
double integral = PID_DEFAULT_I;
|
||||||
|
|
||||||
|
double derivative = PID_DEFAULT_D;
|
||||||
|
|
||||||
|
double temperatureTarget = PID_DEFAULT_TARGET;
|
||||||
|
|
||||||
|
double temperatureOver = PID_DEFAULT_OVER;
|
||||||
|
|
||||||
double temperatureCurrent = NAN;
|
double temperatureCurrent = NAN;
|
||||||
|
|
||||||
double temperatureMaxOvershoot = 5;
|
|
||||||
|
|
||||||
double heaterPWM = 0;
|
double heaterPWM = 0;
|
||||||
|
|
||||||
double proportional = 1;
|
|
||||||
|
|
||||||
double integral = 0;
|
|
||||||
|
|
||||||
double derivative = 0;
|
|
||||||
|
|
||||||
void patrixSetup() {
|
void patrixSetup() {
|
||||||
dallas.begin();
|
dallas.begin();
|
||||||
analogWriteResolution(CONTROL_PWM_BITS);
|
analogWriteResolution(CONTROL_PWM_BITS);
|
||||||
|
|
||||||
configLoad();
|
configLoaded();
|
||||||
|
|
||||||
pid.begin(&temperatureCurrent, &heaterPWM, &temperatureTarget, proportional, integral, derivative);
|
pid.begin(&temperatureCurrent, &heaterPWM, &temperatureTarget, proportional, integral, derivative);
|
||||||
pid.setOutputLimits(0, CONTROL_PWM_MAX);
|
pid.setOutputLimits(0, CONTROL_PWM_MAX);
|
||||||
@ -52,7 +60,7 @@ void patrixLoop() {
|
|||||||
heaterPWM = 0;
|
heaterPWM = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool emergencyCutOff = heaterPWM > 0 && temperatureCurrent > temperatureTarget + temperatureMaxOvershoot;
|
const bool emergencyCutOff = heaterPWM > 0 && temperatureCurrent > temperatureTarget + temperatureOver;
|
||||||
if (emergencyCutOff) {
|
if (emergencyCutOff) {
|
||||||
heaterPWM = 0;
|
heaterPWM = 0;
|
||||||
}
|
}
|
||||||
@ -67,7 +75,7 @@ void patrixLoop() {
|
|||||||
int heaterPercent = (int) round(100.0 * heaterPWM / CONTROL_PWM_MAX);
|
int heaterPercent = (int) round(100.0 * heaterPWM / CONTROL_PWM_MAX);
|
||||||
debug("p: %.10f | i: %.10f | d: %.10f | current: %5.2f | target: %5.2f | heater: %3d%%", proportional, integral, derivative, temperatureCurrent, temperatureTarget, heaterPercent);
|
debug("p: %.10f | i: %.10f | d: %.10f | current: %5.2f | target: %5.2f | heater: %3d%%", proportional, integral, derivative, temperatureCurrent, temperatureTarget, heaterPercent);
|
||||||
if (emergencyCutOff) {
|
if (emergencyCutOff) {
|
||||||
error("[EMERGENCY CUTOFF] temperatureCurrent (=%5.2f) > temperatureTarget + %5.2f (=%5.2f) [EMERGENCY CUTOFF]", temperatureCurrent, temperatureMaxOvershoot, temperatureTarget);
|
error("[EMERGENCY CUTOFF] temperatureCurrent (=%5.2f) > temperatureTarget + %5.2f (=%5.2f) [EMERGENCY CUTOFF]", temperatureCurrent, temperatureOver, temperatureTarget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,15 +107,15 @@ bool setDouble(const char *name, double *destinationPtr, double min, double max)
|
|||||||
|
|
||||||
bool patrix_command(char *first) {
|
bool patrix_command(char *first) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
if (strcmp(first, "over") == 0) {
|
if (strcmp(first, "over") == 0 || strcmp(first, "o") == 0) {
|
||||||
result = setDouble("over", &temperatureMaxOvershoot, 0, 20);
|
result = setDouble("over", &temperatureOver, 0, 20);
|
||||||
} else if (strcmp(first, "target") == 0) {
|
} else if (strcmp(first, "target") == 0 || strcmp(first, "t") == 0) {
|
||||||
result = setDouble("target", &temperatureTarget, -10, 60);
|
result = setDouble("target", &temperatureTarget, -10, 60);
|
||||||
} else if (strcmp(first, "p") == 0) {
|
} else if (strcmp(first, "proportional") == 0 || strcmp(first, "p") == 0) {
|
||||||
result = setDouble("p", &proportional, NAN, NAN);
|
result = setDouble("p", &proportional, NAN, NAN);
|
||||||
} else if (strcmp(first, "i") == 0) {
|
} else if (strcmp(first, "integral") == 0 || strcmp(first, "i") == 0) {
|
||||||
result = setDouble("i", &integral, NAN, NAN);
|
result = setDouble("i", &integral, NAN, NAN);
|
||||||
} else if (strcmp(first, "d") == 0) {
|
} else if (strcmp(first, "derivative") == 0 || strcmp(first, "d") == 0) {
|
||||||
result = setDouble("d", &derivative, NAN, NAN);
|
result = setDouble("d", &derivative, NAN, NAN);
|
||||||
}
|
}
|
||||||
if (result) {
|
if (result) {
|
||||||
@ -116,11 +124,13 @@ bool patrix_command(char *first) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void configLoad() {
|
void configLoaded() {
|
||||||
proportional = configGetDouble("p", 3000);
|
proportional = configGetDouble("p", PID_DEFAULT_P);
|
||||||
integral = configGetDouble("i", 10);
|
integral = configGetDouble("i", PID_DEFAULT_I);
|
||||||
derivative = configGetDouble("d", 0);
|
derivative = configGetDouble("d", PID_DEFAULT_D);
|
||||||
temperatureTarget = configGetDouble("target", 31);
|
temperatureTarget = configGetDouble("target", PID_DEFAULT_TARGET);
|
||||||
temperatureMaxOvershoot = configGetDouble("over", 5);
|
temperatureOver = configGetDouble("over", PID_DEFAULT_OVER);
|
||||||
pid.setCoefficients(proportional, integral, derivative);
|
pid.setCoefficients(proportional, integral, derivative);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
23
src/Test.cpp
Normal file
23
src/Test.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#if defined(TEST8266) || defined(TEST32)
|
||||||
|
|
||||||
|
#include <Patrix.h>
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
void patrixSetup() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void patrixLoop() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void configLoaded() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool patrix_command(char *first) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Reference in New Issue
Block a user