Initialize properties on arduino power up

Hello all,

I am using an Arduino MKR WiFi 1010 to control my portable air conditioner. I use my Amazon Alexa to send commands to the arduino, and the arduino modulates an IR transmitter to control the air conditioner (power, temperature, fan speed, etc.).

I programmed state machines into the code so that the air conditioner and the code are always in sync (i.e. the code knows what temperature the AC is set to). Because of this, when I power the arduino on, I have to make sure that all the settings the code is set to matches the current settings of the air conditioner. The problem is, the arduino cloud saves the last property settings before the arduino powers down, so that when I power up the arduino again, it reverts back to those settings. Sometimes I dont remember what those previous settings were, so it’s a hassle to get the two in sync.

The question is: is there any way to initialize the property values to a known value when the arduino is powered up? I use a switch “thing” to control the power of the AC. Is there any way to initialize the switch property to off on start up? For the temperature control, I use the light brightness “thing”. Is there any way to set the brightness to 70% on arduino power up?

I appreciate any help. Please let me know if more information is needed.

hi Vince

of course you can! :slight_smile:

use one of the available callbacks to check when your properties have synced between board and cloud
and use a state to reset them before you use them

here’s a chunk of code to get you started, and just so you know we have callbacks for CONNECT and DISCONNECT events :wink:

void setup(){
  ...
  ...
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  
  ArduinoCloud.addCallback(ArduinoIoTCloudEvent::SYNC, onIoTSync);
  ...
}

void loop(){

}

void onIoTSync(){

  // set your initial values here

}
1 Like

Ubidefeo,

Thank you for the speedy reply! I look forward to trying that out. In the mean time, is there any documentation that lists all of the useful callbacks like the one you shared? As of now, I'm only familiar with the callbacks that the arduino cloud tutorials use, so I'm curious what other functionality I might be missing out on.

I'll try that out and report back.

Thank you for the help!

I'm happy to report that your suggestion worked perfectly. While implementing that, I noticed another issue that I would like to improve. When I power up the Arduino, it seems to execute the "on change" functions. For example, I have a switch state function that executes code when I toggle the switch on or off. When I plug the Arduino in, it automatically executes this function prematurely. When I power the arduino on, I need the code and AC to be in sync, so when it runs those on change functions prematurely, it changes the state of the AC.

Again, thanks for your help!

Edit:

I have 1 more piece of information. When I power up the Arduino, it seems to execute those on change functions before the OnIoTSync() function is executed. In other words, it runs those functions with the old variables that existed before the Arduino powered down. After it runs, the cloud variables are updated to the new values via OnIoTSync().

hey Vince

Glad to hear it worked, I have been a promoter of those callbacks because I had the feeling they’d be useful in many cases :slight_smile:

As I mentioned the 3 events you can subscribe to are

arduinoiotcloudevent::CONNECT

arduinoiotcloudevent::SYNC

arduinoiotcloudevent::DISCONNECT

I’d like to help you out with your other issues, but I’m afrai without code it’s gonna be hard.
Coould your share your sketch?

Of course. I'm working on adding comments to my code. I will upload tomorrow or Saturday. Thanks!

Here is the main code. I left off the onChange functions because I was over the 9000 character limit. Basically, the following is happening. Whenever I have the properties set to values other than their default values that I assign at start up, if I power up the arduino or the arduino loses connection to the Cloud and then reconnects, the code thinks that the properties were changed, so it executes the onChange functions. Here is an example: the default values that I try to assign during start up are 70 degrees for the temperature, 3 for the fan speed, and OFF for the AC power state. Say I turn my AC on and change the temperature to 72. When the Arduino loses connection to the cloud and then reconnects, it executes the onChange functions, so my AC will randomly get turned off or changed to a different temperature. Let me know if more information is needed. I will post the rest of the code in additional posts. Thanks for your help!

