Added channel utilisation and airtime accounting
This commit is contained in:
parent
6393d3feab
commit
41a7abff57
24
Config.h
24
Config.h
|
@ -301,6 +301,7 @@
|
||||||
int lora_txp = 0xFF;
|
int lora_txp = 0xFF;
|
||||||
uint32_t lora_bw = 0;
|
uint32_t lora_bw = 0;
|
||||||
uint32_t lora_freq = 0;
|
uint32_t lora_freq = 0;
|
||||||
|
uint32_t lora_bitrate = 0;
|
||||||
|
|
||||||
// Operational variables
|
// Operational variables
|
||||||
bool radio_locked = true;
|
bool radio_locked = true;
|
||||||
|
@ -337,6 +338,26 @@
|
||||||
uint32_t stat_rx = 0;
|
uint32_t stat_rx = 0;
|
||||||
uint32_t stat_tx = 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_detected = false;
|
||||||
bool stat_signal_synced = false;
|
bool stat_signal_synced = false;
|
||||||
bool stat_rx_ongoing = false;
|
bool stat_rx_ongoing = false;
|
||||||
|
@ -346,7 +367,7 @@
|
||||||
uint16_t dcd_count = 0;
|
uint16_t dcd_count = 0;
|
||||||
uint16_t dcd_threshold = 15;
|
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;
|
uint32_t last_status_update = 0;
|
||||||
|
|
||||||
// Status flags
|
// Status flags
|
||||||
|
@ -366,6 +387,7 @@
|
||||||
float battery_percent = 0.0;
|
float battery_percent = 0.0;
|
||||||
uint8_t battery_state = 0x00;
|
uint8_t battery_state = 0x00;
|
||||||
uint8_t display_intensity = 0xFF;
|
uint8_t display_intensity = 0xFF;
|
||||||
|
bool display_diagnostics = true;
|
||||||
bool device_init_done = false;
|
bool device_init_done = false;
|
||||||
bool eeprom_ok = false;
|
bool eeprom_ok = false;
|
||||||
bool firmware_update_mode = false;
|
bool firmware_update_mode = false;
|
||||||
|
|
11
Display.h
11
Display.h
|
@ -436,6 +436,17 @@ void draw_disp_area() {
|
||||||
} else {
|
} else {
|
||||||
disp_area.drawBitmap(0, 0, fb, disp_area.width(), disp_area.height(), SSD1306_WHITE, SSD1306_BLACK);
|
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);
|
LoRa.setPins(pin_cs, pin_reset, pin_dio);
|
||||||
|
|
||||||
#if MCU_VARIANT == MCU_ESP32
|
#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
|
// Check installed transceiver chip and
|
||||||
// probe boot parameters.
|
// probe boot parameters.
|
||||||
if (LoRa.preInit()) {
|
if (LoRa.preInit()) {
|
||||||
|
@ -396,6 +399,27 @@ void flushQueue(void) {
|
||||||
queue_flushing = false;
|
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) {
|
void transmit(uint16_t size) {
|
||||||
if (radio_online) {
|
if (radio_online) {
|
||||||
if (!promisc) {
|
if (!promisc) {
|
||||||
|
@ -416,14 +440,14 @@ void transmit(uint16_t size) {
|
||||||
written++;
|
written++;
|
||||||
|
|
||||||
if (written == 255) {
|
if (written == 255) {
|
||||||
LoRa.endPacket();
|
LoRa.endPacket(); add_airtime(written);
|
||||||
LoRa.beginPacket();
|
LoRa.beginPacket();
|
||||||
LoRa.write(header);
|
LoRa.write(header);
|
||||||
written = 1;
|
written = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LoRa.endPacket();
|
LoRa.endPacket(); add_airtime(written);
|
||||||
led_tx_off();
|
led_tx_off();
|
||||||
|
|
||||||
lora_receive();
|
lora_receive();
|
||||||
|
@ -452,7 +476,7 @@ void transmit(uint16_t size) {
|
||||||
|
|
||||||
written++;
|
written++;
|
||||||
}
|
}
|
||||||
LoRa.endPacket();
|
LoRa.endPacket(); add_airtime(written);
|
||||||
led_tx_off();
|
led_tx_off();
|
||||||
|
|
||||||
lora_receive();
|
lora_receive();
|
||||||
|
@ -858,6 +882,22 @@ void updateModemStatus() {
|
||||||
void checkModemStatus() {
|
void checkModemStatus() {
|
||||||
if (millis()-last_status_update >= status_interval_ms) {
|
if (millis()-last_status_update >= status_interval_ms) {
|
||||||
updateModemStatus();
|
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) {
|
if (!dcd) {
|
||||||
dcd_waiting = false;
|
dcd_waiting = false;
|
||||||
|
|
||||||
flushQueue();
|
flushQueue();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
dcd_waiting = true;
|
dcd_waiting = true;
|
||||||
}
|
}
|
||||||
|
|
17
Utilities.h
17
Utilities.h
|
@ -860,12 +860,28 @@ inline uint8_t packetSequence(uint8_t header) {
|
||||||
return header >> 4;
|
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() {
|
void setSpreadingFactor() {
|
||||||
if (radio_online) LoRa.setSpreadingFactor(lora_sf);
|
if (radio_online) LoRa.setSpreadingFactor(lora_sf);
|
||||||
|
updateBitrate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCodingRate() {
|
void setCodingRate() {
|
||||||
if (radio_online) LoRa.setCodingRate4(lora_cr);
|
if (radio_online) LoRa.setCodingRate4(lora_cr);
|
||||||
|
updateBitrate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_implicit_length(uint8_t len) {
|
void set_implicit_length(uint8_t len) {
|
||||||
|
@ -912,6 +928,7 @@ void getBandwidth() {
|
||||||
if (radio_online) {
|
if (radio_online) {
|
||||||
lora_bw = LoRa.getSignalBandwidth();
|
lora_bw = LoRa.getSignalBandwidth();
|
||||||
}
|
}
|
||||||
|
updateBitrate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setBandwidth() {
|
void setBandwidth() {
|
||||||
|
|
Loading…
Reference in New Issue