deep code refactoring
This commit is contained in:
		
							parent
							
								
									53fbab8f92
								
							
						
					
					
						commit
						beb7d9aab8
					
				| @ -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_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 */ |   /* 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 */ |   /* spi_mode = */ 0,		/* active high, rising edge */ | ||||||
|   /* i2c_bus_clock_100kHz = */ 1, |   /* ==> i2c_bus_clock_100kHz = */ 4, | ||||||
|   /* data_setup_time_ns = */ 40, |   /* data_setup_time_ns = */ 40, | ||||||
|   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */ |   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */ | ||||||
|   /* tile_width = */ 16, |   /* tile_width = */ 16, | ||||||
|  | |||||||
| @ -19,24 +19,22 @@ env_default = heltec | |||||||
| ;env_default = lopy | ;env_default = lopy | ||||||
| ;env_default = lopy4 | ;env_default = lopy4 | ||||||
| ;env_default = fipy | ;env_default = fipy | ||||||
| ;env_default = lolin32lite | ;env_default = lolin32litelora | ||||||
| ;env_default = lolin32 | ;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. | 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] | [common_env_data] | ||||||
| ;platform_espressif32 = espressif32@1.0.2 | platform_espressif32 = espressif32@1.0.2 | ||||||
| ;platform_espressif32 = espressif32@1.1.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 | board_build.partitions = no_ota.csv | ||||||
| monitor_speed = 115200 |  | ||||||
| upload_speed = 921600 |  | ||||||
| lib_deps_all = | lib_deps_all = | ||||||
| lib_deps_display = | lib_deps_display = | ||||||
| ;   U8g2@>=2.23.12 | ;   U8g2@>=2.23.12 | ||||||
| ; U8g2 library stored local to tweak i2c display speed down to 100khz | ; U8g2 library stored local to tweak i2c display speed down to 100khz | ||||||
| ; speed 400khz causes interrupt injection error with espressif32 core v1.1.x | ; speed, because 400khz causes interrupt injection error with espressif32 core v1.1.x | ||||||
| ; will be removed again after bug in espressif32 core is solved | ; will be removed again after bug in espressif32 core v1.1.x is solved | ||||||
| lib_deps_rgbled = | lib_deps_rgbled = | ||||||
|     SmartLeds@>=1.1.3 |     SmartLeds@>=1.1.3 | ||||||
| lib_deps_gps = | lib_deps_gps = | ||||||
| @ -88,6 +86,7 @@ platform = ${common_env_data.platform_espressif32} | |||||||
| framework = arduino | framework = arduino | ||||||
| board = esp32dev | board = esp32dev | ||||||
| board_build.partitions = ${common_env_data.board_build.partitions} | board_build.partitions = ${common_env_data.board_build.partitions} | ||||||
|  | upload_speed = 921600 | ||||||
| monitor_speed = 115200 | monitor_speed = 115200 | ||||||
| lib_deps =  | lib_deps =  | ||||||
|     ${common_env_data.lib_deps_all} |     ${common_env_data.lib_deps_all} | ||||||
| @ -100,6 +99,7 @@ platform = ${common_env_data.platform_espressif32} | |||||||
| framework = arduino | framework = arduino | ||||||
| board = esp32dev | board = esp32dev | ||||||
| board_build.partitions = ${common_env_data.board_build.partitions} | board_build.partitions = ${common_env_data.board_build.partitions} | ||||||
|  | upload_speed = 921600 | ||||||
| monitor_speed = 115200 | monitor_speed = 115200 | ||||||
| lib_deps =  | lib_deps =  | ||||||
|     ${common_env_data.lib_deps_all} |     ${common_env_data.lib_deps_all} | ||||||
| @ -112,6 +112,7 @@ platform = ${common_env_data.platform_espressif32} | |||||||
| framework = arduino | framework = arduino | ||||||
| board = esp32dev | board = esp32dev | ||||||
| board_build.partitions = ${common_env_data.board_build.partitions} | board_build.partitions = ${common_env_data.board_build.partitions} | ||||||
|  | upload_speed = 921600 | ||||||
| monitor_speed = 115200 | monitor_speed = 115200 | ||||||
| lib_deps =  | lib_deps =  | ||||||
|     ${common_env_data.lib_deps_all} |     ${common_env_data.lib_deps_all} | ||||||
| @ -124,6 +125,7 @@ platform = ${common_env_data.platform_espressif32} | |||||||
| framework = arduino | framework = arduino | ||||||
| board = esp32dev | board = esp32dev | ||||||
| board_build.partitions = ${common_env_data.board_build.partitions} | board_build.partitions = ${common_env_data.board_build.partitions} | ||||||
|  | upload_speed = 921600 | ||||||
| monitor_speed = 115200 | monitor_speed = 115200 | ||||||
| lib_deps =  | lib_deps =  | ||||||
|     ${common_env_data.lib_deps_all} |     ${common_env_data.lib_deps_all} | ||||||
| @ -136,6 +138,7 @@ platform = ${common_env_data.platform_espressif32} | |||||||
| framework = arduino | framework = arduino | ||||||
| board = esp32dev | board = esp32dev | ||||||
| board_build.partitions = ${common_env_data.board_build.partitions} | board_build.partitions = ${common_env_data.board_build.partitions} | ||||||
|  | upload_speed = 921600 | ||||||
| monitor_speed = 115200 | monitor_speed = 115200 | ||||||
| lib_deps =  | lib_deps =  | ||||||
|     ${common_env_data.lib_deps_all} |     ${common_env_data.lib_deps_all} | ||||||
| @ -149,6 +152,7 @@ platform = ${common_env_data.platform_espressif32} | |||||||
| framework = arduino | framework = arduino | ||||||
| board = esp32dev | board = esp32dev | ||||||
| board_build.partitions = ${common_env_data.board_build.partitions} | board_build.partitions = ${common_env_data.board_build.partitions} | ||||||
|  | upload_speed = 921600 | ||||||
| monitor_speed = 115200 | monitor_speed = 115200 | ||||||
| lib_deps = | lib_deps = | ||||||
|     ${common_env_data.lib_deps_all} |     ${common_env_data.lib_deps_all} | ||||||
| @ -157,11 +161,12 @@ lib_deps = | |||||||
| build_flags = | build_flags = | ||||||
|     ${common_env_data.build_flags} |     ${common_env_data.build_flags} | ||||||
| 
 | 
 | ||||||
