I have developed a custom xbee3 end device using micropython (SM=0, CE=6) based on the zigbee pro stack (ZS=2) so it can interact with external coordinators. I perform ZDO pass through to perform the necessary interview steps, with encryption and a fixed link key in a centralized trust center.
When I open the join window from the coordinator the device can be paired without problem and after closing it I can restart the end device as many times as I want it since it will rejoin the network. However, as soon as I move the end device away and loses connection it won’t rejoin the network again until I reopen the join window. I have played with node join time (“NJ”), network timeout (“NW”), commissioning (“CB”) and a bunch other things with no avail (everything issued on the end device of course, with a proper saved “ID” and all stored to memory); when the end device loses connection it forgets the coordinator. Is there a way to make the end device never leave its parent? Some post suggest this is not possible as it is stack dependent, but I find it to be a weird behavior.
Thank you in advance
No there is not a way to do that as that would violate IEEE and Zigbee standards.
What you are running into is a Network Watchdog timer and for End Devices to forget the parent info after 3 unsuccessful communications attempts with its parent. It will then try a soft rejoin. After 3 more attempts, it will go into a full join process.
It’s the answer I would expect, thank you. By the way, is there any option to customize this behavior? For example, changing the period between those 3 communication attempts. I haven’t read anything in this regard in the docs if I recall correctly, but just to be sure.
The attempts are 3x the sleep times. I would suggest reading over the documentation about the sleep commands (SM, SP, ST, SO, PO, and especially the ET command.)
The thing here is that I’m using micropython sleep (SM=6) so in theory the sleep option commands (SP, ST, SO) wouldn’t have any effect, right? And as I understand it, ET command determines the time after which the parent will forget the child, and not the way around, so how can it be useful in this situation?
Edit: I can emulate the cyclic sleep behavior (3x the sleep times you mentioned) by idling the device and then using the “poll_now” command. In this way, the end device will only forget its parent after 3 poll_now requests (indicated by modem status = 0x03, disassociated)
The problem arises when I transmit data. I have tried the combinations of polling/not polling and transmitting with tx_options = 0/1 (ACK, not ACK), but as soon as the first transmit fails, the device gets disassociated (indicated by modem status = 0x03, disassociated).
Is there a way to check if an ACK was received after issuing a “poll_now”, so I can decide if I want to transmit data?
I think I’m seeing this same issue. I’ll be running a loop in micropython with data being transmitted, then what appears to be randomly the device stopps transmission, there is no output for exception from the try block, and the device current jumps to about 20mA at 2.5V continuously. The python environment doesn’t react and any remote AT commands and cycling power on the end device seems to be the only fix. I’ve even changed the joining period on the coordinator to FF so devices can always join but the end device doesn’t seem to ever pair back up once it hits this state. Should the Micropython environment be doing more to manage this connection?
With ACK enabled when transmitting (default mode) I’ve also experienced sometimes that the system hangs if no coordinator/parent is available, implementing a watchdog can help with that.
I would suggest adding a watchdog timer in your code.