Rapid reboot of Arduino Opta when setting/reading device properties with watchdog enabled

Hello everyone,

I’m encountering an issue where the Arduino Opta suddenly reboots (non-watchdog reboots) under certain conditions. Specifically, the reboots occur when:
• A relay is turned on/off via the API or a dashboard widget (there is a need to turn it on/off min. 1-3 times, sometimes more).
• All of the following code elements are present:

  1. Setting a property under the resource Input.
  2. Reading and/or setting a property within the loop() function.
  3. The watchdog timer is enabled.
    If any of these elements is omitted, the reboots do not occur.

Here’s the code to reproduce the issue:

#define THINGER_SERIAL_DEBUG
#define THINGER_SERVER "acme.aws.thinger.io"

#include <ThingerMbedEth.h>
#include <ThingerPortentaOTA.h>
#include "arduino_secrets.h"

// Define the watchdog timeout
#define WATCHDOG_TIME_MS 10000

// Get the instance of the Watchdog
mbed::Watchdog& watchdog = mbed::Watchdog::get_instance(); // Required element 3

ThingerMbedEth thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);
ThingerPortentaOTA ota(thing);

int propertyValue2 = 1;
bool isThingerAuthenticated = false;  // Status if connected to Thinger.io

void setup() {
  Serial.begin(115200);

  // configure leds for output
  pinMode(LED_D0, OUTPUT);
  pinMode(LED_D1, OUTPUT);
  pinMode(LED_D2, OUTPUT);
  pinMode(LED_D3, OUTPUT);
  pinMode(LEDR, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);

  // configure relays for output
  pinMode(D0, OUTPUT);
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
  pinMode(D3, OUTPUT);

  // Set state listener to update authentication status
  thing.set_state_listener([](ThingerClient::THINGER_STATE state) {
    isThingerAuthenticated = (state == ThingerClient::THINGER_AUTHENTICATED);
  });

  thing["relay_1"] << [](pson& in) {
    if (in.is_empty()) {
      in = (bool)digitalRead(D0);
    } else {
      digitalWrite(D0, in ? HIGH : LOW);
      digitalWrite(LED_D0, in ? HIGH : LOW);

      // Required element 1 start
      pson set_prop;
      set_prop["variable"] = false;
      thing.set_property("varStatus", set_prop, true);
      // Required element 1 end
    }
  };

  // start thinger on its own task
  thing.start();

  // Start the watchdog timer
  watchdog.start(WATCHDOG_TIME_MS); // Required element 3
}

void loop() {
  watchdog.kick(); // Required element 3
  if (isThingerAuthenticated) {
    // Required element 2 start
    pson send_data;
    send_data["propertyValue1"] = 1;
    thing.set_property("property_data", send_data, true);
    pson read_data;
    thing.get_property("property_data2", read_data);
    propertyValue2 = read_data["propertyValue2"];
    // Required element 2 end
  }
  delay(2000);
}

Has anyone experienced a similar problem or can offer insights into why this might be happening? Any assistance would be greatly appreciated.

Thank you!

Upon further investigation, it appears that the reboots are being triggered by the watchdog timer. Frequently pressing the relay control button (via the dashboard or API) causes significant delays in the loop, which eventually leads to a watchdog timeout.
I don’t know how communication across different threads is being handled in this context.

Hi,

Do you mean pressing many times in a short period of time? I ask this because is weird, the communication should be fast enough to avoid trigger the watchdog, however I dont know how long is this watchdog timer.

Have you tested disabling the WDT? this in order to confirm that this is the rebooting cause.

Hope this helps.

Hi,
Yes, I’m referring to rapidly pressing the button multiple times within a short period. I measured the loop time, and without pressing the button, it averages around 90 ms. However, when the button is pressed, the loop time easily extends to 10 seconds or more, which eventually triggers the watchdog. It seems that the set_property and get_property functions, when combined with the RTOS, are causing the blocking behavior that leads to the watchdog timeout. To mitigate this, I’ve increased the watchdog timeout to 30 seconds.

Just to be sure: Did you check your power supply?
A weak power supply may lead to brownouts when relays are activated.

On myside I also have some reboots when my Telecom provider (aaaaargh!) delivers again crappy Internet connections. I have defined a grace pause handling to help dealing with this annoyance:

