OPTA Waits for internet ignoring process

Hello! I am using Arduino Opta to test if it fits a pumping station for a large irrigation system. So far so good it seems it's doing ok, but in fact, the only problem I have is that as long as we lose internet connection it will get stuck in waiting for the internet. Now, I am enjoying a remote dashboard to see data and maybe control a few things, it generates triggers so it does the job well.

If this product addresses small industry applications, then the process itself must be its number one priority and not waiting for an Arduino cloud connection.

I have introduced on top of my code a line that keeps one of the 4 LED's blinking every second and if the OPTA is connected to internet it works ok but if we loose internet connection it stays stuck on for some seconds (about 20-30 seconds) then off for 1 sec then on again 30 sec. During this time there are no basic actions, no code following, nothing so the VFD of the pump will stop because the flow meter is going through OPTA which is not delivering data.

Anyway, all in all I am interested if there is a way to put the arduino clound connection second priority...

I have used ST to program and ignore the ladder logic or FB since I needed to test various instances from a remote location OTA and ST is the only one that I can use in the online editor.

I can paste the code if this helps.

Thanks

1 Like

I think posting code would be your best bet for anyone to be able to help you. I am OK with coding as ling as its clean and simple and may be able to help.

Connection management is important and like you’ve stated, super important for code to continue executing regardless of state of connection. I can’t stand the fact that most IoT solutions always end up blocking code when connection is lost , wether it be to the router or cloud.

2 caveats, i am not familiar with OPTA or Arduino cloud but lets give it a shot?? :wink::man_shrugging:t2:

Hi!
You may want to use the callbacks to change the block that you are getting
Check out the example ArduinoIoTCloud/examples/ArduinoIoTCloud-Callbacks/ArduinoIoTCloud-Callbacks.ino at master · arduino-libraries/ArduinoIoTCloud · GitHub

Thanks Aubery.
I have used the arduino on line web editor and this is the code:

/* 
  Sketch generated by the Arduino IoT Cloud Thing "Untitled"
  https://create.arduino.cc/cloud/things/4ea6bfa3-1544-41ca-94a5-db8e1217a10b 

  Arduino IoT Cloud Variables description

  The following variables are automatically generated and updated when changes are made to the Thing

  float service;
  int average_pulse;
  int high_flow_limit;
  int low_flow_limit;
  bool high_flow;
  bool lipsa_apa;
  bool lipsa_curgere;
  bool low_flow;
  bool pompa_avarie;
  bool pompa_pornita;
  bool tensiune;

  Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/

#include "thingProperties.h"

unsigned long previousMillis = 0;  // Stores the last time the pulse count was updated
const long interval = 20000;  // Interval of 30 seconds for reporting

unsigned long ledToggleMillis = 0;  // For toggling LED_D3 every 5 seconds
bool ledD3State = false;  // Current state of LED_D3

int pulseCount = 0;  // Initialize the pulse count
unsigned long lastPulseTime = 0;  // Time since the last pulse was detected

// Variable to hold the last average number of pulses
float lastAveragePulses = 0.0;

int average_pulse_raw = 0;

unsigned long startTime = 0;
unsigned long startTimeH = 0;



//3 variables code 2
unsigned long pulseIntervalSum; // Variable to accumulate pulse intervals
unsigned int pulseCount2; // Variable to count the number of pulses
float averageInterval = 0;



void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500); 

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  
  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
 */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
  
  
  pinMode(LED_D0, OUTPUT);
  pinMode(LED_D1, OUTPUT);
  pinMode(LED_D2, OUTPUT);
  pinMode(LED_D3, OUTPUT);
  pinMode(BTN_USER, INPUT);
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  pinMode(A4, INPUT);
  pinMode(A5, INPUT);
  pinMode(A6, INPUT);
  pinMode(A7, INPUT);
  pinMode(D0, OUTPUT);
  
  
  // code 2 2 things:
  pulseCount = 0;
  pulseIntervalSum = 0;

  
}

