Do LoRa(WAN) nodes perform any activity detection and/or collision detection?

:warning: The following does not apply to all regions. It applies to, e.g., the EU region but regions such as Korea, do implement Listen Before Talk in LoRaWAN.

I see a lot of references to the ALOHA protocol, as in: nodes transmit whenever they feel like it, which is also why regulations require a maximum duty cycle. Like from the LoRaWAN specifications:

End-devices may transmit on any channel available at any time, using any available data rate, as long as the following rules are respected:

  • The end-device changes channel in a pseudo-random fashion for every transmission. The resulting frequency diversity makes the system more robust to interferences.
  • The end-device respects the maximum transmit duty cycle relative to the sub-band used and local regulations.
  • The end-device respects the maximum transmit duration (or dwell time) relative to the sub-band used and local regulations.


Bi-directional end-devices (Class A): End-devices of Class A allow for bi-directional communications whereby each end-device’s uplink transmission is followed by two short downlink receive windows. The transmission slot scheduled by the end-device is based on its own communication needs with a small variation based on a random time basis (ALOHA-type of protocol).

To me, this reads like “fire and forget”. Even more, the LoRaWAN “Confirmed Data Messages” in the same specifications explain how a node may retransmit its data if an ACK is requested but not received (which could have been caused by collisions), but does not mention any collision detection.

Though “ALOHA-type of protocol” is not very specific, so-called “pure” ALOHA seems to check for collisions while transmitting; from Wikipedia:

The first version of the protocol (now called “Pure ALOHA”, and the one implemented in ALOHAnet) was quite simple:

  • If you have data to send, send the data
  • If, while you are transmitting data, you receive any data from another station, there has been a message collision. All transmitting stations will need to try resending “later”.

Note that the first step implies that Pure ALOHA does not check whether the channel is busy before transmitting.

And the Semtech LoRa FAQ explains that a node could detect LoRa(WAN) activity:

What is the process of the LoRa® CAD (Channel Activity Detector) mode?

Instead of using a RSSI (Received Signal Strength Indicator) method to identify if a signal is present the channel activity detector (CAD) is used to detect the presence of a LoRa signal. The CAD detection has the advantage of being much faster than a typical RSSI detection and the capability to differentiate between noise and a desired LoRa signal. The CAD process requires two symbols, and if the CAD is detected, the CAD_Detected interrupt will be asserted and the device will stay in RX mode to receive the data payload.

But even if “CAD” is used in LoRaWAN, then maybe such is only used for Class B and C end-devices, that want to preserve battery life but still need like to know if they can expect any data?

So: does (should) a LoRa(WAN) node check if channels are busy before starting to transmit, and/or perform any collision detection while sending?


Found elsewhere in this forum:

Definitions of “pure” ALOHA might differ then.

It seems no detection is done, and “confirmed uplinks” might be needed to tell if data was received. (But the number of confirmed uplinks is limited too.)

As my conclusion is solely based on browsing documentation and code, some background below.

For plain LoRa, the Semtech SX127x datasheet shows that collision detection is available while receiving, but no word about transmitting.

For transmitting, given the following operating modes:

  • […]
  • STANDBY: Both Crystal oscillator and LoRa baseband blocks are turned on. RF part and PLLs are disabled.
  • TX: When activated the SX1276/77/78/79 powers all remaining blocks required for transmit, ramps the PA, transmits the packet and returns to Standby mode.

…the datasheet describes the following in the Data Transmission Sequence:

  • […]
  • The LoRa FIFO can only be filled in Standby mode.
  • Data transmission is initiated by sending TX mode request.
  • Upon completion the TxDone interrupt is issued and the radio returns to Standby mode.

So: all without a word about activity detection or collision detection.

To detect if one should switch on receiving, channel activity detection is described as:

  • […]
  • Once the calculation is finished the modem generates the CadDone interrupt. If the correlation was successful, CadDetected is generated simultaneously.
  • The chip goes back to Standby mode.
  • If a preamble was detected, clear the interrupt, then initiate the reception by putting the radio in RX single mode or RX continuous mode.

For LoRaWAN, the IBM LMiC library also performs no activity detection before sending, neither in the high level examples, nor in the lower level library code. Like in radio.c:

static void opmode (u1_t mode) {
    writeReg(RegOpMode, (readReg(RegOpMode) & ~OPMODE_MASK) | mode);

static void txlora () {
    // select LoRa modem (from sleep mode)
    //writeReg(RegOpMode, OPMODE_LORA);
    ASSERT((readReg(RegOpMode) & OPMODE_LORA) != 0);

    // enter standby mode (required for FIFO loading))
    // configure LoRa modem (cfg1, cfg2)
    // configure frequency
    // configure output power
    writeReg(RegPaRamp, (readReg(RegPaRamp) & 0xF0) | 0x08); // set PA ramp-up time 50 uSec
    // set sync word
    writeReg(LORARegSyncWord, LORA_MAC_PREAMBLE);
    // set the IRQ mapping DIO0=TxDone DIO1=NOP DIO2=NOP
    // clear all radio IRQ flags
    writeReg(LORARegIrqFlags, 0xFF);
    // mask all IRQs but TxDone
    writeReg(LORARegIrqFlagsMask, ~IRQ_LORA_TXDONE_MASK);

    // initialize the payload size and address pointers    
    writeReg(LORARegFifoTxBaseAddr, 0x00);
    writeReg(LORARegFifoAddrPtr, 0x00);
    writeReg(LORARegPayloadLength, LMIC.dataLen);
    // download buffer to the radio FIFO
    writeBuf(RegFifo, LMIC.frame, LMIC.dataLen);

    // enable antenna switch for TX
    // now we actually start the transmission

And when handling the LoRa interrupts in radio_irq_handler, only TxDone, RxDone and RxTimeout are expected, and for the first nothing is validated either:

// called by hal ext IRQ handler
// (radio goes to stanby mode after tx/rx operations)
void radio_irq_handler (u1_t dio) {
    ostime_t now = os_getTime();
    if( (readReg(RegOpMode) & OPMODE_LORA) != 0) { // LORA modem
        u1_t flags = readReg(LORARegIrqFlags);
        if( flags & IRQ_LORA_TXDONE_MASK ) {
            // save exact tx time
            LMIC.txend = now - us2osticks(43); // TXDONE FIXUP
        } else if( flags & IRQ_LORA_RXDONE_MASK ) {
        } else if( flags & IRQ_LORA_RXTOUT_MASK ) {

LBT (listen-before-talk) may be energy-prohibitive on the end-device side (though I would love to be proven wrong). Then Gateways have the energy budget for LBT, but cannot use it as they need to conform to tight transmit timing due to small end-device RX windows (except for the rare case of class C end-devices).

Luckily, gateways can instruct end-devices to avoid certain channels (via LinkADRReq MAC command) if the gateways detects the channel is in use (say, by a non-LoRa user). This would need to be implemented in the gateway firmware.

1 Like

@nmap, i understand that “Gateways have the energy budget for LBT, but cannot use it as they need to conform to tight transmit timing due to small end-device RX windows”.

I also wonder about why LoRaWAN devices does not use LBT or not implemented yet. In wireless sensor network, many nodes use LBT or CSMA/CA to avoid collision which has power consumption but do that.

1 Like