2022-01-07 21:02:27 +01:00
|
|
|
#include <Arduino.h>
|
|
|
|
#include <Wire.h>
|
|
|
|
#include <U8g2lib.h>
|
|
|
|
#include <ESP8266WiFi.h>
|
|
|
|
#include <ESP8266WiFiMulti.h>
|
|
|
|
#include <ESP8266mDNS.h>
|
|
|
|
#include <ArduinoOTA.h>
|
|
|
|
#include <RemoteDebug.h>
|
|
|
|
#include <FastLED.h>
|
2022-01-07 23:36:02 +01:00
|
|
|
#include <Ticker.h>
|
2022-01-07 21:02:27 +01:00
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
#include "rmtdbghelp.h"
|
2022-01-08 03:14:26 +01:00
|
|
|
#include "lubeapp.h"
|
|
|
|
#include "webui.h"
|
2022-01-09 20:51:16 +01:00
|
|
|
#include "config.h"
|
2022-01-10 00:02:21 +01:00
|
|
|
#include "globals.h"
|
2022-01-07 21:02:27 +01:00
|
|
|
|
2022-01-07 23:36:02 +01:00
|
|
|
const char *ssid = QUOTE(WIFI_SSID);
|
|
|
|
const char *password = QUOTE(WIFI_PASSWORD);
|
|
|
|
|
|
|
|
const uint32_t connectTimeoutMs = 5000;
|
2022-01-07 21:02:27 +01:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
const bool debug_flag = true;
|
|
|
|
#else
|
|
|
|
const bool debug_flag = false;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
bool startSetupMode = false;
|
|
|
|
char DeviceName[33];
|
|
|
|
|
2022-01-10 00:02:21 +01:00
|
|
|
Globals_t globals;
|
|
|
|
uint32_t TravelDistance_highRes;
|
2022-01-07 23:36:02 +01:00
|
|
|
volatile uint32_t wheel_pulse = 0;
|
|
|
|
|
2022-01-07 21:02:27 +01:00
|
|
|
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(-1);
|
|
|
|
RemoteDebug Debug;
|
|
|
|
ESP8266WiFiMulti wifiMulti;
|
2022-01-07 23:36:02 +01:00
|
|
|
CRGB leds[1];
|
2022-01-07 21:02:27 +01:00
|
|
|
|
|
|
|
// Function-Prototypes
|
|
|
|
String IpAddress2String(const IPAddress &ipAddress);
|
|
|
|
void processCmdRemoteDebug();
|
|
|
|
void RemotDebug_printSystemInfo();
|
|
|
|
void RemoteDebug_printWifiInfo();
|
2022-01-07 23:36:02 +01:00
|
|
|
void wifiMaintainConnectionTicker_callback();
|
|
|
|
void IRAM_ATTR trigger_ISR();
|
2022-01-10 00:02:21 +01:00
|
|
|
void LED_Process(tSystem_Status newStatus = sysStat_NOP);
|
2022-01-10 00:55:04 +01:00
|
|
|
void DisplayProcess();
|
2022-01-07 21:02:27 +01:00
|
|
|
|
2022-01-07 23:36:02 +01:00
|
|
|
Ticker WiFiMaintainConnectionTicker(wifiMaintainConnectionTicker_callback, 1000, 0, MILLIS);
|
2022-01-07 21:02:27 +01:00
|
|
|
|
|
|
|
void setup()
|
|
|
|
{
|
|
|
|
system_update_cpu_freq(SYS_CPU_80MHZ);
|
2022-01-10 00:02:21 +01:00
|
|
|
|
2022-01-07 21:02:27 +01:00
|
|
|
snprintf(DeviceName, 32, HOST_NAME, ESP.getChipId());
|
2022-01-10 00:02:21 +01:00
|
|
|
|
2022-01-07 21:02:27 +01:00
|
|
|
WiFi.mode(WIFI_OFF);
|
|
|
|
WiFi.persistent(false);
|
2022-01-10 00:02:21 +01:00
|
|
|
|
2022-01-07 21:02:27 +01:00
|
|
|
Serial.begin(115200);
|
|
|
|
Serial.setDebugOutput(true);
|
|
|
|
|
2022-01-07 23:36:02 +01:00
|
|
|
Serial.println("Souko's ChainLube Mk1");
|
2022-01-07 21:02:27 +01:00
|
|
|
Serial.println(DeviceName);
|
|
|
|
|
2022-01-09 20:51:16 +01:00
|
|
|
GetConfig_EEPROM();
|
|
|
|
|
2022-01-07 21:02:27 +01:00
|
|
|
u8x8.begin();
|
|
|
|
u8x8.setFont(u8x8_font_chroma48medium8_r);
|
|
|
|
|
2022-01-07 23:36:02 +01:00
|
|
|
FastLED.addLeds<WS2811, GPIO_LED, GRB>(leds, 1); // GRB ordering is assumed
|
|
|
|
|
2022-01-07 21:02:27 +01:00
|
|
|
pinMode(GPIO_TRIGGER, INPUT_PULLUP);
|
|
|
|
pinMode(GPIO_BUTTON, INPUT_PULLUP);
|
|
|
|
pinMode(GPIO_PUMP, OUTPUT);
|
|
|
|
|
2022-01-07 23:36:02 +01:00
|
|
|
attachInterrupt(digitalPinToInterrupt(GPIO_TRIGGER), trigger_ISR, FALLING);
|
|
|
|
|
2022-01-07 21:02:27 +01:00
|
|
|
WiFi.mode(WIFI_STA);
|
|
|
|
WiFi.setHostname(DeviceName);
|
2022-01-07 23:36:02 +01:00
|
|
|
wifiMulti.addAP(QUOTE(WIFI_SSID), QUOTE(WIFI_PASSWORD));
|
2022-01-07 21:02:27 +01:00
|
|
|
|
2022-01-07 23:36:02 +01:00
|
|
|
WiFiMaintainConnectionTicker.start();
|
|
|
|
|
2022-01-07 21:02:27 +01:00
|
|
|
if (MDNS.begin(DeviceName))
|
|
|
|
MDNS.addService("telnet", "tcp", 23);
|
|
|
|
|
|
|
|
Debug.begin(DeviceName); // Initialize the WiFi server
|
|
|
|
Debug.setResetCmdEnabled(true); // Enable the reset command
|
|
|
|
Debug.showProfiler(true); // Profiler (Good to measure times, to optimize codes)
|
|
|
|
Debug.showColors(true); // Colors
|
2022-01-07 23:36:02 +01:00
|
|
|
Debug.setPassword(QUOTE(ADMIN_PASSWORD));
|
2022-01-07 21:02:27 +01:00
|
|
|
|
|
|
|
Debug.setHelpProjectsCmds(helpCmd);
|
|
|
|
Debug.setCallBackProjectCmds(&processCmdRemoteDebug);
|
|
|
|
|
|
|
|
ArduinoOTA.setPort(8266);
|
|
|
|
ArduinoOTA.setHostname(DeviceName);
|
2022-01-07 23:36:02 +01:00
|
|
|
ArduinoOTA.setPassword(QUOTE(ADMIN_PASSWORD));
|
2022-01-07 21:02:27 +01:00
|
|
|
|
|
|
|
ArduinoOTA.onStart([]()
|
|
|
|
{
|
|
|
|
u8x8.clearDisplay();
|
|
|
|
u8x8.drawString(0, 0, "OTA-Update");
|
|
|
|
u8x8.refreshDisplay(); });
|
|
|
|
|
|
|
|
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total)
|
|
|
|
{
|
|
|
|
static bool refreshed = false;
|
|
|
|
if (!refreshed)
|
|
|
|
{
|
|
|
|
u8x8.clearDisplay();
|
|
|
|
refreshed = true;
|
|
|
|
u8x8.drawString(0, 0, "OTA Upload");
|
|
|
|
}
|
|
|
|
uint32_t percent = progress / (total / 100);
|
|
|
|
u8x8.setCursor(0, 1);
|
|
|
|
u8x8.printf("%d %%", percent);
|
|
|
|
u8x8.refreshDisplay(); });
|
|
|
|
|
|
|
|
ArduinoOTA.onEnd([]()
|
|
|
|
{
|
|
|
|
u8x8.clearDisplay();
|
|
|
|
u8x8.drawString(0, 0, "OTA-Restart");
|
|
|
|
u8x8.refreshDisplay(); });
|
|
|
|
|
|
|
|
ArduinoOTA.begin();
|
|
|
|
|
|
|
|
u8x8.clearDisplay();
|
2022-01-07 23:36:02 +01:00
|
|
|
u8x8.drawString(4, 0, "Souko's");
|
|
|
|
u8x8.drawString(1, 1, "ChainLube Mk1");
|
2022-01-07 21:02:27 +01:00
|
|
|
u8x8.refreshDisplay();
|
|
|
|
|
2022-01-07 23:36:02 +01:00
|
|
|
initWebUI();
|
2022-01-07 21:02:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void loop()
|
|
|
|
{
|
2022-01-10 00:55:04 +01:00
|
|
|
LED_Process(globals.systemStatus);
|
2022-01-10 00:02:21 +01:00
|
|
|
RunLubeApp(&wheel_pulse);
|
2022-01-07 21:02:27 +01:00
|
|
|
|
2022-01-10 00:02:21 +01:00
|
|
|
WiFiMaintainConnectionTicker.update();
|
2022-01-09 20:51:16 +01:00
|
|
|
|
2022-01-10 00:55:04 +01:00
|
|
|
DisplayProcess();
|
2022-01-07 23:36:02 +01:00
|
|
|
|
2022-01-07 21:02:27 +01:00
|
|
|
ArduinoOTA.handle();
|
|
|
|
Debug.handle();
|
|
|
|
yield();
|
|
|
|
}
|
|
|
|
|
|
|
|
String IpAddress2String(const IPAddress &ipAddress)
|
|
|
|
{
|
|
|
|
return String(ipAddress[0]) + String(".") +
|
|
|
|
String(ipAddress[1]) + String(".") +
|
|
|
|
String(ipAddress[2]) + String(".") +
|
|
|
|
String(ipAddress[3]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void processCmdRemoteDebug()
|
|
|
|
{
|
|
|
|
String lastCmd = Debug.getLastCommand();
|
|
|
|
|
|
|
|
if (lastCmd == "sysinfo")
|
|
|
|
RemotDebug_printSystemInfo();
|
|
|
|
else if (lastCmd == "netinfo")
|
|
|
|
RemoteDebug_printWifiInfo();
|
|
|
|
}
|
|
|
|
|
|
|
|
void RemotDebug_printSystemInfo()
|
|
|
|
{
|
|
|
|
debugA("Souko's ChainOiler Mk1");
|
|
|
|
debugA("Hostname: %s", DeviceName);
|
|
|
|
|
2022-01-08 03:14:26 +01:00
|
|
|
FlashMode_t ideMode = ESP.getFlashChipMode();
|
2022-01-07 21:02:27 +01:00
|
|
|
debugA("Sdk version: %s", ESP.getSdkVersion());
|
|
|
|
debugA("Core Version: %s", ESP.getCoreVersion().c_str());
|
|
|
|
debugA("Boot Version: %u", ESP.getBootVersion());
|
|
|
|
debugA("Boot Mode: %u", ESP.getBootMode());
|
|
|
|
debugA("CPU Frequency: %u MHz", ESP.getCpuFreqMHz());
|
|
|
|
debugA("Reset reason: %s", ESP.getResetReason().c_str());
|
2022-01-08 03:14:26 +01:00
|
|
|
debugA("Flash Size: %d", ESP.getFlashChipRealSize());
|
|
|
|
debugA("Flash Size IDE: %d", ESP.getFlashChipSize());
|
2022-01-09 20:51:16 +01:00
|
|
|
debugA("Flash ide mode: %s", (ideMode == FM_QIO ? "QIO" : ideMode == FM_QOUT ? "QOUT"
|
|
|
|
: ideMode == FM_DIO ? "DIO"
|
|
|
|
: ideMode == FM_DOUT ? "DOUT"
|
|
|
|
: "UNKNOWN"));
|
2022-01-07 23:36:02 +01:00
|
|
|
debugA("OTA-Pass: %s", QUOTE(ADMIN_PASSWORD));
|
2022-01-07 21:02:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void RemoteDebug_printWifiInfo()
|
|
|
|
{
|
|
|
|
}
|
2022-01-07 23:36:02 +01:00
|
|
|
|
|
|
|
void wifiMaintainConnectionTicker_callback()
|
|
|
|
{
|
|
|
|
static uint32_t WiFiFailCount = 0;
|
|
|
|
const uint32_t WiFiFailMax = 20;
|
|
|
|
|
|
|
|
if (wifiMulti.run(connectTimeoutMs) == WL_CONNECTED)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (WiFiFailCount < WiFiFailMax)
|
|
|
|
{
|
|
|
|
WiFiFailCount++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Serial.println("WiFi not connected! - Start AP");
|
|
|
|
WiFi.mode(WIFI_OFF);
|
|
|
|
WiFi.softAP(DeviceName, QUOTE(WIFI_AP_PASSWORD));
|
|
|
|
WiFiMaintainConnectionTicker.stop();
|
|
|
|
Serial.println("WiFi AP started, stopped Maintain-Timer");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void trigger_ISR()
|
|
|
|
{
|
|
|
|
wheel_pulse++;
|
2022-01-09 20:51:16 +01:00
|
|
|
}
|
|
|
|
|
2022-01-10 00:02:21 +01:00
|
|
|
void LED_Process(tSystem_Status newSysStatus)
|
2022-01-09 20:51:16 +01:00
|
|
|
{
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
LED_Startup,
|
|
|
|
LED_Normal,
|
|
|
|
LED_Confirm_Normal,
|
|
|
|
LED_Rain,
|
|
|
|
LED_Confirm_Rain,
|
|
|
|
LED_Purge,
|
|
|
|
LED_Error
|
|
|
|
} tLED_Status;
|
|
|
|
|
|
|
|
static tSystem_Status oldSysStatus = sysStat_NOP;
|
2022-01-10 00:02:21 +01:00
|
|
|
static tLED_Status LED_Status = LED_Startup;
|
2022-01-09 20:51:16 +01:00
|
|
|
|
2022-01-10 00:02:21 +01:00
|
|
|
uint8_t color = 0;
|
|
|
|
uint32_t timer = 0;
|
|
|
|
uint32_t timestamp = 0;
|
|
|
|
|
2022-01-10 00:55:04 +01:00
|
|
|
if (oldSysStatus != newSysStatus)
|
2022-01-09 20:51:16 +01:00
|
|
|
{
|
2022-01-10 00:55:04 +01:00
|
|
|
switch (newSysStatus)
|
2022-01-09 20:51:16 +01:00
|
|
|
{
|
2022-01-10 00:55:04 +01:00
|
|
|
case sysStat_Startup:
|
|
|
|
LED_Status = LED_Startup;
|
|
|
|
break;
|
|
|
|
case sysStat_Normal:
|
|
|
|
timestamp = millis() + 1500;
|
|
|
|
LED_Status = LED_Confirm_Normal;
|
|
|
|
FastLED.setBrightness(64);
|
|
|
|
break;
|
|
|
|
case sysStat_Rain:
|
|
|
|
timestamp = millis() + 1500;
|
|
|
|
LED_Status = LED_Confirm_Rain;
|
|
|
|
FastLED.setBrightness(64);
|
|
|
|
break;
|
|
|
|
case sysStat_Purge:
|
|
|
|
LED_Status = LED_Purge;
|
|
|
|
break;
|
|
|
|
case sysStat_Error:
|
|
|
|
LED_Status = LED_Error;
|
|
|
|
break;
|
2022-01-09 20:51:16 +01:00
|
|
|
}
|
2022-01-10 00:55:04 +01:00
|
|
|
oldSysStatus = newSysStatus;
|
2022-01-09 20:51:16 +01:00
|
|
|
}
|
2022-01-10 00:55:04 +01:00
|
|
|
|
2022-01-09 20:51:16 +01:00
|
|
|
timer = millis();
|
|
|
|
|
|
|
|
switch (LED_Status)
|
|
|
|
{
|
|
|
|
case LED_Startup:
|
|
|
|
timer = timer % 2000;
|
|
|
|
color = timer > 500 ? 0 : (uint8_t)(timer / 2);
|
|
|
|
leds[0] = CRGB(color, color, 0);
|
|
|
|
break;
|
2022-01-10 00:02:21 +01:00
|
|
|
|
2022-01-09 20:51:16 +01:00
|
|
|
case LED_Confirm_Normal:
|
2022-01-10 00:02:21 +01:00
|
|
|
if (timestamp < timer)
|
|
|
|
LED_Status = LED_Normal;
|
|
|
|
leds[0] = timer % 500 > 250 ? CRGB::Green : CRGB::Black;
|
2022-01-09 20:51:16 +01:00
|
|
|
break;
|
2022-01-10 00:02:21 +01:00
|
|
|
|
2022-01-09 20:51:16 +01:00
|
|
|
case LED_Normal:
|
2022-01-10 00:02:21 +01:00
|
|
|
leds[0] = timer % 2000 > 1950 ? CRGB::Green : CRGB::Black;
|
2022-01-09 20:51:16 +01:00
|
|
|
break;
|
2022-01-10 00:02:21 +01:00
|
|
|
|
2022-01-09 20:51:16 +01:00
|
|
|
case LED_Confirm_Rain:
|
2022-01-10 00:02:21 +01:00
|
|
|
if (timestamp < timer)
|
|
|
|
LED_Status = LED_Rain;
|
|
|
|
leds[0] = timer % 500 > 250 ? CRGB::Blue : CRGB::Black;
|
2022-01-09 20:51:16 +01:00
|
|
|
break;
|
2022-01-10 00:02:21 +01:00
|
|
|
|
2022-01-09 20:51:16 +01:00
|
|
|
case LED_Rain:
|
2022-01-10 00:02:21 +01:00
|
|
|
leds[0] = timer % 2000 > 1950 ? CRGB::Blue : CRGB::Black;
|
2022-01-09 20:51:16 +01:00
|
|
|
break;
|
2022-01-10 00:02:21 +01:00
|
|
|
|
2022-01-09 20:51:16 +01:00
|
|
|
case LED_Purge:
|
2022-01-10 00:02:21 +01:00
|
|
|
timer = timer % 500;
|
|
|
|
color = timer / 2;
|
|
|
|
leds[0] = CRGB::DeepPink;
|
|
|
|
if (timer < 250)
|
|
|
|
FastLED.setBrightness(color);
|
|
|
|
else
|
|
|
|
FastLED.setBrightness(250 - color);
|
2022-01-09 20:51:16 +01:00
|
|
|
break;
|
2022-01-10 00:02:21 +01:00
|
|
|
|
2022-01-09 20:51:16 +01:00
|
|
|
case LED_Error:
|
2022-01-10 00:02:21 +01:00
|
|
|
leds[0] = timer % 500 > 250 ? CRGB::Red : CRGB::Black;
|
2022-01-09 20:51:16 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2022-01-10 00:02:21 +01:00
|
|
|
FastLED.show();
|
2022-01-09 20:51:16 +01:00
|
|
|
}
|
2022-01-10 00:55:04 +01:00
|
|
|
|
|
|
|
void DisplayProcess()
|
|
|
|
{
|
|
|
|
u8x8.setCursor(0, 3);
|
|
|
|
u8x8.printf("Dist.: %4d m\n", TravelDistance_highRes / 1000);
|
|
|
|
u8x8.printf("Purge: %4d\n", globals.purgePulses);
|
|
|
|
u8x8.printf("Tank: %4d ml\n", LubeConfig.tankRemain_µl / 1000);
|
|
|
|
u8x8.refreshDisplay();
|
|
|
|
}
|