Avoiding timeouts & other hangs caused by ubidots connection

The project I’m working on controls something (a pet door) in real time, using an Arduino NANO 33 IOT. It checks sensors for conditions that need to be acted on promptly. It is also connected to Ubidots. What I am finding is that the ubidots connection some times goes down, and when it does, there are rather long timeouts.

The only solution I can think of is to use two Arduinos, dedicating one to the Ubidots connection and the other to operating the control system. Otherwise this thing might kill a cat… :frowning:

Will

Greetings, can you expand more about “the ubidots connection”, I really do not get if the issue is related with your local network or with something related with Ubidots. What protocol are you using to retrieve data?

All the best

I am using MQTT. My local network is fast, and constantly monitored by hardware (Fingbox). There were no outages reported during the time I observed the Ubidots connection failures… FYI - I am currently on a STEM account.

When I watch the serial monitor from the Arduino NANO IOT I see that it sometimes loses the connection to Ubidots and has to reconnect again. This takes some time, usually several seconds. While this is happening the main loop of the program is suspended, waiting for the “Reconnect” function to finish.

Thanks,
Will

Thanks for your comments, the MQTT Ubidots broker closes opened sockets from time to time to avoid memory issues, this is due because many of our users usually do not close opened sockets after they publish and letting these instances opened may derive in different sort of problems that would affect our availability, that is why we always recommend to have a reconnection routine in the device side.

Said this, the way of solving your problem is not buying another arduino but refactoring your firmware, there is not way to make lower the connection time after a socket closing (it takes what it needs depending on multiple factors) but you may implement at your routine threads to handle cloud connection and sensor read routines, or, if you have more firmware experience, you may use queues to manage them; these are usually ways in firmware development to make non-blocking routines.

All the best

Thanks. I took a look at the “threads” link you provided. I do not believe it will help in this case. It is protothreading only, if a thread is running, it will not run any other threads until that thread completes. Unless I am missing something I do not see how that will help - if I have a thread that manages the connection to Ubidots, and it needs to re-connect, that will take several seconds, during which time the other threads will not run. Queuing is very interesting, but it is not multi-tasking (I wrote the queue scheduler for some of IBM’s mainframe operating systems back “in the day”). There appear to be a couple multi-tasking libraries for Arduino - I will take a look at using one of those. To make this work properly I would think we need real multitasking (time slicing between tasks), with some way to have the sensor task(s) interrupt the Ubidots task(s)…
Will

Hi there, you are right, there is not really multi-thread using arduino, I missread your initial message and I thought that you were reading just sensors, but you are implementing control routines so queues are not a proper approach to reach the goal. Multitasking is an interesting way of solving the problem, but probably hardware interruptions are enough to stop change your main loop routine at any time needed by the control routine. Let us to know if we can assist you in anything else needed to see your project finished.

All the best

It gets more interesting. For the Nano 33 IOT the timers are different, the normal ones don’t appear to work. I found this for the MKR1010 which I think is the same processor?
https://forum.arduino.cc/index.php?topic=597853.0

I tried this and it runs for a while and then crashes (hangs). I suspect some interaction between my use of this timer and Ubidots? Do you know what timers Ubidots uses, or more importantly which ones it does not?

Thanks,
Will

and it gets even more interesting… I tried using timer0, timer3, and timer4. in each case eventually it would hang. For this test, the only thing the interrupt routine was doing was checking the level on a pin, using analogRead(). So on a hunch I commented that line out. Now it runs. So what the heck? analogRead() must be doing something that isn’t safe in a timer interrupt. If I take that line out, it runs without any problems.

I’m in over my head now, and this is becoming too much of a time sink. I’ve already got an Arduino NRF52 to scan for BLE beacons, so I think I’ll just give up and move all the sensor checks to that, and let the NANO manage the rest of it.

Sheesh…

Will

so, in case anyone is following this, I have learned a bit more. Turns out that analogRead() uses an interrupt, and therefore cannot be used in an interrupt routine. My hang had nothing to do with Ubidots.

I now have code that does an analog read asychronously, based on a tutorial for the SAMD21 that I found (the tutorial did not work but I managed to sort that out). So if anyone wants to know how to do this, let me know. It’s pretty complex and takes a bit of code, but I can post it here on in a new thread if anyone wants it).

Hey, Will, I’m glad you found where the problem was coming from. It would be very useful if you could share your experience in another thread so that anyone who is having the same problems can solve it quickly thanks to your support. In addition, we could refer to the new thread within this conversation.

Best wishes for you and your project.

All the best,
Maria H.

Something to think about when trying to use Ubidots in a robust system - when the MQTT connection goes down, the current timeout for reconnect attempts is 15 seconds. During that entire time your mainline program (Arduino loop) is not running. For a real time system, this is far too long to be ignoring things…

I did find out how to change the timeout to something more reaonable, by editing pubsubclient.h. It’s a pity this isn’t a parameter in the setup, but at least by doing this I can run with a somewhat reasonable watchdog time…

Will

Can you please explain this a bit more? How does one close opened sockets?

I keep getting into a situation where the MQTT connection is dropped, and the reconnect fails several times, and then I get “no socket available”. It seems to be using up all the sockets without freeing them. When this happens there does not seem to be any way to recover.

Thanks,
Will

Greetings @wbp, the way to close sockets is different from one device to another one, but usually it is implemented using a public method in the TCP client, i.e the PubSubclient library uses the method close() or stop() to close the socket. I am not sure what library Arduino Nano uses, but if you are using its WiFi library the stop() method should free for you new sockets to connect to the cloud.

All the best

Ok guys, please help me out here. I didn’t open any sockets directly. I followed your example to connect to Ubidots, using the Reconnect() function example, called from loop(); Since ubidots.connect(), which is really PubSubClient.connect() I guess, is the one that is getting “no available sockets”, doesn’t that mean that the problem is with PubSubClient and not my code???

Greetings @wbp, if you follow just the raw example, do you still get these messages?