Added airtime limiting and channel timing stat reporting over serial/USB/bluetooth

This commit is contained in:
Mark Qvist 2023-09-13 20:05:05 +02:00
parent f2e1791562
commit eb7b5c6c26
5 changed files with 139 additions and 20 deletions

View File

@ -359,6 +359,9 @@
float us_per_byte = 0.0; float us_per_byte = 0.0;
#define current_airtime_bin(void) (millis()%AIRTIME_LONGTERM_MS)/AIRTIME_BINLEN_MS #define current_airtime_bin(void) (millis()%AIRTIME_LONGTERM_MS)/AIRTIME_BINLEN_MS
#endif #endif
float st_airtime_limit = 0.0;
float lt_airtime_limit = 0.0;
bool airtime_lock = false;
bool stat_signal_detected = false; bool stat_signal_detected = false;
bool stat_signal_synced = false; bool stat_signal_synced = false;

View File

@ -33,6 +33,8 @@
#define CMD_DETECT 0x08 #define CMD_DETECT 0x08
#define CMD_IMPLICIT 0x09 #define CMD_IMPLICIT 0x09
#define CMD_LEAVE 0x0A #define CMD_LEAVE 0x0A
#define CMD_ST_ALOCK 0x0B
#define CMD_LT_ALOCK 0x0C
#define CMD_PROMISC 0x0E #define CMD_PROMISC 0x0E
#define CMD_READY 0x0F #define CMD_READY 0x0F
@ -40,6 +42,7 @@
#define CMD_STAT_TX 0x22 #define CMD_STAT_TX 0x22
#define CMD_STAT_RSSI 0x23 #define CMD_STAT_RSSI 0x23
#define CMD_STAT_SNR 0x24 #define CMD_STAT_SNR 0x24
#define CMD_STAT_CHTM 0x25
#define CMD_BLINK 0x30 #define CMD_BLINK 0x30
#define CMD_RANDOM 0x40 #define CMD_RANDOM 0x40

View File

@ -312,6 +312,8 @@ bool startRadio() {
} else { } else {
radio_online = true; radio_online = true;
init_channel_stats();
setTXPower(); setTXPower();
setBandwidth(); setBandwidth();
setSpreadingFactor(); setSpreadingFactor();
@ -395,6 +397,9 @@ void flushQueue(void) {
queue_height = 0; queue_height = 0;
queued_bytes = 0; queued_bytes = 0;
#if MCU_VARIANT == MCU_ESP32
update_airtime();
#endif
queue_flushing = false; queue_flushing = false;
} }
@ -427,6 +432,8 @@ void update_airtime() {
longterm_channel_util_sum += longterm_bins[bin]; longterm_channel_util_sum += longterm_bins[bin];
} }
longterm_channel_util = (float)longterm_channel_util_sum/(float)AIRTIME_BINS; longterm_channel_util = (float)longterm_channel_util_sum/(float)AIRTIME_BINS;
kiss_indicate_channel_stats();
#endif #endif
} }
@ -650,6 +657,52 @@ void serialCallback(uint8_t sbyte) {
startRadio(); startRadio();
kiss_indicate_radiostate(); kiss_indicate_radiostate();
} }
} else if (command == CMD_ST_ALOCK) {
if (sbyte == FESC) {
ESCAPE = true;
} else {
if (ESCAPE) {
if (sbyte == TFEND) sbyte = FEND;
if (sbyte == TFESC) sbyte = FESC;
ESCAPE = false;
}
if (frame_len < CMD_L) cmdbuf[frame_len++] = sbyte;
}
if (frame_len == 2) {
uint16_t at = (uint16_t)cmdbuf[0] << 8 | (uint16_t)cmdbuf[1];
if (at == 0) {
st_airtime_limit = 0.0;
} else {
st_airtime_limit = (float)at/(100.0*100.0);
if (st_airtime_limit >= 1.0) { st_airtime_limit = 0.0; }
}
kiss_indicate_st_alock();
}
} else if (command == CMD_LT_ALOCK) {
if (sbyte == FESC) {
ESCAPE = true;
} else {
if (ESCAPE) {
if (sbyte == TFEND) sbyte = FEND;
if (sbyte == TFESC) sbyte = FESC;
ESCAPE = false;
}
if (frame_len < CMD_L) cmdbuf[frame_len++] = sbyte;
}
if (frame_len == 2) {
uint16_t at = (uint16_t)cmdbuf[0] << 8 | (uint16_t)cmdbuf[1];
if (at == 0) {
lt_airtime_limit = 0.0;
} else {
lt_airtime_limit = (float)at/(100.0*100.0);
if (lt_airtime_limit >= 1.0) { lt_airtime_limit = 0.0; }
}
kiss_indicate_lt_alock();
}
} else if (command == CMD_STAT_RX) { } else if (command == CMD_STAT_RX) {
kiss_indicate_stat_rx(); kiss_indicate_stat_rx();
} else if (command == CMD_STAT_TX) { } else if (command == CMD_STAT_TX) {
@ -885,7 +938,11 @@ void updateModemStatus() {
if (dcd_led) { if (dcd_led) {
led_rx_on(); led_rx_on();
} else { } else {
led_rx_off(); if (airtime_lock) {
led_indicate_airtime_lock();
} else {
led_rx_off();
}
} }
} }
@ -905,7 +962,10 @@ void checkModemStatus() {
total_channel_util = local_channel_util + airtime; total_channel_util = local_channel_util + airtime;
if (total_channel_util > 1.0) total_channel_util = 1.0; if (total_channel_util > 1.0) total_channel_util = 1.0;
longterm_bins[current_airtime_bin()] = total_channel_util; int16_t cb = current_airtime_bin();
uint16_t nb = cb+1; if (nb == AIRTIME_BINS) { nb = 0; }
if (total_channel_util > longterm_bins[cb]) longterm_bins[cb] = total_channel_util;
longterm_bins[nb] = 0.0;
update_airtime(); update_airtime();
} }
@ -1047,23 +1107,29 @@ void loop() {
kiss_indicate_stat_snr(); kiss_indicate_stat_snr();
kiss_write_packet(); kiss_write_packet();
} }
airtime_lock = false;
if (st_airtime_limit != 0.0 && airtime >= st_airtime_limit) airtime_lock = true;
if (lt_airtime_limit != 0.0 && longterm_airtime >= lt_airtime_limit) airtime_lock = true;
#endif #endif
if (queue_height > 0) { if (!airtime_lock) {
if (!dcd_waiting) updateModemStatus(); if (queue_height > 0) {
if (!dcd_waiting) updateModemStatus();
if (!dcd && !dcd_led) { if (!dcd && !dcd_led) {
if (dcd_waiting) delay(lora_rx_turnaround_ms); if (dcd_waiting) delay(lora_rx_turnaround_ms);
updateModemStatus(); updateModemStatus();
if (!dcd) { if (!dcd) {
dcd_waiting = false; dcd_waiting = false;
flushQueue(); flushQueue();
}
} else {
dcd_waiting = true;
} }
} else {
dcd_waiting = true;
} }
} }