#if defined(GRACE_PAUSE)  // Prevent locking if Thinger does not answer
  if (GracePause > 0) GracePause--;
  thingHandleTime = millis();
  if (GracePause == 0) thing.handle();                    // do not call permanently Thinger if it takes too long to respond.
  if (millis() - thingHandleTime > 500) GracePause = 16;  // if the Thinger call took longer than 500ms, make 2s pause before retrying
#else
  thing.handle();
#endif

Thank you for your suggestion! I can confirm that the power supply is not the issue, as I’m using a 3.5A source, which should be sufficient. The measurements I took show that the loop time is around 90 ms without any action, but increases significantly when switching the relay. I will try switching to a fiber router instead of the GSM router and repeat the tests to see if the results (loop times) are similar. Thanks again for your input!

" but increases significantly when switching the relay "
Can you post the code that does that?
A loop time of 90 sec is quite long.
I do really a LOT with my weak ESP8266 and my loop times are just a few mS:

GracePause: 000
Job Durations(mS) Current - Max
Sche:000 - 001 
Fast:001 - 003
Slow:007 - 008
Stat:000 - 000
Disp:002 - 004
Seri:003 - 002
Wifi:001 - 002

Without relay switching, the loop time is ~90 ms (milliseconds). With switching, it gets to order of seconds.

Below is the full code. Please note that inside the "relay_1" I use set_property which is one of the required elements to have this behavior.

#define THINGER_SERIAL_DEBUG
#define THINGER_SERVER "acme.aws.thinger.io"

#include <ThingerMbedEth.h>
#include <ThingerPortentaOTA.h>
#include "arduino_secrets.h"

// Define the watchdog timeout
#define WATCHDOG_TIME_MS 10000

// Get the instance of the Watchdog
mbed::Watchdog& watchdog = mbed::Watchdog::get_instance(); // Required element 3

ThingerMbedEth thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);
ThingerPortentaOTA ota(thing);

int propertyValue2 = 1;
bool isThingerAuthenticated = false;  // Status if connected to Thinger.io