void loop() {
  ArduinoCloud.update();

 
 unsigned long currentMillis = millis();

  // Toggle LED_D3 every 2 seconds
  if (currentMillis - ledToggleMillis >= 1000) {
    ledToggleMillis = currentMillis;
    ledD3State = !ledD3State;
    digitalWrite(LED_D3, ledD3State ? HIGH : LOW);
  }

    // Check for pulse
  if (pulseIn(A0, HIGH) > 0) {  // No timeout for responsiveness
    digitalWrite(LED_D0, HIGH);  // Turn on the LED
    digitalWrite(D0, HIGH); // Set digital output D0 high
    delay(45);  // Keep D0 high for 45 milliseconds
    digitalWrite(LED_D0, LOW); // Set digital output D0 low
    digitalWrite(D0, LOW);
    pulseCount += 1;  // Increment the pulse count
    lastPulseTime = currentMillis;  // Update the last pulse time
  }

  // Check if 5 seconds have passed since the last pulse
  if (currentMillis - lastPulseTime > 5000 && lastPulseTime != 0) {
    pulseCount = 0;  // Reset pulse count if no pulse for 5 seconds
    lastPulseTime = 0;  // Reset last pulse time
  }

  // Every 30 seconds, update lastAveragePulses and reset pulseCount
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    // Calculate the average number of pulses in the last 30 seconds
    // Since you're counting pulses over a fixed interval, the "average" is just the total count in this case.
    lastAveragePulses = pulseCount;

    pulseCount = 0;  // Reset the pulse count for the next cycle
  }

  // Update lastAveragePulses to 0 if no pulses are detected
  if (currentMillis - lastPulseTime > 5000) {
    lastAveragePulses = 0;
  }

  // The variable lastAveragePulses now holds the last calculated average number of pulses
  // You can use lastAveragePulses in your code as needed from this point

 
  average_pulse_raw = map(lastAveragePulses, 0, service, 0, 100);
  average_pulse=average_pulse_raw;
  
 
  int pin7State = digitalRead(A7);
  if (pin7State == HIGH) {
    tensiune = true;
  }
  else{
    tensiune = false;
  }
  
    int pin4State = digitalRead(A4);
  if (pin4State == HIGH) {
    lipsa_apa = true;
  }
  else{
    lipsa_apa = false;
  }
  
   int pin5State = digitalRead(A5);
  if (pin5State == HIGH) {
    lipsa_curgere = true;
  }
  else{
    lipsa_curgere = false;
  }

 int pin2State = digitalRead(A2);
  if (pin2State == HIGH) {
    pompa_pornita = true;
  }
  else{
    pompa_pornita = false;
  }
  
   int pin3State = digitalRead(A3);
  if (pin3State == HIGH) {
    pompa_avarie = true;
  }
  else{
    pompa_avarie = false;
  }
  
  if (average_pulse > 10 && average_pulse < low_flow_limit) {
    if (!low_flow) {
      if (currentMillis - startTime >= 60000) {
        low_flow = true;
        // Do something when variable is within the specified range for more than a minute
      }
    }
  } else {
    low_flow = false;
    startTime = currentMillis;
  }
  
  
    if (average_pulse > high_flow_limit) {
    if (!high_flow) {
      if (currentMillis - startTimeH >= 60000) {
        high_flow = true;
        // Do something when variable is within the specified range for more than a minute
      }
    }
  } else {
    high_flow = false;
    startTimeH = currentMillis;
  }
  
  delay(10);
  
 }