| [env:lolin32lite] | [env:lolin32litelora] | ||||||
| platform = ${common_env_data.platform_espressif32} | platform = ${common_env_data.platform_espressif32} | ||||||
| framework = arduino | framework = arduino | ||||||
| board = lolin32 | board = lolin32 | ||||||
| board_build.partitions = ${common_env_data.board_build.partitions} | board_build.partitions = ${common_env_data.board_build.partitions} | ||||||
|  | upload_speed = 921600 | ||||||
| monitor_speed = 115200 | monitor_speed = 115200 | ||||||
| lib_deps =  | lib_deps =  | ||||||
|     ${common_env_data.lib_deps_all} |     ${common_env_data.lib_deps_all} | ||||||
| @ -169,11 +174,12 @@ lib_deps = | |||||||
| build_flags = | build_flags = | ||||||
|     ${common_env_data.build_flags} |     ${common_env_data.build_flags} | ||||||
| 
 | 
 | ||||||
| [env:lolin32] | [env:lolin32lora] | ||||||
| platform = ${common_env_data.platform_espressif32} | platform = ${common_env_data.platform_espressif32} | ||||||
| framework = arduino  | framework = arduino  | ||||||
| board = lolin32 | board = lolin32 | ||||||
| board_build.partitions = ${common_env_data.board_build.partitions} | board_build.partitions = ${common_env_data.board_build.partitions} | ||||||
|  | upload_speed = 921600 | ||||||
| monitor_speed = 115200 | monitor_speed = 115200 | ||||||
| lib_deps =  | lib_deps =  | ||||||
|     ${common_env_data.lib_deps_all} |     ${common_env_data.lib_deps_all} | ||||||
|  | |||||||
							
								
								
									
										7
									
								
								src/antenna.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/antenna.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | #ifndef antenna_H | ||||||
|  | #define antenna_H | ||||||
|  | 
 | ||||||
|  | void antenna_init(void); | ||||||
|  | void antenna_select(const uint8_t _ant); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
| @ -2,12 +2,6 @@ | |||||||
| 
 | 
 | ||||||
| #include "globals.h" | #include "globals.h" | ||||||
| 
 | 
 | ||||||
| #include <driver/adc.h> |  | ||||||
| #include <esp_adc_cal.h> |  | ||||||
| 
 |  | ||||||