void setup() {
  Serial.begin(115200);

  // configure leds for output
  pinMode(LED_D0, OUTPUT);
  pinMode(LED_D1, OUTPUT);
  pinMode(LED_D2, OUTPUT);
  pinMode(LED_D3, OUTPUT);
  pinMode(LEDR, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(LED_USER, OUTPUT);

  // configure relays for output
  pinMode(D0, OUTPUT);
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
  pinMode(D3, OUTPUT);

  // Set state listener to update authentication status
  thing.set_state_listener([](ThingerClient::THINGER_STATE state) {
    isThingerAuthenticated = (state == ThingerClient::THINGER_AUTHENTICATED);
  });

  thing["relay_1"] << [](pson& in) {
    if (in.is_empty()) {
      in = (bool)digitalRead(D0);
    } else {
      digitalWrite(D0, in ? HIGH : LOW);
      digitalWrite(LED_D0, in ? HIGH : LOW);

      // Required element 1 start
      pson set_prop;
      set_prop["propertyValue3"] = false;
      thing.set_property("property_data3", set_prop, true);
      // Required element 1 end
    }
  };

  // start thinger on its own task
  thing.start();

  // Start the watchdog timer
  watchdog.start(WATCHDOG_TIME_MS); // Required element 3
}

void loop() {
  unsigned long loopStartTime = millis(); 

  watchdog.kick(); // Required element 3
  
  if (isThingerAuthenticated) {
    digitalWrite(LED_USER, HIGH);

    // Required element 2 start
    pson send_data;
    send_data["propertyValue1"] = 1;
    thing.set_property("property_data1", send_data, true);
    
    pson read_data;
    thing.get_property("property_data2", read_data);
    propertyValue2 = read_data["propertyValue2"];
    // Required element 2 end
  } else {
    digitalWrite(LED_USER, LOW);
  }

  unsigned long loopEndTime = millis(); 
  unsigned long loopDuration = loopEndTime - loopStartTime; 

  Serial.print("Loop duration: ");
  Serial.print(loopDuration);
  Serial.println(" ms");

  delay(2000);
}

Why do you use a delay?

Do you have thinger process running in other core?

The whole code seems very short, 90ms looks like a very long time for that.

Delay is there for no reason. Yes, the thinger process is running in other core.

I use this to turn on/off relay:

I tested the GSM router and Fiber router:

Results:

GSM router; Loop without turning on/off relay:

[THINGER] Writing bytes: 43 [OK]

[THINGER] Writing bytes: 21 [OK]

Loop duration: 123 ms

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 21 [OK]

Loop duration: 100 ms

[THINGER] Writing bytes: 43 [OK]

[THINGER] Writing bytes: 21 [OK]

Loop duration: 105 ms

GSM router; Loop with turning on/off relay repeatedly:

[THINGER] Available bytes: 20

[THINGER] Writing bytes: 43 [OK]

[THINGER] Writing bytes: 8 [OK]

[THINGER] Available bytes: 19

[THINGER] Writing bytes: 43 [OK]

[THINGER] Writing bytes: 7 [OK]

[THINGER] Available bytes: 20

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 8 [OK]

[THINGER] Available bytes: 20

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 8 [OK]

[THINGER] Available bytes: 20

[THINGER] Writing bytes: 43 [OK]

[THINGER] Writing bytes: 8 [OK]

[THINGER] Available bytes: 19

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 7 [OK]

[THINGER] Available bytes: 20

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 8 [OK]

[THINGER] Available bytes: 20

[THINGER] Writing bytes: 43 [OK]

[THINGER] Writing bytes: 8 [OK]

[THINGER] Available bytes: 20

[THINGER] Writing bytes: 43 [OK]

[THINGER] Writing bytes: 8 [OK]

[THINGER] Available bytes: 20

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 8 [OK]

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 21 [OK]

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 8 [OK]

[_SOCKET] Cannot read from socket!

Loop duration: 10158 ms

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 21 [OK]

Loop duration: 230 ms

Fiber router; Loop without turning on/off relay:

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 21 [OK]

Loop duration: 28 ms

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 21 [OK]

Loop duration: 31 ms

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 21 [OK]

Loop duration: 37 ms

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 21 [OK]

Loop duration: 35 ms

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 21 [OK]

Loop duration: 29 ms

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 21 [OK]

Loop duration: 32 ms

Fiber router; Loop with turning on/off relay repeatedly:

[THINGER] Available bytes: 20

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 8 [OK]

[THINGER] Available bytes: 20

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 8 [OK]

[THINGER] Available bytes: 20

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 8 [OK]

[THINGER] Available bytes: 20

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 8 [OK]

[THINGER] Available bytes: 19

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 7 [OK]

[THINGER] Available bytes: 20

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 8 [OK]

[THINGER] Writing bytes: 44 [OK]

[THINGER] Writing bytes: 21 [OK]

[THINGER] Writing bytes: 43 [OK]

[THINGER] Writing bytes: 8 [OK]

[_SOCKET] Cannot read from socket!

Loop duration: 10063 ms

Only now I noticed that there is an issue with the socket.

Also, type of router makes a difference.

Blame your Internet provider ! I have the same problem here.
Many http://exchanges are suffering from awful lags. On a website it just leads to a short no-update, but on IoT expecting deterministic response times it means “reboot”.

I did additional test:
I translated the code above to communicate over WiFi on Opta (device 1) but instead of relay I just used built-in LED, and I removed the delay at the end. Then I also moved this code on Arduino WiFi Rev.2 (device 2), to compare the results. Without switching on/off relay (LED) the loop duration on Opta is ~40 ms:

[THINGER] Writing bytes: 44 [OK]
[THINGER] Writing bytes: 21 [OK]
Loop duration: 38 ms
[THINGER] Writing bytes: 43 [OK]
[THINGER] Writing bytes: 21 [OK]
Loop duration: 40 ms

while on WiFi Rev.2 it is ~10000 ms:

[THINGER] Writing bytes: 21 [OK]
[_SOCKET] Cannot read from socket!
Loop duration: 10031 ms
[THINGER] Writing bytes: 44 [OK]
[THINGER] Writing bytes: 21 [OK]
[_SOCKET] Cannot read from socket!
Loop duration: 10031 ms

What [_SOCKET] Cannot read from socket! exactly means? If this is related to the Internet provider only, then why during uninterrupted loop (with triggering the led/relay), I do not see this issue on Opta and on WiFi Rev.2 it is occurring every loop?

Here is the code for WiFi Rev.2:

#define THINGER_SERIAL_DEBUG
#define THINGER_USE_STATIC_MEMORY
#define THINGER_STATIC_MEMORY_SIZE 512
#define _DISABLE_TLS_

// define private server instance
#define THINGER_SERVER "acme.aws.thinger.io"

#include <WiFi.h>
#include <ThingerWifi.h>
#include "arduino_secrets.h"

ThingerWifi thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);

