Recently I open a post regarding some issues I was facing with Libelium and its LoraWAN stack implementation while connecting to my TTN backend.
After quite a lot of debuging, I have been able to point out that the issue lies on the fact that apparently the device runs into a lack of free channel to upload its payload. The bihaviour is quite weird since it happens after having sent the 8th packet, then I get the error _no_free_channel and it stalls there forever ( as shown below in the debug). Just mention that I register my motes as ABP.
My question is then, could someone explain me how could a device run out of free channels?
Thanks again,
Kind regards!
[debug] cmd:mac tx uncnf 3 0100000000C3
[debug] ans1:ok
[debug] ans2:invalid_param
[debug] ans3:not_joined
[debug] ans4:no_free_ch
[debug] ans:ok
::sendUnconfirmed: command->mac tx uncnf 3 0100000000C3
::sendUnconfirmed: status->[debug] found:mac_tx_ok
[debug] cmd:mac save
[debug] ans1:ok
[debug] ans2:invalid_param
[debug] ans:ok
Sent properly data: 0100000000C3
3. Send Unconfirmed packet OK
[debug] cmd:mac get upctr
[debug] ans1:
[debug] ans2:invalid_param
[debug] ans:
parseValue::The buffer is this ->7
[debug] cmd:mac get dnctr
[debug] ans1:
[debug] ans2:invalid_param
[debug] ans:
parseValue::The buffer is this ->1
Up Counter is:7
Down Counter is:1
[debug] cmd:mac tx uncnf 3 0100000000C3
[debug] ans1:ok
[debug] ans2:invalid_param
[debug] ans3:not_joined
[debug] ans4:no_free_ch
[debug] ans:ok
::sendUnconfirmed: command->mac tx uncnf 3 0100000000C3
::sendUnconfirmed: status->[debug] found:mac_tx_ok
[debug] cmd:mac save
[debug] ans1:ok
[debug] ans2:invalid_param
[debug] ans:ok
Sent properly data: 0100000000C3
3. Send Unconfirmed packet OK
[debug] cmd:mac get upctr
[debug] ans1:
[debug] ans2:invalid_param
[debug] ans:
parseValue::The buffer is this ->8
[debug] cmd:mac get dnctr
[debug] ans1:
[debug] ans2:invalid_param
[debug] ans:
parseValue::The buffer is this ->1
Up Counter is:8
Down Counter is:1
[debug] cmd:mac tx uncnf 3 0100000000C3
[debug] ans1:ok
[debug] ans2:invalid_param
[debug] ans3:not_joined
[debug] ans4:no_free_ch
[debug] ans:no_free_ch
::sendUnconfirmed: command->mac tx uncnf 3 0100000000C3
::sendUnconfirmed: status->[debug] cmd:mac save
[debug] ans1:ok
[debug] ans2:invalid_param
[debug] ans:ok
3. Send Unconfirmed packet error = 10
[debug] cmd:mac get upctr
[debug] ans1:
[debug] ans2:invalid_param
[debug] ans:
parseValue::The buffer is this ->8
[debug] cmd:mac get dnctr
[debug] ans1:
[debug] ans2:invalid_param
[debug] ans:
parseValue::The buffer is this ->1
Up Counter is:8
Down Counter is:1
[debug] cmd:mac tx uncnf 3 0100000000C3F5BE418022804200053FB7
[debug] ans1:ok
[debug] ans2:invalid_param
[debug] ans3:not_joined
[debug] ans4:no_free_ch
[debug] ans:no_free_ch
::sendUnconfirmed: command->mac tx uncnf 3 0100000000C3F5BE418022804200053FB7
::sendUnconfirmed: status->[debug] cmd:mac save
This means there is no channel available for a transmission due to the duty cycle of the channel. There are 8 channels, so after the 8th message, the device has to wait until it’s allowed to send on the first channel again.
Solutions:
Sending less frequently will not give you this error
Sending at a faster data rate will decrease the time you have to wait
Also, keep in mind that TTN has the Fair Use Policy, so if you reach the hardware-enforced limit, you’re way over the TTN Fair Use limit.
Thank for you explanation! I have taken as approach your first solution. Thus, in order to try to avoid the error, I have increased the time between transmission depending on the duty cycle that the example has.
So, I see that in the waspmote example the duty cycle (dC) is set to 100/40000=0.0025 thus according to Lora Standard(section 7.1.2) I should wait a time of Toff = TimeOnAir/dC - TimeOnAir, for a Tx power of 18dBm the TimeOnAir is around 0.21811s. Using that equation I should have a Toff = 87.03s.
Setting this time should grant that I can use again the same channel, however this is not like this, and I still face the same problem, is it something I am doing wrong? I think that a minute and a half is quite a time…
On the other hand, I wonder why I do face this issue with the Libelium stack and not with the TTUno for instance, is it due to the fact that in the TTUno the duty cycle is not set and therefore I am not compliant with the standard?
I personally don’t have experience with the Libelium stack, but its LoRa module is based on the RN2483 chip (same as The Things Uno). Therefore, the duty cycle enforced by the hardware/firmware in the RN2483 should be the same for both devices.
If you use SF7 you should be able to send every ~30 seconds without problems.
That is the weirdest thing, I am currently using such as SF ( I haven’t set it in the firmware it is apparently set by default ) according to what I see from TTN log coming from my Lora GW. So I cannot understand why I get no free channel even having set the tx time till 88s
Thanks for your reply, checking their code comments I can see that they are setting a real duty cycle of X[%] = 100/(dcycle +1) so if dcycle = 333333 => X[%] = 0.0002999994
dcycle = 40000 => X[%] = 0.0024999375
Which are really low right?
UPDATE: I have increased the dutycycle as @JDP suggested till 0.1% for all the channels, and it does seem to resolve the problem that I have been facing for so long, even people at Libelium didn’t know!!
/*!
* @brief This function sets the duty cycle on the given channel ID
*
* @param uint16_t dcycle: frequency to be set [0..65535]
* uint8_t channel: channel to be set [0..15]
*
* @remarks The "dcycle" value that needs to be configured can be obtained
* from the actual duty cycle X (in percentage) using the following formula:
* dcycle = (100/X) - 1
*
* @return
* @arg '0' if OK
* @arg '1' if error
* @arg '2' if no answer
* @arg '7' if input channel parameter error
* @arg '8' module does not support function
*/
uint8_t arduinoLoRaWAN::setChannelDutyCycle(uint8_t channel, uint16_t dcycle)
There is an optional feature within OTAA called CF-List. It can set up the channel plan, so must set duty cycle as well. But I don’t know if TTN has implemented CF-List.
TTN’s backend implements the CFList for the EU-868 band. However, the CFList does not include duty cycle information (see the spec) so you have to make sure that your device is configured for the European duty cycles. As far as I know, the default firmware and configuration do this correctly.
Unfortunately, after TTN provides the CFList in the join accept message, still manual action is required.
From the RN2483 documentation:
“The default settings consider only the three default channels (0-2), and their default duty cycle is 0.33%. If a new channel is created either by the server or by the user, all the channels (including the default ones) must be updated by the user in terms of duty cycle to comply with the ETSI regulations.”
@JDP: it would be nice of the RN2483 module would be able to automatically take care of this.
Admittedly I should have checked this but I was rushing yesterday. I’m surprised - to me it seems like the intention of the CF-List function is to allow the network to configure a default node to the networks local preferences. If application intervention is needed, it seems like a bit of a fail in the spec.
As an aside, when wondering why the error might only show after sending a few messages quickly after one another, see the Duty Cycle Wiki page. This explains how some modules (such as the RN2483) implement a per-channel duty cycle rather than an overall duty cycle.