| #define DEFAULT_VREF 1100 // tbd: use adc2_vref_to_gpio() for better estimate
 |  | ||||||
| #define NO_OF_SAMPLES 64  // we do multisampling
 |  | ||||||
| 
 |  | ||||||
| // Local logging tag
 | // Local logging tag
 | ||||||
| static const char TAG[] = "main"; | static const char TAG[] = "main"; | ||||||
| 
 | 
 | ||||||
							
								
								
									
										12
									
								
								src/battery.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/battery.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | #ifndef battery_H | ||||||
|  | #define battery_H | ||||||
|  | 
 | ||||||
|  | #include <driver/adc.h> | ||||||
|  | #include <esp_adc_cal.h> | ||||||
|  | 
 | ||||||
|  | #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 | ||||||
							
								
								
									
										7
									
								
								src/blescan.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/blescan.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | #ifndef BLESCAN_H | ||||||
|  | #define BLESCAN_H | ||||||
|  | 
 | ||||||
|  | void start_BLEscan(void); | ||||||
|  | void stop_BLEscan(void); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
| @ -8,14 +8,8 @@ | |||||||
| static const char TAG[] = "flash"; | static const char TAG[] = "flash"; | ||||||
| 
 | 
 | ||||||
| nvs_handle my_handle; | nvs_handle my_handle; | ||||||
| 
 |  | ||||||
| esp_err_t err; | 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
 | // populate cfg vars with factory settings
 | ||||||
| void defaultConfig() { | void defaultConfig() { | ||||||
|   cfg.lorasf = LORASFDEFAULT; // 7-12, initial lora sf, see pacounter.conf
 |   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
 |     // 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); |     antenna_select(cfg.wifiant); | ||||||
| #endif | #endif | ||||||
|   } |   } | ||||||
|  | |||||||
							
								
								
									
										158
									
								
								src/display.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								src/display.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,158 @@ | |||||||
|  | #ifdef HAS_DISPLAY | ||||||
|  | 
 | ||||||
|  | // Basic Config
 | ||||||
|  | #include "globals.h" | ||||||
|  | #include <esp_spi_flash.h> // 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
 | ||||||
							
								
								
									
										10
									
								
								src/display.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/display.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | #ifndef DISPLAY_H | ||||||
|  | #define DISPLAY_H | ||||||
|  | 
 | ||||||
|  | #include <U8x8lib.h> | ||||||
|  | 
 | ||||||
|  | void init_display(const char *Productname, const char *Version); | ||||||
|  | void refreshDisplay(void); | ||||||
|  | void DisplayKey(const uint8_t *key, uint8_t len, bool lsb); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
| @ -6,39 +6,27 @@ | |||||||
| #include <array> | #include <array> | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| 
 | 
 | ||||||
| // OLED Display
 | // basics
 | ||||||
| #ifdef HAS_DISPLAY |  | ||||||
| #include <U8x8lib.h> |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| // GPS
 |  | ||||||
| #ifdef HAS_GPS |  | ||||||
| #include <TinyGPS++.h> |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #ifdef HAS_LORA |  | ||||||
| // LMIC-Arduino LoRaWAN Stack
 |  | ||||||
| #include <lmic.h> |  | ||||||
| #include <hal/hal.h> |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| // LED controls
 |  | ||||||
| #ifdef HAS_RGB_LED |  | ||||||
| #include <SmartLeds.h> |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #include "rgb_led.h" |  | ||||||
| #include "macsniff.h" |  | ||||||
| #include "main.h" | #include "main.h" | ||||||
|  | #include "led.h" | ||||||
|  | #include "macsniff.h" | ||||||
| #include "payload.h" | #include "payload.h" | ||||||
| 
 | 
 | ||||||
| extern configData_t cfg; | extern configData_t cfg; | ||||||
| extern char display_line6[], display_line7[]; | extern char display_line6[], display_line7[]; | ||||||
| extern uint64_t uptimecounter; |  | ||||||
| extern int countermode, screensaver, adrmode, lorasf, txpower, rlim; | 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 uint16_t macs_total, macs_wifi, macs_ble; // MAC counters
 | ||||||
|  | extern uint64_t uptimecounter; | ||||||
| extern std::set<uint16_t> macs; | extern std::set<uint16_t> macs; | ||||||
| extern hw_timer_t *channelSwitch, *sendCycle; | 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 | #ifdef HAS_GPS | ||||||
| extern gpsStatus_t gps_status; // struct for storing gps data
 | extern gpsStatus_t gps_status; // struct for storing gps data
 | ||||||
