state machine (part 1)

This commit is contained in:
Klaus K Wilting 2018-04-17 18:08:47 +02:00
parent e69c911586
commit 688d0993af
4 changed files with 204 additions and 166 deletions

View File

@ -44,7 +44,7 @@ typedef struct {
extern configData_t cfg; extern configData_t cfg;
extern uint8_t mydata[]; extern uint8_t mydata[];
extern uint64_t uptimecounter; extern uint64_t currentMillis ;
extern osjob_t sendjob; extern osjob_t sendjob;
extern char display_lora[], display_lmic[]; extern char display_lora[], display_lmic[];
extern int countermode, screensaver, adrmode, lorasf, txpower, rlim; extern int countermode, screensaver, adrmode, lorasf, txpower, rlim;

View File

@ -13,9 +13,6 @@
// Local logging Tag // Local logging Tag
static const char *TAG = "lorawan"; static const char *TAG = "lorawan";
// function defined in main.cpp
void set_onboard_led(int state);
// functions defined in rcommand.cpp // functions defined in rcommand.cpp
void rcommand(int cmd, int arg); void rcommand(int cmd, int arg);
void switch_lora(int sf, int tx); void switch_lora(int sf, int tx);

View File

@ -47,8 +47,10 @@ osjob_t sendjob, initjob; // LMIC
char display_lora[16], display_lmic[16]; char display_lora[16], display_lmic[16];
uint8_t channel = 0; uint8_t channel = 0;
int macnum = 0; int macnum = 0;
uint64_t uptimecounter = 0; uint64_t currentMillis = 0, previousLEDmillis = 0, previousDisplaymillis = 0;
bool joinstate = false; bool joinstate = false;
uint8_t DisplayState, LEDState;
uint16_t LEDBlinkduration = 500, LEDInterval = 1000, color = COLOR_NONE;
std::set<uint16_t> macs; // associative container holds total of unique MAC adress hashes (Wifi + BLE) std::set<uint16_t> macs; // associative container holds total of unique MAC adress hashes (Wifi + BLE)
std::set<uint16_t> wifis; // associative container holds unique Wifi MAC adress hashes std::set<uint16_t> wifis; // associative container holds unique Wifi MAC adress hashes
@ -77,10 +79,6 @@ void eraseConfig(void);
void saveConfig(void); void saveConfig(void);
void loadConfig(void); void loadConfig(void);
#ifdef HAS_LED
void set_onboard_led(int st);
#endif
/* begin LMIC specific parts ------------------------------------------------------------ */ /* begin LMIC specific parts ------------------------------------------------------------ */
// defined in lorawan.cpp // defined in lorawan.cpp
@ -151,46 +149,35 @@ static void lora_init (osjob_t* j) {
void lorawan_loop(void * pvParameters) { void lorawan_loop(void * pvParameters) {
configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check
static bool led_state;
bool new_led_state;
while(1) { while(1) {
uint16_t color;
os_runloop_once(); os_runloop_once();
// All follow is Led management // LED management for viusalizing LoRaWAN state
// Let join at the begining of if sequence,
// is prior to send because joining state send data
if ( LMIC.opmode & (OP_JOINING | OP_REJOIN) ) { if ( LMIC.opmode & (OP_JOINING | OP_REJOIN) ) {
color = COLOR_YELLOW;
// quick blink 20ms on each 1/5 second // quick blink 20ms on each 1/5 second
new_led_state = ((millis() % 200) < 20) ? HIGH : LOW; color = COLOR_YELLOW;
LEDBlinkduration = 20;
LEDInterval = 200;
LEDState = 1;
// TX data pending // TX data pending
} else if (LMIC.opmode & (OP_TXDATA | OP_TXRXPEND)) { } else if (LMIC.opmode & (OP_TXDATA | OP_TXRXPEND)) {
color = COLOR_BLUE;
// small blink 10ms on each 1/2sec (not when joining) // small blink 10ms on each 1/2sec (not when joining)
new_led_state = ((millis() % 500) < 20) ? HIGH : LOW; color = COLOR_BLUE;
LEDBlinkduration = 10;
LEDInterval = 500;
LEDState =1;
// This should not happen so indicate a problem // This should not happen so indicate a problem
} else if ( LMIC.opmode & (OP_TXDATA | OP_TXRXPEND | OP_JOINING | OP_REJOIN) == 0 ) { } else if ( LMIC.opmode & (OP_TXDATA | OP_TXRXPEND | OP_JOINING | OP_REJOIN) == 0 ) {
color = COLOR_RED;
// heartbeat long blink 200ms on each 2 seconds // heartbeat long blink 200ms on each 2 seconds
new_led_state = ((millis() % 2000) < 200) ? HIGH : LOW; color = COLOR_RED;
LEDBlinkduration = 200;
LEDInterval = 2000;
LEDState = 1;
} else { } else {
// led off // led off
rgb_set_color(COLOR_NONE); color = COLOR_NONE;
} LEDState = 0;
// led need to change state? avoid digitalWrite() for nothing
if (led_state != new_led_state) {
if (new_led_state == HIGH) {
set_onboard_led(1);
rgb_set_color(color);
} else {
set_onboard_led(0);
rgb_set_color(COLOR_NONE);
}
led_state = new_led_state;
} }
vTaskDelay(10/portTICK_PERIOD_MS); vTaskDelay(10/portTICK_PERIOD_MS);
@ -218,21 +205,6 @@ void lorawan_loop(void * pvParameters) {
bool btstop = btStop(); bool btstop = btStop();
#endif #endif
void set_onboard_led(int st){
#ifdef HAS_LED
switch (st) {
#ifdef LED_ACTIVE_LOW
case 1: digitalWrite(HAS_LED, LOW); break;
case 0: digitalWrite(HAS_LED, HIGH); break;
#else
case 1: digitalWrite(HAS_LED, HIGH); break;
case 0: digitalWrite(HAS_LED, LOW); break;
#endif
}
#endif
};
#ifdef HAS_BUTTON #ifdef HAS_BUTTON
// Button Handling, board dependent -> perhaps to be moved to hal/<$board.h> // Button Handling, board dependent -> perhaps to be moved to hal/<$board.h>
// IRAM_ATTR necessary here, see https://github.com/espressif/arduino-esp32/issues/855 // IRAM_ATTR necessary here, see https://github.com/espressif/arduino-esp32/issues/855
@ -304,15 +276,6 @@ void sniffer_loop(void * pvParameters) {
} }
sprintf(display_lora, " "); // clear LoRa wait message fromd display sprintf(display_lora, " "); // clear LoRa wait message fromd display
/*
// TBD: need to check if long 2000ms pause causes stack problems while scanning continues
if (cfg.screenon && cfg.screensaver) {
vTaskDelay(2000/portTICK_PERIOD_MS); // pause for displaying results
yield();
u8x8.setPowerSave(1 && cfg.screensaver); // set display off if screensaver is enabled
}
*/
} // end of send data cycle } // end of send data cycle
} // end of infinite wifi channel rotation loop } // end of infinite wifi channel rotation loop
@ -330,6 +293,7 @@ uint64_t uptime() {
} }
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
// Print a key on display // Print a key on display
void DisplayKey(const uint8_t * key, uint8_t len, bool lsb) { void DisplayKey(const uint8_t * key, uint8_t len, bool lsb) {
uint8_t start=lsb?len:0; uint8_t start=lsb?len:0;
@ -390,8 +354,104 @@ void init_display(const char *Productname, const char *Version) {
delay(5000); delay(5000);
u8x8.clear(); u8x8.clear();
} }
void refreshDisplay() {
// update counter display (lines 0-4)
char buff[16];
snprintf(buff, sizeof(buff), "PAX:%-4d", (int) macs.size()); // convert 16-bit MAC counter to decimal counter value
u8x8.draw2x2String(0, 0, buff); // display number on unique macs total Wifi + BLE
u8x8.setCursor(0,4);
u8x8.printf("WIFI: %-4d", (int) wifis.size());
#ifdef BLECOUNTER
u8x8.setCursor(0,3);
if (cfg.blescan)
u8x8.printf("BLTH: %-4d", (int) bles.size());
else
u8x8.printf("%-16s", "BLTH: off");
#endif
// update wifi channel display (line 4)
u8x8.setCursor(11,4);
u8x8.printf("ch:%02i", channel);
// update RSSI limiter status display (line 5)
u8x8.setCursor(0,5);
u8x8.printf(!cfg.rssilimit ? "RLIM: off" : "RLIM: %-4d", cfg.rssilimit);
// update LoRa status display (line 6)
u8x8.setCursor(0,6);
u8x8.printf("%-16s", display_lora);
// update LMiC event display (line 7)
u8x8.setCursor(0,7);
u8x8.printf("%-16s", display_lmic);
}
void updateDisplay() {
// timed display refresh according to frames per second setting
if (currentMillis - previousDisplaymillis >= ( 1 / DISPLAYFPS * (1000/portTICK_PERIOD_MS))) {
refreshDisplay();
previousDisplaymillis += ( 1 / DISPLAYFPS * (1000/portTICK_PERIOD_MS));
}
// set display on/off according to current device configuration
if (DisplayState != cfg.screenon) {
DisplayState = cfg.screenon;
u8x8.setPowerSave(!cfg.screenon);
}
} // updateDisplay()
#endif // HAS_DISPLAY #endif // HAS_DISPLAY
#ifdef HAS_BUTTON
void readButton() {
if (ButtonTriggered) {
ButtonTriggered = false;
ESP_LOGI(TAG, "Button pressed, resetting device to factory defaults");
eraseConfig();
esp_restart();
}
}
#endif
#ifdef HAS_LED
void updateLEDstatus() {
if (LEDState == LOW) {
if (currentMillis - previousLEDmillis >= LEDInterval) {
LEDState = HIGH;
previousLEDmillis += LEDInterval;
}
}
else {
if (currentMillis - previousLEDmillis >= LEDBlinkduration) {
LEDState = LOW;
previousLEDmillis += LEDBlinkduration;
}
}
}; // updateLEDstatus()
void refreshLED() {
static bool previousLEDState;
// led need to change state? avoid digitalWrite() for nothing
if (LEDState != previousLEDState) {
#ifdef LED_ACTIVE_LOW
digitalWrite(HAS_LED, LEDState);
#else
digitalWrite(HAS_LED, !LEDState);
#endif
#ifdef HAS_RGB_LED
rgb_set_color(color);
#endif
previousLEDState = LEDState;
}
}; // refreshLED()
#endif
/* begin Aruino SETUP ------------------------------------------------------------ */ /* begin Aruino SETUP ------------------------------------------------------------ */
void setup() { void setup() {
@ -436,8 +496,17 @@ void setup() {
// initialize led if needed // initialize led if needed
#ifdef HAS_LED #ifdef HAS_LED
LEDState = 0;
color = COLOR_NONE;
pinMode(HAS_LED, OUTPUT); pinMode(HAS_LED, OUTPUT);
digitalWrite(HAS_LED, LOW); #ifdef LED_ACTIVE_LOW
digitalWrite(HAS_LED, LEDState);
#else
digitalWrite(HAS_LED, !LEDState);
#endif
#ifdef HAS_RBG_LED
rgb_set_color (color);
#endif
#endif #endif
// initialize button handling if needed // initialize button handling if needed
@ -461,6 +530,7 @@ void setup() {
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
// initialize display // initialize display
init_display(PROGNAME, PROGVERSION); init_display(PROGNAME, PROGVERSION);
DisplayState = cfg.screenon;
u8x8.setPowerSave(!cfg.screenon); // set display off if disabled u8x8.setPowerSave(!cfg.screenon); // set display off if disabled
u8x8.draw2x2String(0, 0, "PAX:0"); u8x8.draw2x2String(0, 0, "PAX:0");
u8x8.setCursor(0,4); u8x8.setCursor(0,4);
@ -513,55 +583,26 @@ do_send(&sendjob);
// https://techtutorialsx.com/2017/05/09/esp32-get-task-execution-core/ // https://techtutorialsx.com/2017/05/09/esp32-get-task-execution-core/
void loop() { void loop() {
uptimecounter = uptime() / 1000; // count uptime seconds // state machine for central control of all timimg based features
#ifdef HAS_BUTTON // ...then check if pressed currentMillis = uptime() / 1000; // count uptime seconds
if (ButtonTriggered) {
ButtonTriggered = false; #ifdef HAS_BUTTON
ESP_LOGI(TAG, "Button pressed, resetting device to factory defaults"); readButton();
eraseConfig();
esp_restart();
}
#endif #endif
#ifdef HAS_DISPLAY // ...then update mask #ifdef HAS_DISPLAY
updateDisplay();
// set display on/off according to current device configuration
u8x8.setPowerSave(!cfg.screenon);
// update counter display (lines 0-4)
char buff[16];
snprintf(buff, sizeof(buff), "PAX:%-4d", (int) macs.size()); // convert 16-bit MAC counter to decimal counter value
u8x8.draw2x2String(0, 0, buff); // display number on unique macs total Wifi + BLE
u8x8.setCursor(0,4);
u8x8.printf("WIFI: %-4d", (int) wifis.size());
#ifdef BLECOUNTER
u8x8.setCursor(0,3);
if (cfg.blescan)
u8x8.printf("BLTH: %-4d", (int) bles.size());
else
u8x8.printf("%-16s", "BLTH: off");
#endif #endif
// update wifi channel display (line 4) #ifdef HAS_LED
u8x8.setCursor(11,4); updateLEDstatus();
u8x8.printf("ch:%02i", channel); refreshLED();
// update RSSI limiter status display (line 5)
u8x8.setCursor(0,5);
u8x8.printf(!cfg.rssilimit ? "RLIM: off" : "RLIM: %-4d", cfg.rssilimit);
// update LoRa status display (line 6)
u8x8.setCursor(0,6);
u8x8.printf("%-16s", display_lora);
// update LMiC event display (line 7)
u8x8.setCursor(0,7);
u8x8.printf("%-16s", display_lmic);
#endif #endif
vTaskDelay(1000/DISPLAYFPS/portTICK_PERIOD_MS); //sendPayload();
} }

View File

@ -210,9 +210,9 @@ void get_config (int val) {
void get_uptime (int val) { void get_uptime (int val) {
ESP_LOGI(TAG, "Remote command: get uptime"); ESP_LOGI(TAG, "Remote command: get uptime");
int size = sizeof(uptimecounter); int size = sizeof(currentMillis );
unsigned char *sendData = new unsigned char[size]; unsigned char *sendData = new unsigned char[size];
memcpy(sendData, (unsigned char*)&uptimecounter, size); memcpy(sendData, (unsigned char*)&currentMillis , size);
LMIC_setTxData2(RCMDPORT, sendData, size-1, 0); // send data unconfirmed on RCMD Port LMIC_setTxData2(RCMDPORT, sendData, size-1, 0); // send data unconfirmed on RCMD Port
delete sendData; // free memory delete sendData; // free memory
ESP_LOGI(TAG, "%i bytes queued in send queue", size-1); ESP_LOGI(TAG, "%i bytes queued in send queue", size-1);