/*
  Sketch generated by the Arduino IoT Cloud Thing "AC"
  https://create.arduino.cc/cloud/things/a8fee181-3993-4900-b267-c9dcc801cf7a

  Arduino IoT Cloud Properties description

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

  CloudDimmedLight aCFanSpeed;
  CloudDimmedLight aCTemperature;
  CloudSwitch aCPower;

  Properties 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.
*/

/*

  Code Name: 
  AC_Controller.ino
  
  Author:
  Vincent Palermo

  Description:
  This code adds Arduino Cloud IoT and Amazon Alexa integration to the Honeywell portable air conditioner. This code makes it possible to change the power state, temperature, and
  fan speed using the cloud or Alexa. The Arduino receives commands from the Arduino IoT Cloud or Alexa and uses an IR transmitter to control the AC using the appropriate commands.y
  
  Arduino Used:
  MKR WiFi 1010 or Nano 33 IoT

*/

#include "thingProperties.h"
#include "IRremote.h"

IRsend irsend;

//Initialize and start timers
unsigned long panelTimerSeconds = millis() / 1000 + 60;
unsigned long tempChangeTimerSeconds = millis() / 1000 + 10;

//Initialize variables
int currentACPowerState = 0;
int newACPowerState = 0;

int currentACTemperatureFahrenheit = 70;
int newACTemperatureFahrenheit = 70;
int minimumAllowedACTemperatureFahrenheit = 61;
int maximumAllowedACTemperatureFahrenheit = 89;
int temperatureDifferenceFahrenheit = 0;

int currentACFanSpeed = 3;
int newACFanSpeed = 3;
int numberOfTimesToSendCommand = 0;
int minimumAllowedACFanSpeed = 1;
int maximumAllowedACFanSpeed = 3;

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);
  
  // Initialize cloud variables
  ArduinoCloud.addCallback(ArduinoIoTCloudEvent::SYNC, onIoTSync);

  /*
     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();
  // Your code here
}

void onIoTSync() {

  // Initialize temperature
  aCTemperature.setBrightness(70);
  
  // Initialize power
  aCPower = 0;
  
  // Initialize fan speed
  aCFanSpeed.setBrightness(3);
  
  Serial.println("Arduino synced to IoT Cloud");

}

Here is my thingProperties.h

#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>


const char THING_ID[] = "a8fee181-3993-4900-b267-c9dcc801cf7a";

const char SSID[]     = SECRET_SSID;    // Network SSID (name)
const char PASS[]     = SECRET_PASS;    // Network password (use for WPA, or use as key for WEP)

void onACFanSpeedChange();
void onACTemperatureChange();
void onACPowerChange();

CloudDimmedLight aCFanSpeed;
CloudDimmedLight aCTemperature;
CloudSwitch aCPower;

void initProperties(){

  ArduinoCloud.setThingId(THING_ID);
  ArduinoCloud.addProperty(aCFanSpeed, READWRITE, ON_CHANGE, onACFanSpeedChange);
  ArduinoCloud.addProperty(aCTemperature, READWRITE, ON_CHANGE, onACTemperatureChange);
  ArduinoCloud.addProperty(aCPower, READWRITE, ON_CHANGE, onACPowerChange);

}

WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);

Such a great project, you should use one of the available callbacks to check when your properties have synced between board and cloud.

@vincep65
I think the issue is that the properties are synced and "used" (change event) before you get the chance to set them.
I'd add a flag to check once they are updated/synced and then only set it to "true" once sync is done.
Basically set a global bool sincDone and in your "onChange" events put as first line

if(!syncDone) return;

I'm doing some guessing here because I don't know what happens in your change events,
and I believe they are fired before the SYNC event is, should look at the source to be sure but it's already 1am here :smiley:

Let me know if this helps
ciao.u

1 Like

I was able to get it to work flawlessly with the methods you suggested. Thank you for the help.

Happy to help, Vince :slight_smile: