Home Automation with Opta™️

This application note describes building a home automation application using Opta™️.

Introduction

The home automation systems allow to control electronic devices remotely and to perform automatic routines based on the user's programming preferences, making domestic environments more convenient, comfortable, and efficient, also optimizing energy costs.

Home automation applications allow, for example, smart lights management and HVAC control. Thanks to its industrial IoT capabilities, Opta™️ is an excellent product for home automation applications.

Opta™️ with Wi-Fi® connectivity support
Opta™️ with Wi-Fi® connectivity support

Goals

This application note shows a home automation system based on an Opta™️, capable of controlling a roller window shade, also known as roller blind, based on a programmed scenario. The application note's goals are to:

  • Implement the roller window shade control (opening and closing) upon a programmed scenario
  • Get inputs from limit switches included in the roller window shade's control system, for feedback and security reinforcement
  • Control and monitor the roller window shade via Arduino Cloud

Hardware and Software Requirements

Hardware Requirements

  • Opta™️ PLC with wireless connectivity support (x1)

  • USB-C® cable (x1)

  • 12 V / 30 RPM DC motor (x1)

  • Full-bridge motor driver (x1)

  • A 3D printed case for the DC motor and its driver (.stl files of the case can be downloaded here)

  • Normally Open (NO) Single Pole Double Throw (SPDT) limit switch (x2)

  • 24AWG twisted-pair cable (for electrical connections)

  • 12 V / 2 A DC power supply (x1)

Software Requirements

Hardware Setup Overview

The following diagram shows the electrical connections of the intended application:

Application electrical connections
Application electrical connections

The Opta™️ controls a DC motor via a driver using the digital output terminals

D0
and
D1
; two NO SPDT limit switches are connected to digital input terminals
I3
and
I4
of the Opta™️. A 12V DC/2A power supply is used to power the Opta™️, the DC motor, and the rest of the application.

Note: The maximum voltage of Opta™️ digital input pins is 24 VDC.

Demonstration Description

Application Overview

The first task of the program is to create the connection between the Opta™️ and the predefined Wi-Fi® network by the user in the Arduino IoT Cloud; when the Wi-Fi® connection is established, the internal real-time clock (RTC) of the Opta™️ will be synced using a Network Time Protocol (NTP) server.

Opta™️ RTC will be synced with the NTP server periodically (in this example, every 30 minutes) for security and reliability reasons.

The NTP is a protocol used to synchronize the clocks of servers and clients across the Internet; it is intended to synchronize computers participating in the network within a few milliseconds of Coordinated Universal Time (UTC). You can read more about the NTP protocol here.

After the RTC is synced, Opta™️ will be programmed for opening and closing the roller window shades using the DC motor, at specific hours every day:

  • The roller window shade will open automatically in the morning as the sun rises (e.g. 6:00 AM) and close in the evening (e.g. 6:00 PM)
  • The NO SPDT limit switches will provide Opta™️ a feedback for the sun shield's upper or lower end limit, triggering the motor's stop

Example Sketch of the Application

Hereafter the sketch explained. Note that this code must be updated considering the proper parameters of your roller window shade and DC motor characteristics.

The first part of the sketch includes some definitions needed to:

  • Enable a Wi-Fi® connection to a network
  • Set the the NTP client configuration
  • Declare variables related to the RTC update interval and the programmed scenarios for the control of the shade
1// Libraries used in the sketch
2#include <WiFi.h>
3#include <NTPClient.h>
4#include <mbed_mktime.h>
5
6// Wi-Fi network credentials (replace with your network credentials)
7char ssid[] = "YOUR_WIFI_SSID";
8char pass[] = "YOUR_WIFI_PASSWORD";
9int status = WL_IDLE_STATUS;
10
11// NTP client configuration and RTC update interval
12WiFiUDP ntpUDP;
13NTPClient timeClient(ntpUDP, "pool.ntp.org", -6*3600, 0);
14unsigned long interval = 60*30*1000UL;
15unsigned long lastTime = 0;
16
17// Programmed scenarios
18int local_hour;
19int local_minutes;
20int programmed_hour_1 = 6;
21int programmed_hour_2 = 18;
22int programmed_minutes_1 = 0;
23int programmed_minutes_2 = 0;