int propertyValue2 = 1;
bool isThingerAuthenticated = false;  // Status if connected to Thinger.io

void setup() {
  // open serial for debugging
  Serial.begin(115200);

  // Set state listener to update authentication status
  thing.set_state_listener([](ThingerClient::THINGER_STATE state) {
    isThingerAuthenticated = (state == ThingerClient::THINGER_AUTHENTICATED);
  });

  pinMode(LED_BUILTIN, OUTPUT);

  thing["relay_1"] << [](pson& in) {
    if (in.is_empty()) {
      in = (bool)digitalRead(LED_BUILTIN);
    } else {
      digitalWrite(LED_BUILTIN, in ? HIGH : LOW);

      // Required element 1 start
      pson set_prop;
      set_prop["propertyValue3"] = false;
      thing.set_property("property_data3", set_prop, true);
      // Required element 1 end
    }
  };

  // Configure WiFi network
  thing.add_wifi(SSID, SSID_PASSWORD);
}

void loop() {
  thing.handle();

  unsigned long loopStartTime = millis(); 

  if (isThingerAuthenticated) {
    // Required element 2 start
    pson send_data;
    send_data["propertyValue1"] = 1;
    thing.set_property("property_data1", send_data, true);

    pson read_data;
    thing.get_property("property_data2", read_data);
    propertyValue2 = read_data["propertyValue2"];
    // Required element 2 end
  }

  unsigned long loopEndTime = millis();
  unsigned long loopDuration = loopEndTime - loopStartTime;

  Serial.print("Loop duration: ");
  Serial.print(loopDuration);
  Serial.println(" ms");
}

Hi,

I would recommend to have the thinger instructions at one core and the control process at the other, to have more order, it would be difficult to follow what is going on if both cores are sending instructions.

I would do this by bool variables, for example if the control core need to update a property, I would declare a variable as global

bool isUpdatingProperty = 0;

when needed to update

isUpdatingProperty = 1;

And at the thinger core

if(isUpdatingProperty)
{
//update property instruction and other actions if needed...
isUpdatingProperty = 0;
}

This will warrantee that the setting property will just run once, I mention this bc the line

I[quote=“aeromek, post:8, topic:5224”]
if (isThingerAuthenticated)
[/quote]

It is allowing to set the “property_data1” and reading “property_data2” as fast as the uC can, I would recommend to control this update and reading frequency, is not scalable having a kind of devices writing/reading without control to a cloud instance.

Hope this helps.

1 Like

Thank you so much @ega! I’ve modified it according to your suggestions, and now everything is working as it should.

Edit:
I’m not getting consistent results at the moment… I’ll run some additional tests and follow up with the findings.

2 Likes

Hi,

Those are good news! Regardless the connection? Im curious, how much takes the loop after the modifications.

BR

I conducted an additional test and updated the code based on the feedback. I tested the setup with both a fiber router connection over WiFi and an Ethernet cable. The stability of relay_1’s operation has improved significantly, especially when communicating over the Ethernet connection. By “stability”, I’m referring to the reduced frequency of: [_SOCKET] Cannot read from socket!

However, I still haven’t been able to achieve the millisecond-level performance as mentioned earlier.

Here are results:

1. Exchanging the properties with set_property and get_property functions:
Over WiFi:

[THINGER] Writing bytes: 44 [OK]
[THINGER] Writing bytes: 21 [OK]
Thinger loop duration: 37 ms

Over ethernet cable:

[THINGER] Writing bytes: 44 [OK]
[THINGER] Writing bytes: 21 [OK]
Thinger loop duration: 29 ms

So it is about a few ms faster over the ethernet cable.

2. Toggling relay_1 from Thinger.io (over WiFi/Etherenet the timing is the same):

[THINGER] Available bytes: 20
[THINGER] Writing bytes: 44 [OK]
[THINGER] Writing bytes: 8 [OK]
Thinger loop duration: 16 ms

3. Repeatedly toggling relay_1 on and off while connected over WiFi:

