first draft for dashboard and global status
This commit is contained in:
parent
1329190b41
commit
2a3445b9bb
2104
esp8266-RM370-interrupt/Schematic_RM370_2021-01-24.pdf
Normal file
2104
esp8266-RM370-interrupt/Schematic_RM370_2021-01-24.pdf
Normal file
File diff suppressed because it is too large
Load Diff
@ -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';
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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]);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user