1

This is my first time working with Arduino, an esp32 and MQTT. I made a motion sensor that prints to an LCD when it senses movement and publishes a message to mqtt, but it loops on forever. I am trying to make it so it will only start when start is published through mqtt and stops when stop is published. However, I am having some trouble figuring it out. Here is my current code (the main part excluding the MQTT set up), and I've been told putting it in callback may help but I get an error saying "a function-definition is not allowed here before '{' token" referring to void loop. Any suggestions are appreciated.

void callback(char *topic, byte *payload, unsigned int length) {
 Serial.print("Message arrived in topic: ");
 Serial.println(topic);
 Serial.print("Message:");
 for (int i = 0; i < length; i++) {
     Serial.print((char) payload[i]);
 }
 Serial.println();
 Serial.println("-----------------------");
}

void loop() {
 client.loop();
 
  int motion = digitalRead(sensorPin);
  if (motion == HIGH)
  {
    lcd.setCursor(0, 0);
    lcd.print("!!!!!MOTION!!!!!");
   client.publish(topic, "MOTION");
        delay(100);
}
else
{
   lcd.setCursor(0, 0);
    lcd.print("   no  motion   ");
   client.publish(topic, "NO MOTION");
       delay(500);

}
}
Conner
  • 11
  • 2
  • 2
    Show us your attempt; adding code to `callback` to handle messages and set a flag should be relatively simple (you are also going to need to `subscribe` to the topic). – Brits May 22 '22 at 15:06

1 Answers1

0

first: why would you publish unlimited times on mqtt when motion is detected? you detect the motion (digitalRead), publish it (i.e. with retain=true), and once published, set the flag i.e. published=true. Store the previous state of the motion and don't publish until it changed (either from motion to no-motion or vice versa). Your code is publishing for ever when motion is detected (client.publish(topic, "MOTION");) or when motion is cleared (client.publish(topic, "NO MOTION");)

if I get you correctly: you want to publish motion state ONLY when the message on MQTT came: "start checking the motion", right? if so, in callback you change the global variable i.e. "start_checking_motion = true" when message arrives (before the command on MQTT you set it to false) Then in loop, first what you do is to check if start_checking_motion == true - if so, you perform the check of the motion and you publish - but again: only when motion changed - see the first paragraph of my post

Zygfryd Homonto
  • 151
  • 1
  • 3