For Wi-Fi® connectivity, we will use

WiFi
library.

For the connection to an NTP server and to retrieve time information from it, we will use

NTPClient
.

We are going to use specific RTC management methods from Mbed™️ to handle the internal RTC of the Opta™️ microcontroller. More information regarding those methods can be found here.

From the code shown above, there are two important lines:

1WiFiUDP ntpUDP;
2NTPClient timeClient(ntpUDP, "pool.ntp.org", -6*3600, 0);

The parameters of the

timeClient
object are as follows:

  • The first parameter defines the type of connection with the NTP server (via UDP).
  • The second parameter specifies the NTP server used for retrieving the date and time used for updating the internal RTC of the Opta™️; in this case we are going to use
    pool.ntp.org
    .
  • The third parameter defines the time offset (your timezone) in seconds.
  • Finally, the fourth parameter defines an update interval of the NTP client (in milliseconds).

These are some time offset examples to use for different timezones:

  • GMT +1:
    3600
  • GMT +8:
    28800
  • GMT -1:
    -3600
  • GMT 0:
    0

The variables

programmed_hour_1
,
programmed_hour_2
,
programmed_minutes_1
, and
programmed_minutes_2
are used to open or close the roller window shade at two specific times of the day. They can be changed according to your needs.

The Opta™️ setup is shown as follows:

1// Opta initialization
2void setup() {
3 Serial.begin(9600);
4 while (!Serial) {
5 ;
6 }
7 delay(5000);
8
9 // Attempt Wi-Fi connection
10 while (status != WL_CONNECTED) {
11 Serial.print("- Attempting to connect to WPA SSID: ");
12 Serial.println(ssid);
13 status = WiFi.begin(ssid, pass);
14 delay(500);
15 }
16
17 // Display Wi-Fi network information
18 Serial.println();
19 Serial.println("- NETWORK INFORMATION");
20 Serial.print("- You're now connected to the network ");
21 printCurrentNet();
22 printWifiData();
23 delay(5000);
24
25 // NTP client object initialization and time update, display updated time on the Serial Monitor
26 timeClient.begin();
27 updateTime();
28
29 // Digital inputs, digital outputs, built-in LEDs initialization
30 pinMode(LED_D0, OUTPUT);
31 pinMode(LED_D1, OUTPUT);
32 pinMode(DO, OUTPUT);
33 pinMode(D1, OUTPUT);
34 pinMode(A2, INPUT);
35 pinMode(A3, INPUT);
36
37 // Stop the roller window shade from moving
38 digitalWrite(LED_D0, LOW);
39 digitalWrite(LED_D1, LOW);
40 stop_shade();
41}

There are five essential steps in the setup function:

  • The serial port is initialized to

    9600
    bauds; it will be used in the application for debugging purposes.

  • A Wi-Fi® connection is attempted; the application will not start unless the Wi-Fi® connection is established successfully.

  • After establishing a Wi-Fi® connection, the connected network information is displayed using the

    printCurrentNet()
    and
    printWifiData()
    functions in the Arduino IDE Serial Monitor. This information will be used for debugging purposes.

  • The NTP client is initialized, and Opta™️ PLC's RTC is aligned with the updated time retrieved from the NTP server.

  • Two digital inputs, two digital outputs, and two built-in LEDs of Opta™️ are initialized, the roller window shade is stopped using the

    stop_shade()
    function. The built-in LEDs of Opta™️ are used in the application as visual feedback for user feedback and debugging purposes.

The main loop shown below:

1void loop() {
2 // Check and verify if it's time to move up or down the roller window shade
3
4 local_hour = getLocalHour();
5 local_minutes = getLocalMinutes();
6
7 if (programmed_hour_1 == local_hour && programmed_minutes_1 == local_minutes) {
8 Serial.println("- Rolling down shade!");
9 roll_down_shade();
10 } else if (programmed_hour_2 == local_hour && programmed_minutes_2 == local_minutes) {
11 Serial.println("- Rolling up shade!");
12 roll_up_shade();
13 } else {
14 stop_shade();
15 }
16
17 // Update time client periodically
18 unsigned long currentTime = millis();
19 if (currentTime - lastTime >= interval) {
20 updateTime();
21 lastTime = currentTime;
22 }
23}

