Downlinks have nothing to do with ADR. More with the device class.
In Class A LoRaWAN nodes can only receive downlinks after they sent an uplink.
In Class C LoRaWAN nodes are in receive mode always.
But some LoRaWAN servers (like Chirpstack), allow an downlink only after the node has sent at least one uplink.
For the downlink decoding, I have an example that could be adapted to your application.
This code part checks the received packet and then parses the received data:
void lorawan_rx_handler(lmh_app_data_t *app_data)
Serial.printf("LoRa Packet received on port %d, size:%d, rssi:%d, snr:%d, data:%s\n",
app_data->port, app_data->buffsize, app_data->rssi, app_data->snr, app_data->buffer);
for (int idx = 0; idx < app_data->buffsize; idx++)
// Check if uplink was a send frequency change command
if ((app_data->port == 3) && (app_data->buffsize == 6))
if (app_data->buffer == 0xAA)
if (app_data->buffer == 0x55)
uint32_t new_send_frequency = 0;
new_send_frequency |= (uint32_t)(app_data->buffer) << 24;
new_send_frequency |= (uint32_t)(app_data->buffer) << 16;
new_send_frequency |= (uint32_t)(app_data->buffer) << 8;
new_send_frequency |= (uint32_t)(app_data->buffer);
Serial.printf("Received new send frequency %ld s\n", new_send_frequency);
// Save the new send frequency
LORAWAN_APP_INTERVAL = new_send_frequency * 1000;
// Set the timer to the new send frequency
if (LORAWAN_APP_INTERVAL != 0)
xTimerChangePeriod(appTimer, LORAWAN_APP_INTERVAL / portTICK_PERIOD_MS, 0);