|  | |||||||
							
								
								
									
										9
									
								
								src/gps.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/gps.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | #ifndef gps_H | ||||||
|  | #define gps_H | ||||||
|  | 
 | ||||||
|  | #include <TinyGPS++.h> | ||||||
|  | 
 | ||||||
|  | void gps_read(void); | ||||||
|  | void gps_loop(void *pvParameters); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
| @ -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
 | // See https://github.com/hallard/LoLin32-Lite-Lora
 | ||||||
| 
 | 
 | ||||||
| // disable brownout detection (avoid unexpected reset on some boards)
 | // disable brownout detection (avoid unexpected reset on some boards)
 | ||||||
| @ -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
 | // See https://github.com/hallard/LoLin32-Lora
 | ||||||
| 
 | 
 | ||||||
| // disable brownout detection (avoid unexpected reset on some boards)
 | // disable brownout detection (avoid unexpected reset on some boards)
 | ||||||
| @ -15,7 +15,7 @@ | |||||||
| #define RST   LMIC_UNUSED_PIN | #define RST   LMIC_UNUSED_PIN | ||||||
| #define DIO0  GPIO_NUM_23 // LoRa IRQ
 | #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 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)
 | // select WIFI antenna (internal = onboard / external = u.fl socket)
 | ||||||
| #define HAS_ANTENNA_SWITCH  21      // pin for switching wifi antenna
 | #define HAS_ANTENNA_SWITCH  21      // pin for switching wifi antenna
 | ||||||
|  | |||||||
							
								
								
									
										6
									
								
								src/hash.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/hash.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | |||||||
|  | #ifndef hash_H | ||||||
|  | #define hash_H | ||||||
|  | 
 | ||||||
|  | uint32_t rokkit(const char *data, int len); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										161
									
								
								src/led.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								src/led.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -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)
 | ||||||
| @ -1,5 +1,9 @@ | |||||||
| 
 | 
 | ||||||
| #pragma once | //#pragma once
 | ||||||
|  | 
 | ||||||
|  | #ifdef HAS_RGB_LED | ||||||
|  | #include <SmartLeds.h> | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| // value for HSL color
 | // value for HSL color
 | ||||||
| // see http://www.workwithcolor.com/blue-color-hue-range-01.htm
 | // see http://www.workwithcolor.com/blue-color-hue-range-01.htm
 | ||||||
