Repeat batch ACKs to cover RX latency
- Add ACK_REPEAT_COUNT/ACK_REPEAT_DELAY_MS and repeat ACK sends - Update README with repeat-ACK behavior
This commit is contained in:
@@ -239,6 +239,7 @@ Notes:
|
|||||||
- Total power is computed on receiver as `p1 + p2 + p3`.
|
- Total power is computed on receiver as `p1 + p2 + p3`.
|
||||||
- Sender error counters are carried in the batch header and applied to all samples.
|
- Sender error counters are carried in the batch header and applied to all samples.
|
||||||
- Receiver ACKs MeterBatch as soon as the batch is reassembled, before MQTT/web/UI work, to avoid missing the sender ACK window.
|
- Receiver ACKs MeterBatch as soon as the batch is reassembled, before MQTT/web/UI work, to avoid missing the sender ACK window.
|
||||||
|
- Receiver repeats ACKs (`ACK_REPEAT_COUNT`) spaced by `ACK_REPEAT_DELAY_MS` to cover sender RX latency.
|
||||||
|
|
||||||
## Device IDs
|
## Device IDs
|
||||||
- Derived from WiFi STA MAC.
|
- Derived from WiFi STA MAC.
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ constexpr uint32_t METER_SEND_INTERVAL_MS = 30000;
|
|||||||
constexpr uint32_t BATTERY_SAMPLE_INTERVAL_MS = 60000;
|
constexpr uint32_t BATTERY_SAMPLE_INTERVAL_MS = 60000;
|
||||||
constexpr float BATTERY_CAL = 1.083f;
|
constexpr float BATTERY_CAL = 1.083f;
|
||||||
constexpr uint32_t BATCH_ACK_TIMEOUT_MS = 3000;
|
constexpr uint32_t BATCH_ACK_TIMEOUT_MS = 3000;
|
||||||
|
constexpr uint8_t ACK_REPEAT_COUNT = 3;
|
||||||
|
constexpr uint32_t ACK_REPEAT_DELAY_MS = 200;
|
||||||
constexpr uint8_t BATCH_MAX_RETRIES = 2;
|
constexpr uint8_t BATCH_MAX_RETRIES = 2;
|
||||||
constexpr uint8_t METER_BATCH_MAX_SAMPLES = 30;
|
constexpr uint8_t METER_BATCH_MAX_SAMPLES = 30;
|
||||||
constexpr uint8_t BATCH_QUEUE_DEPTH = 10;
|
constexpr uint8_t BATCH_QUEUE_DEPTH = 10;
|
||||||
|
|||||||
15
src/main.cpp
15
src/main.cpp
@@ -497,10 +497,17 @@ static void send_batch_ack(uint16_t batch_id, uint16_t sender_id) {
|
|||||||
write_u16_le(&ack.payload[0], batch_id);
|
write_u16_le(&ack.payload[0], batch_id);
|
||||||
write_u16_le(&ack.payload[2], sender_id);
|
write_u16_le(&ack.payload[2], sender_id);
|
||||||
write_u16_le(&ack.payload[4], g_short_id);
|
write_u16_le(&ack.payload[4], g_short_id);
|
||||||
if (SERIAL_DEBUG_MODE) {
|
uint8_t repeats = ACK_REPEAT_COUNT == 0 ? 1 : ACK_REPEAT_COUNT;
|
||||||
serial_debug_printf("ack: tx batch_id=%u to sender=%04X", batch_id, sender_id);
|
for (uint8_t i = 0; i < repeats; ++i) {
|
||||||
|
if (SERIAL_DEBUG_MODE) {
|
||||||
|
serial_debug_printf("ack: tx repeat %u/%u batch_id=%u", static_cast<unsigned>(i + 1),
|
||||||
|
static_cast<unsigned>(repeats), batch_id);
|
||||||
|
}
|
||||||
|
lora_send(ack);
|
||||||
|
if (i + 1 < repeats && ACK_REPEAT_DELAY_MS > 0) {
|
||||||
|
delay(ACK_REPEAT_DELAY_MS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lora_send(ack);
|
|
||||||
lora_receive_continuous();
|
lora_receive_continuous();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -852,7 +859,7 @@ static void sender_loop() {
|
|||||||
if (ack_sender == g_short_id && ack_receiver == ack_pkt.device_id_short &&
|
if (ack_sender == g_short_id && ack_receiver == ack_pkt.device_id_short &&
|
||||||
g_batch_ack_pending && ack_id == g_last_sent_batch_id) {
|
g_batch_ack_pending && ack_id == g_last_sent_batch_id) {
|
||||||
g_last_acked_batch_id = ack_id;
|
g_last_acked_batch_id = ack_id;
|
||||||
serial_debug_printf("ack: ok batch_id=%u", ack_id);
|
serial_debug_printf("ack: rx ok batch_id=%u", ack_id);
|
||||||
finish_inflight_batch();
|
finish_inflight_batch();
|
||||||
} else if (SERIAL_DEBUG_MODE) {
|
} else if (SERIAL_DEBUG_MODE) {
|
||||||
serial_debug_printf("ack: reject batch_id=%u sender=%u receiver=%u exp_batch=%u exp_sender=%u",
|
serial_debug_printf("ack: reject batch_id=%u sender=%u receiver=%u exp_batch=%u exp_sender=%u",
|
||||||
|
|||||||
Reference in New Issue
Block a user