diff --git a/Software/ChainLube/src/config.cpp b/Software/ChainLube/src/config.cpp new file mode 100644 index 0000000..5e555ac --- /dev/null +++ b/Software/ChainLube/src/config.cpp @@ -0,0 +1,44 @@ +#include <Arduino.h> +#include "config.h" + +LubeConfig_t LubeConfig; + +void StoreConfig_EEPROM() +{ + LubeConfig.checksum = 0; + LubeConfig.checksum = Checksum_EEPROM((uint8_t *)&LubeConfig, sizeof(LubeConfig)); + + EEPROM.begin(512); + EEPROM.put(0, LubeConfig); + EEPROM.commit(); + EEPROM.end(); +} + +void GetConfig_EEPROM() +{ + EEPROM.begin(512); + EEPROM.get(0, LubeConfig); + EEPROM.end(); + + uint32_t checksum = LubeConfig.checksum; + LubeConfig.checksum = 0; + + if (Checksum_EEPROM((uint8_t *)&LubeConfig, sizeof(LubeConfig)) == checksum) + Serial.printf("Checksum OK"); + else + Serial.printf("Checksum BAD"); +} + +uint32_t Checksum_EEPROM(uint8_t const *data, size_t len) +{ + if (data == NULL) + return 0; + uint32_t crc = 0; + while (len--) + { + crc ^= *data++; + for (uint8_t k = 0; k < 8; k++) + crc = crc & 1 ? (crc >> 1) ^ 0xb2 : crc >> 1; + } + return crc ^ 0xff; +} \ No newline at end of file diff --git a/Software/ChainLube/src/config.h b/Software/ChainLube/src/config.h new file mode 100644 index 0000000..107c9e9 --- /dev/null +++ b/Software/ChainLube/src/config.h @@ -0,0 +1,29 @@ +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +#include <Arduino.h> +#include <EEPROM.h> + +typedef struct +{ + uint32_t DistancePerLube_Default = 0; + uint32_t DistancePerLube_Rain = 0; + uint32_t tankCapacity_ml = 320; + uint32_t amountPerDose_µl = 0; + uint32_t tankRemain_µl = 0; + uint8_t TankRemindAtPercentage = 30; + uint8_t PulsePerRevolution = 1; + uint32_t TireWidth_mm = 150; + uint32_t TireWidthHeight_Ratio = 70; + uint32_t RimDiameter_Inch = 18; + uint32_t DistancePerRevolution_mm = 2000; + uint32_t checksum = 0; +} LubeConfig_t; + +void StoreConfig_EEPROM(); +void GetConfig_EEPROM(); +uint32_t Checksum_EEPROM(uint8_t const *data, size_t len); + +extern LubeConfig_t LubeConfig; + +#endif // _CONFIG_H_ \ No newline at end of file diff --git a/Software/ChainLube/src/lubeapp.cpp b/Software/ChainLube/src/lubeapp.cpp index 3cbbdc5..4339648 100644 --- a/Software/ChainLube/src/lubeapp.cpp +++ b/Software/ChainLube/src/lubeapp.cpp @@ -1,6 +1,7 @@ #include "lubeapp.h" -void RunLubeApp(sLubeConfig *cfg) + +void RunLubeApp(LubeConfig_t *cfg) { } \ No newline at end of file diff --git a/Software/ChainLube/src/lubeapp.h b/Software/ChainLube/src/lubeapp.h index eac4538..4ffab84 100644 --- a/Software/ChainLube/src/lubeapp.h +++ b/Software/ChainLube/src/lubeapp.h @@ -2,22 +2,18 @@ #define _LUBEAPP_H_ #include <Arduino.h> +#include "config.h" -typedef struct tLubeConfig +typedef enum eSystem_Status { - uint32_t DistancePerLube_Default = 0; - uint32_t DistancePerLube_Rain = 0; - uint32_t tankCapacity_ml = 320; - uint32_t amountPerDose_µl = 0; - uint32_t tankRemain_µl = 0; - uint8_t TankRemindAtPercentage = 30; - uint8_t PulsePerRevolution = 1; - uint32_t TireWidth_mm = 150; - uint32_t TireWidthHeight_Ratio = 70; - uint32_t RimDiameter_Inch = 18; - uint32_t DistancePerRevolution_mm = 2000; -} sLubeConfig; + sysStat_NOP, + sysStat_Startup, + sysStat_Normal, + sysStat_Rain, + sysStat_Purge, + sysStat_Error +} tSystem_Status; -extern void RunLubeApp(sLubeConfig *cfg); +void RunLubeApp(LubeConfig_t *cfg); #endif \ No newline at end of file diff --git a/Software/ChainLube/src/main.cpp b/Software/ChainLube/src/main.cpp index ff7ee6d..d8f899b 100644 --- a/Software/ChainLube/src/main.cpp +++ b/Software/ChainLube/src/main.cpp @@ -8,12 +8,12 @@ #include <RemoteDebug.h> #include <FastLED.h> #include <Ticker.h> -#include <EEPROM.h> #include "common.h" #include "rmtdbghelp.h" #include "lubeapp.h" #include "webui.h" +#include "config.h" const char *ssid = QUOTE(WIFI_SSID); const char *password = QUOTE(WIFI_PASSWORD); @@ -31,8 +31,6 @@ char DeviceName[33]; volatile uint32_t wheel_pulse = 0; -sLubeConfig LubeConfig; - U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(-1); RemoteDebug Debug; ESP8266WiFiMulti wifiMulti; @@ -45,15 +43,12 @@ void RemotDebug_printSystemInfo(); void RemoteDebug_printWifiInfo(); void wifiMaintainConnectionTicker_callback(); void IRAM_ATTR trigger_ISR(); +void LED_Process(tSystem_Status newStatus); Ticker WiFiMaintainConnectionTicker(wifiMaintainConnectionTicker_callback, 1000, 0, MILLIS); void setup() { - EEPROM.begin(512); - EEPROM.get(0, LubeConfig); - EEPROM.end(); - system_update_cpu_freq(SYS_CPU_80MHZ); snprintf(DeviceName, 32, HOST_NAME, ESP.getChipId()); WiFi.mode(WIFI_OFF); @@ -64,6 +59,8 @@ void setup() Serial.println("Souko's ChainLube Mk1"); Serial.println(DeviceName); + GetConfig_EEPROM(); + u8x8.begin(); u8x8.setFont(u8x8_font_chroma48medium8_r); @@ -144,8 +141,12 @@ void setup() void loop() { - leds[0] = digitalRead(GPIO_BUTTON) ? CRGB::Green : CRGB::Red; + tSystem_Status status = sysStat_NOP; + + // status = digitalRead(GPIO_BUTTON) ? Ready_normal : Ready_rain; + + LED_Process(status); RunLubeApp(&LubeConfig); WiFiMaintainConnectionTicker.update(); @@ -187,7 +188,10 @@ void RemotDebug_printSystemInfo() debugA("Reset reason: %s", ESP.getResetReason().c_str()); debugA("Flash Size: %d", ESP.getFlashChipRealSize()); debugA("Flash Size IDE: %d", ESP.getFlashChipSize()); - debugA("Flash ide mode: %s", (ideMode == FM_QIO ? "QIO" : ideMode == FM_QOUT ? "QOUT" : ideMode == FM_DIO ? "DIO" : ideMode == FM_DOUT ? "DOUT" : "UNKNOWN")); + debugA("Flash ide mode: %s", (ideMode == FM_QIO ? "QIO" : ideMode == FM_QOUT ? "QOUT" + : ideMode == FM_DIO ? "DIO" + : ideMode == FM_DOUT ? "DOUT" + : "UNKNOWN")); debugA("OTA-Pass: %s", QUOTE(ADMIN_PASSWORD)); } @@ -195,7 +199,6 @@ void RemoteDebug_printWifiInfo() { } - void wifiMaintainConnectionTicker_callback() { static uint32_t WiFiFailCount = 0; @@ -225,4 +228,79 @@ void wifiMaintainConnectionTicker_callback() void trigger_ISR() { wheel_pulse++; -} \ No newline at end of file +} + +void LED_Process(tSystem_Status newSysStatus = sysStat_NOP) +{ + + typedef enum + { + LED_NOP, + LED_Startup, + LED_Normal, + LED_Confirm_Normal, + LED_Rain, + LED_Confirm_Rain, + LED_Purge, + LED_Error + } tLED_Status; + + static tSystem_Status oldSysStatus = sysStat_NOP; + static tLED_Status LED_Status = LED_NOP; + uint8_t color; + uint32_t timer; + + if (oldSysStatus != newSysStatus) + { + switch (newSysStatus) + { + case sysStat_NOP: + break; + case sysStat_Startup: + break; + case sysStat_Normal: + break; + case sysStat_Rain: + break; + case sysStat_Purge: + break; + case sysStat_Error: + break; + } + } + + FastLED.setBrightness(64); + timer = millis(); + + switch (LED_Status) + { + case LED_NOP: + break; + case LED_Startup: + timer = timer % 2000; + color = timer > 500 ? 0 : (uint8_t)(timer / 2); + leds[0] = CRGB(color, color, 0); + break; + case LED_Confirm_Normal: + leds[0] = millis() % 2000 > 1900 ? CRGB::Green : CRGB::Black; + break; + case LED_Normal: + leds[0] = millis() % 2000 > 1900 ? CRGB::Blue : CRGB::Black; + break; + case LED_Confirm_Rain: + leds[0] = millis() % 2000 > 1900 ? CRGB::Green : CRGB::Black; + break; + case LED_Rain: + leds[0] = millis() % 2000 > 1900 ? CRGB::Blue : CRGB::Black; + break; + case LED_Purge: + leds[0] = millis() % 2000 > 1900 ? CRGB::HotPink : CRGB::Black; + break; + case LED_Error: + leds[0] = millis() % 500 > 250 ? CRGB::Red : CRGB::Black; + break; + + default: + break; + } +} diff --git a/Software/ChainLube/src/webui.cpp b/Software/ChainLube/src/webui.cpp index 6993d3f..9d427a6 100644 --- a/Software/ChainLube/src/webui.cpp +++ b/Software/ChainLube/src/webui.cpp @@ -1,15 +1,16 @@ #include <Arduino.h> #include <ESPUI.h> -#include <EEPROM.h> -#include "lubeapp.h" - -extern sLubeConfig LubeConfig; +#include "config.h" uint16_t tab_lube; uint16_t tab_wheel; uint16_t tab_tank; +uint16_t tab_maintenance; +uint16_t tab_store; + uint16_t num_lubedist_normal; uint16_t num_lubedist_rain; +uint16_t button_lubedist; uint16_t num_wheel_width; uint16_t num_wheel_ratio; @@ -17,66 +18,109 @@ uint16_t num_wheel_rim; uint16_t button_wheelcalc; uint16_t num_wheel_ppr; uint16_t num_wheel_dist; -uint16_t button_wheel; -void numberCall(Control *sender, int type) +uint16_t num_tank_capacity; +uint16_t num_tank_notify; + +uint16_t label_tankRemain; +uint16_t button_reset_tank; +uint16_t num_purge_pulses; +uint16_t button_purge; + +uint16_t button_store; +uint16_t button_reload; +uint16_t label_storeStatus; + +void SettingChanged_Callback(Control *sender, int type) { - Serial.print("Slider: ID: "); - Serial.print(sender->label); - Serial.print(", Value: "); - Serial.println(sender->value); + if (sender->id == num_lubedist_normal) + LubeConfig.DistancePerLube_Default = ESPUI.getControl(num_lubedist_normal)->value.toInt(); + else if (sender->id == num_lubedist_rain) + LubeConfig.DistancePerLube_Rain = ESPUI.getControl(num_lubedist_rain)->value.toInt(); + else if (sender->id == num_wheel_width) + LubeConfig.TireWidth_mm = ESPUI.getControl(num_wheel_width)->value.toInt(); + else if (sender->id == num_wheel_ratio) + LubeConfig.TireWidthHeight_Ratio = ESPUI.getControl(num_wheel_ratio)->value.toInt(); + else if (sender->id == num_wheel_rim) + LubeConfig.RimDiameter_Inch = ESPUI.getControl(num_wheel_rim)->value.toInt(); + else if (sender->id == num_wheel_ppr) + LubeConfig.PulsePerRevolution = ESPUI.getControl(num_wheel_ppr)->value.toInt(); + else if (sender->id == num_wheel_dist) + LubeConfig.DistancePerRevolution_mm = ESPUI.getControl(num_wheel_dist)->value.toInt(); + else if (sender->id == num_tank_capacity) + LubeConfig.tankCapacity_ml = ESPUI.getControl(num_tank_capacity)->value.toInt(); + else if (sender->id == num_tank_notify) + LubeConfig.TankRemindAtPercentage = ESPUI.getControl(num_tank_notify)->value.toInt(); } -void wheelcalc(Control *sender, int type) +void buttons_Callback(Control *sender, int type) { - static uint32_t wheel_ppr = 0; - static uint32_t wheel_dist = 0; + if (type != B_UP) return; - if (sender->id == num_wheel_ppr) - wheel_ppr = sender->value.toInt(); - if (sender->id == num_wheel_dist) - wheel_dist = sender->value.toInt(); - - if (type == B_UP && sender->id == button_wheelcalc) + if (sender->id == button_wheelcalc) { LubeConfig.TireWidth_mm = ESPUI.getControl(num_wheel_width)->value.toInt(); LubeConfig.RimDiameter_Inch = ESPUI.getControl(num_wheel_rim)->value.toInt(); LubeConfig.TireWidthHeight_Ratio = ESPUI.getControl(num_wheel_ratio)->value.toInt(); - wheel_dist = (uint32_t)((((((float)LubeConfig.TireWidthHeight_Ratio / 100.0) * (float)LubeConfig.TireWidth_mm) * 2.0) + ((float)LubeConfig.RimDiameter_Inch * 25.4)) * 3.1416); - ESPUI.updateControlValue(num_wheel_dist, String(wheel_dist)); + LubeConfig.DistancePerRevolution_mm = (uint32_t)((((((float)LubeConfig.TireWidthHeight_Ratio / 100.0) * (float)LubeConfig.TireWidth_mm) * 2.0) + ((float)LubeConfig.RimDiameter_Inch * 25.4)) * 3.1416); + ESPUI.updateControlValue(num_wheel_dist, String(LubeConfig.DistancePerRevolution_mm)); } - if (type == B_UP && sender->id == button_wheel) - { - LubeConfig.DistancePerRevolution_mm = wheel_dist; - LubeConfig.PulsePerRevolution = wheel_ppr; - EEPROM.begin(512); - EEPROM.put(0, LubeConfig); - EEPROM.commit(); - EEPROM.end(); + if(sender->id == button_reset_tank) + { + LubeConfig.tankRemain_µl = LubeConfig.tankCapacity_ml * 1000; + ESPUI.print(label_tankRemain, String(LubeConfig.tankRemain_µl / 1000)); + } + + if(sender->id == button_purge) + { + int pulses = ESPUI.getControl(num_purge_pulses)->value.toInt(); + Serial.printf("Starting to Purge with %d pulses", pulses); + } + + + if (sender->id == button_store) + { + StoreConfig_EEPROM(); + ESPUI.print(label_storeStatus, "Successfully Stored Settings"); + } + + if (sender->id == button_reload) + { + GetConfig_EEPROM(); + ESPUI.print(label_storeStatus, "Successfully Reloaded Settings"); } } -void initWebUI(void) +void initWebUI() { - - tab_lube = ESPUI.addControl(ControlType::Tab, "Schmierung", "Schmierung"); - tab_wheel = ESPUI.addControl(ControlType::Tab, "Wegesignal", "Wegesignal"); + tab_lube = ESPUI.addControl(ControlType::Tab, "Dosierung", "Dosierung"); + tab_wheel = ESPUI.addControl(ControlType::Tab, "Erfassung", "Erfassung"); tab_tank = ESPUI.addControl(ControlType::Tab, "Tank", "Tank"); + tab_maintenance = ESPUI.addControl(ControlType::Tab, "Wartung", "Wartung"); + tab_store = ESPUI.addControl(ControlType::Tab, "Speichern", "Speichern"); - num_lubedist_normal = ESPUI.addControl(ControlType::Number, "Distanz Normal (m)", String(LubeConfig.DistancePerLube_Default), ControlColor::Wetasphalt, tab_lube, &numberCall); - num_lubedist_rain = ESPUI.addControl(ControlType::Number, "Distanz Regen (m)", String(LubeConfig.DistancePerLube_Rain), ControlColor::Wetasphalt, tab_lube, &numberCall); + num_lubedist_normal = ESPUI.addControl(ControlType::Number, "Öl-Impuls alle x Meter (Normal)", String(LubeConfig.DistancePerLube_Default), ControlColor::Emerald, tab_lube, &SettingChanged_Callback); + num_lubedist_rain = ESPUI.addControl(ControlType::Number, "Öl-Impuls alle x Meter (Regen)", String(LubeConfig.DistancePerLube_Rain), ControlColor::Emerald, tab_lube, &SettingChanged_Callback); - num_wheel_width = ESPUI.addControl(ControlType::Number, "Reifenbreite (mm)", String(LubeConfig.TireWidth_mm), ControlColor::Dark, tab_wheel, &wheelcalc); - num_wheel_ratio = ESPUI.addControl(ControlType::Number, "Höhe/Breite-Verhältniss", String(LubeConfig.TireWidthHeight_Ratio), ControlColor::Dark, tab_wheel, &wheelcalc); - num_wheel_rim = ESPUI.addControl(ControlType::Number, "Felgendurchmesser (Zoll)", String(LubeConfig.RimDiameter_Inch), ControlColor::Dark, tab_wheel, &wheelcalc); - button_wheelcalc = ESPUI.addControl(ControlType::Button, "Abrollumfang", "Berechnen", ControlColor::Dark, tab_wheel, &wheelcalc); - num_wheel_dist = ESPUI.addControl(ControlType::Number, "Strecke pro Umdrehung (mm)", String(LubeConfig.DistancePerRevolution_mm), ControlColor::Wetasphalt, tab_wheel, &wheelcalc); - num_wheel_ppr = ESPUI.addControl(ControlType::Number, "Pulse pro Umdrehung", String(LubeConfig.PulsePerRevolution), ControlColor::Wetasphalt, tab_wheel, &wheelcalc); - button_wheel = ESPUI.addControl(ControlType::Button, "Wegesignal", "Speichern", ControlColor::Wetasphalt, tab_wheel, &wheelcalc); + num_wheel_width = ESPUI.addControl(ControlType::Number, "Reifenbreite (mm)", String(LubeConfig.TireWidth_mm), ControlColor::Peterriver, tab_wheel, &SettingChanged_Callback); + num_wheel_ratio = ESPUI.addControl(ControlType::Number, "Höhe/Breite-Verhältniss", String(LubeConfig.TireWidthHeight_Ratio), ControlColor::Peterriver, tab_wheel, &SettingChanged_Callback); + num_wheel_rim = ESPUI.addControl(ControlType::Number, "Felgendurchmesser (Zoll)", String(LubeConfig.RimDiameter_Inch), ControlColor::Peterriver, tab_wheel, &SettingChanged_Callback); + button_wheelcalc = ESPUI.addControl(ControlType::Button, "Abrollumfang aus Reifendaten berechnen", "Berechnen", ControlColor::Peterriver, tab_wheel, &buttons_Callback); + num_wheel_dist = ESPUI.addControl(ControlType::Number, "Wegstrecke pro Umdrehung (mm)", String(LubeConfig.DistancePerRevolution_mm), ControlColor::Wetasphalt, tab_wheel, &SettingChanged_Callback); + num_wheel_ppr = ESPUI.addControl(ControlType::Number, "Sensorimpulse pro Umdrehung", String(LubeConfig.PulsePerRevolution), ControlColor::Wetasphalt, tab_wheel, &SettingChanged_Callback); - ESPUI.addControl(ControlType::Number, "Tankinhalt maximal (ml)", String(LubeConfig.tankCapacity_ml), ControlColor::Wetasphalt, tab_tank, &numberCall); - ESPUI.addControl(ControlType::Number, "Tankinhalt Warnung (%)", String(LubeConfig.TankRemindAtPercentage), ControlColor::Wetasphalt, tab_tank, &numberCall); + num_tank_capacity = ESPUI.addControl(ControlType::Number, "Tankinhalt maximal (ml)", String(LubeConfig.tankCapacity_ml), ControlColor::Carrot, tab_tank, &SettingChanged_Callback); + num_tank_notify = ESPUI.addControl(ControlType::Number, "Tankinhalt Warnung (%)", String(LubeConfig.TankRemindAtPercentage), ControlColor::Carrot, tab_tank, &SettingChanged_Callback); + + label_tankRemain = ESPUI.addControl(ControlType::Label, "Tankinhalt verbleibend (ml, geschätzt)",String(LubeConfig.tankRemain_µl / 1000), ControlColor::Alizarin, tab_maintenance); + button_reset_tank = ESPUI.addControl(ControlType::Button, "Tankinhalt zurücksetzen", "Reset", ControlColor::Alizarin, tab_maintenance, &buttons_Callback); + num_purge_pulses = ESPUI.addControl(ControlType::Number, "Entlüftung Impulse", "10", ControlColor::Alizarin, tab_maintenance); + button_purge = ESPUI.addControl(ControlType::Button, "Leitung Entlüften", "Start", ControlColor::Alizarin, tab_maintenance, &buttons_Callback); + + button_store = ESPUI.addControl(ControlType::Button, "Einstellungen permanent speichern", "Speichern", ControlColor::Turquoise, tab_store, &buttons_Callback); + button_reload = ESPUI.addControl(ControlType::Button, "Einstellungen neu laden", "Laden", ControlColor::Turquoise, tab_store, &buttons_Callback); + label_storeStatus = ESPUI.addControl(ControlType::Label, "Status", "", ControlColor::Turquoise, tab_store); ESPUI.begin("Souko's ChainLube Mk1"); }