| @ -25,5 +29,9 @@ struct RGBColor { | |||||||
|   uint8_t B; |   uint8_t B; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | enum led_states { LED_OFF, LED_ON }; | ||||||
|  | 
 | ||||||
| // Exported Functions
 | // Exported Functions
 | ||||||
| void rgb_set_color(uint16_t hue); | void rgb_set_color(uint16_t hue); | ||||||
|  | void blink_LED(uint16_t set_color, uint16_t set_blinkduration); | ||||||
|  | void led_loop(); | ||||||
| @ -2,11 +2,7 @@ | |||||||
| 
 | 
 | ||||||
| // Basic Config
 | // Basic Config
 | ||||||
| #include "globals.h" | #include "globals.h" | ||||||
| 
 | #include "rcommand.h" | ||||||
| // LMIC-Arduino LoRaWAN Stack
 |  | ||||||
| #include "loraconf.h" |  | ||||||
| #include <lmic.h> |  | ||||||
| #include <hal/hal.h> |  | ||||||
| 
 | 
 | ||||||
| #ifdef MCP_24AA02E64_I2C_ADDRESS | #ifdef MCP_24AA02E64_I2C_ADDRESS | ||||||
| #include <Wire.h> // Needed for 24AA02E64, does not hurt anything if included and not used
 | #include <Wire.h> // Needed for 24AA02E64, does not hurt anything if included and not used
 | ||||||
| @ -15,10 +11,6 @@ | |||||||
| // Local logging Tag
 | // Local logging Tag
 | ||||||
| static const char TAG[] = "lora"; | 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
 | // DevEUI generator using devices's MAC address
 | ||||||
| void gen_lora_deveui(uint8_t *pdeveui) { | void gen_lora_deveui(uint8_t *pdeveui) { | ||||||
|   uint8_t *p = pdeveui, dmac[6]; |   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) { | void get_hard_deveui(uint8_t *pdeveui) { | ||||||
|   // read DEVEUI from Microchip 24AA02E64 2Kb serial eeprom if present
 |   // read DEVEUI from Microchip 24AA02E64 2Kb serial eeprom if present
 | ||||||
| #ifdef MCP_24AA02E64_I2C_ADDRESS | #ifdef MCP_24AA02E64_I2C_ADDRESS | ||||||
|  | |||||||
| @ -1,13 +1,17 @@ | |||||||
| #ifdef HAS_LORA |  | ||||||
| 
 |  | ||||||
| #ifndef LORAWAN_H | #ifndef LORAWAN_H | ||||||
| #define LORAWAN_H | #define LORAWAN_H | ||||||
| 
 | 
 | ||||||
|  | // LMIC-Arduino LoRaWAN Stack
 | ||||||
|  | #include <lmic.h> | ||||||
|  | #include <hal/hal.h> | ||||||
|  | #include "loraconf.h" | ||||||
|  | 
 | ||||||
| void onEvent(ev_t ev); | void onEvent(ev_t ev); | ||||||
| void gen_lora_deveui(uint8_t *pdeveui); | void gen_lora_deveui(uint8_t *pdeveui); | ||||||
| void RevBytes(unsigned char *b, size_t c); | void RevBytes(unsigned char *b, size_t c); | ||||||
| void get_hard_deveui(uint8_t *pdeveui); | 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 | ||||||
| 
 |  | ||||||
| #endif // HAS_LORA
 |  | ||||||
| @ -9,9 +9,14 @@ | |||||||
| // Local logging tag
 | // Local logging tag
 | ||||||
| static const char TAG[] = "wifi"; | static const char TAG[] = "wifi"; | ||||||
| 
 | 
 | ||||||
|  | /* change for future Espressif v1.1.x
 | ||||||
| static wifi_country_t wifi_country = {WIFI_MY_COUNTRY, WIFI_CHANNEL_MIN, | static wifi_country_t wifi_country = {WIFI_MY_COUNTRY, WIFI_CHANNEL_MIN, | ||||||
|                                       WIFI_CHANNEL_MAX, 0, |                                       WIFI_CHANNEL_MAX, 0, | ||||||
|                                       WIFI_COUNTRY_POLICY_MANUAL}; |                                       WIFI_COUNTRY_POLICY_MANUAL}; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | static wifi_country_t wifi_country = {WIFI_MY_COUNTRY, WIFI_CHANNEL_MIN, | ||||||
|  |                                       WIFI_CHANNEL_MAX, WIFI_COUNTRY_POLICY_MANUAL}; | ||||||
| 
 | 
 | ||||||
| // globals
 | // globals
 | ||||||
| uint16_t salt; | uint16_t salt; | ||||||
|  | |||||||
| @ -4,6 +4,8 @@ | |||||||
| // ESP32 Functions
 | // ESP32 Functions
 | ||||||
| #include <esp_wifi.h> | #include <esp_wifi.h> | ||||||
| 
 | 
 | ||||||
|  | #include "hash.h" | ||||||
|  | 
 | ||||||
| #define MAC_SNIFF_WIFI 0 | #define MAC_SNIFF_WIFI 0 | ||||||
| #define MAC_SNIFF_BLE 1 | #define MAC_SNIFF_BLE 1 | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										461
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										461
									
								
								src/main.cpp
									
									
									
									
									
								
							| @ -25,21 +25,6 @@ licenses. Refer to LICENSE.txt file in repository for more details. | |||||||
| // Basic Config
 | // Basic Config
 | ||||||
| #include "globals.h" | #include "globals.h" | ||||||
| 
 | 
 | ||||||
| // Does nothing and avoid any compilation error with I2C
 |  | ||||||
| #include <Wire.h> |  | ||||||
| 
 |  | ||||||
| #ifdef HAS_LORA |  | ||||||
| // LMIC-Arduino LoRaWAN Stack
 |  | ||||||
| #include "loraconf.h" |  | ||||||
| #include <hal/hal.h> |  | ||||||
| #include <lmic.h> |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| // ESP32 lib Functions
 |  | ||||||
| #include <esp32-hal-log.h>  // needed for ESP_LOGx on arduino framework
 |  | ||||||
| #include <esp_event_loop.h> // needed for Wifi event handler
 |  | ||||||
| #include <esp_spi_flash.h>  // needed for reading ESP32 chip attributes
 |  | ||||||
| 
 |  | ||||||
| // Initialize global variables
 | // Initialize global variables
 | ||||||
| configData_t cfg; // struct holds current device configuration
 | configData_t cfg; // struct holds current device configuration
 | ||||||
| char display_line6[16], display_line7[16]; // display buffers
 | 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, | uint16_t macs_total = 0, macs_wifi = 0, | ||||||
|          macs_ble = 0; // MAC counters globals for display
 |          macs_ble = 0; // MAC counters globals for display
 | ||||||
| uint8_t channel = 0;   // wifi channel rotation counter global 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, | hw_timer_t *channelSwitch = NULL, *displaytimer = NULL, | ||||||
|            *sendCycle = NULL; // configure hardware timer for cyclic tasks
 |            *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
 | TinyGPSPlus gps;        // create TinyGPS++ instance
 | ||||||
| #endif | #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_TYPE timerMux = | ||||||
|     portMUX_INITIALIZER_UNLOCKED; // sync main loop and ISR when modifying IRQ
 |     portMUX_INITIALIZER_UNLOCKED; // sync main loop and ISR when modifying IRQ
 | ||||||
|                                   // handler shared variables
 |                                   // handler shared variables
 | ||||||
| @ -80,10 +63,6 @@ CayenneLPP payload(PAYLOAD_BUFFER_SIZE); | |||||||
| #error "No valid payload converter defined" | #error "No valid payload converter defined" | ||||||
| #endif | #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
 | // local Tag for logging
 | ||||||
| static const char TAG[] = "main"; | static const char TAG[] = "main"; | ||||||
| 
 | 
 | ||||||
| @ -106,37 +85,6 @@ void reset_counters() { | |||||||
| 
 | 
 | ||||||
| #ifdef HAS_LORA | #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
 | // LMIC enhanced Pin mapping
 | ||||||
| const lmic_pinmap lmic_pins = {.mosi = PIN_SPI_MOSI, | const lmic_pinmap lmic_pins = {.mosi = PIN_SPI_MOSI, | ||||||
|                                .miso = PIN_SPI_MISO, |                                .miso = PIN_SPI_MISO, | ||||||
| @ -146,6 +94,16 @@ const lmic_pinmap lmic_pins = {.mosi = PIN_SPI_MOSI, | |||||||
|                                .rst = RST, |                                .rst = RST, | ||||||
|                                .dio = {DIO0, DIO1, DIO2}}; |                                .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
 | // LMIC FreeRTos Task
 | ||||||
| void lorawan_loop(void *pvParameters) { | void lorawan_loop(void *pvParameters) { | ||||||
| 
 | 
 | ||||||
| @ -165,56 +123,62 @@ void lorawan_loop(void *pvParameters) { | |||||||
| /* beginn hardware specific parts
 | /* beginn hardware specific parts
 | ||||||
|  * -------------------------------------------------------- */ |  * -------------------------------------------------------- */ | ||||||
| 
 | 
 | ||||||
| #ifdef HAS_DISPLAY | // Setup IRQ handler routines for button, channel rotation, send cycle´, display
 | ||||||
| 
 | // attention, enable cache:
 | ||||||
| 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
 |  | ||||||
| // https://github.com/espressif/arduino-esp32/issues/855
 | // 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() { | void IRAM_ATTR ChannelSwitchIRQ() { | ||||||
|   portENTER_CRITICAL(&timerMux); |   portENTER_CRITICAL(&timerMux); | ||||||
|   ChannelTimerIRQ++; |   ChannelTimerIRQ++; | ||||||
|   portEXIT_CRITICAL(&timerMux); |   portEXIT_CRITICAL(&timerMux); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Send Cycle Timer IRQ Handler Routine
 |  | ||||||
| void IRAM_ATTR SendCycleIRQ() { | void IRAM_ATTR SendCycleIRQ() { | ||||||
|   portENTER_CRITICAL(&timerMux); |   portENTER_CRITICAL(&timerMux); | ||||||
|   SendCycleTimerIRQ++; |   SendCycleTimerIRQ++; | ||||||
|   portEXIT_CRITICAL(&timerMux); |   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
 | /* end hardware specific parts
 | ||||||
|  * -------------------------------------------------------- */ |  * -------------------------------------------------------- */ | ||||||
| 
 | 
 | ||||||
| /* begin wifi specific parts
 | // Wifi channel rotation task
 | ||||||
|  * ---------------------------------------------------------- */ | void wifi_channel_loop(void *pvParameters) { | ||||||
| 
 |  | ||||||
| // Sniffer Task
 |  | ||||||
| void sniffer_loop(void *pvParameters) { |  | ||||||
| 
 | 
 | ||||||
|   configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
 |   configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
 | ||||||
| 
 | 
 | ||||||
| @ -235,9 +199,6 @@ void sniffer_loop(void *pvParameters) { | |||||||
|   } // end of infinite wifi channel rotation loop
 |   } // end of infinite wifi channel rotation loop
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* end wifi specific parts
 |  | ||||||
|  * ------------------------------------------------------------ */ |  | ||||||
| 
 |  | ||||||
| // uptime counter 64bit to prevent millis() rollover after 49 days
 | // uptime counter 64bit to prevent millis() rollover after 49 days
 | ||||||
| uint64_t uptime() { | uint64_t uptime() { | ||||||
|   static uint32_t low32, high32; |   static uint32_t low32, high32; | ||||||
| @ -248,245 +209,7 @@ uint64_t uptime() { | |||||||
|   return (uint64_t)high32 << 32 | low32; |   return (uint64_t)high32 << 32 | low32; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef HAS_DISPLAY | void sendPayload() { | ||||||
| 
 |  | ||||||
| #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() { |  | ||||||
| 
 | 
 | ||||||
|   if (SendCycleTimerIRQ) { |   if (SendCycleTimerIRQ) { | ||||||
|     portENTER_CRITICAL(&timerMux); |     portENTER_CRITICAL(&timerMux); | ||||||
| @ -521,7 +244,7 @@ void updatePayload() { | |||||||
| 
 | 
 | ||||||
|     senddata(PAYLOADPORT); |     senddata(PAYLOADPORT); | ||||||
|   } |   } | ||||||
| } // updatePayload()
 | } // sendPayload()
 | ||||||
| 
 | 
 | ||||||
| /* begin Aruino SETUP
 | /* begin Aruino SETUP
 | ||||||
|  * ------------------------------------------------------------ */ |  * ------------------------------------------------------------ */ | ||||||
| @ -607,6 +330,14 @@ void setup() { | |||||||
| #ifdef HAS_ANTENNA_SWITCH | #ifdef HAS_ANTENNA_SWITCH | ||||||
|   strcat_P(features, " ANT"); |   strcat_P(features, " ANT"); | ||||||
|   antenna_init(); |   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 | #endif | ||||||
| 
 | 
 | ||||||
| // initialize gps if present
 | // initialize gps if present
 | ||||||
| @ -614,28 +345,13 @@ void setup() { | |||||||
|   strcat_P(features, " GPS"); |   strcat_P(features, " GPS"); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | // initialize display if present
 | ||||||
| #ifdef HAS_DISPLAY | #ifdef HAS_DISPLAY | ||||||
|   strcat_P(features, " OLED"); |   strcat_P(features, " OLED"); | ||||||
|   // initialize display
 |  | ||||||
|   init_display(PROGNAME, PROGVERSION); |  | ||||||
|   DisplayState = cfg.screenon; |   DisplayState = cfg.screenon; | ||||||
|   u8x8.setPowerSave(!cfg.screenon); // set display off if disabled
 |   init_display(PROGNAME, PROGVERSION); | ||||||
|   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); |  | ||||||
| 
 | 
 | ||||||
| #ifdef HAS_LORA |   // setup display refresh trigger IRQ using esp32 hardware timer
 | ||||||
|   sprintf(display_line6, "Join wait"); |  | ||||||
| #endif // HAS_LORA
 |  | ||||||
| 
 |  | ||||||
|   // setup display refresh trigger IRQ using esp32 hardware timer 0
 |  | ||||||
|   // for explanation see
 |  | ||||||
|   // https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/
 |   // https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/
 | ||||||
|   displaytimer = timerBegin(0, 80, true); // prescaler 80 -> divides 80 MHz CPU
 |   displaytimer = timerBegin(0, 80, true); // prescaler 80 -> divides 80 MHz CPU
 | ||||||
|                                           // freq to 1 MHz, timer 0, count up
 |                                           // 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/
 |   // https://techtutorialsx.com/2017/05/09/esp32-get-task-execution-core/
 | ||||||
| 
 | 
 | ||||||
|   ESP_LOGI(TAG, "Starting Lora task on core 1"); |   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); |                           (5 | portPRIVILEGE_BIT), NULL, 1); | ||||||
| #endif | #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
 |   // start wifi in monitor mode and start channel rotation task on core 0
 | ||||||
|   ESP_LOGI(TAG, "Starting Wifi task on core 0"); |   ESP_LOGI(TAG, "Starting Wifi task on core 0"); | ||||||
|   wifi_sniffer_init(); |   wifi_sniffer_init(); | ||||||
| @ -704,26 +438,9 @@ void setup() { | |||||||
|   // arduino-esp32 core note: do this *after* wifi has started, since function
 |   // arduino-esp32 core note: do this *after* wifi has started, since function
 | ||||||
|   // gets it's seed from RF noise
 |   // gets it's seed from RF noise
 | ||||||
|   reset_salt(); // get new 16bit for salting hashes
 |   reset_salt(); // get new 16bit for salting hashes
 | ||||||
|   xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 2048, (void *)1, 1, NULL, |   xTaskCreatePinnedToCore(wifi_channel_loop, "wifiloop", 2048, (void *)1, 1, | ||||||
|                           0); |                           NULL, 0); | ||||||
| 
 | } // setup
 | ||||||
| // 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 |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| /* end Arduino SETUP
 | /* end Arduino SETUP
 | ||||||
|  * ------------------------------------------------------------ */ |  * ------------------------------------------------------------ */ | ||||||
| @ -763,7 +480,7 @@ void loop() { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // check send cycle and send payload if cycle is expired
 |     // check send cycle and send payload if cycle is expired
 | ||||||
|     updatePayload(); |     sendPayload(); | ||||||
| 
 | 
 | ||||||
|     vTaskDelay(1 / portTICK_PERIOD_MS); // reset watchdog
 |     vTaskDelay(1 / portTICK_PERIOD_MS); // reset watchdog
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										54
									
								
								src/main.h
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								src/main.h
									
									
									
									
									
								
							| @ -1,15 +1,42 @@ | |||||||
| 
 | 
 | ||||||
| #include "configmanager.h" | #include "configmanager.h" | ||||||
| #include "macsniff.h" |  | ||||||
| #include "senddata.h" | #include "senddata.h" | ||||||
| 
 | 
 | ||||||
|  | // Does nothing and avoid any compilation error with I2C
 | ||||||
|  | #include <Wire.h> | ||||||
|  | 
 | ||||||
|  | // ESP32 lib Functions
 | ||||||
|  | #include <esp32-hal-log.h>  // needed for ESP_LOGx on arduino framework | ||||||
|  | #include <esp_event_loop.h> // needed for Wifi event handler | ||||||
|  | #include <esp_spi_flash.h>  // needed for reading ESP32 chip attributes | ||||||
|  | 
 | ||||||
| #ifdef HAS_LORA | #ifdef HAS_LORA | ||||||
| #include "lorawan.h" | #include "lorawan.h" | ||||||
| #endif | #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
 | // program version - note: increment version after modifications to configData_t
 | ||||||
| // struct!!
 | // struct!!
 | ||||||
| #define PROGVERSION "1.3.9" // use max 10 chars here!
 | #define PROGVERSION "1.3.91" // use max 10 chars here!
 | ||||||
| #define PROGNAME "PAXCNT" | #define PROGNAME "PAXCNT" | ||||||
| 
 | 
 | ||||||
| //--- Declarations ---
 | //--- Declarations ---
 | ||||||
| @ -46,29 +73,6 @@ extern gpsStatus_t gps_status; // struct for storing gps data | |||||||
| extern TinyGPSPlus gps;        // Make TinyGPS++ instance globally availabe
 | extern TinyGPSPlus gps;        // Make TinyGPS++ instance globally availabe
 | ||||||
| #endif | #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 reset_counters(void); | ||||||
| void blink_LED(uint16_t set_color, uint16_t set_blinkduration); | void blink_LED(uint16_t set_color, uint16_t set_blinkduration); | ||||||
| void led_loop(void); | 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 |  | ||||||
| @ -16,18 +16,8 @@ typedef struct { | |||||||
|   const bool store; |   const bool store; | ||||||
| } cmd_t; | } 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 | #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) { | void switch_lora(uint8_t sf, uint8_t tx) { | ||||||
|   if (tx > 20) |   if (tx > 20) | ||||||
|     return; |     return; | ||||||
|  | |||||||
							
								
								
									
										7
									
								
								src/rcommand.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/rcommand.h
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||||
| @ -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 |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user