Arduino Cloud messenger only send one message

Hello everyone!

I want do built an automatic watering system with moisture sensor and a 5v waterpump.
The measurement and the watering works okay but I'm only working with delay. I know with delay in the void loop is not the best way and working with Millies would be better but I'm pretty new to the coding with Arduino so I have no cloud how to do it. The main problem is that I want a message if the plant needs water, when it has enough water, when the pump will turn on and when the pump will turn off. I'm only getting the messages when the plant needs water and when it has enough but the messages for the pump aren't working. Somebody has an idea how to get it to work?

#include "arduino_secrets.h"
/*
  Sketch generated by the Arduino IoT Cloud Thing "Untitled 2"
  https://create.arduino.cc/cloud/things/96bcc51b-9f5d-46b6-9d18-0ccbd11a1b3e

  Arduino IoT Cloud Variables description

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

  String message;
  int moistureLevel;
  CloudPercentage moisturePercent;
  CloudRelativeHumidity hum;
  CloudTemperature temp;

  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"
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#define DHT_ENSOR_PIN 3
#define DHT_SENSOR_TYPE DHT22
#define PUMP_PIN 2
DHT dht_sensor(DHT_ENSOR_PIN, DHT_SENSOR_TYPE);

int soilMoistureLevel;
int soilMoisturePercent;

int airValue = 830;
int waterValue = 360;

void setup() {
  pinMode(DHT_ENSOR_PIN, INPUT);
  dht_sensor.begin();
  // Initialize serial and wait for port to open:
  Serial.begin(9600);

  delay(1500);

  pinMode(PUMP_PIN, OUTPUT);

  // 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();
}

void loop() {
  ArduinoCloud.update(); // Update the Cloud's data

  hum = dht_sensor.readHumidity();
  temp = dht_sensor.readTemperature();
  if(isnan(hum) || isnan(temp)){
  Serial.println("Failed to read from DHT Sensor!");
  }else{
  Serial.print("Humidity: "); Serial.print(hum);Serial.print("%"); Serial.print(" | ");
  Serial.print("Temperature: "); Serial.print(temp);Serial.println("°C"); //ALT 0176

  if (hum > 75)
  
  {
    //Send message to Arduino Cloud messenger on dashboard
    message = "Luftfeuchtigkeit zu hoch!";
  }
  }

  //Read data from Analog Pin 1 on Nano 33 IoT and print to Serial Monitor for debugging
  soilMoistureLevel = analogRead(1);
  Serial.println(soilMoistureLevel);

  //Convert soilMoistureLevel integer into percentage by using air and water values defined above and mapping with 0 - 100
  soilMoisturePercent = map(soilMoistureLevel, airValue, waterValue, 0, 100);
  Serial.println(soilMoisturePercent); //Print to Serial Monitor for debugging


  //Update Arduino IoT Cloud values
  moistureLevel = soilMoistureLevel;
  moisturePercent = soilMoisturePercent;

  //If the moisture percentage is less than 50%
  if (moisturePercent < 50)
  {
    //Send message to Arduino Cloud messenger on dashboard
    message = "Wasserlevel niedrig, Gießvorgang gestartet!";

    digitalWrite(2, LOW);

    Serial.println("Pumpe an");
    message = "Pumpe an";

    delay(5000);

    digitalWrite(2, HIGH);

    Serial.println("Pumpe aus");
    message = "Pumpe aus";

    Serial.print("Humidity: "); Serial.print(hum);Serial.print("%"); Serial.print(" | ");
    Serial.print("Temperature: "); Serial.print(temp);Serial.println("°C"); //ALT 0176

    delay(5000);
  }

  //If the moisture percentage is greater than 70%
  if (moisturePercent > 70)
  {
    //Send message to Arduino Cloud messenger on dashboard
    message = "Wasserlevel in Ornung, Gießvorgang beendet!";

    digitalWrite(2, HIGH);

    Serial.println("Pumpe aus");
    message = "Pumpe aus";

    delay(5000);
    }

}

Hi @racer2030.

Are you sure about that? I would expect the opposite from looking at your code.

The message is sent when your sketch program calls ArduinoCloud.update().

If you set the message variable multiple times between ArduinoCloud.update() calls, you aren't going to get multiple messages. You are only going to get the message from the value of the message variable at the time ArduinoCloud.update() is called.

This code will not produce three messages. It will only produce one message: "Pumpe aus".

You should redesign your sketch so that it does not use delay at all. The loop function should run unimpeded, calling ArduinoCloud.update() frequently.

You can accomplish the timing without the use of delay by using the millis function instead. You can learn how to do that from this tutorial:

You might also want to do some research on the subject of "state machine" (AKA "finite-state machine"), which is the formal name for the style of program that will be best suited for your project. Unfortunately a lot of what is written about this subject is overly complex, so you might find it overwhelming at first, but you can probably find a tutorial that explains it in an understandable manner with a bit of searching.

Hi @ptillisch

you are right. The message I get from this is "Pump aus".

I´ve looked for examples with state machine but don't know how to adopt it to my project.
Is it possible to call ArduinoCloud.update() multiple times in the void loop ?

My suggestion is to spend some time studying the "Blink Without Delay" tutorial and then start to adapt your project to using millis instead of delay using the same approach as demonstrated in the "BlinkWithoutDelay" example sketch.

You will likely end up with something like a state machine as a matter of course. Once you have independently discovered this program architecture, you will likely have an easier time of understanding the tutorials you find about using state machines and be able to easily incorporate any enhancements (e.g., using switch ... case and enum) you learn from the tutorials into the state machines in your own programs in the future.

Yes, you can call it as many times as you like.

1 Like

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