Binary file not shown.

View File

@ -218,6 +218,13 @@ void led_indicate_error(int cycles) {
#endif #endif
} }
// LED Indication: Airtime Lock
void led_indicate_airtime_lock() {
#if HAS_NP == true
npset(32,0,2);
#endif
}
// LED Indication: Boot Error // LED Indication: Boot Error
void led_indicate_boot_error() { void led_indicate_boot_error() {
#if HAS_NP == true #if HAS_NP == true
@ -687,6 +694,44 @@ void kiss_indicate_frequency() {
serial_write(FEND); serial_write(FEND);
} }
void kiss_indicate_st_alock() {
uint16_t at = (uint16_t)(st_airtime_limit*100*100);
serial_write(FEND);
serial_write(CMD_ST_ALOCK);
escaped_serial_write(at>>8);
escaped_serial_write(at);
serial_write(FEND);
}
void kiss_indicate_lt_alock() {
uint16_t at = (uint16_t)(lt_airtime_limit*100*100);
serial_write(FEND);
serial_write(CMD_LT_ALOCK);
escaped_serial_write(at>>8);
escaped_serial_write(at);
serial_write(FEND);
}
void kiss_indicate_channel_stats() {
#if MCU_VARIANT == MCU_ESP32
uint16_t ats = (uint16_t)(airtime*100*100);
uint16_t atl = (uint16_t)(longterm_airtime*100*100);
uint16_t cls = (uint16_t)(total_channel_util*100*100);
uint16_t cll = (uint16_t)(longterm_channel_util*100*100);
serial_write(FEND);
serial_write(CMD_STAT_CHTM);
escaped_serial_write(ats>>8);
escaped_serial_write(ats);
escaped_serial_write(atl>>8);
escaped_serial_write(atl);
escaped_serial_write(cls>>8);
escaped_serial_write(cls);
escaped_serial_write(cll>>8);
escaped_serial_write(cll);
serial_write(FEND);
#endif
}
void kiss_indicate_btpin() { void kiss_indicate_btpin() {
#if HAS_BLUETOOTH #if HAS_BLUETOOTH
serial_write(FEND); serial_write(FEND);
@ -1182,13 +1227,15 @@ void unlock_rom() {
} }
void init_channel_stats() { void init_channel_stats() {
for (uint16_t ai = 0; ai < DCD_SAMPLES; ai++) { util_samples[ai] = false; } #if MCU_VARIANT == MCU_ESP32
for (uint16_t ai = 0; ai < AIRTIME_BINS; ai++) { airtime_bins[ai] = 0; } for (uint16_t ai = 0; ai < DCD_SAMPLES; ai++) { util_samples[ai] = false; }
for (uint16_t ai = 0; ai < AIRTIME_BINS; ai++) { longterm_bins[ai] = 0.0; } for (uint16_t ai = 0; ai < AIRTIME_BINS; ai++) { airtime_bins[ai] = 0; }
local_channel_util = 0.0; for (uint16_t ai = 0; ai < AIRTIME_BINS; ai++) { longterm_bins[ai] = 0.0; }
total_channel_util = 0.0; local_channel_util = 0.0;
airtime = 0.0; total_channel_util = 0.0;
longterm_airtime = 0.0; airtime = 0.0;
longterm_airtime = 0.0;
#endif
} }
typedef struct FIFOBuffer typedef struct FIFOBuffer