From b61bead60a8107effcbab3c08aa81f96270d9b50 Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Thu, 14 Sep 2023 22:32:26 +0200 Subject: [PATCH] Implemented adaptive CSMA scheme --- Config.h | 20 +++++++++------ Makefile | 6 ++--- RNode_Firmware.ino | 63 ++++++++++++++++++++++++++++++++-------------- Utilities.h | 1 + 4 files changed, 60 insertions(+), 30 deletions(-) diff --git a/Config.h b/Config.h index ccf1937..b1affe3 100644 --- a/Config.h +++ b/Config.h @@ -290,7 +290,10 @@ // MCU independent configuration parameters const long serial_baudrate = 115200; const int lora_rx_turnaround_ms = 50; - const int csma_slot_ms = lora_rx_turnaround_ms; + uint8_t csma_p = 0; + float csma_p_min = 0.1; + float csma_p_max = 0.8; + int csma_slot_ms = lora_rx_turnaround_ms; // SX1276 RSSI offset to get dBm value from // packet RSSI register @@ -311,11 +314,11 @@ // Operational variables bool radio_locked = true; bool radio_online = false; - bool community_fw = true; + bool community_fw = true; bool hw_ready = false; - bool radio_error = false; - bool disp_ready = false; - bool pmu_ready = false; + bool radio_error = false; + bool disp_ready = false; + bool pmu_ready = false; bool promisc = false; bool implicit = false; uint8_t implicit_l = 0; @@ -370,11 +373,12 @@ bool stat_signal_detected = false; bool stat_signal_synced = false; bool stat_rx_ongoing = false; - bool dcd = false; + bool dcd = false; bool dcd_led = false; bool dcd_waiting = false; + long dcd_wait_until = 0; uint16_t dcd_count = 0; - uint16_t dcd_threshold = 15; + uint16_t dcd_threshold = 6; uint32_t status_interval_ms = STATUS_INTERVAL_MS; uint32_t last_status_update = 0; @@ -396,7 +400,7 @@ float battery_percent = 0.0; uint8_t battery_state = 0x00; uint8_t display_intensity = 0xFF; - bool display_diagnostics = true; + bool display_diagnostics = true; bool device_init_done = false; bool eeprom_ok = false; bool firmware_update_mode = false; diff --git a/Makefile b/Makefile index 3108f4a..fb7c546 100644 --- a/Makefile +++ b/Makefile @@ -99,11 +99,11 @@ upload-mega2560: arduino-cli upload -p /dev/ttyACM0 --fqbn arduino:avr:mega upload-tbeam: - arduino-cli upload -p /dev/ttyUSB1 --fqbn esp32:esp32:t-beam + arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:t-beam @sleep 1 - rnodeconf /dev/ttyUSB1 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.t-beam/RNode_Firmware.ino.bin) + rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.t-beam/RNode_Firmware.ino.bin) @sleep 3 - python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyUSB1 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin + python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyACM0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin upload-lora32_v10: arduino-cli upload -p /dev/ttyUSB0 --fqbn esp32:esp32:ttgo-lora32 diff --git a/RNode_Firmware.ino b/RNode_Firmware.ino index ae34b72..0bf649a 100644 --- a/RNode_Firmware.ino +++ b/RNode_Firmware.ino @@ -373,6 +373,7 @@ void flushQueue(void) { if (!queue_flushing) { queue_flushing = true; + led_tx_on(); uint16_t processed = 0; #if MCU_VARIANT == MCU_ESP32 @@ -394,6 +395,9 @@ void flushQueue(void) { processed++; } } + + lora_receive(); + led_tx_off(); } queue_height = 0; @@ -439,6 +443,7 @@ void update_airtime() { } longterm_channel_util = (float)longterm_channel_util_sum/(float)AIRTIME_BINS; + update_csma_p(); kiss_indicate_channel_stats(); #endif } @@ -446,7 +451,6 @@ void update_airtime() { void transmit(uint16_t size) { if (radio_online) { if (!promisc) { - led_tx_on(); uint16_t written = 0; uint8_t header = random(256) & 0xF0; @@ -471,9 +475,6 @@ void transmit(uint16_t size) { } LoRa.endPacket(); add_airtime(written); - led_tx_off(); - - lora_receive(); } else { // In promiscuous mode, we only send out // plain raw LoRa packets with a maximum @@ -500,9 +501,6 @@ void transmit(uint16_t size) { written++; } LoRa.endPacket(); add_airtime(written); - led_tx_off(); - - lora_receive(); } } else { kiss_indicate_error(ERROR_TXFAILED); @@ -934,7 +932,7 @@ void updateModemStatus() { } } else { if (dcd_count > 0) { - dcd_count--; + dcd_count = 0; } else { dcd_led = false; } @@ -1099,6 +1097,13 @@ void validate_status() { } } +#define _e 2.71828183 +#define _S 10.0 +float csma_slope(float u) { return (pow(_e,_S*u-_S/2.0))/(pow(_e,_S*u-_S/2.0)+1.0); } +void update_csma_p() { + csma_p = (uint8_t)((1.0-(csma_p_min+(csma_p_max-csma_p_min)*csma_slope(airtime)))*255.0); +} + void loop() { if (radio_online) { checkModemStatus(); @@ -1121,21 +1126,41 @@ void loop() { if (!airtime_lock) { if (queue_height > 0) { - if (!dcd_waiting) updateModemStatus(); + #if MCU_VARIANT == MCU_ESP32 - if (!dcd && !dcd_led) { - if (dcd_waiting) delay(lora_rx_turnaround_ms); + if (dcd_waiting && (millis() >= dcd_wait_until)) { dcd_waiting = false; } + if (!dcd_waiting) { + updateModemStatus(); + long check_time = millis(); - updateModemStatus(); - - if (!dcd) { - dcd_waiting = false; - flushQueue(); + if (!dcd) { + uint8_t csma_r = (uint8_t)random(256); + if (csma_p >= csma_r) { + flushQueue(); + } else { + dcd_waiting = true; + dcd_wait_until = check_time+csma_slot_ms; + } + } } + + #else + if (!dcd_waiting) updateModemStatus(); - } else { - dcd_waiting = true; - } + if (!dcd && !dcd_led) { + if (dcd_waiting) delay(lora_rx_turnaround_ms); + + updateModemStatus(); + + if (!dcd) { + dcd_waiting = false; + flushQueue(); + } + + } else { + dcd_waiting = true; + } + #endif } } diff --git a/Utilities.h b/Utilities.h index db02258..3c71618 100644 --- a/Utilities.h +++ b/Utilities.h @@ -912,6 +912,7 @@ void updateBitrate() { lora_symbol_time_ms = (1.0/lora_symbol_rate)*1000.0; lora_bitrate = (uint32_t)(lora_sf * ( (4.0/(float)lora_cr) / ((float)(pow(2, lora_sf))/((float)lora_bw/1000.0)) ) * 1000.0); lora_us_per_byte = 1000000.0/((float)lora_bitrate/8.0); + csma_slot_ms = lora_symbol_time_ms*10; } else { lora_bitrate = 0; }