diff --git a/lib/U8g2_ID942-tweaked/src/clib/u8x8_d_ssd1306_128x64_noname.c b/lib/U8g2_ID942-tweaked/src/clib/u8x8_d_ssd1306_128x64_noname.c index 671aa04c..09b16ab5 100644 --- a/lib/U8g2_ID942-tweaked/src/clib/u8x8_d_ssd1306_128x64_noname.c +++ b/lib/U8g2_ID942-tweaked/src/clib/u8x8_d_ssd1306_128x64_noname.c @@ -298,7 +298,7 @@ static const u8x8_display_info_t u8x8_ssd1306_128x64_noname_display_info = /* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */ /* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ /* spi_mode = */ 0, /* active high, rising edge */ - /* i2c_bus_clock_100kHz = */ 1, + /* ==> i2c_bus_clock_100kHz = */ 4, /* data_setup_time_ns = */ 40, /* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */ /* tile_width = */ 16, diff --git a/platformio.ini b/platformio.ini index 98b73fc2..ee8b6a34 100644 --- a/platformio.ini +++ b/platformio.ini @@ -19,24 +19,22 @@ env_default = heltec ;env_default = lopy ;env_default = lopy4 ;env_default = fipy -;env_default = lolin32lite -;env_default = lolin32 +;env_default = lolin32litelora +;env_default = lolin32lora ; description = Paxcounter is a proof-of-concept ESP32 device for metering passenger flows in realtime. It counts how many mobile devices are around. [common_env_data] -;platform_espressif32 = espressif32@1.0.2 +platform_espressif32 = espressif32@1.0.2 ;platform_espressif32 = espressif32@1.1.2 -platform_espressif32 = https://github.com/platformio/platform-espressif32.git#feature/stage +;platform_espressif32 = https://github.com/platformio/platform-espressif32.git#feature/stage board_build.partitions = no_ota.csv -monitor_speed = 115200 -upload_speed = 921600 lib_deps_all = lib_deps_display = ; U8g2@>=2.23.12 ; U8g2 library stored local to tweak i2c display speed down to 100khz -; speed 400khz causes interrupt injection error with espressif32 core v1.1.x -; will be removed again after bug in espressif32 core is solved +; speed, because 400khz causes interrupt injection error with espressif32 core v1.1.x +; will be removed again after bug in espressif32 core v1.1.x is solved lib_deps_rgbled = SmartLeds@>=1.1.3 lib_deps_gps = @@ -88,6 +86,7 @@ platform = ${common_env_data.platform_espressif32} framework = arduino board = esp32dev board_build.partitions = ${common_env_data.board_build.partitions} +upload_speed = 921600 monitor_speed = 115200 lib_deps = ${common_env_data.lib_deps_all} @@ -100,6 +99,7 @@ platform = ${common_env_data.platform_espressif32} framework = arduino board = esp32dev board_build.partitions = ${common_env_data.board_build.partitions} +upload_speed = 921600 monitor_speed = 115200 lib_deps = ${common_env_data.lib_deps_all} @@ -112,6 +112,7 @@ platform = ${common_env_data.platform_espressif32} framework = arduino board = esp32dev board_build.partitions = ${common_env_data.board_build.partitions} +upload_speed = 921600 monitor_speed = 115200 lib_deps = ${common_env_data.lib_deps_all} @@ -124,6 +125,7 @@ platform = ${common_env_data.platform_espressif32} framework = arduino board = esp32dev board_build.partitions = ${common_env_data.board_build.partitions} +upload_speed = 921600 monitor_speed = 115200 lib_deps = ${common_env_data.lib_deps_all} @@ -136,6 +138,7 @@ platform = ${common_env_data.platform_espressif32} framework = arduino board = esp32dev board_build.partitions = ${common_env_data.board_build.partitions} +upload_speed = 921600 monitor_speed = 115200 lib_deps = ${common_env_data.lib_deps_all} @@ -149,6 +152,7 @@ platform = ${common_env_data.platform_espressif32} framework = arduino board = esp32dev board_build.partitions = ${common_env_data.board_build.partitions} +upload_speed = 921600 monitor_speed = 115200 lib_deps = ${common_env_data.lib_deps_all} @@ -157,11 +161,12 @@ lib_deps = build_flags = ${common_env_data.build_flags} -[env:lolin32lite] +[env:lolin32litelora] platform = ${common_env_data.platform_espressif32} framework = arduino board = lolin32 board_build.partitions = ${common_env_data.board_build.partitions} +upload_speed = 921600 monitor_speed = 115200 lib_deps = ${common_env_data.lib_deps_all} @@ -169,11 +174,12 @@ lib_deps = build_flags = ${common_env_data.build_flags} -[env:lolin32] +[env:lolin32lora] platform = ${common_env_data.platform_espressif32} framework = arduino board = lolin32 board_build.partitions = ${common_env_data.board_build.partitions} +upload_speed = 921600 monitor_speed = 115200 lib_deps = ${common_env_data.lib_deps_all} diff --git a/src/antenna.h b/src/antenna.h new file mode 100644 index 00000000..14986287 --- /dev/null +++ b/src/antenna.h @@ -0,0 +1,7 @@ +#ifndef antenna_H +#define antenna_H + +void antenna_init(void); +void antenna_select(const uint8_t _ant); + +#endif \ No newline at end of file diff --git a/src/adcread.cpp b/src/battery.cpp similarity index 88% rename from src/adcread.cpp rename to src/battery.cpp index 977cae80..ce9b0924 100644 --- a/src/adcread.cpp +++ b/src/battery.cpp @@ -2,12 +2,6 @@ #include "globals.h" -#include -#include - -#define DEFAULT_VREF 1100 // tbd: use adc2_vref_to_gpio() for better estimate -#define NO_OF_SAMPLES 64 // we do multisampling - // Local logging tag static const char TAG[] = "main"; diff --git a/src/battery.h b/src/battery.h new file mode 100644 index 00000000..1ee5ad2f --- /dev/null +++ b/src/battery.h @@ -0,0 +1,12 @@ +#ifndef battery_H +#define battery_H + +#include +#include + +#define DEFAULT_VREF 1100 // tbd: use adc2_vref_to_gpio() for better estimate +#define NO_OF_SAMPLES 64 // we do multisampling + +uint16_t read_voltage(void); + +#endif diff --git a/src/blescan.h b/src/blescan.h new file mode 100644 index 00000000..a546f532 --- /dev/null +++ b/src/blescan.h @@ -0,0 +1,7 @@ +#ifndef BLESCAN_H +#define BLESCAN_H + +void start_BLEscan(void); +void stop_BLEscan(void); + +#endif \ No newline at end of file diff --git a/src/configmanager.cpp b/src/configmanager.cpp index 390a8379..66936b8f 100644 --- a/src/configmanager.cpp +++ b/src/configmanager.cpp @@ -8,14 +8,8 @@ static const char TAG[] = "flash"; nvs_handle my_handle; - esp_err_t err; -// defined in antenna.cpp -#ifdef HAS_ANTENNA_SWITCH -void antenna_select(const uint8_t _ant); -#endif - // populate cfg vars with factory settings void defaultConfig() { cfg.lorasf = LORASFDEFAULT; // 7-12, initial lora sf, see pacounter.conf @@ -324,7 +318,7 @@ void loadConfig() { // put actions to be triggered after config loaded here -#ifdef HAS_ANTENNA_SWITCH // set antenna type, if device has one +#ifdef HAS_ANTENNA_SWITCH // set antenna type antenna_select(cfg.wifiant); #endif } diff --git a/src/display.cpp b/src/display.cpp new file mode 100644 index 00000000..21719a2d --- /dev/null +++ b/src/display.cpp @@ -0,0 +1,158 @@ +#ifdef HAS_DISPLAY + +// Basic Config +#include "globals.h" +#include // needed for reading ESP32 chip attributes + +HAS_DISPLAY u8x8(OLED_RST, OLED_SCL, OLED_SDA); + +// helper function, prints a hex key on display +void DisplayKey(const uint8_t *key, uint8_t len, bool lsb) { + const uint8_t *p; + for (uint8_t i = 0; i < len; i++) { + p = lsb ? key + len - i - 1 : key + i; + u8x8.printf("%02X", *p); + } + u8x8.printf("\n"); +} + +// show startup screen +void init_display(const char *Productname, const char *Version) { + uint8_t buf[32]; + u8x8.begin(); + u8x8.setFont(u8x8_font_chroma48medium8_r); + u8x8.clear(); + u8x8.setFlipMode(0); + u8x8.setInverseFont(1); + u8x8.draw2x2String(0, 0, Productname); + u8x8.setInverseFont(0); + u8x8.draw2x2String(2, 2, Productname); + delay(1500); + u8x8.clear(); + u8x8.setFlipMode(1); + u8x8.setInverseFont(1); + u8x8.draw2x2String(0, 0, Productname); + u8x8.setInverseFont(0); + u8x8.draw2x2String(2, 2, Productname); + delay(1500); + + u8x8.setFlipMode(0); + u8x8.clear(); + +#ifdef DISPLAY_FLIP + u8x8.setFlipMode(1); +#endif + +// Display chip information +#ifdef VERBOSE + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + u8x8.printf("ESP32 %d cores\nWiFi%s%s\n", chip_info.cores, + (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", + (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); + u8x8.printf("ESP Rev.%d\n", chip_info.revision); + u8x8.printf("%dMB %s Flash\n", spi_flash_get_chip_size() / (1024 * 1024), + (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "int." : "ext."); +#endif // VERBOSE + + u8x8.print(Productname); + u8x8.print(" v"); + u8x8.println(PROGVERSION); + +#ifdef HAS_LORA + u8x8.println("DEVEUI:"); + os_getDevEui((u1_t *)buf); + DisplayKey(buf, 8, true); +#endif // HAS_LORA + + delay(5000); + u8x8.clear(); + u8x8.setPowerSave(!cfg.screenon); // set display off if disabled + u8x8.draw2x2String(0, 0, "PAX:0"); +#ifdef BLECOUNTER + u8x8.setCursor(0, 3); + u8x8.printf("BLTH:0"); +#endif + u8x8.setCursor(0, 4); + u8x8.printf("WIFI:0"); + u8x8.setCursor(0, 5); + u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%d", cfg.rssilimit); + +} // init_display + +void refreshDisplay() { + + // set display on/off according to current device configuration + if (DisplayState != cfg.screenon) { + DisplayState = cfg.screenon; + u8x8.setPowerSave(!cfg.screenon); + } + + // if display is switched off we don't need to refresh it and save time + if (!DisplayState) + return; + + // update counter (lines 0-1) + 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 + + // update GPS status (line 2) +#ifdef HAS_GPS + u8x8.setCursor(7, 2); + if (!gps.location.isValid()) // if no fix then display Sats value inverse + { + u8x8.setInverseFont(1); + u8x8.printf("Sats: %.3d", gps.satellites.value()); + u8x8.setInverseFont(0); + } else + u8x8.printf("Sats: %.3d", gps.satellites.value()); +#endif + + // update bluetooth counter + LoRa SF (line 3) +#ifdef BLECOUNTER + u8x8.setCursor(0, 3); + if (cfg.blescan) + u8x8.printf("BLTH:%-4d", macs_ble); + else + u8x8.printf("%s", "BLTH:off"); +#endif + +#ifdef HAS_LORA + u8x8.setCursor(11, 3); + u8x8.printf("SF:"); + if (cfg.adrmode) // if ADR=on then display SF value inverse + u8x8.setInverseFont(1); + u8x8.printf("%c%c", lora_datarate[LMIC.datarate * 2], + lora_datarate[LMIC.datarate * 2 + 1]); + if (cfg.adrmode) // switch off inverse if it was turned on + u8x8.setInverseFont(0); +#endif // HAS_LORA + + // update wifi counter + channel display (line 4) + u8x8.setCursor(0, 4); + u8x8.printf("WIFI:%-4d", macs_wifi); + u8x8.setCursor(11, 4); + u8x8.printf("ch:%02d", channel); + + // update RSSI limiter status & free memory display (line 5) + u8x8.setCursor(0, 5); + u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%-4d", cfg.rssilimit); + u8x8.setCursor(10, 5); + u8x8.printf("%4dKB", ESP.getFreeHeap() / 1024); + +#ifdef HAS_LORA + // update LoRa status display (line 6) + u8x8.setCursor(0, 6); + u8x8.printf("%-16s", display_line6); + + // update LMiC event display (line 7) + u8x8.setCursor(0, 7); + u8x8.printf("%-16s", display_line7); +#endif // HAS_LORA +} // refreshDisplay() + +#endif // HAS_DISPLAY \ No newline at end of file diff --git a/src/display.h b/src/display.h new file mode 100644 index 00000000..a0ef19a6 --- /dev/null +++ b/src/display.h @@ -0,0 +1,10 @@ +#ifndef DISPLAY_H +#define DISPLAY_H + +#include + +void init_display(const char *Productname, const char *Version); +void refreshDisplay(void); +void DisplayKey(const uint8_t *key, uint8_t len, bool lsb); + +#endif \ No newline at end of file diff --git a/src/globals.h b/src/globals.h index 606d9e69..ca25a9a9 100644 --- a/src/globals.h +++ b/src/globals.h @@ -6,39 +6,27 @@ #include #include -// OLED Display -#ifdef HAS_DISPLAY -#include -#endif - -// GPS -#ifdef HAS_GPS -#include -#endif - -#ifdef HAS_LORA -// LMIC-Arduino LoRaWAN Stack -#include -#include -#endif - -// LED controls -#ifdef HAS_RGB_LED -#include -#endif - -#include "rgb_led.h" -#include "macsniff.h" +// basics #include "main.h" +#include "led.h" +#include "macsniff.h" #include "payload.h" extern configData_t cfg; extern char display_line6[], display_line7[]; -extern uint64_t uptimecounter; extern int countermode, screensaver, adrmode, lorasf, txpower, rlim; +extern uint8_t channel, DisplayState; extern uint16_t macs_total, macs_wifi, macs_ble; // MAC counters +extern uint64_t uptimecounter; extern std::set macs; extern hw_timer_t *channelSwitch, *sendCycle; +extern portMUX_TYPE timerMux; + +#if defined(CFG_eu868) +const char lora_datarate[] = {"1211100908077BFSNA"}; +#elif defined(CFG_us915) +const char lora_datarate[] = {"100908078CNA121110090807"}; +#endif #ifdef HAS_GPS extern gpsStatus_t gps_status; // struct for storing gps data diff --git a/src/gpsread.cpp b/src/gps.cpp similarity index 100% rename from src/gpsread.cpp rename to src/gps.cpp diff --git a/src/gps.h b/src/gps.h new file mode 100644 index 00000000..00c98d38 --- /dev/null +++ b/src/gps.h @@ -0,0 +1,9 @@ +#ifndef gps_H +#define gps_H + +#include + +void gps_read(void); +void gps_loop(void *pvParameters); + +#endif \ No newline at end of file diff --git a/src/hal/lolin32lite.h b/src/hal/lolin32litelora.h similarity index 97% rename from src/hal/lolin32lite.h rename to src/hal/lolin32litelora.h index e3685bab..4275ea00 100644 --- a/src/hal/lolin32lite.h +++ b/src/hal/lolin32litelora.h @@ -1,4 +1,4 @@ -// Hardware related definitions for lolin32 lite loraNode32 shield +// Hardware related definitions for lolin32 lite with loraNode32 shield // See https://github.com/hallard/LoLin32-Lite-Lora // disable brownout detection (avoid unexpected reset on some boards) diff --git a/src/hal/lolin32.h b/src/hal/lolin32lora.h similarity index 97% rename from src/hal/lolin32.h rename to src/hal/lolin32lora.h index 6db4a49f..976092d7 100644 --- a/src/hal/lolin32.h +++ b/src/hal/lolin32lora.h @@ -1,4 +1,4 @@ -// Hardware related definitions for lolin32 loraNode32 shield +// Hardware related definitions for lolin32 with loraNode32 shield // See https://github.com/hallard/LoLin32-Lora // disable brownout detection (avoid unexpected reset on some boards) diff --git a/src/hal/lopy4.h b/src/hal/lopy4.h index 4cba1549..38f89e10 100644 --- a/src/hal/lopy4.h +++ b/src/hal/lopy4.h @@ -15,7 +15,7 @@ #define RST LMIC_UNUSED_PIN #define DIO0 GPIO_NUM_23 // LoRa IRQ #define DIO1 GPIO_NUM_23 // Pin tied via diode to DIO0 -#define DIO1 GPIO_NUM_23 // Pin tied via diode to DIO0 +#define DIO2 GPIO_NUM_23 // Pin tied via diode to DIO0 // select WIFI antenna (internal = onboard / external = u.fl socket) #define HAS_ANTENNA_SWITCH 21 // pin for switching wifi antenna diff --git a/src/rokkithash.cpp b/src/hash.cpp similarity index 100% rename from src/rokkithash.cpp rename to src/hash.cpp diff --git a/src/hash.h b/src/hash.h new file mode 100644 index 00000000..f69eccfc --- /dev/null +++ b/src/hash.h @@ -0,0 +1,6 @@ +#ifndef hash_H +#define hash_H + +uint32_t rokkit(const char *data, int len); + +#endif diff --git a/src/led.cpp b/src/led.cpp new file mode 100644 index 00000000..412b4872 --- /dev/null +++ b/src/led.cpp @@ -0,0 +1,161 @@ +// Basic Config +#include "globals.h" + +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 + +uint16_t LEDColor = COLOR_NONE, LEDBlinkDuration = 0; // state machine variables +unsigned long LEDBlinkStarted = 0; // When (in millis() led blink started) + +#ifdef HAS_RGB_LED + +// RGB Led instance +SmartLed rgb_led(LED_WS2812, 1, HAS_RGB_LED); + +float rgb_CalcColor(float p, float q, float t) { + if (t < 0.0f) + t += 1.0f; + if (t > 1.0f) + t -= 1.0f; + + if (t < 1.0f / 6.0f) + return p + (q - p) * 6.0f * t; + + if (t < 0.5f) + return q; + + if (t < 2.0f / 3.0f) + return p + ((q - p) * (2.0f / 3.0f - t) * 6.0f); + + return p; +} + +// ------------------------------------------------------------------------ +// Hue, Saturation, Lightness color members +// HslColor using H, S, L values (0.0 - 1.0) +// L should be limited to between (0.0 - 0.5) +// ------------------------------------------------------------------------ +RGBColor rgb_hsl2rgb(float h, float s, float l) { + RGBColor RGB_color; + float r; + float g; + float b; + + if (s == 0.0f || l == 0.0f) { + r = g = b = l; // achromatic or black + } else { + float q = l < 0.5f ? l * (1.0f + s) : l + s - (l * s); + float p = 2.0f * l - q; + r = rgb_CalcColor(p, q, h + 1.0f / 3.0f); + g = rgb_CalcColor(p, q, h); + b = rgb_CalcColor(p, q, h - 1.0f / 3.0f); + } + + RGB_color.R = (uint8_t)(r * 255.0f); + RGB_color.G = (uint8_t)(g * 255.0f); + RGB_color.B = (uint8_t)(b * 255.0f); + + return RGB_color; +} + +void rgb_set_color(uint16_t hue) { + if (hue == COLOR_NONE) { + // Off + rgb_led[0] = Rgb(0, 0, 0); + } else { + // see http://www.workwithcolor.com/blue-color-hue-range-01.htm + // H (is color from 0..360) should be between 0.0 and 1.0 + // S is saturation keep it to 1 + // L is brightness should be between 0.0 and 0.5 + // cfg.rgblum is between 0 and 100 (percent) + RGBColor target = rgb_hsl2rgb(hue / 360.0f, 1.0f, 0.005f * cfg.rgblum); + // uint32_t color = target.R<<16 | target.G<<8 | target.B; + rgb_led[0] = Rgb(target.R, target.G, target.B); + } + // Show + rgb_led.show(); +} + +#else + +// No RGB LED empty functions +void rgb_set_color(uint16_t hue) {} + +#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 + LEDBlinkStarted = millis(); // Time Start here + LEDState = LED_ON; // Let main set LED on +} + +void led_loop() { + // Custom blink running always have priority other LoRaWAN led management + if (LEDBlinkStarted && LEDBlinkDuration) { + // Custom blink is finished, let this order, avoid millis() overflow + if ((millis() - LEDBlinkStarted) >= LEDBlinkDuration) { + // Led becomes off, and stop blink + LEDState = LED_OFF; + LEDBlinkStarted = 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 { + +#ifdef HAS_LORA + // 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) < 10) ? 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 +#endif // HAS_LORA + { + // led off + LEDColor = COLOR_NONE; + LEDState = LED_OFF; + } + } + // 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() + +#endif // #if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED) diff --git a/src/rgb_led.h b/src/led.h similarity index 76% rename from src/rgb_led.h rename to src/led.h index 49aa5f76..591db1cc 100644 --- a/src/rgb_led.h +++ b/src/led.h @@ -1,5 +1,9 @@ -#pragma once +//#pragma once + +#ifdef HAS_RGB_LED +#include +#endif // value for HSL color // see http://www.workwithcolor.com/blue-color-hue-range-01.htm @@ -25,5 +29,9 @@ struct RGBColor { uint8_t B; }; +enum led_states { LED_OFF, LED_ON }; + // Exported Functions void rgb_set_color(uint16_t hue); +void blink_LED(uint16_t set_color, uint16_t set_blinkduration); +void led_loop(); diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 7d5990c7..eba99276 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -2,11 +2,7 @@ // Basic Config #include "globals.h" - -// LMIC-Arduino LoRaWAN Stack -#include "loraconf.h" -#include -#include +#include "rcommand.h" #ifdef MCP_24AA02E64_I2C_ADDRESS #include // Needed for 24AA02E64, does not hurt anything if included and not used @@ -15,10 +11,6 @@ // Local logging Tag static const char TAG[] = "lora"; -// functions defined in rcommand.cpp -void rcommand(uint8_t cmd, uint8_t arg); -void switch_lora(uint8_t sf, uint8_t tx); - // DevEUI generator using devices's MAC address void gen_lora_deveui(uint8_t *pdeveui) { uint8_t *p = pdeveui, dmac[6]; @@ -46,6 +38,33 @@ void RevBytes(unsigned char *b, size_t c) { } } +// LMIC callback functions +void os_getDevKey(u1_t *buf) { memcpy(buf, APPKEY, 16); } + +void os_getArtEui(u1_t *buf) { + memcpy(buf, APPEUI, 8); + RevBytes(buf, 8); // TTN requires it in LSB First order, so we swap bytes +} + +void os_getDevEui(u1_t *buf) { + int i = 0, k = 0; + memcpy(buf, DEVEUI, 8); // get fixed DEVEUI from loraconf.h + for (i = 0; i < 8; i++) { + k += buf[i]; + } + if (k) { + RevBytes(buf, 8); // use fixed DEVEUI and swap bytes to LSB format + } else { + gen_lora_deveui(buf); // generate DEVEUI from device's MAC + } + +// Get MCP 24AA02E64 hardware DEVEUI (override default settings if found) +#ifdef MCP_24AA02E64_I2C_ADDRESS + get_hard_deveui(buf); + RevBytes(buf, 8); // swap bytes to LSB format +#endif +} + void get_hard_deveui(uint8_t *pdeveui) { // read DEVEUI from Microchip 24AA02E64 2Kb serial eeprom if present #ifdef MCP_24AA02E64_I2C_ADDRESS diff --git a/src/lorawan.h b/src/lorawan.h index 8e2e785a..bef8da19 100644 --- a/src/lorawan.h +++ b/src/lorawan.h @@ -1,13 +1,17 @@ -#ifdef HAS_LORA - #ifndef LORAWAN_H #define LORAWAN_H +// LMIC-Arduino LoRaWAN Stack +#include +#include +#include "loraconf.h" + void onEvent(ev_t ev); void gen_lora_deveui(uint8_t *pdeveui); void RevBytes(unsigned char *b, size_t c); void get_hard_deveui(uint8_t *pdeveui); +void os_getDevKey(u1_t *buf); +void os_getArtEui(u1_t *buf); +void os_getDevEui(u1_t *buf); -#endif - -#endif // HAS_LORA \ No newline at end of file +#endif \ No newline at end of file diff --git a/src/macsniff.cpp b/src/macsniff.cpp index ba9e6824..7da0dbd4 100644 --- a/src/macsniff.cpp +++ b/src/macsniff.cpp @@ -9,9 +9,14 @@ // Local logging tag static const char TAG[] = "wifi"; +/* change for future Espressif v1.1.x static wifi_country_t wifi_country = {WIFI_MY_COUNTRY, WIFI_CHANNEL_MIN, WIFI_CHANNEL_MAX, 0, WIFI_COUNTRY_POLICY_MANUAL}; +*/ + +static wifi_country_t wifi_country = {WIFI_MY_COUNTRY, WIFI_CHANNEL_MIN, + WIFI_CHANNEL_MAX, WIFI_COUNTRY_POLICY_MANUAL}; // globals uint16_t salt; diff --git a/src/macsniff.h b/src/macsniff.h index 5e7a0c96..fe1b0f5a 100644 --- a/src/macsniff.h +++ b/src/macsniff.h @@ -4,6 +4,8 @@ // ESP32 Functions #include +#include "hash.h" + #define MAC_SNIFF_WIFI 0 #define MAC_SNIFF_BLE 1 diff --git a/src/main.cpp b/src/main.cpp index 212e925d..ce5882af 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,21 +25,6 @@ licenses. Refer to LICENSE.txt file in repository for more details. // Basic Config #include "globals.h" -// Does nothing and avoid any compilation error with I2C -#include - -#ifdef HAS_LORA -// LMIC-Arduino LoRaWAN Stack -#include "loraconf.h" -#include -#include -#endif - -// ESP32 lib Functions -#include // needed for ESP_LOGx on arduino framework -#include // needed for Wifi event handler -#include // needed for reading ESP32 chip attributes - // Initialize global variables configData_t cfg; // struct holds current device configuration char display_line6[16], display_line7[16]; // display buffers @@ -48,12 +33,6 @@ uint8_t DisplayState = 0; // globals for state machine 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 -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 LEDBlinkStarted = 0; // When (in millis() led blink started) -uint16_t LEDBlinkDuration = 0; // How long the blink need to be -uint16_t LEDColor = COLOR_NONE; // state machine variable to set RGB LED color hw_timer_t *channelSwitch = NULL, *displaytimer = NULL, *sendCycle = NULL; // configure hardware timer for cyclic tasks @@ -62,6 +41,10 @@ gpsStatus_t gps_status; // struct for storing gps data TinyGPSPlus gps; // create TinyGPS++ instance #endif +// this variables will be changed in the ISR, and read in main loop +static volatile int ButtonPressedIRQ = 0, ChannelTimerIRQ = 0, + SendCycleTimerIRQ = 0, DisplayTimerIRQ = 0; + portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; // sync main loop and ISR when modifying IRQ // handler shared variables @@ -80,10 +63,6 @@ CayenneLPP payload(PAYLOAD_BUFFER_SIZE); #error "No valid payload converter defined" #endif -// this variables will be changed in the ISR, and read in main loop -static volatile int ButtonPressedIRQ = 0, DisplayTimerIRQ = 0, - ChannelTimerIRQ = 0, SendCycleTimerIRQ = 0; - // local Tag for logging static const char TAG[] = "main"; @@ -106,37 +85,6 @@ void reset_counters() { #ifdef HAS_LORA -#ifdef VERBOSE -void printKeys(void); -#endif // VERBOSE - -// LMIC callback functions -void os_getDevKey(u1_t *buf) { memcpy(buf, APPKEY, 16); } - -void os_getArtEui(u1_t *buf) { - memcpy(buf, APPEUI, 8); - RevBytes(buf, 8); // TTN requires it in LSB First order, so we swap bytes -} - -void os_getDevEui(u1_t *buf) { - int i = 0, k = 0; - memcpy(buf, DEVEUI, 8); // get fixed DEVEUI from loraconf.h - for (i = 0; i < 8; i++) { - k += buf[i]; - } - if (k) { - RevBytes(buf, 8); // use fixed DEVEUI and swap bytes to LSB format - } else { - gen_lora_deveui(buf); // generate DEVEUI from device's MAC - } - -// Get MCP 24AA02E64 hardware DEVEUI (override default settings if found) -#ifdef MCP_24AA02E64_I2C_ADDRESS - get_hard_deveui(buf); - RevBytes(buf, 8); // swap bytes to LSB format -#endif -} - // LMIC enhanced Pin mapping const lmic_pinmap lmic_pins = {.mosi = PIN_SPI_MOSI, .miso = PIN_SPI_MISO, @@ -146,6 +94,16 @@ const lmic_pinmap lmic_pins = {.mosi = PIN_SPI_MOSI, .rst = RST, .dio = {DIO0, DIO1, DIO2}}; +#ifdef VERBOSE +void printKeys(void); +#endif // VERBOSE + +// Get MCP 24AA02E64 hardware DEVEUI (override default settings if found) +#ifdef MCP_24AA02E64_I2C_ADDRESS +get_hard_deveui(buf); +RevBytes(buf, 8); // swap bytes to LSB format +#endif + // LMIC FreeRTos Task void lorawan_loop(void *pvParameters) { @@ -165,56 +123,62 @@ void lorawan_loop(void *pvParameters) { /* beginn hardware specific parts * -------------------------------------------------------- */ -#ifdef HAS_DISPLAY - -HAS_DISPLAY u8x8(OLED_RST, OLED_SCL, OLED_SDA); - -// Display Refresh IRQ -void IRAM_ATTR DisplayIRQ() { - portENTER_CRITICAL_ISR(&timerMux); - DisplayTimerIRQ++; - portEXIT_CRITICAL_ISR(&timerMux); -} -#endif - -#ifdef HAS_ANTENNA_SWITCH -// defined in antenna.cpp -void antenna_init(); -void antenna_select(const uint8_t _ant); -#endif - -#ifndef BLECOUNTER -bool btstop = btStop(); -#endif - -// Button IRQ Handler Routine, IRAM_ATTR necessary here, see +// Setup IRQ handler routines for button, channel rotation, send cycle´, display +// attention, enable cache: // https://github.com/espressif/arduino-esp32/issues/855 -#ifdef HAS_BUTTON -void IRAM_ATTR ButtonIRQ() { ButtonPressedIRQ++; } -#endif -// Wifi Channel Rotation Timer IRQ Handler Routine void IRAM_ATTR ChannelSwitchIRQ() { portENTER_CRITICAL(&timerMux); ChannelTimerIRQ++; portEXIT_CRITICAL(&timerMux); } -// Send Cycle Timer IRQ Handler Routine void IRAM_ATTR SendCycleIRQ() { portENTER_CRITICAL(&timerMux); SendCycleTimerIRQ++; portEXIT_CRITICAL(&timerMux); } +#ifdef HAS_DISPLAY +void IRAM_ATTR DisplayIRQ() { + portENTER_CRITICAL_ISR(&timerMux); + DisplayTimerIRQ++; + portEXIT_CRITICAL_ISR(&timerMux); +} + +void updateDisplay() { + // refresh display according to refresh cycle setting + if (DisplayTimerIRQ) { + portENTER_CRITICAL(&timerMux); + DisplayTimerIRQ = 0; + portEXIT_CRITICAL(&timerMux); + refreshDisplay(); + } +} + +#endif + +#ifdef HAS_BUTTON +void IRAM_ATTR ButtonIRQ() { ButtonPressedIRQ++; } + +void readButton() { + if (ButtonPressedIRQ) { + portENTER_CRITICAL(&timerMux); + ButtonPressedIRQ = 0; + portEXIT_CRITICAL(&timerMux); + ESP_LOGI(TAG, "Button pressed"); + ESP_LOGI(TAG, "Button pressed, resetting device to factory defaults"); + eraseConfig(); + esp_restart(); + } +} +#endif + /* end hardware specific parts * -------------------------------------------------------- */ -/* begin wifi specific parts - * ---------------------------------------------------------- */ - -// Sniffer Task -void sniffer_loop(void *pvParameters) { +// Wifi channel rotation task +void wifi_channel_loop(void *pvParameters) { configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check @@ -235,9 +199,6 @@ void sniffer_loop(void *pvParameters) { } // end of infinite wifi channel rotation loop } -/* end wifi specific parts - * ------------------------------------------------------------ */ - // uptime counter 64bit to prevent millis() rollover after 49 days uint64_t uptime() { static uint32_t low32, high32; @@ -248,245 +209,7 @@ uint64_t uptime() { return (uint64_t)high32 << 32 | low32; } -#ifdef HAS_DISPLAY - -#ifdef HAS_LORA -// Print a key on display -void DisplayKey(const uint8_t *key, uint8_t len, bool lsb) { - const uint8_t *p; - for (uint8_t i = 0; i < len; i++) { - p = lsb ? key + len - i - 1 : key + i; - u8x8.printf("%02X", *p); - } - u8x8.printf("\n"); -} -#endif // HAS_LORA - -void init_display(const char *Productname, const char *Version) { - uint8_t buf[32]; - u8x8.begin(); - u8x8.setFont(u8x8_font_chroma48medium8_r); - u8x8.clear(); - u8x8.setFlipMode(0); - u8x8.setInverseFont(1); - u8x8.draw2x2String(0, 0, Productname); - u8x8.setInverseFont(0); - u8x8.draw2x2String(2, 2, Productname); - delay(1500); - u8x8.clear(); - u8x8.setFlipMode(1); - u8x8.setInverseFont(1); - u8x8.draw2x2String(0, 0, Productname); - u8x8.setInverseFont(0); - u8x8.draw2x2String(2, 2, Productname); - delay(1500); - - u8x8.setFlipMode(0); - u8x8.clear(); - -#ifdef DISPLAY_FLIP - u8x8.setFlipMode(1); -#endif - -// Display chip information -#ifdef VERBOSE - esp_chip_info_t chip_info; - esp_chip_info(&chip_info); - u8x8.printf("ESP32 %d cores\nWiFi%s%s\n", chip_info.cores, - (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", - (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); - u8x8.printf("ESP Rev.%d\n", chip_info.revision); - u8x8.printf("%dMB %s Flash\n", spi_flash_get_chip_size() / (1024 * 1024), - (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "int." : "ext."); -#endif // VERBOSE - - u8x8.print(Productname); - u8x8.print(" v"); - u8x8.println(PROGVERSION); - -#ifdef HAS_LORA - u8x8.println("DEVEUI:"); - os_getDevEui((u1_t *)buf); - DisplayKey(buf, 8, true); -#endif // HAS_LORA - - delay(5000); - u8x8.clear(); -} - -void refreshDisplay() { - // update counter (lines 0-1) - 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 - - // update GPS status (line 2) -#ifdef HAS_GPS - u8x8.setCursor(7, 2); - if (!gps.location.isValid()) // if no fix then display Sats value inverse - { - u8x8.setInverseFont(1); - u8x8.printf("Sats: %.3d", gps.satellites.value()); - u8x8.setInverseFont(0); - } else - u8x8.printf("Sats: %.3d", gps.satellites.value()); -#endif - - // update bluetooth counter + LoRa SF (line 3) -#ifdef BLECOUNTER - u8x8.setCursor(0, 3); - if (cfg.blescan) - u8x8.printf("BLTH:%-4d", macs_ble); - else - u8x8.printf("%s", "BLTH:off"); -#endif - -#ifdef HAS_LORA - u8x8.setCursor(11, 3); - u8x8.printf("SF:"); - if (cfg.adrmode) // if ADR=on then display SF value inverse - u8x8.setInverseFont(1); - u8x8.printf("%c%c", lora_datarate[LMIC.datarate * 2], - lora_datarate[LMIC.datarate * 2 + 1]); - if (cfg.adrmode) // switch off inverse if it was turned on - u8x8.setInverseFont(0); -#endif // HAS_LORA - - // update wifi counter + channel display (line 4) - u8x8.setCursor(0, 4); - u8x8.printf("WIFI:%-4d", macs_wifi); - u8x8.setCursor(11, 4); - u8x8.printf("ch:%02d", channel); - - // update RSSI limiter status & free memory display (line 5) - u8x8.setCursor(0, 5); - u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%-4d", cfg.rssilimit); - u8x8.setCursor(10, 5); - u8x8.printf("%4dKB", ESP.getFreeHeap() / 1024); - -#ifdef HAS_LORA - // update LoRa status display (line 6) - u8x8.setCursor(0, 6); - u8x8.printf("%-16s", display_line6); - - // update LMiC event display (line 7) - u8x8.setCursor(0, 7); - u8x8.printf("%-16s", display_line7); -#endif // HAS_LORA -} - -void updateDisplay() { - // refresh display according to refresh cycle setting - if (DisplayTimerIRQ) { - portENTER_CRITICAL(&timerMux); - DisplayTimerIRQ = 0; - portEXIT_CRITICAL(&timerMux); - - refreshDisplay(); - - // set display on/off according to current device configuration - if (DisplayState != cfg.screenon) { - DisplayState = cfg.screenon; - u8x8.setPowerSave(!cfg.screenon); - } - } -} // updateDisplay() -#endif // HAS_DISPLAY - -#ifdef HAS_BUTTON -void readButton() { - if (ButtonPressedIRQ) { - portENTER_CRITICAL(&timerMux); - ButtonPressedIRQ = 0; - portEXIT_CRITICAL(&timerMux); - ESP_LOGI(TAG, "Button pressed"); - ESP_LOGI(TAG, "Button pressed, resetting device to factory defaults"); - eraseConfig(); - esp_restart(); - } -} -#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 - LEDBlinkStarted = millis(); // Time Start here - LEDState = LED_ON; // Let main set LED on -} - -void led_loop() { - // Custom blink running always have priority other LoRaWAN led management - if (LEDBlinkStarted && LEDBlinkDuration) { - // Custom blink is finished, let this order, avoid millis() overflow - if ((millis() - LEDBlinkStarted) >= LEDBlinkDuration) { - // Led becomes off, and stop blink - LEDState = LED_OFF; - LEDBlinkStarted = 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 { - -#ifdef HAS_LORA - // 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) < 10) ? 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 -#endif // HAS_LORA - { - // led off - LEDColor = COLOR_NONE; - LEDState = LED_OFF; - } - } - // 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() - -#endif // #if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED) - -void updatePayload() { +void sendPayload() { if (SendCycleTimerIRQ) { portENTER_CRITICAL(&timerMux); @@ -521,7 +244,7 @@ void updatePayload() { senddata(PAYLOADPORT); } -} // updatePayload() +} // sendPayload() /* begin Aruino SETUP * ------------------------------------------------------------ */ @@ -607,6 +330,14 @@ void setup() { #ifdef HAS_ANTENNA_SWITCH strcat_P(features, " ANT"); antenna_init(); + antenna_select(cfg.wifiant); +#endif + +// switch off bluetooth on esp32 module, if not compiled +#ifdef BLECOUNTER + strcat_P(features, " BLE"); +#else + bool btstop = btStop(); #endif // initialize gps if present @@ -614,28 +345,13 @@ void setup() { strcat_P(features, " GPS"); #endif +// initialize display if present #ifdef HAS_DISPLAY strcat_P(features, " OLED"); - // initialize display - init_display(PROGNAME, PROGVERSION); DisplayState = cfg.screenon; - u8x8.setPowerSave(!cfg.screenon); // set display off if disabled - u8x8.draw2x2String(0, 0, "PAX:0"); -#ifdef BLECOUNTER - u8x8.setCursor(0, 3); - u8x8.printf("BLTH:0"); -#endif - u8x8.setCursor(0, 4); - u8x8.printf("WIFI:0"); - u8x8.setCursor(0, 5); - u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%d", cfg.rssilimit); + init_display(PROGNAME, PROGVERSION); -#ifdef HAS_LORA - sprintf(display_line6, "Join wait"); -#endif // HAS_LORA - - // setup display refresh trigger IRQ using esp32 hardware timer 0 - // for explanation see + // setup display refresh trigger IRQ using esp32 hardware timer // https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/ displaytimer = timerBegin(0, 80, true); // prescaler 80 -> divides 80 MHz CPU // freq to 1 MHz, timer 0, count up @@ -693,10 +409,28 @@ void setup() { // https://techtutorialsx.com/2017/05/09/esp32-get-task-execution-core/ ESP_LOGI(TAG, "Starting Lora task on core 1"); - xTaskCreatePinnedToCore(lorawan_loop, "loratask", 2048, (void *)1, + xTaskCreatePinnedToCore(lorawan_loop, "loraloop", 2048, (void *)1, (5 | portPRIVILEGE_BIT), NULL, 1); #endif +// if device has GPS and it is enabled, start GPS reader task on core 0 with +// higher priority than wifi channel rotation task since we process serial +// streaming NMEA data +#ifdef HAS_GPS + if (cfg.gpsmode) { + ESP_LOGI(TAG, "Starting GPS task on core 0"); + xTaskCreatePinnedToCore(gps_loop, "gpsloop", 2048, (void *)1, 2, NULL, 0); + } +#endif + +// start BLE scan callback if BLE function is enabled in NVRAM configuration +#ifdef BLECOUNTER + if (cfg.blescan) { + ESP_LOGI(TAG, "Starting BLE task on core 1"); + start_BLEscan(); + } +#endif + // start wifi in monitor mode and start channel rotation task on core 0 ESP_LOGI(TAG, "Starting Wifi task on core 0"); wifi_sniffer_init(); @@ -704,26 +438,9 @@ void setup() { // arduino-esp32 core note: do this *after* wifi has started, since function // gets it's seed from RF noise reset_salt(); // get new 16bit for salting hashes - xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 2048, (void *)1, 1, NULL, - 0); - -// start BLE scan callback if BLE function is enabled in NVRAM configuration -#ifdef BLECOUNTER - if (cfg.blescan) { - start_BLEscan(); - } -#endif - -// if device has GPS and it is enabled, start GPS reader task on core 0 -// higher priority than wifi channel rotation task since we process serial -// streaming NMEA data -#ifdef HAS_GPS - if (cfg.gpsmode) { - ESP_LOGI(TAG, "Starting GPS task on core 0"); - xTaskCreatePinnedToCore(gps_loop, "gpsfeed", 2048, (void *)1, 2, NULL, 0); - } -#endif -} + xTaskCreatePinnedToCore(wifi_channel_loop, "wifiloop", 2048, (void *)1, 1, + NULL, 0); +} // setup /* end Arduino SETUP * ------------------------------------------------------------ */ @@ -763,7 +480,7 @@ void loop() { } // check send cycle and send payload if cycle is expired - updatePayload(); + sendPayload(); vTaskDelay(1 / portTICK_PERIOD_MS); // reset watchdog diff --git a/src/main.h b/src/main.h index 027e9f09..a4e48df5 100644 --- a/src/main.h +++ b/src/main.h @@ -1,15 +1,42 @@ #include "configmanager.h" -#include "macsniff.h" #include "senddata.h" +// Does nothing and avoid any compilation error with I2C +#include + +// ESP32 lib Functions +#include // needed for ESP_LOGx on arduino framework +#include // needed for Wifi event handler +#include // needed for reading ESP32 chip attributes + #ifdef HAS_LORA #include "lorawan.h" #endif +#ifdef HAS_DISPLAY +#include "display.h" +#endif + +#ifdef HAS_GPS +#include "gps.h" +#endif + +#ifdef BLECOUNTER +#include "blescan.h" +#endif + +#ifdef HAS_BATTERY_PROBE +#include "battery.h" +#endif + +#ifdef HAS_ANTENNA_SWITCH +#include "antenna.h" +#endif + // program version - note: increment version after modifications to configData_t // struct!! -#define PROGVERSION "1.3.9" // use max 10 chars here! +#define PROGVERSION "1.3.91" // use max 10 chars here! #define PROGNAME "PAXCNT" //--- Declarations --- @@ -46,29 +73,6 @@ extern gpsStatus_t gps_status; // struct for storing gps data extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe #endif -enum led_states { LED_OFF, LED_ON }; - -#if defined(CFG_eu868) -const char lora_datarate[] = {"1211100908077BFSNA"}; -#elif defined(CFG_us915) -const char lora_datarate[] = {"100908078CNA121110090807"}; -#endif - -//--- Prototypes --- - -// defined in main.cpp void reset_counters(void); void blink_LED(uint16_t set_color, uint16_t set_blinkduration); -void led_loop(void); - -// defined in blescan.cpp -#ifdef BLECOUNTER -void start_BLEscan(void); -void stop_BLEscan(void); -#endif - -// defined in gpsread.cpp -#ifdef HAS_GPS -void gps_read(void); -void gps_loop(void *pvParameters); -#endif \ No newline at end of file +void led_loop(void); \ No newline at end of file diff --git a/src/rcommand.cpp b/src/rcommand.cpp index 243b6fc3..2c307b3a 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -16,18 +16,8 @@ typedef struct { const bool store; } cmd_t; -// function defined in antenna.cpp -#ifdef HAS_ANTENNA_SWITCH -void antenna_select(const uint8_t _ant); -#endif - -// function defined in adcread.cpp -#ifdef HAS_BATTERY_PROBE -uint16_t read_voltage(void); -#endif - #ifdef HAS_LORA -// help function to assign LoRa datarates to numeric spreadfactor values +// helper function to assign LoRa datarates to numeric spreadfactor values void switch_lora(uint8_t sf, uint8_t tx) { if (tx > 20) return; diff --git a/src/rcommand.h b/src/rcommand.h new file mode 100644 index 00000000..9cc55e69 --- /dev/null +++ b/src/rcommand.h @@ -0,0 +1,7 @@ +#ifndef rcommand_H +#define rcommand_H + +void rcommand(uint8_t cmd, uint8_t arg); +void switch_lora(uint8_t sf, uint8_t tx); + +#endif \ No newline at end of file diff --git a/src/rgb_led.cpp b/src/rgb_led.cpp deleted file mode 100644 index 772f0a0b..00000000 --- a/src/rgb_led.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// Basic Config -#include "globals.h" - -#ifdef HAS_RGB_LED - -// RGB Led instance -SmartLed rgb_led(LED_WS2812, 1, HAS_RGB_LED); - -float rgb_CalcColor(float p, float q, float t) { - if (t < 0.0f) - t += 1.0f; - if (t > 1.0f) - t -= 1.0f; - - if (t < 1.0f / 6.0f) - return p + (q - p) * 6.0f * t; - - if (t < 0.5f) - return q; - - if (t < 2.0f / 3.0f) - return p + ((q - p) * (2.0f / 3.0f - t) * 6.0f); - - return p; -} - -// ------------------------------------------------------------------------ -// Hue, Saturation, Lightness color members -// HslColor using H, S, L values (0.0 - 1.0) -// L should be limited to between (0.0 - 0.5) -// ------------------------------------------------------------------------ -RGBColor rgb_hsl2rgb(float h, float s, float l) { - RGBColor RGB_color; - float r; - float g; - float b; - - if (s == 0.0f || l == 0.0f) { - r = g = b = l; // achromatic or black - } else { - float q = l < 0.5f ? l * (1.0f + s) : l + s - (l * s); - float p = 2.0f * l - q; - r = rgb_CalcColor(p, q, h + 1.0f / 3.0f); - g = rgb_CalcColor(p, q, h); - b = rgb_CalcColor(p, q, h - 1.0f / 3.0f); - } - - RGB_color.R = (uint8_t)(r * 255.0f); - RGB_color.G = (uint8_t)(g * 255.0f); - RGB_color.B = (uint8_t)(b * 255.0f); - - return RGB_color; -} - -void rgb_set_color(uint16_t hue) { - if (hue == COLOR_NONE) { - // Off - rgb_led[0] = Rgb(0, 0, 0); - } else { - // see http://www.workwithcolor.com/blue-color-hue-range-01.htm - // H (is color from 0..360) should be between 0.0 and 1.0 - // S is saturation keep it to 1 - // L is brightness should be between 0.0 and 0.5 - // cfg.rgblum is between 0 and 100 (percent) - RGBColor target = rgb_hsl2rgb(hue / 360.0f, 1.0f, 0.005f * cfg.rgblum); - // uint32_t color = target.R<<16 | target.G<<8 | target.B; - rgb_led[0] = Rgb(target.R, target.G, target.B); - } - // Show - rgb_led.show(); -} - -#else - -// No RGB LED empty functions -void rgb_set_color(uint16_t hue) {} - -#endif