first draft for dashboard and global status

This commit is contained in:
coelner 2021-06-17 15:15:37 +02:00
parent 1329190b41
commit 2a3445b9bb
5 changed files with 2264 additions and 92 deletions

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@ bool initCommunication() {
}
WifiEspNowBroadcast.onReceive(processRx, nullptr);
LOG("MAC address of this node is %s", WiFi.softAPmacAddress().c_str());
WiFi.softAPmacAddress(ownState.originMAC);
return true;
}
@ -16,7 +17,7 @@ ICACHE_RAM_ATTR void processRx(const uint8_t mac[6], const uint8_t* buf, size_t
}
else
{
receiveBuffer[rxCounter] = *(rm370*)buf;
receiveBuffer[rxCounter] = *(rm370*)buf; //ToDo check if it breaks anything
//shift ring buffer input pointer
if (rxCounter + 1 < MAX_PEERS) {
rxCounter++;
@ -25,7 +26,7 @@ ICACHE_RAM_ATTR void processRx(const uint8_t mac[6], const uint8_t* buf, size_t
rxCounter = 0;
}
}
LOG("Message from %02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
LOG("[%02d] Message from %02X:%02X:%02X:%02X:%02X:%02X", rxCounter, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
void checkMessage() {
@ -34,11 +35,6 @@ void checkMessage() {
byte loopPointer = (rxCounter + 1 < MAX_PEERS) ? (rxCounter + 1) : 0;
while (loopPointer != rxHandlePointer)
{
int ret = memcmp(receiveBuffer[loopPointer].messageID, receiveBuffer[rxHandlePointer].messageID, sizeof(receiveBuffer[rxHandlePointer].messageID));
if (ret == 0) {
DEBUGLOG("already processed message");
return;
}
//shift ring buffer working pointer
if (loopPointer + 1 < MAX_PEERS) {
loopPointer++;
@ -46,38 +42,57 @@ void checkMessage() {
else {
loopPointer = 0;
}
}
//check against our own state
int ret = memcmp(ownState.messageID, receiveBuffer[rxHandlePointer].messageID, sizeof(ownState.messageID));
}//Todo wrong bracket placement?
//check against our own state - could or should also be done by MAC
int ret = memcmp(&ownState.originMAC[0], &receiveBuffer[rxHandlePointer].originMAC[0], sizeof(receiveBuffer[rxHandlePointer].originMAC));
//int ret = memcmp(ownState.messageID, receiveBuffer[rxHandlePointer].messageID, sizeof(ownState.messageID));
if (ret == 0) {
DEBUGLOG("backloop message");
return;
}
else {
//copy latest messageID
memcpy(transmitBuffer.messageID, &receiveBuffer[rxHandlePointer].messageID, sizeof(transmitBuffer.messageID));
}
transmitBuffer = receiveBuffer[rxHandlePointer];
//copy latest messageID and origins MAC
//memcpy(transmitBuffer.messageID, &receiveBuffer[rxHandlePointer].messageID, sizeof(transmitBuffer.messageID));
//memcpy(transmitBuffer.batteryWarning, &receiveBuffer[rxHandlePointer].batteryWarning, sizeof(transmitBuffer.batteryWarning));
//memcpy(&transmitBuffer.originMAC[0], &receiveBuffer[rxHandlePointer].originMAC[0], sizeof(transmitBuffer.originMAC));
LOG("Origin MAC %02X:%02X:%02X:%02X:%02X:%02X",
transmitBuffer.originMAC[0],
transmitBuffer.originMAC[1],
transmitBuffer.originMAC[2],
transmitBuffer.originMAC[3],
transmitBuffer.originMAC[4],
transmitBuffer.originMAC[5]);
switch (receiveBuffer[rxHandlePointer].code) {
case 'r':
alarmTrigger = true;
warningTrigger = false;
transmitBuffer.code = 'r';
LOG("ALARM received");
LOG("\tALARM received");
break;
case 'y':
if (!alarmTrigger) {
warningTrigger = true;
LOG("WARNING received");
LOG("\tWARNING received");
}
else {
LOG("\tWARNING received - NOP");
}
transmitBuffer.code = 'y';
break;
case 'g':
transmitBuffer.code = 'g';
#if defined(GLOBAL_VERBOSE)
LOG("\tGREEN received - relay");
#endif
break;
default:
break;
}
}
}
else {
DEBUGLOG("Payload does not contain known preamble.");
}
@ -97,7 +112,9 @@ void sendMessage() {
for (int i = 0; i < nPeers; ++i) {
DEBUGLOG(" %02X:%02X:%02X:%02X:%02X:%02X", peers[i].mac[0], peers[i].mac[1], peers[i].mac[2], peers[i].mac[3], peers[i].mac[4], peers[i].mac[5]);
}
if (transmitBuffer.code == 'r' || transmitBuffer.code == 'y') {
globalStart = millis();
//clean state
transmitBuffer.code = 'g';
}
//clean state
transmitBuffer.code = 'X';
}

View File

@ -3,6 +3,8 @@
//#define DEBUGLOG(fmt, ...)
#define DEBUGLOG(fmt, ...) (Serial.printf("%09llu: [DEBUG] " fmt "\n", GetTimestamp(), ##__VA_ARGS__));
#define GLOBAL_VERBOSE 1//activate if the 'GREEN' status should be globally available
#define debounceDelay 1000 //LED shining duration
#define globalDelay 20000
#define alarmDelay 50
@ -21,12 +23,14 @@ const uint8_t key[16] = { 0 };
#include <WifiEspNowBroadcast.h> //https://github.com/yoursunny/WifiEspNow
#include <Ticker.h> //Ticker Library
//version 1.1 - added originMAC
typedef struct {
char PREAMBLE1 = 'R';
char PREAMBLE2 = 'M';
uint8_t messageID[20];
char code = 'g'; // [g, y, r]
char code = 'g'; // [g, y, r, X]
bool batteryWarning = false; //ToDo not implemented yet
uint8_t originMAC[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
} rm370;
@ -52,10 +56,9 @@ volatile unsigned long globalStart = 0; //real physics workaround
volatile unsigned long debounceStart = 0; //real physics workaround
volatile unsigned long nowMillis = millis(); //real physics workaround
volatile unsigned long lastADCRead = 0;
volatile byte rxCounter = 0;
volatile byte rxHandlePointer = 0;
volatile byte rxCounter = 0; //marker for the receive interrupt callback
volatile byte rxHandlePointer = 0; //marker for internal processing
//uint8_t broadcastMac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
int64_t GetTimestamp() {
struct timeval tv;
@ -73,10 +76,10 @@ void buzzerTone() {
void batteryCheck() {
int sensorValue = analogRead(BAT_Pin);
DEBUGLOG("[DEBUG] AnalogRead: %i",sensorValue);
DEBUGLOG("AnalogRead: %i", sensorValue);
lastADCRead = millis();
int voltage = map(sensorValue, 0, 1023, 0, 5000);
DEBUGLOG("[DEBUG] VoltageMap: %i mV",voltage);
DEBUGLOG("VoltageMap: %i mV", voltage);
if (voltage < 3000) {
ownState.batteryWarning = true;
}
@ -149,7 +152,9 @@ void setup() {
Serial.flush();
delay(1000);
LOG("\n\nInterrupt D7,D6,D5 with Serial.print");
#if defined(GLOBAL_VERBOSE)
LOG("\nGlobal verbose ACTIVE");
#endif
if (!initCommunication()) {
ESP.restart();
}
@ -176,11 +181,16 @@ void loop() {
if (ownState.code == 'y') {
DEBUGLOG("YELLOW LED");
}
//Todo check for code 'g'
if (!(ownState.code == 'r' || ownState.code == 'y')) {
DEBUGLOG("GREEN LED");
}
//send own status
#if defined(GLOBAL_VERBOSE)
if (ownState.code == 'r' || ownState.code == 'y' || ownState.code == 'g') {
#else
if (ownState.code == 'r' || ownState.code == 'y') {
#endif
//generate unique identifier
char messageIDString[65];
itoa(millis(), messageIDString, 10);
@ -202,13 +212,17 @@ void loop() {
rxHandlePointer = 0;
}
//forward received messages
#if defined(GLOBAL_VERBOSE)
if (transmitBuffer.code == 'r' || transmitBuffer.code == 'y' || transmitBuffer.code == 'g') {
#else
if (transmitBuffer.code == 'r' || transmitBuffer.code == 'y') {
#endif
sendMessage();
}
}
}
ICACHE_RAM_ATTR void IntREDCallback() {
if (!debounceTrigger) {
alarmTrigger = true;

View File

@ -10,16 +10,20 @@ bool initCommunication() {
return true;
}
/*
process wifi stack Rx interrupt
*/
ICACHE_RAM_ATTR void processRx(const uint8_t mac[6], const uint8_t* buf, size_t count, void* cbarg) {
if (count != sizeof(receiveBuffer[rxCounter].payload)) {
//simple frame size check
if (count != sizeof(receiveBuffer[rxCounter])) {
return;
}
else
{
memcpy(receiveBuffer[rxCounter].mac, &mac, sizeof(mac));
receiveBuffer[rxCounter].payload = *(rm370*)buf;
receiveBuffer[rxCounter] = *(rm370*)buf;
//memcpy(&receiveBuffer[rxCounter].originMAC[0], &mac, sizeof(receiveBuffer[rxCounter].originMAC)); //dont overwrite original package
//shift ring buffer input pointer
if (rxCounter < MAX_PEERS) {
if (rxCounter + 1 < MAX_PEERS) {
rxCounter++;
}
else {
@ -29,40 +33,43 @@ ICACHE_RAM_ATTR void processRx(const uint8_t mac[6], const uint8_t* buf, size_t
LOG("Message from %02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
/*
*/
void checkMessage() {
if (receiveBuffer[rxHandlePointer].payload.PREAMBLE1 == 'R' && receiveBuffer[rxHandlePointer].payload.PREAMBLE2 == 'M') {
switch (receiveBuffer[rxHandlePointer].payload.code) {
if (receiveBuffer[rxHandlePointer].PREAMBLE1 == 'R' && receiveBuffer[rxHandlePointer].PREAMBLE2 == 'M') {
LOG("Origin MAC %02X:%02X:%02X:%02X:%02X:%02X || \tStatus: %c | BatWarn: %c",
receiveBuffer[rxHandlePointer].originMAC[0],
receiveBuffer[rxHandlePointer].originMAC[1],
receiveBuffer[rxHandlePointer].originMAC[2],
receiveBuffer[rxHandlePointer].originMAC[3],
receiveBuffer[rxHandlePointer].originMAC[4],
receiveBuffer[rxHandlePointer].originMAC[5],
receiveBuffer[rxHandlePointer].code,
(receiveBuffer[rxHandlePointer].batteryWarning) ? '!' : '.');
switch (receiveBuffer[rxHandlePointer].code) {
case 'r':
//LOG("\tALARM received");
break;
case 'y':
//LOG("\tWARNING received");
break;
case 'g':
//LOG("\tGREEN received");
break;
default:
break;
}
if (receiveBuffer[rxHandlePointer].payload.batteryWarning == true) {
if (receiveBuffer[rxHandlePointer].batteryWarning == true) {
//LOG("\tBAT Warning received");
}
refreshGlobalStatus = true;
}
else {
DEBUGLOG("Payload does not contain known preamble.");
}
}
void sendMessage() {
/*
uint8_t transmitBuf[sizeof(transmitBuffer)];
//copy buffer
memcpy(transmitBuf, &transmitBuffer, sizeof(transmitBuffer));
WifiEspNowBroadcast.send(transmitBuf, sizeof(transmitBuf));
DEBUGLOG("Sending message: %c", transmitBuffer.code);
//EXPLAINATION WifiEspNow Broadcast
DEBUGLOG("Recipients:");
WifiEspNowPeerInfo peers[MAX_PEERS];
int nPeers = std::min(WifiEspNow.listPeers(peers, MAX_PEERS), MAX_PEERS);
for (int i = 0; i < nPeers; ++i) {
DEBUGLOG(" %02X:%02X:%02X:%02X:%02X:%02X", peers[i].mac[0], peers[i].mac[1], peers[i].mac[2], peers[i].mac[3], peers[i].mac[4], peers[i].mac[5]);
}
*/
}

View File

@ -17,32 +17,24 @@ const uint8_t key[16] = {0};
#include <Ticker.h> //Ticker Library
//the sended message over the ether
typedef struct {
char PREAMBLE1 = 'R';
char PREAMBLE2 = 'M';
uint8_t messageID[20];
char code = 'g'; // [g, y, r]
bool batteryWarning = false; //ToDo not implemented yet
uint8_t originMAC[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
} rm370;
typedef struct {
uint8_t mac[6];
rm370 payload;
} rm370_message;
typedef struct {
rm370_message* lastMessage;
char identifier[20];
} node;
rm370_message receiveBuffer[MAX_PEERS];
rm370 receiveBuffer[MAX_PEERS];
Ticker globalStatusTicker;
volatile unsigned long globalStart = 0; //real physics workaround
volatile unsigned long now = millis(); //real physics workaround
volatile byte rxCounter = 0;
volatile byte rxHandlePointer = 0;
//uint8_t broadcastMac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
volatile bool refreshGlobalStatus = false;
int64_t GetTimestamp() {
struct timeval tv;
@ -51,17 +43,55 @@ int64_t GetTimestamp() {
}
void globalStatus() {
/*
print global overview
battery warning
ToDo:
last message time stamp --> see following task
show missing stations --> new structure needed
*/
if (!refreshGlobalStatus) {
return;
}
DEBUGLOG("available Peers:");
WifiEspNowPeerInfo peers[MAX_PEERS];
int nPeers = std::min(WifiEspNow.listPeers(peers, MAX_PEERS), MAX_PEERS);
byte loopPointer = (rxCounter - 1 >= 0) ? (rxCounter - 1) : MAX_PEERS - 1;
byte lastLoopPointer = rxCounter;
for (int i = 0; i < nPeers; ++i) {
LOG(" %02X:%02X:%02X:%02X:%02X:%02X", peers[i].mac[0], peers[i].mac[1], peers[i].mac[2], peers[i].mac[3], peers[i].mac[4], peers[i].mac[5]);
//walk backwards through the buffer to get the latest message
while (loopPointer != lastLoopPointer)
{
//DEBUGLOG("lastLoopPointer | loopPointer: %d|%d", lastLoopCounter, loopPointer);
int ret = memcmp(&receiveBuffer[loopPointer].originMAC[0], &peers[i].mac, sizeof(receiveBuffer[loopPointer].originMAC));
if (ret == 0) {
LOG("\tStatus: %c | BatWarn: %c", receiveBuffer[loopPointer].code, (receiveBuffer[loopPointer].batteryWarning) ? '!' : '.');
lastLoopPointer = loopPointer;
break;
}
if (loopPointer - 1 >= 0) {
loopPointer--;
}
else {
loopPointer = MAX_PEERS - 1;
}
}
}
refreshGlobalStatus = false;
}
void setup() {
Serial.begin(115200);
Serial.flush();
delay(1000);
LOG("\n\nwith Serial.print");
LOG("\n\nDashboard with Serial.print");
if (!initCommunication()) {
ESP.restart();
}
globalStatusTicker.attach(1.0, globalStatus);
LOG("Setup completed.\n");
}
@ -69,14 +99,14 @@ void loop() {
//loop things
now = millis();
WifiEspNowBroadcast.loop();
globalStatus();
//process remaining rxBuffer
while (rxHandlePointer != rxCounter)
{
checkMessage();
//shift ring buffer working pointer
if (rxHandlePointer < MAX_PEERS) {
if (rxHandlePointer + 1 < MAX_PEERS) {
rxHandlePointer++;
}
else {