Cant get IoT to stay Stable

This has been bugging me for the last 3 weeks now. I cant get my Arduino RP2040 to stop crashing every minute. Even with Basic Code, which works fine without IoT functionality, But as soon as I try to run it with the Cloud, it doesnt work.
Looking at the Serial Monitor when it first starts, It works, gives me values, doesnt show on the dashboard, but anyways as soon as the first disconnect happens nothing comes out anymore
status

/*
  Sketch generated by the Arduino IoT Cloud Thing "Untitled"
  https://create.arduino.cc/cloud/things/397063f0-9f78-491e-afb5-eb53cf19ac86

  Arduino IoT Cloud Variables description

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

  String message;
  float average_Moisture;
  float humidity;
  float moisture1;
  float moisture2;
  float temperature;
  float water_Level;
  int moisture_Level_Activate;
  int moisture_Level_Target;
  CloudSchedule schedule;
  bool pump;

  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"  //Including of IoT Library
#include "DHT.h"              //Including of DHT Sensor Library
#include <Wire.h>             //Including of I2C Connection Library

int RELAY_PIN = 14;            //setting the relay pin to the integer 6
int MOISTURE1_PIN = A3;  //setting a moisture sesnor pin to the integer A1
int MOISTURE2_PIN = A2;  //setting a moisture sesnor pin to the integer A2

const int dry = 786; // value for dry sensor
const int wet = 391; // value for wet sensor

#define DHTTYPE DHT22 // setting the DHT type to DHT22
#define DHTPIN 15      // Defining the Pin used for DHT-Sensor

DHT dht(DHTPIN, DHTTYPE); //Setting up the DHT Function with the defined Type and Pin

//Sourced from https://wiki.seeedstudio.com/Grove-Water-Level-Sensor/
unsigned char low_data[8] = {0};    //Initialising of Array 1x8 in sized, filled with the value 0
unsigned char high_data[12] = {0};  //Initialising of Array 1x12 in sized, filled with the value 0
#define NO_TOUCH       0xFE       //Defining of an Adress 
#define THRESHOLD      100
#define ATTINY1_HIGH_ADDR   0x78  //Defining of an Adress 
#define ATTINY2_LOW_ADDR   0x77   //Defining of an Adress 

void getHigh12SectionValue(void)  //Sourced from https://wiki.seeedstudio.com/Grove-Water-Level-Sensor/
{
  memset(high_data, 0, sizeof(high_data));
  Wire.requestFrom(ATTINY1_HIGH_ADDR, 12);    //get 12 bytes through I2C connecion from the named adress
  while (12 != Wire.available());   //as long as there aren't 12 bytes, don't do anything

  for (int i = 0; i < 12; i++)  //for every integer i, below the value of 12, every execution with 1 added
  {
    high_data[i] = Wire.read(); //Fill the array space i with the I2C connection read value
  }
}

void getLow8SectionValue(void)  //Sourced from https://wiki.seeedstudio.com/Grove-Water-Level-Sensor/
{
  memset(low_data, 0, sizeof(low_data));
  Wire.requestFrom(ATTINY2_LOW_ADDR, 8);    //get 8 bytes through I2C connection from the named address
  while (8 != Wire.available());    //as long as there aren't 8 bytes, don't do anything

  for (int i = 0; i < 8 ; i++)  //for every integer i, below the value of 12, every execution with 1 added
  {
    low_data[i] = Wire.read(); //Fill the array space i with the I2C connection read value
  }
}

float checkWater() //Sourced from https://wiki.seeedstudio.com/Grove-Water-Level-Sensor/
{
  int sensorvalue_min = 250;    //define lowest value of measuring tolerance
  int sensorvalue_max = 255;    //define highest value of measuring tolerance
  uint32_t touch_val = 0;       //variable in which the number of bytes with a high value is equivalent to the number of touched sections of the sensor
  uint8_t trig_section = 0;     //counter of 1 in touch_val
  getLow8SectionValue();
  delay(10);
  getHigh12SectionValue();
  delay(10);

  for (int i = 0 ; i < 8; i++)
  {
    if (low_data[i] > THRESHOLD)
    {
      touch_val |= 1 << i;
    }
  }
  for (int i = 0 ; i < 12; i++)
  {
    if (high_data[i] > THRESHOLD)
    {
      touch_val |= (uint32_t)1 << (8 + i);
    }
  }
  while (touch_val & 0x01)
  {
    trig_section++;
    touch_val >>= 1;
  }
  return (trig_section * 5);
}

void setup()
{
  Serial.begin(9600); // Initialize serial and wait for port to open:
  dht.begin();  //boots the DHT sesnor connection
  Wire.begin();
  delay(1500);  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  initProperties();               // Defined in thingProperties.h
  ArduinoCloud.begin(ArduinoIoTPreferredConnection, false);  // Connect to Arduino IoT Cloud
  setDebugMessageLevel(4);        //Setting the debug message level for the network and IoT cloud connection to 2 (the lower the less information and vise versa)
  ArduinoCloud.printDebugInfo();  //Outputs the errors onto the Arduino Cloud

  pinMode(RELAY_PIN, OUTPUT);     //Setting the relay pin as an output
  pinMode(MOISTURE1_PIN, INPUT);  //Setting the first moisture pin as an input
  pinMode(MOISTURE2_PIN, INPUT);  //Setting the second moisture pin as an input
}

void loop()
{
  ArduinoCloud.update();                //Updates the Cloud Variables
  temperature = dht.readTemperature();  //using the DHT Library, temperature is updated using the read command
  humidity = dht.readHumidity();        //using the DHT Library, humidity is updated using the read command
  moisture1 = map(analogRead(MOISTURE1_PIN), wet, dry, 100, 0); //map function compares the read analog value, to where it is between 100%(wet) and 0%(dry)
  moisture2 = map(analogRead(MOISTURE2_PIN), wet, dry, 100, 0); //map function compares the read analog value, to where it is between 100%(wet) and 0%(dry)
  average_Moisture = ((moisture1 + moisture2) / 2); //creating an average value for comparisons
  water_Level = checkWater();


  if (water_Level < 20 && water_Level > 10) //Message output when the Water level is between 10% and 20%
  {
    message = "Please Refill Water Resovior";
  }
  if (water_Level < 10 && water_Level > 1) //Message output when the Water level is between 10% and 1%
  {
    message = "Water Level Critical! Please Refill Water Resovior";
  }
  if (water_Level == 0) //Warning Message when the Water level reaches 0
  {
    message = "Water Resovior Empty! Please Refill Water Resovior";
    pump = false; //pump is turned off to prevent damage
  }

  if (moisture_Level_Activate >= moisture_Level_Target) //the minimum must be lower than the target
  {
    message = "Error: Target Soil Moisture cannot be lower than the Minimum Moisture";
  }
  else
  {
    if (average_Moisture < moisture_Level_Activate) //Checks if the Moisture level over the 2 sensors is below the minimum
    {
      message = "Soil Moisture below Minimum, Pump Activated till Target Reached";
      while (average_Moisture < moisture_Level_Activate) //Pump will be active as long as the moisture is below the target
      {
        pump = true;
      }
      pump = false; //After the moisture has reached the Target, the pump will turn off
    }
    else
    {
      pump = false;
    }
  }

  if (schedule.isActive()) //the Schedule Variable Type works similarrly to a PWM, Calculating how long
    //the pause is between the set on time. if statement will then only activate when the variable become a active signal
    //https://docs.arduino.cc/arduino-cloud/features/cloud-scheduler
  {
    message = "Scheduled Watering: Pump Activated till Target Reached"; //Message updated to activity
    while (average_Moisture < moisture_Level_Target) //code below will be active as long as the average moisture is less than the target
    {
      pump = true; //pump will turn on
    }
    pump = false;
  }
  else //when the schedule variable is no longer active;
  {
    pump = false; //pump will turn off
  }
  delay(2000); //Delay of 2 seconds to allow Sesnors to be effectively read, below 2 seconds will result in inaccurate sensor readings
  //above 2 seconds will effect the feedback of the entire system
  Serial.print("Temperature: ");
  Serial.print(temperature);
  Serial.println( " Celcius");
  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.println( " %");
  Serial.print("Moisture: ");
  Serial.print(average_Moisture);
  Serial.println( " %");
  Serial.print("Water Level: ");
  Serial.print(water_Level);
  Serial.println( " %");
}
/*
  Since Pump is READ_WRITE variable, onPumpChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onPumpChange()  {
  if (pump) //if the bool pump is True
  {
    digitalWrite(RELAY_PIN, HIGH); //Set the relay pin to High
  }
  else //else if it is False
  {
    digitalWrite(RELAY_PIN, LOW); //Set the relay pin to Low
  }
}

This code works perfectly fine if I upload it using IDE 2.2.1 and I remove the IoT Stuff and just use Serial to output all the values. I thought it was because of the I2C Water Level Sensor but no, same issue without it all. The Issue surely lies with Arduinos Cloud.

Someone please help me Im starting to the get fed up with this and regretting paying for a year subscription to the service, that I cant even get to work

2
Sometimes it even stays stable, but still has random down times, where after it starts up again it kinda still works, kinda because the serial monitor doesnt output anything

Hi!

My first suggestion would be that you remove the delay()'s that are called in the loop() or any of the functions called from the loop().

You can follow this guide.

Another potential issue can be the while() loops right after the Wire requests. What happens if the Wire request fails? I would suggest adding some retries. Otherwise, the code can get stuck into an endless loop.

Can you also monitor the Serial port to check what are the messages printed before rebooting?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.