Added channel utilisation and airtime accounting
This commit is contained in:
		
							parent
							
								
									6393d3feab
								
							
						
					
					
						commit
						41a7abff57
					
				
							
								
								
									
										26
									
								
								Config.h
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								Config.h
									
									
									
									
									
								
							| @ -22,7 +22,7 @@ | ||||
| 	#define MIN_VERS  0x3F | ||||
| 
 | ||||
| 	#define PLATFORM_AVR   0x90 | ||||
|     #define PLATFORM_ESP32 0x80 | ||||
|   #define PLATFORM_ESP32 0x80 | ||||
| 
 | ||||
| 	#define MCU_1284P 0x91 | ||||
| 	#define MCU_2560  0x92 | ||||
| @ -301,6 +301,7 @@ | ||||
| 	int  lora_txp      = 0xFF; | ||||
| 	uint32_t lora_bw   = 0; | ||||
| 	uint32_t lora_freq = 0; | ||||
| 	uint32_t lora_bitrate = 0; | ||||
| 
 | ||||
| 	// Operational variables
 | ||||
| 	bool radio_locked  = true; | ||||
| @ -337,6 +338,26 @@ | ||||
| 	uint32_t stat_rx		= 0; | ||||
| 	uint32_t stat_tx		= 0; | ||||
| 
 | ||||
| 	#define STATUS_INTERVAL_MS 3 | ||||
| 	#if MCU_VARIANT == MCU_ESP32 | ||||
| 	  #define DCD_SAMPLES 2500 | ||||
| 		#define UTIL_UPDATE_INTERVAL_MS 1000 | ||||
| 		#define UTIL_UPDATE_INTERVAL (UTIL_UPDATE_INTERVAL_MS/STATUS_INTERVAL_MS) | ||||
| 		#define AIRTIME_LONGTERM 3600 | ||||
| 		#define AIRTIME_LONGTERM_MS (AIRTIME_LONGTERM*1000) | ||||
| 		#define AIRTIME_BINLEN_MS (STATUS_INTERVAL_MS*DCD_SAMPLES) | ||||
| 		#define AIRTIME_BINS ((AIRTIME_LONGTERM*1000)/AIRTIME_BINLEN_MS) | ||||
| 		bool util_samples[DCD_SAMPLES]; | ||||
| 		uint16_t airtime_bins[AIRTIME_BINS]; | ||||
| 		int dcd_sample = 0; | ||||
| 		float local_channel_util = 0.0; | ||||
| 		float total_channel_util = 0.0; | ||||
| 		float airtime = 0.0; | ||||
| 		float longterm_airtime = 0.0; | ||||
| 		float us_per_byte = 0.0; | ||||
| 		#define current_airtime_bin(void) (millis()%AIRTIME_LONGTERM_MS)/AIRTIME_BINLEN_MS | ||||
| 	#endif | ||||
| 
 | ||||
| 	bool stat_signal_detected = false; | ||||
| 	bool stat_signal_synced   = false; | ||||
| 	bool stat_rx_ongoing      = false; | ||||
| @ -346,7 +367,7 @@ | ||||
| 	uint16_t dcd_count        = 0; | ||||
| 	uint16_t dcd_threshold    = 15; | ||||
| 
 | ||||
| 	uint32_t status_interval_ms = 3; | ||||
| 	uint32_t status_interval_ms = STATUS_INTERVAL_MS; | ||||
| 	uint32_t last_status_update = 0; | ||||
| 
 | ||||
| 	// Status flags
 | ||||