[THINGER] Available bytes: 20
[THINGER] Writing bytes: 44 [OK]
[THINGER] Writing bytes: 8 [OK]
Thinger loop duration: 22 ms
[THINGER] Available bytes: 20
[THINGER] Writing bytes: 43 [OK]
[THINGER] Writing bytes: 8 [OK]
Thinger loop duration: 254 ms
[THINGER] Writing bytes: 8 [OK]
[THINGER] Writing bytes: 44 [OK]
[THINGER] Writing bytes: 8 [OK]
[THINGER] Writing bytes: 43 [OK]
[THINGER] Writing bytes: 7 [OK]
[THINGER] Writing bytes: 44 [OK]
…
[THINGER] Writing bytes: 44 [OK]
[THINGER] Writing bytes: 8 [OK]
[_SOCKET] Cannot read from socket!
[THINGER] Writing bytes: 21 [OK]
Thinger loop duration: 26982 ms

With the same toggling rate, I do not observe issues for the Ethernet cable connection. However, when I rapidly toggle relay_1 on and off, I encounter the [_SOCKET] Cannot read from socket!:

…
[THINGER] Writing bytes: 8 [OK]
[_SOCKET] Cannot read from socket!
[THINGER] Writing bytes: 21 [OK]
Thinger loop duration: 11687 ms

Here is the updated code. Please note that I’m using two threads, not two cores, to handle both the Thinger communication and the process control.

#include <Arduino.h>
#include "mbed.h"
#define THINGER_SERIAL_DEBUG
#define _DISABLE_TLS_

// define private server instance
#define THINGER_SERVER "acme.aws.thinger.io"

#include <ThingerMbed.h>
#include "arduino_secrets.h"

// Global variables and constants
ThingerMbed thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);

int propertyValue2 = 1;
bool isThingerAuthenticated = false;

// Flags for updating properties
bool isUpdatingProperty = false;
bool isReadingProperty = false;

unsigned long lastUpdateTime = 0;
const unsigned long updateInterval = 10000;

// Create a thread object
static rtos::Thread secondThread;

// Function that the thread will run
void thingerLoop() {
  while (1) {
    unsigned long loopStartTime = millis();  // Capture the start time
    thing.handle();

    if (millis() - lastUpdateTime >= updateInterval) {
      isUpdatingProperty = true;
      isReadingProperty = true;
      lastUpdateTime = millis();
    }

    if (isThingerAuthenticated) {
      digitalWrite(LED_USER, HIGH);

      if (isUpdatingProperty) {
        pson send_data;
        send_data["propertyValue1"] = 1;
        thing.set_property("property_data1", send_data, true);
        isUpdatingProperty = false;
      }

      if (isReadingProperty) {
        pson read_data;
        thing.get_property("property_data2", read_data);
        propertyValue2 = read_data["propertyValue2"];
        isReadingProperty = false;
      }

    } else {
      digitalWrite(LED_USER, LOW);
    }
    unsigned long loopEndTime = millis();
    unsigned long loopDuration = loopEndTime - loopStartTime;

    if (loopDuration >= 3) {
      Serial.print("Thinger loop duration: ");
      Serial.print(loopDuration);
      Serial.println(" ms");
    }
  }
}

void setup() {
  Serial.begin(115200);

  thing.set_state_listener([](ThingerClient::THINGER_STATE state) {
    isThingerAuthenticated = (state == ThingerClient::THINGER_AUTHENTICATED);
  });


  thing.add_wifi(SSID, SSID_PASSWORD);

  pinMode(LED_D0, OUTPUT);
  pinMode(LED_D1, OUTPUT);

  thing["relay_1"] << [](pson& in) {
    if (in.is_empty()) {
      in = (bool)digitalRead(LED_D0);
    } else {
      digitalWrite(LED_D0, in ? HIGH : LOW);

      // When relay_1 is changed, update property_data3
      pson set_prop;
      set_prop["propertyValue3"] = false;
      thing.set_property("property_data3", set_prop, true);
    }
  };

  secondThread.start(thingerLoop);
}

void loop() {
  digitalWrite(LED_D1, HIGH);  // Turn LED_D0 ON
  delay(250);                  // Wait for 250 milliseconds
  digitalWrite(LED_D1, LOW);   // Turn LED_D0 OFF
  delay(250);                  // Wait for 250 milliseconds
}

Unfortunately, when using the GSM router, I’m not seeing much improvement. The loop duration is still around 100 ms, and I’m frequently running into socket issues when toggling relay_1. On the bright side, the toggling itself is smooth, which makes the persistent socket problems even more confusing.

