diff --git a/src/main.cpp b/src/main.cpp index fe67a55e..71b7ad81 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -41,14 +41,18 @@ Refer to LICENSE.txt file in repository for more details. configData_t cfg; // struct holds current device configuration osjob_t sendjob, initjob; // LMIC jobs uint64_t uptimecounter = 0; // timer global for uptime counter -uint32_t currentMillis = millis(); // timer global for state machine -uint32_t previousDisplaymillis = currentMillis; // Display refresh for state machine +unsigned long currentMillis = millis(); // timer global for state machine +unsigned long previousDisplaymillis = currentMillis; // Display refresh for state machine uint8_t DisplayState = 0; // globals for state machine -uint16_t LEDBlinkduration = 0, LEDInterval = 0, color = COLOR_NONE; // state machine variables uint16_t macs_total = 0, macs_wifi = 0, macs_ble = 0; // MAC counters globals for display uint8_t channel = 0; // wifi channel rotation counter global for display char display_lora[16], display_lmic[16], display_mem[16]; // display buffers -enum states LEDState = LED_OFF, previousLEDState = LED_OFF; // LED state global for state machine +led_states LEDState = LED_OFF; // LED state global for state machine +led_states previousLEDState = LED_ON; // This will force LED to be off at boot since State is OFF +unsigned long LEDBlinkSarted = 0; // When (in millis() led blink started) +uint16_t LEDBlinkDuration = 0; // How long the blink need to be +//uint16_t LEDBlinkduration = 0, LEDInterval = 0, color = COLOR_NONE; // state machine variables +uint16_t LEDColor = COLOR_NONE; // state machine variables bool joinstate = false; // LoRa network joined? global flag bool blinkdone = true; // flag for state machine for blinking LED once const uint32_t heapmem = ESP.getFreeHeap(); // free heap memory after start (:= 100%) @@ -70,13 +74,6 @@ int redirect_log(const char * fmt, va_list args) { } #endif -void blink_LED (uint16_t set_color, uint16_t set_blinkduration, uint16_t set_interval) { - color = set_color; // set color for RGB LED - LEDBlinkduration = set_blinkduration; // duration on - LEDInterval = set_interval; // duration off - on - off - blinkdone = false; -} - void reset_counters() { macs.clear(); // clear all macs container macs_total = 0; // reset all counters @@ -150,22 +147,9 @@ void lorawan_loop(void * pvParameters) { os_runloop_once(); - // LED indicators for viusalizing LoRaWAN state - if ( LMIC.opmode & (OP_JOINING | OP_REJOIN) ) { - // quick blink 20ms on each 1/5 second while joining - blink_LED(COLOR_YELLOW, 20, 200); - // TX data pending - } else if (LMIC.opmode & (OP_TXDATA | OP_TXRXPEND)) { - // small blink 10ms on each 1/2sec (not when joining) - blink_LED(COLOR_BLUE, 10, 500); - // This should not happen so indicate a problem - } else if ( LMIC.opmode & (OP_TXDATA | OP_TXRXPEND | OP_JOINING | OP_REJOIN) == 0 ) { - // heartbeat long blink 200ms on each 2 seconds - blink_LED(COLOR_RED, 200, 2000); - } else { - // led off - blink_LED(COLOR_NONE, 0, 0); - } + #if (HAS_LED != NOT_A_PIN) || defined (HAS_RGB_LED) + led_loop(); + #endif vTaskDelay(10/portTICK_PERIOD_MS); yield(); @@ -393,44 +377,85 @@ uint64_t uptime() { } #endif -#ifdef HAS_LED - void switchLED() { - - // 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 +#if (HAS_LED != NOT_A_PIN) || defined (HAS_RGB_LED) + void blink_LED(uint16_t set_color, uint16_t set_blinkduration) { + LEDColor = set_color; // set color for RGB LED + LEDBlinkDuration = set_blinkduration; // duration + LEDBlinkSarted = millis(); // Time Start here + LEDState = LED_ON; // Let main set LED on + } - #ifdef HAS_RGB_LED - rgb_set_color(LEDState ? color : COLOR_NONE); - #endif + void led_loop() { + // Custom blink running always have priority other LoRaWAN led management + if ( LEDBlinkSarted && LEDBlinkDuration) { - previousLEDState = LEDState; - blinkdone = LEDState ? false : true; // if LED was turned off, a blink was done + //ESP_LOGI(TAG, "Start=%ld for %g",LEDBlinkSarted, LEDBlinkDuration ); + + // Custom blink is finished, let this order, avoid millis() overflow + if ( (millis() - LEDBlinkSarted) >= LEDBlinkDuration) { + // Led besomes off, and stop blink + LEDState = LED_OFF; + LEDBlinkSarted = 0; + LEDBlinkDuration = 0; + LEDColor = COLOR_NONE ; + } else { + // In case of LoRaWAN led management blinked off + LEDState = LED_ON; + } + + // No custom blink, check LoRaWAN state + } else { + + // LED indicators for viusalizing LoRaWAN state + if ( LMIC.opmode & (OP_JOINING | OP_REJOIN) ) { + LEDColor = COLOR_YELLOW; + // quick blink 20ms on each 1/5 second + LEDState = ((millis() % 200) < 20) ? LED_ON : LED_OFF; // TX data pending + } else if (LMIC.opmode & (OP_TXDATA | OP_TXRXPEND)) { + LEDColor = COLOR_BLUE; + // small blink 10ms on each 1/2sec (not when joining) + LEDState = ((millis() % 500) < 20) ? LED_ON : LED_OFF; + // This should not happen so indicate a problem + } else if ( LMIC.opmode & (OP_TXDATA | OP_TXRXPEND | OP_JOINING | OP_REJOIN) == 0 ) { + LEDColor = COLOR_RED; + // heartbeat long blink 200ms on each 2 seconds + LEDState = ((millis() % 2000) < 200) ? LED_ON : LED_OFF; + } else { + // led off + LEDColor = COLOR_NONE; + LEDState = LED_OFF; + } } - }; // switchLED() + //ESP_LOGI(TAG, "state=%d previous=%d Color=%d",LEDState, previousLEDState, LEDColor ); + // led need to change state? avoid digitalWrite() for nothing + if (LEDState != previousLEDState) { + if (LEDState == LED_ON) { + rgb_set_color(LEDColor); + #ifdef LED_ACTIVE_LOW + digitalWrite(HAS_LED, LOW); + #else + digitalWrite(HAS_LED, HIGH); + #endif + } else { + rgb_set_color(COLOR_NONE); + #ifdef LED_ACTIVE_LOW + digitalWrite(HAS_LED, HIGH); + #else + digitalWrite(HAS_LED, LOW); + #endif + } + previousLEDState = LEDState; + } + }; // led_loop() - void switchLEDstate() { - - if (LEDInterval) // LED is blinking, wait until time elapsed, then toggle LED - LEDState = ((currentMillis % LEDInterval) < LEDBlinkduration) ? LED_ON : LED_OFF; - - else // check if in oneblink mode - - if (!blinkdone) // keep LED on until one blink is done - LEDState = (currentMillis % LEDBlinkduration) > 0 ? LED_ON : LED_OFF; - - } // switchLEDstate() -#endif + #endif /* begin Aruino SETUP ------------------------------------------------------------ */ void setup() { + char features[64] = ""; // disable brownout detection #ifdef DISABLE_BROWNOUT @@ -470,18 +495,28 @@ void setup() { loadConfig(); // includes initialize if necessary // initialize led if needed -#ifdef HAS_LED +#if (HAS_LED != NOT_A_PIN) pinMode(HAS_LED, OUTPUT); - blink_LED(COLOR_NONE, 0, 0); // LED off + strcat(features, " LED"); #endif +#ifdef HAS_RGB_LED + rgb_set_color(COLOR_PINK); + strcat(features, " RGB"); + delay(1000); +#endif + + // initialize button handling if needed #ifdef HAS_BUTTON + strcat(features, " BTN_"); #ifdef BUTTON_PULLUP + strcat(features, "PU"); // install button interrupt (pullup mode) pinMode(HAS_BUTTON, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), isr_button_pressed, RISING); #else + strcat(features, "PD"); // install button interrupt (pulldown mode) pinMode(HAS_BUTTON, INPUT_PULLDOWN); attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), isr_button_pressed, FALLING); @@ -490,11 +525,13 @@ void setup() { // initialize wifi antenna if needed #ifdef HAS_ANTENNA_SWITCH + strcat(features, " ANT"); antenna_init(); #endif #ifdef HAS_DISPLAY -// initialize display + strcat(features, " OLED"); + // initialize display init_display(PROGNAME, PROGVERSION); DisplayState = cfg.screenon; u8x8.setPowerSave(!cfg.screenon); // set display off if disabled @@ -511,6 +548,9 @@ void setup() { sprintf(display_lora, "Join wait"); #endif +// Display features compiled for +ESP_LOGI(TAG, "Features %s", features); + // output LoRaWAN keys to console #ifdef VERBOSE printKeys(); @@ -553,15 +593,13 @@ do_send(&sendjob); void loop() { // simple state machine for controlling display, LED, button, etc. - uptimecounter = uptime() / 1000; // counts uptime in seconds (64bit) currentMillis = millis(); // timebase for state machine in milliseconds (32bit) - - #ifdef HAS_LED - switchLEDstate(); - switchLED(); - #endif + #if (HAS_LED != NOT_A_PIN) || defined (HAS_RGB_LED) + led_loop(); + #endif + #ifdef HAS_BUTTON readButton(); #endif diff --git a/src/main.h b/src/main.h index 438d70cd..8e6a7445 100644 --- a/src/main.h +++ b/src/main.h @@ -5,7 +5,7 @@ //--- Declarations --- -enum states { +enum led_states { LED_OFF, LED_ON }; @@ -13,8 +13,10 @@ enum states { //--- Prototypes --- // defined in main.cpp -void blink_LED (uint16_t set_color, uint16_t set_blinkduration, uint16_t set_interval); void reset_counters(); +void reset_counters(void); +void blink_LED(uint16_t set_color, uint16_t set_blinkduration); +void led_loop(void); // defined in configmanager.cpp void eraseConfig(void); @@ -35,6 +37,3 @@ void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); // defined in blescan.cpp void bt_loop(void *ignore); - -// defined in main.cpp -void reset_counters(void); \ No newline at end of file