The main loop can be divided into two essential steps:

  • The
    getLocalHour()
    and
    getLocalMinutes()
    functions are used to acquire Opta™'s local time (from its RTC); this is then compared to the programmed scenarios times (in this example, 6:00 AM and 6:00 PM). The roller window shade must be opened or closed if Optas™'s RTC time matches the programmed scenarios.
  • The Opta™️ RTC is updated periodically (every 30 minutes in the example) using the
    updateTime()
    function.

Complete Example Sketch of the Application

The complete example sketch explained before is shown below; pay attention to the

updateTime()
,
getLocalTime()
,
getLocalHour()
,
roll_down_shade()
,
roll_up_shade()
,
stop_shade()
,
printWifiData()
, and
printCurrentNet()
functions:

1/**
2 Home Automation with Opta (Application Note)
3 Name: window_shade_roller_opta.ino
4 Purpose: Open or close a roller window shade based on a programmed scenario
5
6 @author: José Bagur and Taddy Chung
7 @version: 1.3 (15/02/23)
8*/
9
10// Libraries used in the sketch
11#include <WiFi.h>
12#include <NTPClient.h>
13#include <mbed_mktime.h>
14
15// Wi-Fi network credentials
16char ssid[] = "YOUR_WIFI_SSID";
17char pass[] = "YOUR_WIFI_PASSWORD";
18int status = WL_IDLE_STATUS;
19
20// NTP client configuration and RTC update interval
21WiFiUDP ntpUDP;
22NTPClient timeClient(ntpUDP, "pool.ntp.org", -6*3600, 0);
23unsigned long interval = 60*30*1000UL;
24unsigned long lastTime = 0;
25
26// Programmed scenarios for opening or closing the shade
27int local_hour;
28int local_minutes;
29int programmed_hour_1 = 6;
30int programmed_hour_2 = 18;
31int programmed_minutes_1 = 0;
32int programmed_minutes_2 = 0;
33
34bool shade_state = false;
35
36
37// Opta initialization
38void setup() {
39 Serial.begin(9600);
40 while (!Serial) {
41 ;
42 }
43 delay(5000);
44
45 // Attempt Wi-Fi connection
46 while (status != WL_CONNECTED) {
47 Serial.print("- Attempting to connect to WPA SSID: ");
48 Serial.println(ssid);
49 status = WiFi.begin(ssid, pass);
50 delay(500);
51 }
52
53 // Display Wi-Fi network information
54 Serial.println();
55 Serial.println("- NETWORK INFORMATION");
56 Serial.print("- You're now connected to the network ");
57 printCurrentNet();
58 printWifiData();
59 delay(5000);
60
61 // NTP client object initialization and time update, display updated time on the Serial Monitor
62 timeClient.begin();
63 updateTime();
64
65 // Digital inputs, digital outputs, built-in LEDs initialization
66 pinMode(LED_D0, OUTPUT);
67 pinMode(LED_D1, OUTPUT);
68 pinMode(D0, OUTPUT);
69 pinMode(D1, OUTPUT);
70 pinMode(A2, INPUT);
71 pinMode(A3, INPUT);
72
73 // Stop the roller window shade from moving
74 digitalWrite(LED_D0, LOW);
75 digitalWrite(LED_D1, LOW);
76 stop_shade();
77}
78
79void loop() {
80 // Check and verify if it's time to move up or down the roller window shade
81
82 local_hour = getLocalHour();
83 local_minutes = getLocalMinutes();
84
85 if (programmed_hour_1 == local_hour && programmed_minutes_1 == local_minutes) {
86 Serial.println("- Rolling down shade!");
87 roll_down_shade();
88 } else if (programmed_hour_2 == local_hour && programmed_minutes_2 == local_minutes) {
89 Serial.println("- Rolling up shade!");
90 roll_up_shade();
91 } else {
92 stop_shade();
93 }
94
95 // Update time client periodically
96 unsigned long currentTime = millis();
97 if (currentTime - lastTime >= interval) {
98 updateTime();
99 lastTime = currentTime;
100 }
101}
102
103/**
104 Updates Opta's internal RTC using a NTP server
105
106 @param none
107 @return none
108*/
109void updateTime() {
110 Serial.println();
111 Serial.println("- TIME INFORMATION:");
112 timeClient.update();
113 const unsigned long epoch = timeClient.getEpochTime();
114 set_time(epoch);
115 Serial.print("- UTC time: ");
116 Serial.println(getLocalTime());
117 Serial.print("- Unix time: ");
118 Serial.println(epoch);
119}
120
121/**
122 Retrieves Opta's RTC time
123
124 @param none
125 @return Opta's RTC time in hh:mm:ss format
126*/
127String getLocalTime() {
128 char buffer[32];
129 tm t;
130 _rtc_localtime(time(NULL), &t, RTC_FULL_LEAP_YEAR_SUPPORT);
131 strftime(buffer, 32, "%k:%M:%S", &t);
132 return String(buffer);
133}
134
135/**
136 Retrieves Opta's RTC hour
137
138 @param none
139 @return Opta's RTC hour (int)
140*/
141int getLocalHour() {
142 int hour;
143 tm t;
144 _rtc_localtime(time(NULL), &t, RTC_FULL_LEAP_YEAR_SUPPORT);
145 hour = t.tm_hour;
146 return hour;
147}
148
149/**
150 Retrieves Opta's RTC minutes
151
152 @param none
153 @return Opta's RTC minutes (int)
154*/
155int getLocalMinutes() {
156 int minutes;
157 tm t;
158 _rtc_localtime(time(NULL), &t, RTC_FULL_LEAP_YEAR_SUPPORT);
159 minutes = t.tm_min;
160 return minutes;
161}
162
163/**
164 Rolls down the shade
165
166 @param none
167 @return none
168*/
169void roll_down_shade() {
170 while(digitalRead(A2) == LOW) {
171 Serial.println("- ROLLING DOWN SHADE!");
172 digitalWrite(D0, HIGH);
173 digitalWrite(D1, LOW);
174 digitalWrite(LED_D0, HIGH);
175 digitalWrite(LED_D1, LOW);
176 }
177
178 Serial.println("- STOP SHADE!");
179 digitalWrite(LED_D0, LOW);
180 digitalWrite(LED_D1, LOW);
181 stop_shade();
182 shade_state = false;
183}
184
185/**
186 Rolls up the shade
187
188 @param none
189 @return none
190*/
191void roll_up_shade() {
192 while(digitalRead(A3) == LOW) {
193 Serial.println("- ROLLING UP SHADE!");
194 digitalWrite(D0, LOW);
195 digitalWrite(D1, HIGH);
196 digitalWrite(LED_D0, LOW);
197 digitalWrite(LED_D1, HIGH);
198 }
199
200 Serial.println("- STOP SHADE!");
201 digitalWrite(LED_D0, LOW);
202 digitalWrite(LED_D1, LOW);
203 stop_shade();
204 shade_state = true;
205}
206
207/**
208 Stops the shade from moving up or down
209
210 @param none
211 @return none
212*/
213void stop_shade() {
214 digitalWrite(D0, LOW);
215 digitalWrite(D1, LOW);
216}
217
218/**
219 Prints local Wi-Fi network IP and MAC address
220
221 @param none
222 @return none
223*/
224void printWifiData() {
225 // Display network IP
226 IPAddress ip = WiFi.localIP();
227 Serial.print("- IP address: ");
228 Serial.println(ip);
229
230 // Display MAC address
231 byte mac[6];
232 WiFi.macAddress(mac);
233 Serial.print("- MAC address: ");
234 Serial.print(mac[5], HEX);
235 Serial.print(":");
236 Serial.print(mac[4], HEX);
237 Serial.print(":");
238 Serial.print(mac[3], HEX);
239 Serial.print(":");
240 Serial.print(mac[2], HEX);
241 Serial.print(":");
242 Serial.print(mac[1], HEX);
243 Serial.print(":");
244 Serial.println(mac[0], HEX);
245}
246
247/**
248 Prints connected Wi-Fi network SSID, BSSID, RSSI and encryption type
249
250 @param none
251 @return none
252*/
253void printCurrentNet() {
254 // Display network SSID
255 Serial.println(WiFi.SSID());
256
257 // Display network BSSID
258 byte bssid[6];
259 WiFi.BSSID(bssid);
260 Serial.print("- BSSID: ");
261 Serial.print(bssid[5], HEX);
262 Serial.print(":");
263 Serial.print(bssid[4], HEX);
264 Serial.print(":");
265 Serial.print(bssid[3], HEX);
266 Serial.print(":");
267 Serial.print(bssid[2], HEX);
268 Serial.print(":");
269 Serial.print(bssid[1], HEX);
270 Serial.print(":");
271 Serial.println(bssid[0], HEX);
272
273 // Display network RSSI
274 long rssi = WiFi.RSSI();
275 Serial.print("- Signal strength (RSSI): ");
276 Serial.println(rssi);
277
278 // Display network encryption
279 byte encryption = WiFi.encryptionType();
280 Serial.print("- Encryption type: ");
281 Serial.println(encryption, HEX);
282}