In short, the updated code show better stability as long as I use fiber router, especially over ethernet, though I’m still not hitting millisecond-level performance. I’m still seeing socket read errors when toggling relay_1 over WiFi/GSM router. Given the ongoing socket issues, do you think the code logic could be optimized?

Tell us more about the “millisecond-level performance” what is the goal?

I ask this because the network itself introduces latency (by any media), in the supposed case that the code can be improved as much as make it perfectly efficient for the goal, we cannot go beyond to reduce the network natural latency.

I am curious about the controlled process, can you share the code and details about it?

When I mention “millisecond-level performance,” I’m referring to these examples:

In my current setup, exchanging two properties takes about 40 ms when using a fiber router (over WiFi) and around 100 ms with an industrial GSM router (over Ethernet) in an environment with strong reception. Based on the quotes above, I’ve concluded that the Thinger-related loop times I’m seeing are likely too long.

Question 1: Are the loop times I’m observing within the normal expected range, or are they considered too high?

Additionally, I’m experiencing another issue: when using either the fiber router (WiFi) or the GSM router, simply toggling an LED from the dashboard using the relay_1 function results in the error: [_SOCKET] Cannot read from socket!. This error causes the Thinger communication loop to hang, easily extending the loop times as much as 10 seconds. Given that WiFi from a fiber router should provide a reliable connection, I find this unexpected.

Question 2: Is it normal to encounter the [_SOCKET] Cannot read from socket! error when switching a simple LED, especially when only one property is being updated?

Question 3: Why does toggling the LED still work smoothly despite the Thinger communication loop hanging?

Question 4: Is there anything that can be done to prevent the socket issue ([_SOCKET] Cannot read from socket!) from occurring?

My goal is to achieve stable operation. In the current code, I have isolated the issue by not including the controlled process (in loop()) to better diagnose this problem.

Hi,

When I mentioned

I was meaning the original code, without the thing.handle(); instruction, now with the thing.handle(); instruction in the loop, 40ms I think is a good time for it, I have not paid too much attention about how long does it take each instruction.

What is the difference?
The thing;handle(); command executes the communication tasks, when the line thing.set_property... is executed at the uC, the instruction is not to communicate and set the property in that instant, is set a flag so when next thing.handle command is run, communicate and set the property.

You think that the difference for the loop between fiber router and GSM router is attachable to thinger, I recommend you to reconsider this. with the given information the difference is attachable to the network access media.

40 ms for me are in the normal range, by the explained before.

You say that you are toggling repeatedly, in this scenario there could be packet losses, I guess the system is not developed to have this behaviour, if the relay needs to be toggled so frequently, I recommend to make a local routine to do it.

I understood that this happens when you toggle frequently the switch, note that you have enabled the write confirmation, however it is doing nothing (it returns a bool value, the returned value is not used), I’m not sure if the device is waiting for that confirmation from the platform and the plaftorm does not send it as received a lot of instructions in short time and one overlaped another, it is not crazy to think that if the platform receives two instructions simultaneously from the same device, send just the last confirmation, and the device may wait two confirmations, as no receive all of them, gives the socket error.

If the thinger loop is hanged there is no communication, maybe it is trying to connect again or reconnect with the network or something like this, or still executing other tasks meanwhile waits the confirmation and when hits timeout let the loop keep running and that is why you see it took so long.

Yes, just need that everything involved in the process (end to end hardware, ISP and all its infrastructure) be ideal and isolated from any external perturbation, not real :slight_smile:

I recommend you to disable the writing confirmation at the setting property, as it is not used at all but the platform is sending it and the device of course is waiting for it.
And I also recommend to establish the lapses acceptable for the control process, maybe you are trying to improve some ms when the process has a seconds order tolerance.

Hope this helps,

1 Like

“Why does toggling the LED still work smoothly?”
Just to mention a completely different approach: what is the electrical circuit that drives the relay?

Normally most relay boards are using a separate circuit to drive the coil and use opto couplers.
There is a reason for that: coils switching generate voltage peaks that may cause a controller to run into trouble.
Are you using such an isolating cricuit and are you powering the coil side from a separate power supply?
If not it may be a good thing to test such an isolated coil drive.

It is also a good practice to add a capacitor to the Vcc of the controller.
That has frequently solved weird behaviours…