| @ -366,6 +387,7 @@ | ||||
|     float battery_percent = 0.0; | ||||
|     uint8_t battery_state = 0x00; | ||||
|     uint8_t display_intensity = 0xFF; | ||||
|     bool display_diagnostics = true; | ||||
|     bool device_init_done = false; | ||||
|     bool eeprom_ok = false; | ||||
|     bool firmware_update_mode = false; | ||||
|  | ||||
							
								
								
									
										11
									
								
								Display.h
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								Display.h
									
									
									
									
									
								
							| @ -436,6 +436,17 @@ void draw_disp_area() { | ||||
|     } else { | ||||
|       disp_area.drawBitmap(0, 0, fb, disp_area.width(), disp_area.height(), SSD1306_WHITE, SSD1306_BLACK); | ||||
|     } | ||||
|     if (display_diagnostics) { | ||||
|       disp_area.setCursor(0, 0); | ||||
|       disp_area.setTextColor(SSD1306_WHITE, SSD1306_BLACK); | ||||
|       disp_area.setTextSize(1); | ||||
|       disp_area.printf("B:%.1fK\r\n", (float)lora_bitrate/1000.0); | ||||
|       disp_area.printf("U:%.1f%%\r\n", total_channel_util*100.0); | ||||
|       disp_area.printf("L:%.1f%%\r\n", local_channel_util*100.0); | ||||
|       disp_area.printf("A:%.2f%%\r\n", airtime*100.0); | ||||
|       disp_area.printf("a:%.2f%%\r\n", longterm_airtime*100.0); | ||||
|       disp_area.printf("C:%d\r\n", current_airtime_bin()); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -89,6 +89,9 @@ void setup() { | ||||
|   LoRa.setPins(pin_cs, pin_reset, pin_dio); | ||||
|    | ||||
|   #if MCU_VARIANT == MCU_ESP32 | ||||
|     for (uint16_t ai = 0; ai < DCD_SAMPLES; ai++) { util_samples[ai] = false; } | ||||
|     for (uint16_t ai = 0; ai < AIRTIME_BINS; ai++) { airtime_bins[ai] = 0; } | ||||
| 
 | ||||
|     // Check installed transceiver chip and
 | ||||
|     // probe boot parameters.
 | ||||
|     if (LoRa.preInit()) { | ||||
| @ -396,6 +399,27 @@ void flushQueue(void) { | ||||
|   queue_flushing = false; | ||||
| } | ||||
| 
 | ||||
| void add_airtime(uint16_t written) { | ||||
|   #if MCU_VARIANT == MCU_ESP32 | ||||
|     float ms_cost = ((float)written * us_per_byte)/1000.0; | ||||
|     airtime_bins[current_airtime_bin()] += ms_cost; | ||||
|   #endif | ||||
| } | ||||
| 
 | ||||
| void update_airtime() { | ||||
|   #if MCU_VARIANT == MCU_ESP32 | ||||
|     uint16_t cb = current_airtime_bin(); | ||||
|     uint16_t pb = cb-1; if (cb < 0) { cb = AIRTIME_BINS-1; } | ||||
|     airtime = (float)(airtime_bins[cb]+airtime_bins[pb])/(2.0*AIRTIME_BINLEN_MS); | ||||
| 
 | ||||
|     uint32_t longterm_airtime_sum = 0; | ||||
|     for (uint16_t bin = 0; bin < AIRTIME_BINS; bin++) { | ||||
|       longterm_airtime_sum += airtime_bins[bin]; | ||||
|     } | ||||
|     longterm_airtime = (float)longterm_airtime_sum/(float)AIRTIME_LONGTERM_MS; | ||||
|   #endif | ||||
| } | ||||
| 
 | ||||
| void transmit(uint16_t size) { | ||||
|   if (radio_online) { | ||||
|     if (!promisc) { | ||||
| @ -411,19 +435,19 @@ void transmit(uint16_t size) { | ||||
|       LoRa.write(header); written++; | ||||
| 
 | ||||
|       for (uint16_t i=0; i < size; i++) { | ||||
|         LoRa.write(tbuf[i]);   | ||||
|         LoRa.write(tbuf[i]); | ||||
| 
 | ||||
|         written++; | ||||
| 
 | ||||
|         if (written == 255) { | ||||
|           LoRa.endPacket(); | ||||
|           LoRa.endPacket(); add_airtime(written); | ||||
|           LoRa.beginPacket(); | ||||
|           LoRa.write(header); | ||||
|           written = 1; | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       LoRa.endPacket(); | ||||
|       LoRa.endPacket(); add_airtime(written); | ||||
|       led_tx_off(); | ||||
| 
 | ||||
|       lora_receive(); | ||||
| @ -452,7 +476,7 @@ void transmit(uint16_t size) { | ||||
| 
 | ||||
|         written++; | ||||
|       } | ||||
|       LoRa.endPacket(); | ||||
|       LoRa.endPacket(); add_airtime(written); | ||||
|       led_tx_off(); | ||||
| 
 | ||||
|       lora_receive(); | ||||
| @ -858,6 +882,22 @@ void updateModemStatus() { | ||||
| void checkModemStatus() { | ||||
|   if (millis()-last_status_update >= status_interval_ms) { | ||||
|     updateModemStatus(); | ||||
| 
 | ||||
|     #if MCU_VARIANT == MCU_ESP32 | ||||
|       util_samples[dcd_sample] = dcd; | ||||
|       dcd_sample = (dcd_sample+1)%DCD_SAMPLES; | ||||
|       if (dcd_sample % UTIL_UPDATE_INTERVAL == 0) { | ||||
|         int util_count = 0; | ||||
|         for (int ui = 0; ui < DCD_SAMPLES; ui++) { | ||||
|           if (util_samples[ui]) util_count++; | ||||
|         } | ||||
|         local_channel_util = (float)util_count / (float)DCD_SAMPLES; | ||||
|         total_channel_util = local_channel_util + airtime; | ||||
|         if (total_channel_util > 1.0) total_channel_util = 1.0; | ||||
| 
 | ||||
|         update_airtime(); | ||||
|       } | ||||
|     #endif | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @ -1007,10 +1047,9 @@ void loop() { | ||||
| 
 | ||||
|         if (!dcd) { | ||||
|           dcd_waiting = false; | ||||
| 
 | ||||
|           flushQueue(); | ||||
|            | ||||
|         } | ||||
| 
 | ||||
|       } else { | ||||
|         dcd_waiting = true; | ||||
|       } | ||||
|  | ||||
							
								
								
									
										17
									
								
								Utilities.h
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								Utilities.h
									
									
									
									
									
								
							| @ -860,12 +860,28 @@ inline uint8_t packetSequence(uint8_t header) { | ||||
| 	return header >> 4; | ||||
| } | ||||
| 
 | ||||
| void updateBitrate() { | ||||
| 	#if MCU_VARIANT == MCU_ESP32 | ||||
| 		if (radio_online) { | ||||
| 			//             self.bitrate = self.r_sf * ( (4.0/self.r_cr) / (math.pow(2,self.r_sf)/(self.r_bandwidth/1000)) ) * 1000
 | ||||
| 			//             self.bitrate_kbps = round(self.bitrate/1000.0, 2)
 | ||||
| 			lora_bitrate = (uint32_t)(lora_sf * ( (4.0/(float)lora_cr) / ((float)(pow(2, lora_sf))/((float)lora_bw/1000.0)) ) * 1000.0); | ||||
| 			us_per_byte = 1000000.0/((float)lora_bitrate/8.0); | ||||
| 
 | ||||
| 		} else { | ||||
| 			lora_bitrate = 0; | ||||
| 		} | ||||
| 	#endif | ||||
| } | ||||
| 
 | ||||
| void setSpreadingFactor() { | ||||
| 	if (radio_online) LoRa.setSpreadingFactor(lora_sf); | ||||
| 	updateBitrate(); | ||||
| } | ||||
| 
 | ||||
| void setCodingRate() { | ||||
| 	if (radio_online) LoRa.setCodingRate4(lora_cr); | ||||
| 	updateBitrate(); | ||||
| } | ||||
| 
 | ||||
| void set_implicit_length(uint8_t len) { | ||||
| @ -912,6 +928,7 @@ void getBandwidth() { | ||||
| 	if (radio_online) { | ||||
| 			lora_bw = LoRa.getSignalBandwidth(); | ||||
| 	} | ||||
| 	updateBitrate(); | ||||
| } | ||||
| 
 | ||||
| void setBandwidth() { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user