Arduino Cloud Integration

The example code explained before can be modified to connect the roller window shade to the Arduino Cloud, leveraging the wireless connectivity features of the Opta™️; remember that you must have an Arduino Cloud account. With the Arduino Cloud integration, we are going to add more advanced functionalities such as remote programming, actuation and monitoring to the application:

  • Change the programmed scenarios (hours and minutes).
  • Open or close the roller window shade at any time.
  • Monitor the roller window shade status (open or close).

If you are new to the Arduino Cloud, check out this getting started guide.

After associating your Opta™️ device to your Arduino Cloud account, create a thing; in this example, we called the thing "Shade Controller." In the "Shade Controller" thing, create the Cloud variables explained below:

Variable:

programmed_hour_1

  • Type:
    int
  • Permission:
    Read & Write
  • Update policy:
    On change
  • Description: this variable defines the hour of the first programmed scenario.

Variable:

programmed_hour_2

  • Type:
    int
  • Permission:
    Read & Write
  • Update policy:
    On change
  • Description: this variable defines the hour of the second programmed scenario.

Variable:

programmed_minutes_1

  • Type:
    int
  • Permission:
    Read & Write
  • Update policy:
    On change
  • Description: this variable defines the minutes of the first programmed scenario.

Variable:

programmed_minutes_2

  • Type:
    int
  • Permission:
    Read & Write
  • Update policy:
    On change
  • Description: this variable defines the minutes of the second programmed scenario.

