XBee3 Cellular LTE-M/NB-IoT - Long Term Connectivity & Stability

Hi,

Like @Steven_Keller, I am moving away from Particle after years of working with their products. I have been developing with the XBee3 Cellular LTE-M/NB-IoT modem and the Xbee3 ecosystem as a whole. I am able to easily and consistently get the Xbee3 cellular modem to connect to AT&T and T-Mobile using a Hologram SIM and the following relevant Digi XCTU settings:

  • AN: hologram
  • CP: 0 (auto detect)
  • N3#: 2 (LTE-M Only)

An issue I am running into is not getting connected, but actually having a usable connection. The behavior is such that the modem is returning a True for the cellular.isconnected() method which signifies the modem is connected to a cellular network and has a valid IP address. I am also able to open a socket, and the modem sends the data without catching an error, but it will stop coming through on the cloud side (Ubidots) after a while.

I have a transmission counter set for each send, and it will be chugging along at the set 10min interval and then the transmission count will jump because the cloud side did not receive the data, but the modem thought it was sent so it counted it.

As a test, I purchased a AT&T IOT SIM and put it in the exact same device with the same setup only changing the APN to match the required from AT&T and after 24 hours of testing it has not missed one transmission, where the other identical setup (with Hologram SIM) stopped getting data to the cloud after about an hour from starting the test. At the time the Hologram SIM was showing AT&T Hologram as the network operator.

I could me missing a vital setting or best practice, so I wanted to put it out there to see if anyone had similar experience or suggestions/advice.

Thank you!

Is it possible the socket it closing due to timeout? I think different providers have different timeout thresholds. I think that is something Particle touted that theirs was something like 20minues when most providers were 1 or 2 minutes.

@Steven_Keller thank you for your response.

I don’t think that the socket is closed. Early in my testing I was struggling with the socket timing out and I was getting a time out error “ENOTCONN” when I was opening and closing a socket after each send.

However, because of the nature of the sleepy network that I am building some nodes can wake and send their data in a short timespan between each other.

As a result, I was noticing that the module could not open, close and re-open the socket quick enough without receiving an error. As a result, I was getting errors and missing data from sleepy sensors.

This brought me to leaving the socket open and using a timer to open and close the socket based on an amount of elapsed time (5mins) so I can refresh the socket so it is ready at a moments notice.

I also added the brute force method shown below to catch any instances where the socket might have gone bad and I need to refresh it on the fly. As you will see there are multiple attempts to get the socket to work with a final action of performing a clean shutdown of the entire module.

       request = bytes(    # loading Ubidots payload
       'POST /api/v1.6/devices/%s HTTP/1.1\r\nHost: industrial.api.ubidots.com\r\nX-Auth-Token: '
       '%s\r\nContent-Type: application/json\r\nContent-Length: %s\r\n\r\n%s\r\n' % (
           fromNodeID, UBIDOTS_TOKEN, len(body), body), 'utf8')
        try:        # allows for capturing exceptions due to failed send
            s.send(request)     # sending Ubidots payload
            print("Cellular Send: ", body)
            attempt = 1
            print("1st attempt successful")
        except:     # broad exception; tries socket close and reopen to remedy error
            print("1st try exception")
            try:
                s.close()
                s = usocket.socket()
                time.sleep_ms(1)
                s.connect(("industrial.api.ubidots.com", 80))
                s.settimeout(600)  # sets Xbee socket timeout (secs)
                time.sleep_ms(1)
                s.send(request)  # sending Ubidots payload
                print("2nd attempt successful")
                print("Cellular Send: ", body)
                attempt = 2
            except:
                try:
                    print("2nd try exception")
                    s.close()
                    s = usocket.socket()
                    time.sleep_ms(1)
                    s.connect(("industrial.api.ubidots.com", 80))
                    s.settimeout(600)  # sets Xbee socket timeout (secs)
                    time.sleep_ms(1)
                    s.send(request)  # sending Ubidots payload
                    print("3rd attempt successful")
                    print("Cellular Send: ", body)
                    attempt = 3
                except:     # resets module if socket close and reopen does not remedy error
                    try:
                        print("3rd try exception")
                        s.close()
                        s = usocket.socket()
                        time.sleep_ms(50)
                        s.connect(("industrial.api.ubidots.com", 80))
                        s.settimeout(600)  # sets Xbee socket timeout (secs)
                        time.sleep_ms(50)
                        s.send(request)  # sending Ubidots payload
                        print("4th attempt successful")
                        print("Cellular Send: ", body)
                        attempt = 4
                    except:  # resets module if socket close and reopen does not remedy error
                        print("4th try exception")
                        print("failed closing & opening socket. Rebooting Cell Module")
                        c.shutdown(reset=True)

I have observed that when the data is not making it to the cloud that the module has not been reset and it is typically making it to the 2nd or 3rd attempt. For this reason I do not believe that it is a closed socket issue.

I hope this provides a bit more detail. Possibly I am opening and closing faster than the socket can handle it is is getting stuck in a grey area where it thinks it can send data but it actually cannot.

Thank you.

@backpacker87 I have not done too much with uPython on the XBee cellular other than a few test projects so I am probably don’t have much to offer.

Do you read back the response from Ubidots after a send? It is my understanding that the socket timeout of 600 will wait 600 seconds after you do a socket read to get a response before it times out. Are you getting a response back in that time period?

I am still wondering if the network is breaking the socket after a period of time and not doing a graceful close which would allow the modem to know it is closed. This to me would be the only variable that is changing between the 2 different cellular providers since your code doesn’t seem to have the problem when running directly on ATT.

It would be a big change but have you tried MQTT? Ubidots supports MQTT and it is a far more lightweight protocol and it handles the socket keepalives much better I think than HTTPS. There is a uPython MQTT library for the xbee.

@Steven_Keller thank you for your help. Well my dirty secret is that I am not waiting on a response through a dump_socket. This was another issue I worked there where when I was waiting on a response it was taking ~65 seconds (Ubidots forum post regarding this).

This may have been a fatal mistake that could have lead to idneitfying a root issue, but at the time I was willing to do anything just to get the thing to send more than 3 times in a row!

I am going to go back to basics and go back to this tutorial to try and wait for a response again and see if I get the same results between the Hologram SIM and the AT&T SIM.

I am also going to to look into what it will take to move over to MQTT, thank you for this suggestion.

UPDATE: It appears the AT&T SIM is now acting up in the same way as the Hologram SIM (missing data). Based on your feedback and these new findings I am thinking the root issue is in the connection protocol and not the cellular side of things.

@Steven_Keller, I wanted to thank you again for brainstorming with me and providing advice. I put in a couple hours on Friday and switched over to MQTT. I ran a test over the weekend with a modem pushing every 1 min for a day and then switched it to every 60mins for another day; it did not skip a beat.

Also, my data consumption has significantly decreased which is also a major bonus.

I am going to perform the next level of testing with multiple end nodes being routed through the modem, but I have a feeling this is going to work fine as well.

Bottom line, I think switching over to MQTT may have fixed the fundamental issues I have been battling for months now. Thank you!

I will touch back in after another week or so of testing to give the final results.

@backpacker87, that is fantastic news. I am glad you were able to come up with a solution.
HTTP is a great and versatile protocol but MQTT is purpose-built for IoT and moving data over unreliable and slow wireless connections. I am working on my first real MQTT application. I am using it to connect to Azure IoT using a Nymbelink modem and an embedded processor.

Keep us posted on your results over the next few weeks.

1 Like