On Change functions

Hi,

I'm trying to implement a automation system for three lights: two by switches in the dashboard and one by a PIR sensor. I can put the PIR code in the loop function and it works fine but I think is more efficient to call a onChange function every time the PIR state change, I understand this functions only works if there is a change in the dashboard for this reason I put a switch in the dashboard linked to the PIR cloud variable but the program doesn't enter in this function. Can you help me?

/* 
  Sketch generated by the Arduino IoT Cloud Thing "casa_26"
  https://create.arduino.cc/cloud/things/dc4deab8-bec8-4f8e-b41c-310c3356a0b1 

  Arduino IoT Cloud Variables description

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

  CloudDimmedLight comedor;
  CloudDimmedLight sala;
  CloudLight patio;
  bool sensor;
  bool trigger;

  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"

#define led03 3
#define led05 5
#define led06 6
#define pir 12

int pwm;
int contador=0;
bool lectura_pir;

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

  //Ubicar nuevo codigo de configuracion
  pinMode(led03,OUTPUT);
  pinMode(led05, OUTPUT);
  pinMode(led06, OUTPUT);
  pinMode(13,OUTPUT);
  pinMode(pir, INPUT);

  //Verificacion de funcionamiento de lamparas
  digitalWrite(led03,HIGH);
  digitalWrite(led05,HIGH);
  digitalWrite(led06,HIGH);
  delay(2000);
  digitalWrite(led03,LOW);
  digitalWrite(led05,LOW);
  digitalWrite(led06,LOW);
  
}

void loop()
{
  ArduinoCloud.update();
  deteccion();
  //Ubicar nuevo codigo de operacion
  
}

void deteccion()
{
  sensor=digitalRead(pir);
  trigger=sensor;
  Serial.print("Estado del PIR orig:  ");
  Serial.println(digitalRead(pir));
  Serial.print("Estado del PIR:  ");
  Serial.println(sensor);
  Serial.print("Estado de TRIGGER:  ");
  Serial.println(trigger);

}


/*
  Since Sala is READ_WRITE variable, onSalaChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onSalaChange() 
{
  // Add your code here to act upon Sala change
  if(sala.getSwitch())
  {
    pwm=map(sala.getBrightness(),0,100,20,255);
    analogWrite(led05,pwm);
  }
  else
  {
    analogWrite(led05,0);
  }
}

/*
  Since Comedor is READ_WRITE variable, onComedorChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onComedorChange()
{
  // Add your code here to act upon Comedor change
  if(comedor.getSwitch())
  {
    pwm=map(comedor.getBrightness(),0,100,20,255);
    analogWrite(led06,pwm);
  }
  else
  {
    analogWrite(led06,0);
  }
  
}

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

}


/*
  Since Sensor is READ_WRITE variable, onSensorChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onSensorChange()
{
  // Add your code here to act upon Sensor change
  Serial.print("Funcion onSensorChange");
  
  
}

void onTriggerChange() 
{
  // Add your code here to act upon Trigger change
  if(digitalRead(pir)==true)
  {
    digitalWrite(led03,HIGH);
    patio=true;
    contador++;
    Serial.print("Detecciones:  ");
    Serial.print(contador);
    if(contador>=3)
    {
      digitalWrite(13,HIGH);
      delay(100);
      digitalWrite(13,LOW);
      delay(100);
      digitalWrite(13,HIGH);
      delay(100);
      digitalWrite(13,LOW);
      delay(100);
      digitalWrite(13,HIGH);
      delay(100);
      digitalWrite(13,LOW);
      delay(100);
      contador=0;
    }
  }
  else if(digitalRead(pir)==false)
  {
    digitalWrite(led03,LOW);
    patio=false;
  }
}

Hi @repc_up

Is your goal for this code:

to be executed whenever the state of the PIR sensor's output changes?:

If so, the approach you are attempting is the farthest thing from efficient.

The onTriggerChange function in your sketch will only be called when you manually move the position of the switch Widget on the Arduino Cloud IoT Dashboard.

The function will not be called when the state of the switch changes automatically due to the sketch program having changed the value of the Variable.


Is your goal for this code:

to be executed whenever the state of the PIR sensor's output changes?:

If so, the approach you are attempting is the farthest thing from efficient. You are unnecessarily attempting to configure your code so that the change of state of the pin on the Arduino board must be sent through the Internet to the Arduino Cloud server, then all the way back from that server to the board before the board can act on that state change.

The correct and efficient way to accomplish this is to just configure your code so that the program acts directly when the pin state changes.

To do that, you must make two changes to your code:

First of all, move the PIR state change code out of the onTriggerChange function. You can move it to your deteccion function if you like. The "on*Change" callback functions like onTriggerChange are only a convenient way to execute some code when the dashboard user takes an action. You should not attempt to use those functions for any other purpose. There is no magic "efficiency" to these functions.

The second change you must make is to configure your code to detect a change in state. You can do that by changing this code in your sketch:

  if(digitalRead(pir)==true)
  {

To something like this:

  bool PIRState = digitalRead(pir);
  if(trigger != PIRState)
  {
    trigger = PIRState;