Variable:

open_shade

  • Type:
    bool
  • Permission:
    Read & Write
  • Update policy:
    On change
  • Description: this variable is used to open the roller window shade if it is set to
    true
    .

Variable:

close_shade

  • Type:
    bool
  • Permission:
    Read & Write
  • Update policy:
    On change
  • Description: this variable is used to close the roller window shade if it is set to
    true
    .

Variable:

shade_shade

  • Type:
    bool
  • Permission:
    Read & Write
  • Update policy:
    Periodically
  • Description: this variable is used to monitor the current status of the roller window shade,
    true
    for open and
    false
    for closed.
Variables created in the Arduino Cloud thing of the application
Variables created in the Arduino Cloud thing of the application

We will use a dashboard and widgets to modify the variables explained before. An example dashboard is shown below:

Dashboard created in the Arduino Cloud thing of the application
Dashboard created in the Arduino Cloud thing of the application

In the dashboard shown above:

  • Value
    -type widgets are used to show the current value of the
    programmed_hour_1
    ,
    programmed_hour_2
    ,
    programmed_minutes_1
    , and
    programmed_minutes_2
    variables. These widgets can also be used to modify the value of the linked variables.

  • LED
    -type widget shows the current status of the
    shade_state
    variable, green when the shade is open and red when the shade is closed.

  • Push button
    widgets are used to open or close the shade anytime.

The complete example sketch with the Arduino Cloud integration is shown below:

1#include <NTPClient.h>
2#include <mbed_mktime.h>
3#include "thingProperties.h"
4
5// NTP client configuration and RTC update interval
6WiFiUDP ntpUDP;
7NTPClient timeClient(ntpUDP, "pool.ntp.org", -6 * 3600, 0);
8unsigned long interval = 60 * 30 * 1000UL;
9unsigned long lastTime = 0;
10
11int local_hour;
12int local_minutes;
13
14void setup() {
15 Serial.begin(9600);
16 delay(1500);
17
18 // Arduino Cloud initialization
19 initProperties();
20 ArduinoCloud.begin(ArduinoIoTPreferredConnection);
21 setDebugMessageLevel(2);
22 ArduinoCloud.printDebugInfo();
23
24 while (ArduinoCloud.connected() == 0) {
25 ArduinoCloud.update();
26 Serial.println("- Waiting for connection to Arduino Cloud");
27 delay(1000);
28 }
29
30 // NTP client object initialization and time update, display updated time on the Serial Monitor
31 timeClient.begin();
32 updateTime();
33
34 // Digital inputs, digital outputs, built-in LEDs initialization
35 pinMode(LED_D0, OUTPUT);
36 pinMode(LED_D1, OUTPUT);
37 pinMode(D0, OUTPUT);
38 pinMode(D1, OUTPUT);
39 pinMode(A0, INPUT);
40 pinMode(A1, INPUT);
41
42 // Stop the roller window shade from moving
43 stop_shade();
44 open_shade = false;
45 close_shade = false;
46 programmed_hour_1 = 6;
47 programmed_hour_2 = 18;
48 programmed_minutes_1 = 0;
49 programmed_minutes_2 = 0;
50
51}
52
53void loop() {
54 // Update Arduino Cloud
55 ArduinoCloud.update();
56 delay(1000);
57
58 // Check and verify if it's time to move up or down the roller window shade
59
60 local_hour = getLocalHour();
61 local_minutes = getLocalMinutes();
62
63 if (programmed_hour_1 == local_hour && programmed_minutes_1 == local_minutes) {
64 Serial.println("- Rolling down shade!");
65 roll_down_shade();
66 } else if (programmed_hour_2 == local_hour && programmed_minutes_2 == local_minutes) {
67 Serial.println("- Rolling up shade!");
68 roll_up_shade();
69 } else {
70 stop_shade();
71 }
72
73 // Update time client periodically
74 unsigned long currentTime = millis();
75 if (currentTime - lastTime >= interval) {
76 updateTime();
77 lastTime = currentTime;
78 }
79}
80
81/**
82 Updates Opta's internal RTC using a NTP server
83
84 @param none
85 @return none
86*/
87void updateTime() {
88 Serial.println();
89 Serial.println("- TIME INFORMATION:");
90 timeClient.update();
91 const unsigned long epoch = timeClient.getEpochTime();
92 set_time(epoch);
93 Serial.print("- UTC time: ");
94 Serial.println(getLocalTime());
95 Serial.print("- Unix time: ");
96 Serial.println(epoch);
97}
98
99/**
100 Retrieves Opta's RTC time
101
102 @param none
103 @return Opta's RTC time in hh:mm:ss format
104*/
105String getLocalTime() {
106 char buffer[32];
107 tm t;
108 _rtc_localtime(time(NULL), &t, RTC_FULL_LEAP_YEAR_SUPPORT);
109 strftime(buffer, 32, "%k:%M:%S", &t);
110 return String(buffer);
111}
112
113/**
114 Retrieves Opta's RTC hour
115
116 @param none
117 @return Opta's RTC hour (int)
118*/
119int getLocalHour() {
120 int hour;
121 tm t;
122 _rtc_localtime(time(NULL), &t, RTC_FULL_LEAP_YEAR_SUPPORT);
123 hour = t.tm_hour;
124 return hour;
125}
126
127/**
128 Retrieves Opta's RTC minutes
129
130 @param none
131 @return Opta's RTC minutes (int)
132*/
133int getLocalMinutes() {
134 int minutes;
135 tm t;
136 _rtc_localtime(time(NULL), &t, RTC_FULL_LEAP_YEAR_SUPPORT);
137 minutes = t.tm_min;
138 return minutes;
139}
140
141/**
142 Rolls down the shade
143
144 @param none
145 @return none
146*/
147void roll_down_shade() {
148 while(digitalRead(A0) == LOW) {
149 Serial.println("- ROLLING DOWN SHADE!");
150 digitalWrite(D0, HIGH);
151 digitalWrite(D1, LOW);
152 digitalWrite(LED_D0, HIGH);
153 digitalWrite(LED_D1, LOW);
154 ArduinoCloud.update();
155 delay(1000);
156 }
157
158 Serial.println("- STOP SHADE!");
159 digitalWrite(LED_D0, LOW);
160 digitalWrite(LED_D1, LOW);
161 stop_shade();
162 shade_state = false;
163}
164
165/**
166 Rolls up the shade
167
168 @param none
169 @return none
170*/
171void roll_up_shade() {
172 while(digitalRead(A1) == LOW) {
173 Serial.println("- ROLLING UP SHADE!");
174 digitalWrite(D0, LOW);
175 digitalWrite(D1, HIGH);
176 digitalWrite(LED_D0, LOW);
177 digitalWrite(LED_D1, HIGH);
178 ArduinoCloud.update();
179 delay(1000);
180 }
181
182 Serial.println("- STOP SHADE!");
183 digitalWrite(LED_D0, LOW);
184 digitalWrite(LED_D1, LOW);
185 stop_shade();
186 shade_state = true;
187}
188
189/**
190 Stops the shade from moving up or down
191
192 @param none
193 @return none
194*/
195void stop_shade() {
196 digitalWrite(LED_D0, LOW);
197 digitalWrite(LED_D1, LOW);
198 digitalWrite(D0, LOW);
199 digitalWrite(D1, LOW);
200}
201
202/*
203 Since ProgrammedHour1 is READ_WRITE variable, onProgrammedHour1Change() is
204 executed every time a new value is received from IoT Cloud.
205*/
206void onProgrammedHour1Change() {
207 Serial.println(programmed_hour_1);
208}
209
210/*
211 Since ProgrammedHour2 is READ_WRITE variable, onProgrammedHour2Change() is
212 executed every time a new value is received from IoT Cloud.
213*/
214void onProgrammedHour2Change() {
215 Serial.println(programmed_hour_2);
216}
217
218
219/*
220 Since ProgrammedMinutes1 is READ_WRITE variable, onProgrammedMinutes1Change() is
221 executed every time a new value is received from IoT Cloud.
222*/
223void onProgrammedMinutes1Change() {
224 Serial.println(programmed_minutes_1);
225}
226
227/*
228 Since ProgrammedMinutes2 is READ_WRITE variable, onProgrammedMinutes2Change() is
229 executed every time a new value is received from IoT Cloud.
230*/
231void onProgrammedMinutes2Change() {
232 Serial.println(programmed_minutes_2);
233}
234/*
235 Since CloseShade is READ_WRITE variable, onCloseShadeChange() is
236 executed every time a new value is received from IoT Cloud.
237*/
238void onCloseShadeChange() {
239 if (close_shade == true) {
240 Serial.println("CAMBIO CLOSE SHADE TRUE");
241 close_shade = false;
242 roll_down_shade();
243 }
244}
245/*
246 Since OpenShade is READ_WRITE variable, onOpenShadeChange() is
247 executed every time a new value is received from IoT Cloud.
248*/
249void onOpenShadeChange() {
250 if (open_shade == true) {
251 Serial.println("CAMBIO OPEN SHADE TRUE");
252 open_shade = false;
253 roll_up_shade();
254 }
255}
256/*
257 Since ShadeState is READ_WRITE variable, onShadeStateChange() is
258 executed every time a new value is received from IoT Cloud.
259*/
260void onShadeStateChange() {
261 Serial.println(shade_state);
262}

Conclusion

This application note shows how to implement an effective home automation system that can control roller window shades with Opta™️. By leveraging the internal RTC of the Opta™️ and NTP server time data, the proposed system can accurately and automatically control the shades based on pre-programmed scenarios. Additionally, the proposed system can be easily monitored and controlled through the Arduino Cloud, providing users with remote management capabilities.

Suggest changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.

License

The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.