/*
  Since LipsaApa is READ_WRITE variable, onLipsaApaChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onLipsaApaChange()  {
  // Add your code here to act upon LipsaApa change
}


/*
  Since AveragePulse is READ_WRITE variable, onAveragePulseChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onAveragePulseChange()  {
  // Add your code here to act upon AveragePulse change
}


/*
  Since Service is READ_WRITE variable, onServiceChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onServiceChange()  {
  // Add your code here to act upon Service change
}


/*
  Since HighFlowLimit is READ_WRITE variable, onHighFlowLimitChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onHighFlowLimitChange()  {
  // Add your code here to act upon HighFlowLimit change
}

/*
  Since LowFlowLimit is READ_WRITE variable, onLowFlowLimitChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onLowFlowLimitChange()  {
  // Add your code here to act upon LowFlowLimit change
}

Hello @Marian018

The only thing that catches my eye in your code is that you have 2 delays(). Although not long delays, Without knowing Arduino Cloud that well, does delay() affect the connection/re-connection and handling of "ArduinoCloud.update();" <------ this may need to happen often without any delays?? Maybe code in without delays and use millis() instead...

The only black box that I do not understand is the function call "ArduinoCloud.update();"... Although the documentation states this is not blocking I feel that in this simple case it is possibly the only thing that can block your code?? Maybe someone with better code reading will catch any other blocks.

as @PMarquinez mentioned... you can add one of the connection functions in your setup.

Im not sure how they will help if your code is freezing at "ArduinoCloud.update();" but it would be nice if Arduino.Cloud had boolean variables for connect and disconnect states and you could simply evaluate wether or not it is connected with an "If" statement and ignore the "ArduinoCloud.update();" allowing your code to execute regardless...

You may need to tinker and play around a little and troubleshoot more. Hopefully someone else helps you out...

Hello,

I have looked into call back actions but I had no luck. Opta is placed as an industrial product so I know there is something wrong with my approach, otherwise I expect more people would complain.

Maybe I shall use Leader programming with Arduino IDE? So far I have used ST with on line editor.

To show what I am facing I have recorded this video where I have a simple code blinking the led D1 every second. This stops once internet is off. Imagine the led would be a real process signal…

VIDEO

I have used my opta at 3 pumping stations which will be off once there is an internet problem. I have 7 other locations to arrange and not sure if I shall change the product used or not. So far all the 5 OPTA I boughts have the same behaviour.

Thanks,
Marian

Hello @Marian018

Can I make one suggestion. Do not use the online editor. It seems to be full of issues and although I do not know specifically to the Opta, i believe if this is a production environment, use something safer/stable like Arduino IDE or Arduino PLC IDE

It looks like other OPTA users are encountering the same issue as you when the following 2 scenarios happen, unplugging the USB cable OR unplugging the ethernet cable…. Leads to crashes.

This is a bug, i believe it is known by Arduino??? but you should contact them directly through email perhaps? Especially since this is in production for you…

These threads may help…

I am not sure what product lines are available where you are BUT if this is time critical for a client/contract, you may want to go with a more established company in the “microPLC” market. Companies such as Eaton, Siemens, Allen Bradley all offer prettt much the same 8IN / 4OUT microPLC for substantially cheaper price than Arduino, expandable IO’s, most offer free software to program in whatever language you prefer…
Until the bugs are ironed out with this product of course (and price comes down :wink:)

Thanks for your help @aubrey4485 !

First I will try Arduino IDE or Arduino PLC IDE. I am not sure what would be the difference from the two, but I will explore. Not sure how I will connect to cloud when using those.

I am quite satisfied with Arduino OPTA except this issue which seems simply too serious to believe. I cannot understand why this is not brought up by many other users.

Ultimatelly I might turn my attention to other products, I have used Eaton Easy line as well. Reason for choosing Opta was the semless Arduino IoT Cloud integration with a dashboard acting as remote HMI that can be created with not so much engineering , basically in no time. Arduino Opta was presented and promoted to my client and they have accepted it and so far so good they are quite happy with my progress so far expect the connection issue, subject to this forum post.

I will come back with updated once I have those.

Post scriptum: the refferences to other posts are for the red light blinking and that happends whenever I had an invalid state into my code, which is not the case.

1 Like

Hello All, hello @aubrey4485 ,

I have took a look in Arduino PLC IDE and it gets me a correct feeling. First when adding the OPTA to this environment and enable it through free license, it generates two interfaces, having a "process" layer and an "could and modern" layer. Consequently we can see two COM ports when plugging in the OPTA into PC. Then it seems we can control the process layer with ST, LD and in general a PLC type of programming which will exchange variables values with arduino cloud and dashboard through a sketch that can be programmed in C, similar with how variable data is exchanged with other systems through modbus etc. It is more or less complex, but it gives us what we need. Not sure if I can still handle interrupts in PLC world but most of my code can be translated. However PLC IDE will be the response of transforming the OPTA into an industrial product in my opinion.

Something to start with here:

https://docs.arduino.cc/software/plc-ide/tutorials/plc-ide-cloud-support/

So far, for my project, I have replaced GSM antenna with something bigger and put it on the roof and also selected a better router and now my system is working as desired.

Thanks for all your feedback.

Marian