massive takeover of Firmware-parts from ChainLube
This commit is contained in:
parent
ea5a266ee2
commit
7f0c3e74f6
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@ -3,5 +3,8 @@
|
|||||||
// for the documentation about the extensions.json format
|
// for the documentation about the extensions.json format
|
||||||
"recommendations": [
|
"recommendations": [
|
||||||
"platformio.platformio-ide"
|
"platformio.platformio-ide"
|
||||||
|
],
|
||||||
|
"unwantedRecommendations": [
|
||||||
|
"ms-vscode.cpptools-extension-pack"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
8
git_rev_macro.py
Normal file
8
git_rev_macro.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import subprocess
|
||||||
|
|
||||||
|
revision = (
|
||||||
|
subprocess.check_output(["git", "rev-parse", "--short=10", "HEAD"])
|
||||||
|
.strip()
|
||||||
|
.decode("utf-8")
|
||||||
|
)
|
||||||
|
print("-DGIT_REV='\"%s\"'" % revision)
|
@ -8,6 +8,10 @@
|
|||||||
; Please visit documentation for the other options and examples
|
; Please visit documentation for the other options and examples
|
||||||
; https://docs.platformio.org/page/projectconf.html
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
|
[platformio]
|
||||||
|
extra_configs =
|
||||||
|
wifi_credentials.ini
|
||||||
|
|
||||||
[env:d1_mini]
|
[env:d1_mini]
|
||||||
platform = espressif8266
|
platform = espressif8266
|
||||||
board = d1_mini
|
board = d1_mini
|
||||||
@ -15,27 +19,36 @@ board_build.filesystem = littlefs
|
|||||||
board_build.f_flash = 80000000L
|
board_build.f_flash = 80000000L
|
||||||
board_build.ldscript = eagle.flash.4m1m.ld
|
board_build.ldscript = eagle.flash.4m1m.ld
|
||||||
|
|
||||||
|
monitor_filters = esp8266_exception_decoder
|
||||||
|
monitor_speed = 115200
|
||||||
|
|
||||||
upload_protocol = espota
|
upload_protocol = espota
|
||||||
upload_port = ESP_OTA.local
|
upload_port = 10.0.1.34
|
||||||
upload_flags=
|
upload_flags=
|
||||||
--auth=UploadTheFlag
|
--auth=${wifi_cred.admin_password}
|
||||||
|
|
||||||
build_flags=
|
build_flags=
|
||||||
-D SERIAL_DEBUG
|
!python git_rev_macro.py
|
||||||
-D DEVICE_NAME='"DE CTF Timer Prototype 1"'
|
-DSERIAL_DEBUG
|
||||||
-D WIFI_CLIENT
|
-DREMOTE_DEBUG
|
||||||
-D WIFI_SSID='"BND_Scanner_#42"'
|
-DWIFI_CLIENT
|
||||||
-D WIFI_PASS='"5xMYkerbLMdrsSdF3hpy5DM9"'
|
-DCAPTIVE
|
||||||
;-D WIFI_AP
|
-DWIFI_AP_IP_GW=10,0,0,1
|
||||||
;-D WIFI_SSID='"Dark Emergency CTF Timer"'
|
-DADMIN_PASSWORD=${wifi_cred.admin_password}
|
||||||
;-D WIFI_PASS='"CaptureTheFlag"'
|
-DWIFI_SSID=${wifi_cred.wifi_ssid}
|
||||||
-D FACTION_1_NAME='"GOF"'
|
-DWIFI_PASSWORD=${wifi_cred.wifi_password}
|
||||||
-D FACTION_2_NAME='"MILIZ"'
|
-DWIFI_AP_PASSWORD=${wifi_cred.wifi_ap_password}
|
||||||
-D FACTION_3_NAME='"KGG"'
|
-DDEVICE_NAME='"Dark Emergency Timer"'
|
||||||
|
-DFACTION_1_NAME='"GOF"'
|
||||||
|
-DFACTION_2_NAME='"MILIZ"'
|
||||||
|
-DFACTION_3_NAME='"KGG"'
|
||||||
|
|
||||||
framework = arduino
|
framework = arduino
|
||||||
lib_deps =
|
lib_deps =
|
||||||
smougenot/TM1637@0.0.0-alpha+sha.9486982048
|
smougenot/TM1637@0.0.0-alpha+sha.9486982048
|
||||||
|
joaolopesf/RemoteDebug @ ^2.1.2
|
||||||
me-no-dev/ESP Async WebServer @ ^1.2.3
|
me-no-dev/ESP Async WebServer @ ^1.2.3
|
||||||
sstaub/Ticker @ ^4.2.0
|
sstaub/Ticker @ ^4.2.0
|
||||||
adafruit/Adafruit INA219 @ ^1.1.1
|
adafruit/Adafruit INA219 @ ^1.1.1
|
||||||
|
robtillaart/I2C_EEPROM @ ^1.5.2
|
||||||
|
me-no-dev/ESP Async WebServer @ ^1.2.3
|
||||||
|
38
src/common.h
Normal file
38
src/common.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef _COMMON_H_
|
||||||
|
#define _COMMON_H_
|
||||||
|
|
||||||
|
#define Q(x) #x
|
||||||
|
#define QUOTE(x) Q(x)
|
||||||
|
|
||||||
|
// Module connection pins (ESP GPIO-Nums)
|
||||||
|
#define CLK 16
|
||||||
|
#define DIO_FAC_1_7SEG 14
|
||||||
|
#define DIO_FAC_2_7SEG 12
|
||||||
|
#define DIO_FAC_3_7SEG 13
|
||||||
|
|
||||||
|
#define DIO_FAC_1_TRG 0
|
||||||
|
#define DIO_FAC_2_TRG 2
|
||||||
|
#define DIO_FAC_3_TRG 15
|
||||||
|
|
||||||
|
#ifndef HOST_NAME
|
||||||
|
#define HOST_NAME "DE_Timer_%06X" // Use printf-Formatting - Chip-ID (uin32_t) will be added
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef OTA_DELAY
|
||||||
|
#define OTA_DELAY 50 // ticks -> 10ms / tick
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ADMIN_PASSWORD
|
||||||
|
#error "You need to define ADMIN_PASSWORD for OTA-Update"
|
||||||
|
#endif
|
||||||
|
#ifndef WIFI_PASSWORD
|
||||||
|
#error "You must define an WIFI_PASSWORD for OTA-Update"
|
||||||
|
#endif
|
||||||
|
#ifndef WIFI_SSID
|
||||||
|
#error "You must define an WIFI_SSID for OTA-Update"
|
||||||
|
#endif
|
||||||
|
#ifndef WIFI_AP_PASSWORD
|
||||||
|
#error "You must define an WIFI_AP_PASSWORD for Standalone AP-Mode"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
198
src/config.cpp
Normal file
198
src/config.cpp
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
I2C_eeprom ee(0x50, EEPROM_SIZE_BYTES);
|
||||||
|
configData_t ConfigData;
|
||||||
|
persistenceData_t PersistenceData;
|
||||||
|
uint16_t eePersistenceMarker = 0;
|
||||||
|
uint16_t eeVersion = 0; // inc
|
||||||
|
boolean eeAvailable = false;
|
||||||
|
|
||||||
|
const uint16_t startofConfigData = 16;
|
||||||
|
const uint16_t startofPersistence = 16 + sizeof(startofConfigData) + (sizeof(startofConfigData) % 16);
|
||||||
|
|
||||||
|
|
||||||
|
void InitEEPROM()
|
||||||
|
{
|
||||||
|
#ifdef SERIAL_DEBUG
|
||||||
|
Serial.printf("connecting I2C EEPROM");
|
||||||
|
#endif
|
||||||
|
ee.begin();
|
||||||
|
if (!ee.isConnected())
|
||||||
|
{
|
||||||
|
MaintainDTC(DTC_NO_EEPROM_FOUND, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EEPROM_Process()
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (globals.requestEEAction)
|
||||||
|
{
|
||||||
|
case EE_CFG_SAVE:
|
||||||
|
StoreConfig_EEPROM();
|
||||||
|
globals.requestEEAction = EE_IDLE;
|
||||||
|
break;
|
||||||
|
case EE_CFG_LOAD:
|
||||||
|
GetConfig_EEPROM();
|
||||||
|
globals.requestEEAction = EE_IDLE;
|
||||||
|
break;
|
||||||
|
case EE_PDS_SAVE:
|
||||||
|
StorePersistence_EEPROM();
|
||||||
|
globals.requestEEAction = EE_IDLE;
|
||||||
|
break;
|
||||||
|
case EE_PDS_LOAD:
|
||||||
|
GetPersistence_EEPROM();
|
||||||
|
globals.requestEEAction = EE_IDLE;
|
||||||
|
break;
|
||||||
|
case EE_IDLE:
|
||||||
|
default:
|
||||||
|
globals.requestEEAction = EE_IDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreConfig_EEPROM()
|
||||||
|
{
|
||||||
|
ConfigData.checksum = 0;
|
||||||
|
ConfigData.checksum = Checksum_EEPROM((uint8_t *)&ConfigData, sizeof(ConfigData));
|
||||||
|
|
||||||
|
if (!ee.isConnected())
|
||||||
|
return;
|
||||||
|
ee.updateBlock(startofConfigData, (uint8_t *)&ConfigData, sizeof(ConfigData));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetConfig_EEPROM()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!ee.isConnected())
|
||||||
|
return;
|
||||||
|
ee.readBlock(startofConfigData, (uint8_t *)&ConfigData, sizeof(ConfigData));
|
||||||
|
|
||||||
|
uint32_t checksum = ConfigData.checksum;
|
||||||
|
ConfigData.checksum = 0;
|
||||||
|
|
||||||
|
if (Checksum_EEPROM((uint8_t *)&ConfigData, sizeof(ConfigData)) != checksum)
|
||||||
|
{
|
||||||
|
MaintainDTC(DTC_EEPROM_CFG_BAD, true);
|
||||||
|
FormatConfig_EEPROM();
|
||||||
|
}
|
||||||
|
ConfigData.checksum = checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t getPersistanceAddress()
|
||||||
|
{
|
||||||
|
return startofPersistence + eePersistenceMarker;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StorePersistence_EEPROM()
|
||||||
|
{
|
||||||
|
if (PersistenceData.writeCycleCounter >= 0xFFF0)
|
||||||
|
MovePersistencePage_EEPROM(false);
|
||||||
|
else
|
||||||
|
PersistenceData.writeCycleCounter++;
|
||||||
|
|
||||||
|
PersistenceData.checksum = 0;
|
||||||
|
PersistenceData.checksum = Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData));
|
||||||
|
|
||||||
|
if (!ee.isConnected())
|
||||||
|
return;
|
||||||
|
ee.updateBlock(getPersistanceAddress(), (uint8_t *)&PersistenceData, sizeof(PersistenceData));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetPersistence_EEPROM()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!ee.isConnected())
|
||||||
|
return;
|
||||||
|
eePersistenceMarker = (ee.readByte(0) << 8) | ee.readByte(1);
|
||||||
|
ee.readBlock(getPersistanceAddress(), (uint8_t *)&PersistenceData, sizeof(PersistenceData));
|
||||||
|
|
||||||
|
uint32_t checksum = PersistenceData.checksum;
|
||||||
|
PersistenceData.checksum = 0;
|
||||||
|
|
||||||
|
if (Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData)) != checksum)
|
||||||
|
{
|
||||||
|
MaintainDTC(DTC_EEPROM_PDS_BAD, true);
|
||||||
|
FormatPersistence_EEPROM();
|
||||||
|
}
|
||||||
|
PersistenceData.checksum = checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FormatConfig_EEPROM()
|
||||||
|
{
|
||||||
|
configData_t defaults;
|
||||||
|
ConfigData = defaults;
|
||||||
|
StoreConfig_EEPROM();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FormatPersistence_EEPROM()
|
||||||
|
{
|
||||||
|
persistenceData_t defaults;
|
||||||
|
PersistenceData = defaults;
|
||||||
|
eePersistenceMarker = 0;
|
||||||
|
StorePersistence_EEPROM();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovePersistencePage_EEPROM(boolean reset)
|
||||||
|
{
|
||||||
|
eePersistenceMarker = reset ? sizeof(PersistenceData) : eePersistenceMarker + sizeof(PersistenceData);
|
||||||
|
PersistenceData.writeCycleCounter = 0;
|
||||||
|
|
||||||
|
if (!ee.isConnected())
|
||||||
|
return;
|
||||||
|
ee.updateByte(0, (uint8_t)(eePersistenceMarker >> 8));
|
||||||
|
ee.updateByte(1, (uint8_t)(eePersistenceMarker & 0xFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Checksum_EEPROM(uint8_t const *data, size_t len)
|
||||||
|
{
|
||||||
|
if (data == NULL)
|
||||||
|
return 0;
|
||||||
|
uint32_t crc, mask;
|
||||||
|
crc = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
while (len--)
|
||||||
|
{
|
||||||
|
crc ^= *data++;
|
||||||
|
for (uint8_t k = 0; k < 8; k++)
|
||||||
|
{
|
||||||
|
mask = -(crc & 1);
|
||||||
|
crc = (crc >> 1) ^ (0xEDB88320 & mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ~crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
|
||||||
|
{
|
||||||
|
#define BLOCK_TO_LENGTH 16
|
||||||
|
|
||||||
|
if (!ee.isConnected())
|
||||||
|
return;
|
||||||
|
|
||||||
|
char ascii_buf[BLOCK_TO_LENGTH + 1];
|
||||||
|
sprintf(ascii_buf, "%*s", BLOCK_TO_LENGTH, "ASCII");
|
||||||
|
Serial.print(PSTR("\nAddress "));
|
||||||
|
for (int x = 0; x < BLOCK_TO_LENGTH; x++)
|
||||||
|
Serial.printf("%3d", x);
|
||||||
|
|
||||||
|
memoryAddress = memoryAddress / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH;
|
||||||
|
length = (length + BLOCK_TO_LENGTH - 1) / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
int blockpoint = memoryAddress % BLOCK_TO_LENGTH;
|
||||||
|
if (blockpoint == 0)
|
||||||
|
{
|
||||||
|
ascii_buf[BLOCK_TO_LENGTH] = 0;
|
||||||
|
Serial.printf(" %s", ascii_buf);
|
||||||
|
Serial.printf("\n0x%05X:", memoryAddress);
|
||||||
|
}
|
||||||
|
ascii_buf[blockpoint] = ee.readByte(memoryAddress);
|
||||||
|
Serial.printf(" %02X", ascii_buf[blockpoint]);
|
||||||
|
if (ascii_buf[blockpoint] < 0x20 || ascii_buf[blockpoint] > 0x7E)
|
||||||
|
ascii_buf[blockpoint] = '.';
|
||||||
|
memoryAddress++;
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
52
src/config.h
Normal file
52
src/config.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#ifndef _CONFIG_H_
|
||||||
|
#define _CONFIG_H_
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <I2C_eeprom.h>
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
|
#include "dtc.h"
|
||||||
|
|
||||||
|
#define EEPROM_SIZE_BYTES I2C_DEVICESIZE_24LC256
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
NONE,
|
||||||
|
FACTION_1,
|
||||||
|
FACTION_2,
|
||||||
|
FACTION_3
|
||||||
|
} factions_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t writeCycleCounter = 0;
|
||||||
|
uint32_t faction_1_timer = 0;
|
||||||
|
uint32_t faction_2_timer = 0;
|
||||||
|
uint32_t faction_3_timer = 0;
|
||||||
|
factions_t activeFaction = NONE;
|
||||||
|
uint32_t checksum = 0;
|
||||||
|
} persistenceData_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t checksum = 0;
|
||||||
|
} configData_t;
|
||||||
|
|
||||||
|
void InitEEPROM();
|
||||||
|
void EEPROM_Process();
|
||||||
|
void StoreConfig_EEPROM();
|
||||||
|
void GetConfig_EEPROM();
|
||||||
|
void StorePersistence_EEPROM();
|
||||||
|
void GetPersistence_EEPROM();
|
||||||
|
void FormatConfig_EEPROM();
|
||||||
|
void FormatPersistence_EEPROM();
|
||||||
|
uint32_t Checksum_EEPROM(uint8_t const *data, size_t len);
|
||||||
|
void dumpEEPROM(uint16_t memoryAddress, uint16_t length);
|
||||||
|
void MovePersistencePage_EEPROM(boolean reset);
|
||||||
|
uint16_t getPersistanceAddress();
|
||||||
|
|
||||||
|
extern configData_t ConfigData;
|
||||||
|
extern persistenceData_t PersistenceData;
|
||||||
|
extern uint16_t eePersistenceMarker;
|
||||||
|
#endif // _CONFIG_H_
|
@ -2,10 +2,10 @@
|
|||||||
#define _DEFAULTS_H_
|
#define _DEFAULTS_H_
|
||||||
|
|
||||||
#ifndef WIFI_CLIENT
|
#ifndef WIFI_CLIENT
|
||||||
#define WIFI_AP
|
#define WIFI_ACCESSPOINT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WIFI_CLIENT) && defined(WIFI_AP)
|
#if defined(WIFI_CLIENT) && defined(WIFI_ACCESSPOINT)
|
||||||
#error "You can't define AP and CLIENT at the same Time!"
|
#error "You can't define AP and CLIENT at the same Time!"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
85
src/dtc.cpp
Normal file
85
src/dtc.cpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#include "dtc.h"
|
||||||
|
|
||||||
|
DTCEntry_s DTCStorage[MAX_DTC_STORAGE];
|
||||||
|
|
||||||
|
void MaintainDTC(DTCNums_t DTC_no, boolean active)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_DTC_STORAGE; i++)
|
||||||
|
{
|
||||||
|
if (DTCStorage[i].Number == DTC_no)
|
||||||
|
{
|
||||||
|
if (active && DTCStorage[i].active != DTC_ACTIVE)
|
||||||
|
{
|
||||||
|
Serial.printf("DTC gone active: %d", DTC_no);
|
||||||
|
DTCStorage[i].timestamp = millis();
|
||||||
|
DTCStorage[i].active = DTC_ACTIVE;
|
||||||
|
}
|
||||||
|
if (!active && DTCStorage[i].active == DTC_ACTIVE)
|
||||||
|
{
|
||||||
|
Serial.printf("DTC gone previous: %d", DTC_no);
|
||||||
|
DTCStorage[i].active = DTC_PREVIOUS;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DTC was not found with upper iteration, but is active
|
||||||
|
// so we need to look for free space to store DTC
|
||||||
|
if (active == true)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_DTC_STORAGE; i++)
|
||||||
|
{
|
||||||
|
if (DTCStorage[i].Number == DTC_LAST_DTC)
|
||||||
|
{
|
||||||
|
Serial.printf("new DTC registered: %d", DTC_no);
|
||||||
|
DTCStorage[i].Number = DTC_no;
|
||||||
|
DTCStorage[i].timestamp = millis();
|
||||||
|
DTCStorage[i].active = DTC_ACTIVE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearDTC(DTCNums_t DTC_no)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_DTC_STORAGE; i++)
|
||||||
|
{
|
||||||
|
if (DTCStorage[i].Number == DTC_no)
|
||||||
|
{
|
||||||
|
DTCStorage[i].Number = DTC_LAST_DTC;
|
||||||
|
DTCStorage[i].active = DTC_NONE;
|
||||||
|
DTCStorage[i].timestamp = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearAllDTC()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_DTC_STORAGE; i++)
|
||||||
|
{
|
||||||
|
DTCStorage[i].Number = DTC_LAST_DTC;
|
||||||
|
DTCStorage[i].active = DTC_NONE;
|
||||||
|
DTCStorage[i].timestamp = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DTCNums_t getlastDTC(boolean only_active)
|
||||||
|
{
|
||||||
|
int8_t pointer = -1;
|
||||||
|
uint32_t lasttimestamp = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_DTC_STORAGE; i++)
|
||||||
|
{
|
||||||
|
if (DTCStorage[i].Number > 0 && DTCStorage[i].timestamp > lasttimestamp)
|
||||||
|
{
|
||||||
|
if (only_active == false || DTCStorage[i].active == DTC_ACTIVE)
|
||||||
|
{
|
||||||
|
pointer = i;
|
||||||
|
lasttimestamp = DTCStorage[i].timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pointer >= 0 ? DTCStorage[pointer].Number : DTC_LAST_DTC;
|
||||||
|
}
|
36
src/dtc.h
Normal file
36
src/dtc.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef _DTC_H_
|
||||||
|
#define _DTC_H_
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#define MAX_DTC_STORAGE 6
|
||||||
|
|
||||||
|
typedef enum DTCNums_e
|
||||||
|
{
|
||||||
|
DTC_NO_EEPROM_FOUND,
|
||||||
|
DTC_EEPROM_CFG_BAD,
|
||||||
|
DTC_EEPROM_PDS_BAD,
|
||||||
|
DTC_LAST_DTC
|
||||||
|
} DTCNums_t;
|
||||||
|
|
||||||
|
typedef enum DTCActive_e
|
||||||
|
{
|
||||||
|
DTC_ACTIVE,
|
||||||
|
DTC_PREVIOUS,
|
||||||
|
DTC_NONE
|
||||||
|
} DTCActive_t;
|
||||||
|
|
||||||
|
typedef struct DTCEntry_s
|
||||||
|
{
|
||||||
|
DTCNums_t Number;
|
||||||
|
uint32_t timestamp;
|
||||||
|
DTCActive_t active;
|
||||||
|
} DTCEntry_t;
|
||||||
|
|
||||||
|
void MaintainDTC(DTCNums_t DTC_no, boolean active);
|
||||||
|
void ClearDTC(DTCNums_t DTC_no);
|
||||||
|
void ClearAllDTC();
|
||||||
|
DTCNums_t getlastDTC(boolean only_active);
|
||||||
|
|
||||||
|
extern DTCEntry_s DTCStorage[MAX_DTC_STORAGE];
|
||||||
|
#endif
|
36
src/globals.h
Normal file
36
src/globals.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef _GLOBALS_H_
|
||||||
|
#define _GLOBALS_H_
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
typedef enum eSystem_Status
|
||||||
|
{
|
||||||
|
sysStat_Startup,
|
||||||
|
sysStat_Normal,
|
||||||
|
sysStat_Error,
|
||||||
|
sysStat_Shutdown
|
||||||
|
} tSystem_Status;
|
||||||
|
|
||||||
|
typedef enum eEERequest
|
||||||
|
{
|
||||||
|
EE_IDLE,
|
||||||
|
EE_CFG_SAVE,
|
||||||
|
EE_CFG_LOAD,
|
||||||
|
EE_PDS_SAVE,
|
||||||
|
EE_PDS_LOAD
|
||||||
|
} tEERequest;
|
||||||
|
|
||||||
|
typedef struct Globals_s
|
||||||
|
{
|
||||||
|
char DeviceName[33];
|
||||||
|
char DeviceName_ID[33+6];
|
||||||
|
tSystem_Status systemStatus = sysStat_Startup;
|
||||||
|
tSystem_Status resumeStatus = sysStat_Startup;
|
||||||
|
eEERequest requestEEAction = EE_IDLE;
|
||||||
|
float loadvoltage = 0;
|
||||||
|
int battery_level = 0;
|
||||||
|
} Globals_t;
|
||||||
|
|
||||||
|
extern Globals_t globals;
|
||||||
|
|
||||||
|
#endif
|
760
src/main.cpp
760
src/main.cpp
@ -1,50 +1,68 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <TM1637Display.h>
|
#include <TM1637Display.h>
|
||||||
#include <Ticker.h>
|
#include <Ticker.h>
|
||||||
#ifdef CAPTIVE
|
|
||||||
#include <DNSServer.h>
|
#include <DNSServer.h>
|
||||||
#endif
|
|
||||||
#ifdef ESP32
|
|
||||||
#include <WiFi.h>
|
|
||||||
#include <AsyncTCP.h>
|
|
||||||
#include <WiFiMulti.h>
|
|
||||||
#elif defined(ESP8266)
|
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#include <ESPAsyncTCP.h>
|
#include <ESPAsyncTCP.h>
|
||||||
#include <ESP8266WiFiMulti.h>
|
|
||||||
#include <ESP8266mDNS.h>
|
#include <ESP8266mDNS.h>
|
||||||
#endif
|
|
||||||
#include <ArduinoOTA.h>
|
#include <ArduinoOTA.h>
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
#include <Adafruit_INA219.h>
|
#include <Adafruit_INA219.h>
|
||||||
|
|
||||||
// local includes
|
// local includes
|
||||||
#include "defaults.h"
|
#include "defaults.h"
|
||||||
|
#include "webui.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "globals.h"
|
||||||
|
#include "dtc.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
// Module connection pins (ESP GPIO-Nums)
|
#ifdef REMOTE_DEBUG
|
||||||
#define CLK 16
|
#include <RemoteDebug.h>
|
||||||
#define DIO_FAC_1_7SEG 14
|
#include "rmtdbghelp.h"
|
||||||
#define DIO_FAC_2_7SEG 12
|
#else
|
||||||
#define DIO_FAC_3_7SEG 13
|
#define debugV Serial.println
|
||||||
|
#define debugE Serial.println
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DIO_FAC_1_TRG 0
|
#ifdef WIFI_CLIENT
|
||||||
#define DIO_FAC_2_TRG 2
|
#include <ESP8266WiFiMulti.h>
|
||||||
#define DIO_FAC_3_TRG 15
|
|
||||||
|
|
||||||
enum Factions
|
const char *ssid = QUOTE(WIFI_SSID);
|
||||||
{
|
const char *password = QUOTE(WIFI_PASSWORD);
|
||||||
NONE,
|
const uint32_t connectTimeoutMs = 5000;
|
||||||
FACTION_1,
|
|
||||||
FACTION_2,
|
ESP8266WiFiMulti wifiMulti;
|
||||||
FACTION_3
|
#endif
|
||||||
};
|
|
||||||
|
|
||||||
void SevenSeg_Output();
|
void SevenSeg_Output();
|
||||||
void FactionTicker_callback();
|
void FactionTicker_callback();
|
||||||
void serialOutTicker_callback();
|
|
||||||
void inputGetterTicker_callback();
|
void inputGetterTicker_callback();
|
||||||
void powerMonitorTicker_callback();
|
void powerMonitorTicker_callback();
|
||||||
|
void EEPROMCyclicPDS_callback();
|
||||||
|
void toggleWiFiAP(boolean shutdown = false);
|
||||||
|
void SystemShutdown();
|
||||||
|
|
||||||
|
#ifdef REMOTE_DEBUG
|
||||||
|
RemoteDebug Debug;
|
||||||
|
String IpAddress2String(const IPAddress &ipAddress);
|
||||||
|
void processCmdRemoteDebug();
|
||||||
|
void RemoteDebug_formatCFG();
|
||||||
|
void RemoteDebug_formatPersistence();
|
||||||
|
void RemotDebug_printSystemInfo();
|
||||||
|
void RemoteDebug_printWifiInfo();
|
||||||
|
void RemoteDebug_CheckEEPOM();
|
||||||
|
void RemoteDebug_dumpConfig();
|
||||||
|
void RemoteDebug_dumpPersistance();
|
||||||
|
void RemoteDebug_ShowDTCs();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIFI_CLIENT
|
||||||
|
void wifiMaintainConnectionTicker_callback();
|
||||||
|
Ticker WiFiMaintainConnectionTicker(wifiMaintainConnectionTicker_callback, 1000, 0, MILLIS);
|
||||||
|
#endif
|
||||||
|
|
||||||
TM1637Display disp_FAC_1(CLK, DIO_FAC_1_7SEG);
|
TM1637Display disp_FAC_1(CLK, DIO_FAC_1_7SEG);
|
||||||
TM1637Display disp_FAC_2(CLK, DIO_FAC_2_7SEG);
|
TM1637Display disp_FAC_2(CLK, DIO_FAC_2_7SEG);
|
||||||
@ -52,309 +70,56 @@ TM1637Display disp_FAC_3(CLK, DIO_FAC_3_7SEG);
|
|||||||
|
|
||||||
Adafruit_INA219 ina219;
|
Adafruit_INA219 ina219;
|
||||||
|
|
||||||
WiFiEventHandler stationConnectedHandler;
|
|
||||||
WiFiEventHandler stationDisconnectedHandler;
|
|
||||||
|
|
||||||
#ifdef WIFI_CLIENT
|
|
||||||
ESP8266WiFiMulti wifiMulti;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CAPTIVE
|
#ifdef CAPTIVE
|
||||||
DNSServer dnsServer;
|
DNSServer dnsServer;
|
||||||
#endif
|
#endif
|
||||||
AsyncWebServer server(80);
|
AsyncWebServer server(80);
|
||||||
|
|
||||||
Ticker FactionTicker(FactionTicker_callback, 1000, 0, MILLIS);
|
Ticker FactionTicker(FactionTicker_callback, 1000, 0, MILLIS);
|
||||||
Ticker SerialOutputTicker(serialOutTicker_callback, 5000, 0, MILLIS);
|
|
||||||
Ticker InputGetterTicker(inputGetterTicker_callback, 250, 0, MILLIS);
|
Ticker InputGetterTicker(inputGetterTicker_callback, 250, 0, MILLIS);
|
||||||
Ticker PowerMonitorTicker(powerMonitorTicker_callback, 5000, 0, MILLIS);
|
Ticker PowerMonitorTicker(powerMonitorTicker_callback, 5000, 0, MILLIS);
|
||||||
|
Ticker EEPROMCyclicPDSTicker(EEPROMCyclicPDS_callback, 60000, 0, MILLIS);
|
||||||
|
|
||||||
Factions activeFaction = NONE;
|
|
||||||
|
|
||||||
uint32_t Count_Faction_1 = 0;
|
|
||||||
uint32_t Count_Faction_2 = 0;
|
|
||||||
uint32_t Count_Faction_3 = 0;
|
|
||||||
uint8_t Faction_1_dot = 0;
|
uint8_t Faction_1_dot = 0;
|
||||||
uint8_t Faction_2_dot = 0;
|
uint8_t Faction_2_dot = 0;
|
||||||
uint8_t Faction_3_dot = 0;
|
uint8_t Faction_3_dot = 0;
|
||||||
|
|
||||||
float loadvoltage = 0;
|
Globals_t globals;
|
||||||
int battery_level = 0;
|
|
||||||
|
|
||||||
const uint8_t sevenSeg_bat[] = {0x00, 0b01111100, 0b01110111, 0b01111000};
|
const uint8_t sevenSeg_bat[] = {0x00, 0b01111100, 0b01110111, 0b01111000};
|
||||||
const uint8_t sevenSeg_low[] = {0b00111000, 0b01011100, 0x00, 0x00};
|
const uint8_t sevenSeg_low[] = {0b00111000, 0b01011100, 0x00, 0x00};
|
||||||
|
|
||||||
String processor(const String &var)
|
|
||||||
{
|
|
||||||
char buffer[16] = {0};
|
|
||||||
|
|
||||||
if (var == "POINTS_FAC_1")
|
|
||||||
itoa(Count_Faction_1, buffer, 10);
|
|
||||||
|
|
||||||
if (var == "POINTS_FAC_2")
|
|
||||||
itoa(Count_Faction_2, buffer, 10);
|
|
||||||
|
|
||||||
if (var == "POINTS_FAC_3")
|
|
||||||
itoa(Count_Faction_3, buffer, 10);
|
|
||||||
|
|
||||||
if (var == "STATUS_FAC_1")
|
|
||||||
return activeFaction == FACTION_1 ? "ACTIVE" : "INACTIVE";
|
|
||||||
|
|
||||||
if (var == "STATUS_FAC_2")
|
|
||||||
return activeFaction == FACTION_2 ? "ACTIVE" : "INACTIVE";
|
|
||||||
|
|
||||||
if (var == "STATUS_FAC_3")
|
|
||||||
return activeFaction == FACTION_3 ? "ACTIVE" : "INACTIVE";
|
|
||||||
|
|
||||||
if (var == "NAME_FAC_1")
|
|
||||||
return FACTION_1_NAME;
|
|
||||||
|
|
||||||
if (var == "NAME_FAC_2")
|
|
||||||
return FACTION_2_NAME;
|
|
||||||
|
|
||||||
if (var == "NAME_FAC_3")
|
|
||||||
return FACTION_3_NAME;
|
|
||||||
|
|
||||||
if (var == "TITLE")
|
|
||||||
return DEVICE_NAME;
|
|
||||||
|
|
||||||
if (var == "BATTERY_LEVEL")
|
|
||||||
{
|
|
||||||
sprintf(buffer, "%d", battery_level);
|
|
||||||
return String(buffer);
|
|
||||||
}
|
|
||||||
if (var == "BATTERY_VOLTAGE")
|
|
||||||
{
|
|
||||||
sprintf(buffer, "%f", loadvoltage);
|
|
||||||
return String(buffer);
|
|
||||||
}
|
|
||||||
return String(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
String macToString(const unsigned char *mac)
|
|
||||||
{
|
|
||||||
char buf[20];
|
|
||||||
snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
||||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
|
||||||
return String(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void onStationConnected(const WiFiEventSoftAPModeStationConnected &evt)
|
|
||||||
{
|
|
||||||
Serial.print("Station connected: ");
|
|
||||||
Serial.println(macToString(evt.mac));
|
|
||||||
}
|
|
||||||
|
|
||||||
void onStationDisconnected(const WiFiEventSoftAPModeStationDisconnected &evt)
|
|
||||||
{
|
|
||||||
Serial.print("Station disconnected: ");
|
|
||||||
Serial.println(macToString(evt.mac));
|
|
||||||
}
|
|
||||||
|
|
||||||
String getValue(String data, char separator, int index)
|
|
||||||
{
|
|
||||||
int found = 0;
|
|
||||||
int strIndex[] = {0, -1};
|
|
||||||
int maxIndex = data.length() - 1;
|
|
||||||
|
|
||||||
for (int i = 0; i <= maxIndex && found <= index; i++)
|
|
||||||
{
|
|
||||||
if (data.charAt(i) == separator || i == maxIndex)
|
|
||||||
{
|
|
||||||
found++;
|
|
||||||
strIndex[0] = strIndex[1] + 1;
|
|
||||||
strIndex[1] = (i == maxIndex) ? i + 1 : i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
class CaptiveRequestHandler : public AsyncWebHandler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CaptiveRequestHandler() {}
|
|
||||||
virtual ~CaptiveRequestHandler() {}
|
|
||||||
|
|
||||||
bool canHandle(AsyncWebServerRequest *request)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleRequest(AsyncWebServerRequest *request)
|
|
||||||
{
|
|
||||||
|
|
||||||
Serial.print("Requested URL: ");
|
|
||||||
Serial.println(request->url());
|
|
||||||
|
|
||||||
//List all parameters
|
|
||||||
int params = request->params();
|
|
||||||
for (int i = 0; i < params; i++)
|
|
||||||
{
|
|
||||||
AsyncWebParameter *p = request->getParam(i);
|
|
||||||
if (p->isFile())
|
|
||||||
{ //p->isPost() is also true
|
|
||||||
Serial.printf("FILE[%s]: %s, size: %u\n", p->name().c_str(), p->value().c_str(), p->size());
|
|
||||||
}
|
|
||||||
else if (p->isPost())
|
|
||||||
{
|
|
||||||
Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Serial.printf("GET[%s]: %s\n", p->name().c_str(), p->value().c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LittleFS.exists(request->url()) == false)
|
|
||||||
{
|
|
||||||
request->send(404, "text/plain", "Not found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request->url() == "/favicon.ico")
|
|
||||||
{
|
|
||||||
request->send(LittleFS, request->url(), "image/x-icon");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request->url() == "/" || request->url() == "/index.html")
|
|
||||||
{
|
|
||||||
request->send(LittleFS, "/index.html", String(), false, processor);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getValue(request->url(), '/', 1) == "css")
|
|
||||||
{
|
|
||||||
request->send(LittleFS, request->url(), "text/css");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void SevenSeg_Output()
|
|
||||||
{
|
|
||||||
if (battery_level < BAT_LOW_PERCENT)
|
|
||||||
{
|
|
||||||
disp_FAC_1.setBrightness(0);
|
|
||||||
disp_FAC_2.setBrightness(0);
|
|
||||||
disp_FAC_3.setBrightness(0);
|
|
||||||
|
|
||||||
disp_FAC_3.setSegments(sevenSeg_bat);
|
|
||||||
disp_FAC_2.setSegments(sevenSeg_low);
|
|
||||||
if (millis() % 5000 > 2500)
|
|
||||||
disp_FAC_1.showNumberDec(battery_level);
|
|
||||||
else
|
|
||||||
disp_FAC_1.showNumberDecEx(loadvoltage * 100, 0x40);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
disp_FAC_1.setBrightness(activeFaction == FACTION_1 ? 7 : 0);
|
|
||||||
disp_FAC_2.setBrightness(activeFaction == FACTION_2 ? 7 : 0);
|
|
||||||
disp_FAC_3.setBrightness(activeFaction == FACTION_3 ? 7 : 0);
|
|
||||||
|
|
||||||
disp_FAC_1.showNumberDecEx(Count_Faction_1 / 60, Faction_1_dot, true, 4, 0);
|
|
||||||
disp_FAC_2.showNumberDecEx(Count_Faction_2 / 60, Faction_2_dot, true, 4, 0);
|
|
||||||
disp_FAC_3.showNumberDecEx(Count_Faction_3 / 60, Faction_3_dot, true, 4, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FactionTicker_callback()
|
|
||||||
{
|
|
||||||
switch (activeFaction)
|
|
||||||
{
|
|
||||||
case FACTION_1:
|
|
||||||
Count_Faction_1++;
|
|
||||||
Faction_1_dot = Faction_1_dot == 0x80 || Faction_1_dot == 0x00 ? 0x10 : Faction_1_dot << 1;
|
|
||||||
Faction_2_dot = 0;
|
|
||||||
Faction_3_dot = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FACTION_2:
|
|
||||||
Count_Faction_2++;
|
|
||||||
Faction_2_dot = Faction_2_dot == 0x80 || Faction_2_dot == 0x00 ? 0x10 : Faction_2_dot << 1;
|
|
||||||
Faction_1_dot = 0;
|
|
||||||
Faction_3_dot = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FACTION_3:
|
|
||||||
Count_Faction_3++;
|
|
||||||
Faction_3_dot = Faction_3_dot == 0x80 || Faction_3_dot == 0x00 ? 0x10 : Faction_3_dot << 1;
|
|
||||||
Faction_1_dot = 0;
|
|
||||||
Faction_2_dot = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void serialOutTicker_callback()
|
|
||||||
{
|
|
||||||
|
|
||||||
static uint32_t SerialPrintCount = 0;
|
|
||||||
|
|
||||||
if (SerialPrintCount % 10 == 0)
|
|
||||||
{
|
|
||||||
Serial.printf("| %8s | %8s | %8s |\n", FACTION_1_NAME, FACTION_2_NAME, FACTION_3_NAME);
|
|
||||||
}
|
|
||||||
Serial.printf(" %8d %8d %8d\n", Count_Faction_1, Count_Faction_2, Count_Faction_3);
|
|
||||||
SerialPrintCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void inputGetterTicker_callback()
|
|
||||||
{
|
|
||||||
activeFaction = NONE;
|
|
||||||
|
|
||||||
if (digitalRead(DIO_FAC_1_TRG) + digitalRead(DIO_FAC_2_TRG) + !digitalRead(DIO_FAC_3_TRG) < 2)
|
|
||||||
{
|
|
||||||
Serial.println("ERROR: More than one Flag active");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (digitalRead(DIO_FAC_1_TRG) == LOW)
|
|
||||||
activeFaction = FACTION_1;
|
|
||||||
|
|
||||||
if (digitalRead(DIO_FAC_2_TRG) == LOW)
|
|
||||||
activeFaction = FACTION_2;
|
|
||||||
|
|
||||||
if (digitalRead(DIO_FAC_3_TRG) == HIGH)
|
|
||||||
activeFaction = FACTION_3;
|
|
||||||
}
|
|
||||||
|
|
||||||
void powerMonitorTicker_callback()
|
|
||||||
{
|
|
||||||
|
|
||||||
// loadvoltage and percentage is global, because of battery Monitoring
|
|
||||||
|
|
||||||
float shuntvoltage = 0;
|
|
||||||
float current_mA = 0;
|
|
||||||
float busvoltage = 0;
|
|
||||||
float power_mW = 0;
|
|
||||||
|
|
||||||
shuntvoltage = ina219.getShuntVoltage_mV();
|
|
||||||
busvoltage = ina219.getBusVoltage_V();
|
|
||||||
current_mA = ina219.getCurrent_mA();
|
|
||||||
power_mW = ina219.getPower_mW();
|
|
||||||
loadvoltage = busvoltage + (shuntvoltage / 1000);
|
|
||||||
battery_level = map(loadvoltage * 100, 655, 840, 0, 100);
|
|
||||||
|
|
||||||
Serial.printf("Battery Level: %d %%\n", battery_level);
|
|
||||||
Serial.printf("Bus Voltage: %f V\n", busvoltage);
|
|
||||||
Serial.printf("Shunt Voltage: %f mV\n", shuntvoltage);
|
|
||||||
Serial.printf("Load Voltage: %f V\n", loadvoltage);
|
|
||||||
Serial.printf("Current: %f mA\n", current_mA);
|
|
||||||
Serial.printf("Power: %f mW\n", power_mW);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
|
system_update_cpu_freq(SYS_CPU_80MHZ);
|
||||||
|
WiFi.persistent(false);
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.print("\n\n\n");
|
||||||
|
|
||||||
|
strcpy(globals.DeviceName, DEVICE_NAME);
|
||||||
|
snprintf(globals.DeviceName_ID, 39, "%s_%06X", globals.DeviceName, ESP.getChipId());
|
||||||
|
|
||||||
pinMode(DIO_FAC_1_TRG, INPUT_PULLUP);
|
pinMode(DIO_FAC_1_TRG, INPUT_PULLUP);
|
||||||
pinMode(DIO_FAC_2_TRG, INPUT_PULLUP);
|
pinMode(DIO_FAC_2_TRG, INPUT_PULLUP);
|
||||||
pinMode(DIO_FAC_3_TRG, INPUT);
|
pinMode(DIO_FAC_3_TRG, INPUT);
|
||||||
|
|
||||||
Serial.begin(9600);
|
#ifdef REMOTE_DEBUG
|
||||||
Serial.print("\n\n\n");
|
if (MDNS.begin(globals.DeviceName_ID))
|
||||||
|
MDNS.addService("telnet", "tcp", 23);
|
||||||
|
|
||||||
|
Debug.begin(globals.DeviceName_ID);
|
||||||
|
Debug.setResetCmdEnabled(true);
|
||||||
|
Debug.showProfiler(false);
|
||||||
|
Debug.showColors(true);
|
||||||
|
Debug.setPassword(QUOTE(ADMIN_PASSWORD));
|
||||||
|
Debug.setSerialEnabled(true);
|
||||||
|
Debug.showDebugLevel(true);
|
||||||
|
|
||||||
|
Debug.setHelpProjectsCmds(helpCmd);
|
||||||
|
Debug.setCallBackProjectCmds(&processCmdRemoteDebug);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SERIAL_DEBUG
|
#ifdef SERIAL_DEBUG
|
||||||
Serial.setDebugOutput(true);
|
Serial.setDebugOutput(true);
|
||||||
#endif
|
#endif
|
||||||
@ -366,32 +131,22 @@ void setup()
|
|||||||
|
|
||||||
LittleFS.begin();
|
LittleFS.begin();
|
||||||
|
|
||||||
WiFi.persistent(false);
|
#ifdef WIFI_CLIENT
|
||||||
|
|
||||||
#ifdef WIFI_AP
|
|
||||||
WiFi.mode(WIFI_AP);
|
|
||||||
WiFi.softAP(WIFI_SSID, WIFI_PASS);
|
|
||||||
|
|
||||||
stationConnectedHandler = WiFi.onSoftAPModeStationConnected(&onStationConnected);
|
|
||||||
stationDisconnectedHandler = WiFi.onSoftAPModeStationDisconnected(&onStationDisconnected);
|
|
||||||
|
|
||||||
#else
|
|
||||||
WiFi.mode(WIFI_STA);
|
WiFi.mode(WIFI_STA);
|
||||||
wifiMulti.addAP(WIFI_SSID, WIFI_PASS);
|
WiFi.setHostname(globals.DeviceName_ID);
|
||||||
|
wifiMulti.addAP(QUOTE(WIFI_SSID), QUOTE(WIFI_PASSWORD));
|
||||||
Serial.println("Connecting Wifi...");
|
WiFiMaintainConnectionTicker.start();
|
||||||
if (wifiMulti.run() == WL_CONNECTED)
|
#else
|
||||||
{
|
WiFi.mode(WIFI_OFF);
|
||||||
Serial.println("");
|
|
||||||
Serial.println("WiFi connected");
|
|
||||||
Serial.println("IP address: ");
|
|
||||||
Serial.print(WiFi.localIP());
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
InitEEPROM();
|
||||||
|
GetConfig_EEPROM();
|
||||||
|
GetPersistence_EEPROM();
|
||||||
|
|
||||||
ArduinoOTA.setPort(8266);
|
ArduinoOTA.setPort(8266);
|
||||||
ArduinoOTA.setHostname(OTA_HOST);
|
ArduinoOTA.setHostname(globals.DeviceName_ID);
|
||||||
ArduinoOTA.setPassword(OTA_PASS);
|
ArduinoOTA.setPassword(QUOTE(ADMIN_PASSWORD));
|
||||||
|
|
||||||
ArduinoOTA.onStart([]()
|
ArduinoOTA.onStart([]()
|
||||||
{
|
{
|
||||||
@ -405,8 +160,7 @@ void setup()
|
|||||||
type = "filesystem";
|
type = "filesystem";
|
||||||
LittleFS.end();
|
LittleFS.end();
|
||||||
}
|
}
|
||||||
Serial.println("Start updating " + type);
|
Serial.println("Start updating " + type); });
|
||||||
});
|
|
||||||
|
|
||||||
ArduinoOTA.onEnd([]()
|
ArduinoOTA.onEnd([]()
|
||||||
{ Serial.println("\nEnd"); });
|
{ Serial.println("\nEnd"); });
|
||||||
@ -426,70 +180,346 @@ void setup()
|
|||||||
else if (error == OTA_RECEIVE_ERROR)
|
else if (error == OTA_RECEIVE_ERROR)
|
||||||
Serial.println("Receive Failed");
|
Serial.println("Receive Failed");
|
||||||
else if (error == OTA_END_ERROR)
|
else if (error == OTA_END_ERROR)
|
||||||
Serial.println("End Failed");
|
Serial.println("End Failed"); });
|
||||||
});
|
|
||||||
ArduinoOTA.begin();
|
ArduinoOTA.begin();
|
||||||
|
|
||||||
#ifdef CAPTIVE
|
#ifdef CAPTIVE
|
||||||
dnsServer.start(53, "*", WiFi.softAPIP());
|
dnsServer.start(53, "*", WiFi.softAPIP());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
server.addHandler(new CaptiveRequestHandler());
|
initWebUI();
|
||||||
server.begin();
|
|
||||||
|
|
||||||
|
EEPROMCyclicPDSTicker.start();
|
||||||
FactionTicker.start();
|
FactionTicker.start();
|
||||||
SerialOutputTicker.start();
|
|
||||||
InputGetterTicker.start();
|
InputGetterTicker.start();
|
||||||
|
Serial.println("Setup Done");
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
|
EEPROMCyclicPDSTicker.update();
|
||||||
FactionTicker.update();
|
FactionTicker.update();
|
||||||
SerialOutputTicker.update();
|
|
||||||
InputGetterTicker.update();
|
InputGetterTicker.update();
|
||||||
PowerMonitorTicker.update();
|
PowerMonitorTicker.update();
|
||||||
ArduinoOTA.handle();
|
ArduinoOTA.handle();
|
||||||
|
SevenSeg_Output();
|
||||||
|
EEPROM_Process();
|
||||||
|
|
||||||
#ifdef CAPTIVE
|
#ifdef CAPTIVE
|
||||||
dnsServer.processNextRequest();
|
dnsServer.processNextRequest();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef REMOTE_DEBUG
|
||||||
|
Debug.handle();
|
||||||
|
#endif
|
||||||
|
#ifdef WIFI_CLIENT
|
||||||
|
WiFiMaintainConnectionTicker.update();
|
||||||
|
#endif
|
||||||
|
if (globals.systemStatus == sysStat_Shutdown)
|
||||||
|
SystemShutdown();
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
|
||||||
SevenSeg_Output();
|
String macToString(const unsigned char *mac)
|
||||||
|
{
|
||||||
|
char buf[20];
|
||||||
|
snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
|
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||||
|
return String(buf);
|
||||||
|
}
|
||||||
|
|
||||||
while (Serial.available() > 0)
|
void SevenSeg_Output()
|
||||||
|
{
|
||||||
|
if (globals.battery_level < BAT_LOW_PERCENT)
|
||||||
{
|
{
|
||||||
char input = Serial.read();
|
disp_FAC_1.setBrightness(0);
|
||||||
|
disp_FAC_2.setBrightness(0);
|
||||||
|
disp_FAC_3.setBrightness(0);
|
||||||
|
|
||||||
switch (input)
|
disp_FAC_3.setSegments(sevenSeg_bat);
|
||||||
|
disp_FAC_2.setSegments(sevenSeg_low);
|
||||||
|
if (millis() % 5000 > 2500)
|
||||||
|
disp_FAC_1.showNumberDec(globals.battery_level);
|
||||||
|
else
|
||||||
|
disp_FAC_1.showNumberDecEx(globals.loadvoltage * 100, 0x40);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
disp_FAC_1.setBrightness(PersistenceData.activeFaction == FACTION_1 ? 7 : 0);
|
||||||
|
disp_FAC_2.setBrightness(PersistenceData.activeFaction == FACTION_2 ? 7 : 0);
|
||||||
|
disp_FAC_3.setBrightness(PersistenceData.activeFaction == FACTION_3 ? 7 : 0);
|
||||||
|
|
||||||
|
disp_FAC_1.showNumberDecEx(PersistenceData.faction_1_timer / 60, Faction_1_dot, true, 4, 0);
|
||||||
|
disp_FAC_2.showNumberDecEx(PersistenceData.faction_2_timer / 60, Faction_2_dot, true, 4, 0);
|
||||||
|
disp_FAC_3.showNumberDecEx(PersistenceData.faction_3_timer / 60, Faction_3_dot, true, 4, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FactionTicker_callback()
|
||||||
|
{
|
||||||
|
switch (PersistenceData.activeFaction)
|
||||||
|
{
|
||||||
|
case FACTION_1:
|
||||||
|
PersistenceData.faction_1_timer++;
|
||||||
|
Faction_1_dot = Faction_1_dot == 0x80 || Faction_1_dot == 0x00 ? 0x10 : Faction_1_dot << 1;
|
||||||
|
Faction_2_dot = 0;
|
||||||
|
Faction_3_dot = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FACTION_2:
|
||||||
|
PersistenceData.faction_2_timer++;
|
||||||
|
Faction_2_dot = Faction_2_dot == 0x80 || Faction_2_dot == 0x00 ? 0x10 : Faction_2_dot << 1;
|
||||||
|
Faction_1_dot = 0;
|
||||||
|
Faction_3_dot = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FACTION_3:
|
||||||
|
PersistenceData.faction_3_timer++;
|
||||||
|
Faction_3_dot = Faction_3_dot == 0x80 || Faction_3_dot == 0x00 ? 0x10 : Faction_3_dot << 1;
|
||||||
|
Faction_1_dot = 0;
|
||||||
|
Faction_2_dot = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void inputGetterTicker_callback()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (digitalRead(DIO_FAC_1_TRG) + digitalRead(DIO_FAC_2_TRG) + !digitalRead(DIO_FAC_3_TRG) < 2)
|
||||||
|
{
|
||||||
|
Serial.println("ERROR: More than one Flag active - setting no Faction active");
|
||||||
|
PersistenceData.activeFaction = NONE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (digitalRead(DIO_FAC_1_TRG) == LOW)
|
||||||
|
PersistenceData.activeFaction = FACTION_1;
|
||||||
|
|
||||||
|
if (digitalRead(DIO_FAC_2_TRG) == LOW)
|
||||||
|
PersistenceData.activeFaction = FACTION_2;
|
||||||
|
|
||||||
|
if (digitalRead(DIO_FAC_3_TRG) == HIGH)
|
||||||
|
PersistenceData.activeFaction = FACTION_3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void powerMonitorTicker_callback()
|
||||||
|
{
|
||||||
|
|
||||||
|
// loadvoltage and percentage is global, because of battery Monitoring
|
||||||
|
|
||||||
|
float shuntvoltage = 0;
|
||||||
|
float current_mA = 0;
|
||||||
|
float busvoltage = 0;
|
||||||
|
float power_mW = 0;
|
||||||
|
|
||||||
|
shuntvoltage = ina219.getShuntVoltage_mV();
|
||||||
|
busvoltage = ina219.getBusVoltage_V();
|
||||||
|
current_mA = ina219.getCurrent_mA();
|
||||||
|
power_mW = ina219.getPower_mW();
|
||||||
|
globals.loadvoltage = busvoltage + (shuntvoltage / 1000);
|
||||||
|
globals.battery_level = map(globals.loadvoltage * 100, 655, 840, 0, 100);
|
||||||
|
|
||||||
|
debugV("Battery Level: %d %%", globals.battery_level);
|
||||||
|
debugV("Bus Voltage: %f V", busvoltage);
|
||||||
|
debugV("Shunt Voltage: %f mV", shuntvoltage);
|
||||||
|
debugV("Load Voltage: %f V", globals.loadvoltage);
|
||||||
|
debugV("Current: %f mA", current_mA);
|
||||||
|
debugV("Power: %f mW", power_mW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EEPROMCyclicPDS_callback()
|
||||||
|
{
|
||||||
|
StorePersistence_EEPROM();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WIFI_CLIENT
|
||||||
|
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
|
||||||
|
toggleWiFiAP(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void toggleWiFiAP(boolean shutdown)
|
||||||
|
{
|
||||||
|
if (WiFi.getMode() != WIFI_OFF && shutdown == true)
|
||||||
|
{
|
||||||
|
WiFi.mode(WIFI_OFF);
|
||||||
|
#ifdef WIFI_CLIENT
|
||||||
|
WiFiMaintainConnectionTicker.stop();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (shutdown == false)
|
||||||
|
{
|
||||||
|
WiFi.mode(WIFI_AP);
|
||||||
|
WiFi.softAPConfig(IPAddress(WIFI_AP_IP_GW), IPAddress(WIFI_AP_IP_GW), IPAddress(255, 255, 255, 0));
|
||||||
|
WiFi.softAP(globals.DeviceName_ID, QUOTE(WIFI_AP_PASSWORD));
|
||||||
|
#ifdef WIFI_CLIENT
|
||||||
|
WiFiMaintainConnectionTicker.stop();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemShutdown()
|
||||||
|
{
|
||||||
|
StoreConfig_EEPROM();
|
||||||
|
ESP.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef REMOTE_DEBUG
|
||||||
|
void processCmdRemoteDebug()
|
||||||
|
{
|
||||||
|
String lastCmd = Debug.getLastCommand();
|
||||||
|
|
||||||
|
if (lastCmd == "sysinfo")
|
||||||
|
RemotDebug_printSystemInfo();
|
||||||
|
else if (lastCmd == "netinfo")
|
||||||
|
RemoteDebug_printWifiInfo();
|
||||||
|
else if (lastCmd == "formatCFG")
|
||||||
|
RemoteDebug_formatCFG();
|
||||||
|
else if (lastCmd == "formatPDS")
|
||||||
|
RemoteDebug_formatPersistence();
|
||||||
|
else if (lastCmd == "checkEE")
|
||||||
|
RemoteDebug_CheckEEPOM();
|
||||||
|
else if (lastCmd == "dumpEE1k")
|
||||||
|
dumpEEPROM(0, 1024);
|
||||||
|
else if (lastCmd == "dumpEE")
|
||||||
|
dumpEEPROM(0, EEPROM_SIZE_BYTES);
|
||||||
|
else if (lastCmd == "resetPageEE")
|
||||||
|
MovePersistencePage_EEPROM(true);
|
||||||
|
else if (lastCmd == "dumpCFG")
|
||||||
|
RemoteDebug_dumpConfig();
|
||||||
|
else if (lastCmd == "dumpPDS")
|
||||||
|
RemoteDebug_dumpPersistance();
|
||||||
|
else if (lastCmd == "saveEE")
|
||||||
|
StoreConfig_EEPROM();
|
||||||
|
else if (lastCmd == "showdtc")
|
||||||
|
RemoteDebug_ShowDTCs();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteDebug_formatCFG()
|
||||||
|
{
|
||||||
|
debugA("Formatting Config-EEPROM and reseting to default");
|
||||||
|
FormatConfig_EEPROM();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteDebug_formatPersistence()
|
||||||
|
{
|
||||||
|
debugA("Formatting Persistence-EEPROM and reseting to default");
|
||||||
|
FormatPersistence_EEPROM();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemotDebug_printSystemInfo()
|
||||||
|
{
|
||||||
|
debugA("DE Timer Mk1");
|
||||||
|
debugA("Hostname: %s", globals.DeviceName_ID);
|
||||||
|
|
||||||
|
FlashMode_t ideMode = ESP.getFlashChipMode();
|
||||||
|
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());
|
||||||
|
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("OTA-Pass: %s", QUOTE(ADMIN_PASSWORD));
|
||||||
|
debugA("Git-Revison: %s", GIT_REV);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteDebug_dumpConfig()
|
||||||
|
{
|
||||||
|
debugA("checksum: 0x%08X", ConfigData.checksum);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteDebug_dumpPersistance()
|
||||||
|
{
|
||||||
|
debugA("writeCycleCounter: %d", PersistenceData.writeCycleCounter);
|
||||||
|
debugA("faction_1_timer: %d", PersistenceData.faction_1_timer);
|
||||||
|
debugA("faction_2_timer: %d", PersistenceData.faction_2_timer);
|
||||||
|
debugA("faction_2_timer: %d", PersistenceData.faction_3_timer);
|
||||||
|
debugA("activeFaction: %d", PersistenceData.activeFaction);
|
||||||
|
debugA("checksum: %d", PersistenceData.checksum);
|
||||||
|
debugA("PSD Adress: 0x%04X", getPersistanceAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteDebug_printWifiInfo()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteDebug_CheckEEPOM()
|
||||||
|
{
|
||||||
|
uint32_t checksum = PersistenceData.checksum;
|
||||||
|
PersistenceData.checksum = 0;
|
||||||
|
|
||||||
|
if (Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData)) == checksum)
|
||||||
|
{
|
||||||
|
debugA("PersistenceData EEPROM Checksum OK\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debugA("PersistenceData EEPROM Checksum BAD\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
PersistenceData.checksum = checksum;
|
||||||
|
|
||||||
|
checksum = ConfigData.checksum;
|
||||||
|
ConfigData.checksum = 0;
|
||||||
|
|
||||||
|
if (Checksum_EEPROM((uint8_t *)&ConfigData, sizeof(ConfigData)) == checksum)
|
||||||
|
{
|
||||||
|
debugA("ConfigData EEPROM Checksum OK\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debugA("ConfigData EEPROM Checksum BAD\n");
|
||||||
|
}
|
||||||
|
ConfigData.checksum = checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteDebug_ShowDTCs()
|
||||||
|
{
|
||||||
|
char buff_timestamp[16]; // Format: DD-hh:mm:ss:xxx
|
||||||
|
char buff_active[9];
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < MAX_DTC_STORAGE; i++)
|
||||||
|
{
|
||||||
|
if (DTCStorage[i].Number > 0)
|
||||||
{
|
{
|
||||||
case 'n':
|
sprintf(buff_timestamp, "%02d-%02d:%02d:%02d:%03d",
|
||||||
activeFaction = NONE;
|
DTCStorage[i].timestamp / 86400000, // Days
|
||||||
break;
|
DTCStorage[i].timestamp / 360000 % 24, // Hours
|
||||||
|
DTCStorage[i].timestamp / 60000 % 60, // Minutes
|
||||||
|
DTCStorage[i].timestamp / 1000 % 60, // Seconds
|
||||||
|
DTCStorage[i].timestamp % 1000); // milliseconds
|
||||||
|
|
||||||
case 'g':
|
if (DTCStorage[i].active == DTC_ACTIVE)
|
||||||
activeFaction = FACTION_1;
|
strcpy(buff_active, "active");
|
||||||
break;
|
else if (DTCStorage[i].active == DTC_PREVIOUS)
|
||||||
|
strcpy(buff_active, "previous");
|
||||||
|
else
|
||||||
|
strcpy(buff_active, "none");
|
||||||
|
|
||||||
case 'k':
|
debugA("%s \t %6d \t %s", buff_timestamp, DTCStorage[i].Number, buff_active);
|
||||||
activeFaction = FACTION_3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'm':
|
|
||||||
activeFaction = FACTION_2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'x':
|
|
||||||
SerialOutputTicker.stop();
|
|
||||||
Serial.println("SerialOutputTicker.stop()");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'y':
|
|
||||||
SerialOutputTicker.resume();
|
|
||||||
Serial.println("SerialOutputTicker.resume()");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
13
src/rmtdbghelp.h
Normal file
13
src/rmtdbghelp.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
const char helpCmd[] = "sysinfo - System Info\r\n"
|
||||||
|
"netinfo - WiFi Info\r\n"
|
||||||
|
"showdtc - Show all DTCs\r\n"
|
||||||
|
"cleardtc - Clear all DTCs\r\n"
|
||||||
|
"formatPDS - Format Persistence EEPROM Data\r\n"
|
||||||
|
"formatCFG - Format Configuration EEPROM Data\r\n"
|
||||||
|
"checkEE - Check EEPROM with checksum\r\n"
|
||||||
|
"dumpEE1k - dump the first 1kb of EEPROM to Serial\r\n"
|
||||||
|
"dumpEE - dump the whole EPPROM to Serial\r\n"
|
||||||
|
"resetPageEE - Reset the PersistenceData Page\r\n"
|
||||||
|
"dumpCFG - print Config struct\r\n"
|
||||||
|
"dumpPDS - print PersistanceStruct\r\n"
|
||||||
|
"saveEE - save EE-Data\r\n";
|
162
src/webui.cpp
Normal file
162
src/webui.cpp
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
#include "webui.h"
|
||||||
|
|
||||||
|
AsyncWebServer webServer(80);
|
||||||
|
|
||||||
|
const char *PARAM_MESSAGE = "message";
|
||||||
|
|
||||||
|
String processor(const String &var);
|
||||||
|
void WebserverPOST_Callback(AsyncWebServerRequest *request);
|
||||||
|
void WebserverNotFound_Callback(AsyncWebServerRequest *request);
|
||||||
|
void Webserver_Callback(AsyncWebServerRequest *request);
|
||||||
|
|
||||||
|
void initWebUI()
|
||||||
|
{
|
||||||
|
if (!LittleFS.begin())
|
||||||
|
{
|
||||||
|
Serial.println("An Error has occurred while mounting LittleFS");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
webServer.serveStatic("/static/", LittleFS, "/static/").setCacheControl("max-age=360000");
|
||||||
|
webServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
|
||||||
|
{ request->redirect("/index.htm"); });
|
||||||
|
webServer.onNotFound(WebserverNotFound_Callback);
|
||||||
|
webServer.on("/index.htm", HTTP_GET, Webserver_Callback);
|
||||||
|
webServer.on("/post.htm", HTTP_POST, WebserverPOST_Callback);
|
||||||
|
|
||||||
|
webServer.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
String processor(const String &var)
|
||||||
|
{
|
||||||
|
if (var == "SHOW_DTC_TABLE")
|
||||||
|
return globals.systemStatus == sysStat_Error ? "" : "hidden";
|
||||||
|
|
||||||
|
if (var == "BAT_REMAIN_CAPACITY")
|
||||||
|
return String(globals.battery_level);
|
||||||
|
|
||||||
|
if (var == "DEVICE_NAME")
|
||||||
|
return String(globals.DeviceName);
|
||||||
|
|
||||||
|
if (var == "BAT_VOLTAGE")
|
||||||
|
return String(globals.loadvoltage);
|
||||||
|
|
||||||
|
if (var == "DTC_TABLE")
|
||||||
|
{
|
||||||
|
String temp;
|
||||||
|
char buff_timestamp[16]; // Format: DD-hh:mm:ss:xxx
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < MAX_DTC_STORAGE; i++)
|
||||||
|
{
|
||||||
|
if (DTCStorage[i].Number > 0)
|
||||||
|
{
|
||||||
|
sprintf(buff_timestamp, "%02d-%02d:%02d:%02d:%03d",
|
||||||
|
DTCStorage[i].timestamp / 86400000, // Days
|
||||||
|
DTCStorage[i].timestamp / 360000 % 24, // Hours
|
||||||
|
DTCStorage[i].timestamp / 60000 % 60, // Minutes
|
||||||
|
DTCStorage[i].timestamp / 1000 % 60, // Seconds
|
||||||
|
DTCStorage[i].timestamp % 1000); // milliseconds
|
||||||
|
|
||||||
|
temp = "<tr><td>" + String(buff_timestamp);
|
||||||
|
temp = temp + "</td><td>" + String(DTCStorage[i].Number) + "</td><td>";
|
||||||
|
|
||||||
|
if (DTCStorage[i].active == DTC_ACTIVE)
|
||||||
|
temp = temp + "active";
|
||||||
|
else if (DTCStorage[i].active == DTC_PREVIOUS)
|
||||||
|
temp = temp + "previous";
|
||||||
|
else
|
||||||
|
temp = temp + "none";
|
||||||
|
|
||||||
|
temp = temp + "</td></tr>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var == "PLACEHOLDER")
|
||||||
|
return "placeholder";
|
||||||
|
|
||||||
|
if (var == "POINTS_FAC_1")
|
||||||
|
{
|
||||||
|
char buff[12];
|
||||||
|
snprintf(buff, 12, "%3d:%02d:%02d", PersistenceData.faction_1_timer / 3600, (PersistenceData.faction_1_timer / 60) % 60, PersistenceData.faction_1_timer % 60);
|
||||||
|
return String(buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var == "POINTS_FAC_2")
|
||||||
|
{
|
||||||
|
char buff[12];
|
||||||
|
snprintf(buff, 12, "%3d:%02d:%02d", PersistenceData.faction_2_timer / 3600, (PersistenceData.faction_2_timer / 60) % 60, PersistenceData.faction_2_timer % 60);
|
||||||
|
return String(buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var == "POINTS_FAC_3")
|
||||||
|
{
|
||||||
|
char buff[12];
|
||||||
|
snprintf(buff, 12, "%3d:%02d:%02d", PersistenceData.faction_3_timer / 3600, (PersistenceData.faction_3_timer / 60) % 60, PersistenceData.faction_3_timer % 60);
|
||||||
|
return String(buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var == "STATUS_FAC_1")
|
||||||
|
return PersistenceData.activeFaction == FACTION_1 ? "ACTIVE" : "INACTIVE";
|
||||||
|
|
||||||
|
if (var == "STATUS_FAC_2")
|
||||||
|
return PersistenceData.activeFaction == FACTION_2 ? "ACTIVE" : "INACTIVE";
|
||||||
|
|
||||||
|
if (var == "STATUS_FAC_3")
|
||||||
|
return PersistenceData.activeFaction == FACTION_3 ? "ACTIVE" : "INACTIVE";
|
||||||
|
|
||||||
|
if (var == "NAME_FAC_1")
|
||||||
|
return FACTION_1_NAME;
|
||||||
|
|
||||||
|
if (var == "NAME_FAC_2")
|
||||||
|
return FACTION_2_NAME;
|
||||||
|
|
||||||
|
if (var == "NAME_FAC_3")
|
||||||
|
return FACTION_3_NAME;
|
||||||
|
|
||||||
|
if (var == "TITLE")
|
||||||
|
return DEVICE_NAME;
|
||||||
|
|
||||||
|
if (var == "BATTERY_LEVEL")
|
||||||
|
{
|
||||||
|
return String(globals.battery_level);
|
||||||
|
}
|
||||||
|
if (var == "BATTERY_VOLTAGE")
|
||||||
|
{
|
||||||
|
return String(globals.loadvoltage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return String();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Webserver_Callback(AsyncWebServerRequest *request)
|
||||||
|
{
|
||||||
|
request->send(LittleFS, "/index.htm", "text/html", false, processor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebserverPOST_Callback(AsyncWebServerRequest *request)
|
||||||
|
{
|
||||||
|
request->send(LittleFS, "/post.htm", "text/html", false, processor);
|
||||||
|
|
||||||
|
Serial.print("POST:\n");
|
||||||
|
int paramsNr = request->params();
|
||||||
|
for (int i = 0; i < paramsNr; i++)
|
||||||
|
{
|
||||||
|
AsyncWebParameter *p = request->getParam(i);
|
||||||
|
Serial.printf("%s : %s\n", p->name().c_str(), p->value().c_str());
|
||||||
|
|
||||||
|
if (p->name() == "resetcount")
|
||||||
|
{
|
||||||
|
PersistenceData.faction_1_timer = 0;
|
||||||
|
PersistenceData.faction_2_timer = 0;
|
||||||
|
PersistenceData.faction_3_timer = 0;
|
||||||
|
globals.requestEEAction = EE_PDS_SAVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebserverNotFound_Callback(AsyncWebServerRequest *request)
|
||||||
|
{
|
||||||
|
request->send(404, "text/html", "Not found");
|
||||||
|
}
|
15
src/webui.h
Normal file
15
src/webui.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef _WEBUI_H_
|
||||||
|
#define _WEBUI_H_
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <FS.h>
|
||||||
|
#include <LittleFS.h>
|
||||||
|
#include <ESPAsyncTCP.h>
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include "config.h"
|
||||||
|
#include "globals.h"
|
||||||
|
#include "dtc.h"
|
||||||
|
|
||||||
|
void initWebUI();
|
||||||
|
|
||||||
|
#endif
|
5
wifi_credentials.example.ini
Normal file
5
wifi_credentials.example.ini
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[wifi_cred]
|
||||||
|
wifi_ap_password = wifiappass
|
||||||
|
wifi_ssid = wifi-ssid
|
||||||
|
wifi_password = wifi-pass
|
||||||
|
admin_password = ota-password
|
5
wifi_credentials.ini
Normal file
5
wifi_credentials.ini
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[wifi_cred]
|
||||||
|
wifi_ap_password = ilovekggmorethangof
|
||||||
|
admin_password = i_am_dr.hiabuto
|
||||||
|
wifi_ssid = BND_Scanner_#42
|
||||||
|
wifi_password = 5xMYkerbLMdrsSdF3hpy5DM9
|
Loading…
x
Reference in New Issue
Block a user