Hardware components | ||||||
![]() |
| × | 1 | |||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
![]() |
|
- I wanted to lower or raise the outdoor curtains using a single command, like "good night". Since I have Alexa 2,.0 I choosed to use SINRIC as proxi server because it is simple and working, even if I don't like to rely on an external service that could drop in any moment.
I wanted to keep the possibility to operate the curtain with a simple external push button, like in the old style, so to avoid conflicts I used the NC contact of the relay to avoid conflicts.
Finally, since the full cycle requires 35 seconds, I wanted to be able to stop the operation by using a voice command. For this reason I used the multitasking capability of ESP32: one task is listening the wifi communication and the second one operates the switches. In this way a second command will stop the motor.
Critical points are the complexity of command chain (Alexa, Alexa server, Sinric server, my device) and the local wifi network.
I used a 3 lights LED to indicate with blue the connection status and red and green the raise or the lower status.
Commands are on and off, but also lower or raise using voice or smart phone Alexa application.
Alexa controlled curtain
C/C++Then go to sinric.com and create account and devices. copy MyApi.ey and MyDeviceID in the code. Insert your wifi network name and password.
[code]
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <WebSocketsClient.h>
#include <ArduinoJson.h> // get it from https://arduinojson.org/ or install via Arduino library manager
#include "pitches.h"
#include <SimpleTimer.h>
#include <Time.h>
WiFiMulti WiFiMulti;
WebSocketsClient webSocket;
//******************************************************************
#define MyApiKey "xxxxxxxxxxxxxxxxxxxxxxxx" // TODO: Change to your sinric API Key. Your API Key is displayed on sinric.com dashboard
//#define MySSID "xxxxxxxx" // TODO: Change to your Wifi network SSID
//#define MyWifiPassword "xxxxxxxx" // TODO: Change to your Wifi network password
//#define MyDeviceID "xxxxxxxxxxxxxxxxxxxxxxx"
#define MySSID "xxxxxxxx"
#define MyWifiPassword "xxxxxx"
#define LED 2
#define red 27
#define green 26
int connec_ted = 2;
// assegnazione dei pin esp32
int status_on = 25; //era 25
int lower = 32;
int raise_up = 33;
int connection = LOW;
int action_time = 35; //35 times 1 second
int what_to_do;
int traffic_light = LOW;
int do_something = LOW;
SimpleTimer timer;
//***********************************************************************************************
void setup() {
Serial.begin(115200);
WiFiMulti.addAP(MySSID, MyWifiPassword);
Serial.println("alexa_curtain 1.1");
Serial.print("Connecting to Wifi: ");
Serial.println(MySSID);
pinMode(connesso, OUTPUT);
pinMode(LED, OUTPUT);
pinMode(red, OUTPUT);
pinMode(green, OUTPUT);
pinMode (status_on, OUTPUT);
pinMode (raise_up, OUTPUT);
pinMode (lower, OUTPUT);
digitalWrite(raise_up, LOW);
digitalWrite(lower, LOW);
digitalWrite(connesso, HIGH);
digitalWrite(red, HIGH);
digitalWrite(green, HIGH);
do_something = LOW; // action switch on high ther is something to do
xTaskCreatePinnedToCore(ActionTask, "ActionTask ", 4000, NULL, 5, NULL, 0); //Task for Core 1 priority set at 5
// Waiting for Wifi connect
while (WiFiMulti.run() != WL_connected) {
delay(500);
if (connection == LOW)
{
digitalWrite(connesso, HIGH);
digitalWrite(status_on, LOW);
connection = HIGH;
} else {
digitalWrite(connesso, LOW);
digitalWrite(status_on, HIGH);
connection = LOW;
}
Serial.print(".");
}
if (WiFiMulti.run() == WL_connected) {
Serial.println("");
Serial.print("WiFi connected. ");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
digitalWrite(connesso, HIGH);
digitalWrite(status_on, LOW);
}
// server address, port and URL
webSocket.begin("iot.sinric.com", 80, "/");
// event handler
webSocket.onEvent(webSocketEvent);
webSocket.setAuthorization("apikey", MyApiKey);
}
//***********************************************************************************************
void loop() {
webSocket.loop();
delay(1);
}
//***********************************************************************************************
void turnOn(String MyDeviceID) {
if (MyDeviceID == "mysinric deviceid") // Device ID of first device
{
Serial.print("Turn ON first device with ID: ");
Serial.println(MyDeviceID);
}
}
//***********************************************************************************************
void turnOff(String MyDeviceID) {
if (MyDeviceID == "mysinric deviceid") // Device ID of device
{
Serial.print("Turn OFF first device with ID: ");
Serial.println(MyDeviceID);
}
}
//***********************************************************************************************
char minus = '-';
int n;
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length)
{
switch (type) {
case WStype_DISconnec_ted:
{ Serial.printf("[WSc] Webservice disconnec_ted from sinric.com!\n");
} break;
case WStype_connec_ted: {
Serial.printf("[WSc] Service connected to sinric.com at url: %s\n", payload);
Serial.printf("Waiting for commands from sinric.com ...\n");
}
break;
case WStype_TEXT: {
Serial.printf("[WSc] get text: %s\n", payload);
// Example payload for ON :
//{"deviceId":"5a2b908a74a6703928abf38b","powerState":"ON"}
DynamicJsonBuffer jsonBuffer (4000);
JsonObject& json = jsonBuffer.parseObject((char*)payload);
String deviceId = json ["deviceId"];
String action = json ["action"];
String value = json ["value"];
if (deviceId == "mysinric deviceid") // Device ID of first device
{
if (traffic_light == LOW)
{ if ( action == "setPowerState")
{ Serial.println ("entry from power");
if (value == "ON")
{ what_to_do = HIGH; //raise_up
do_something = HIGH;
}
if (value == "OFF")
{ what_to_do = LOW; //lower
do_something = HIGH;
}
} if (action == "SetBrightness" )
{ Serial.println ("entry from brightness"); // if below 50% lower otherwise raise
Serial.print (value );
int n = (value [0] - 48) * 10;
n = n + (value [1] - 48);
Serial.println (n );
Serial.print (" value 1 ");
Serial.println (value [1] );
if (n > 50 )
{
what_to_do = HIGH; //raise_up
do_something = HIGH;
Serial.println ("raise_up from brightness");
}
if (n <= 50 )
{ what_to_do = LOW; //lower
do_something = HIGH; Serial.println ("lower from brightness");
}
}
if ( action == "AdjustBrightness")
{ Serial.println ("entry from adjustbrightness");
Serial.print (value );
if ( value [0] != minus)
{
what_to_do = HIGH; //raise_up
do_something = HIGH;
Serial.println ("raise_up from brightness");
}
if ( value [0] == minus)
{ what_to_do = LOW; //lower
do_something = HIGH; Serial.println ("lower from brightness");
}
}
} else {
traffic_light = LOW;
digitalWrite(raise_up, LOW);// stop action
digitalWrite(lower, LOW);
}
}
} break;
case WStype_BIN:
{ Serial.printf("[WSc] get binary length: %u\n", length);
} break;
}
}
//****************************************************
void ActionTask (void * pvParameters)
{
while (1)
{
if (do_something == HIGH)
{ traffic_light = HIGH;
digitalWrite(LED, HIGH);
digitalWrite(status_on, HIGH);
{ if (what_to_do == HIGH) // raise_up curtain
{ digitalWrite(red, LOW);
digitalWrite(raise_up, HIGH); //funziona con logica inversa
actiontime ();
digitalWrite(raise_up, LOW);
digitalWrite(red, HIGH);
}
else // lower curtain
{
if (traffic_light == HIGH)
{ digitalWrite(green, LOW);
digitalWrite(lower, HIGH); //this depend on the relay board switch it could be low or high for operate
actiontime ();
}
digitalWrite(lower, LOW);
digitalWrite(green, HIGH);
}
}
digitalWrite(LED, LOW);
digitalWrite(status_on, LOW);
traffic_light = LOW;
do_something = LOW;
}
vTaskDelay(2);
}
}
//***********************************************************************************************
void actiontime ()
{ for (int i = 0; i < action_time; i++)
{ if (traffic_light == HIGH)
vTaskDelay(1000);
}
}
//***********************************************************************************************
[/code]
[code]
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <WebSocketsClient.h>
#include <ArduinoJson.h> // get it from https://arduinojson.org/ or install via Arduino library manager
#include <SimpleTimer.h>
#include <Time.h>
WiFiMulti WiFiMulti;
WebSocketsClient webSocket;
//******************************************************************
#define MyApiKey "xxxxxxxxxxxxxxxxxxxxxxxx" // TODO: Change to your sinric API Key. Your API Key is displayed on sinric.com dashboard
//#define MySSID "xxxxxxxx" // TODO: Change to your Wifi network SSID
//#define MyWifiPassword "xxxxxxxx" // TODO: Change to your Wifi network password
//#define MyDeviceID "xxxxxxxxxxxxxxxxxxxxxxx"
#define MySSID "xxxxxxxx"
#define MyWifiPassword "xxxxxx"
#define LED 2
#define red 27
#define green 26
int connec_ted = 2;
// assegnazione dei pin esp32
int status_on = 25; //era 25
int lower = 32;
int raise_up = 33;
int connection = LOW;
int action_time = 35; //35 times 1 second
int what_to_do;
int traffic_light = LOW;
int do_something = LOW;
SimpleTimer timer;
//***********************************************************************************************
void setup() {
Serial.begin(115200);
WiFiMulti.addAP(MySSID, MyWifiPassword);
Serial.println("alexa_curtain 1.1");
Serial.print("Connecting to Wifi: ");
Serial.println(MySSID);
pinMode(connec_ted, OUTPUT);
pinMode(LED, OUTPUT);
pinMode(red, OUTPUT);
pinMode(green, OUTPUT);
pinMode (status_on, OUTPUT);
pinMode (raise_up, OUTPUT);
pinMode (lower, OUTPUT);
digitalWrite(raise_up, LOW);
digitalWrite(lower, LOW);
digitalWrite(connec_ted, HIGH);
digitalWrite(red, HIGH);
digitalWrite(green, HIGH);
do_something = LOW; // action switch on high ther is something to do
xTaskCreatePinnedToCore(ActionTask, "ActionTask ", 4000, NULL, 5, NULL, 0); //Task for Core 1 priority set at 5
// Waiting for Wifi connect
while (WiFiMulti.run() != WL_CONNECTED) {
delay(500);
if (connection == LOW)
{
digitalWrite(connec_ted, HIGH);
digitalWrite(status_on, LOW);
connection = HIGH;
} else {
digitalWrite(connec_ted, LOW);
digitalWrite(status_on, HIGH);
connection = LOW;
}
Serial.print(".");
}
if (WiFiMulti.run() == WL_CONNECTED) {
Serial.println("");
Serial.print("WiFi connected. ");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
digitalWrite(connec_ted, HIGH);
digitalWrite(status_on, LOW);
}
// server address, port and URL
webSocket.begin("iot.sinric.com", 80, "/");
// event handler
webSocket.onEvent(webSocketEvent);
webSocket.setAuthorization("apikey", MyApiKey);
}
//***********************************************************************************************
void loop() {
webSocket.loop();
delay(1);
}
//***********************************************************************************************
void turnOn(String MyDeviceID) {
if (MyDeviceID == "mysinric deviceid") // Device ID of first device
{
Serial.print("Turn ON first device with ID: ");
Serial.println(MyDeviceID);
}
}
//***********************************************************************************************
void turnOff(String MyDeviceID) {
if (MyDeviceID == "mysinric deviceid") // Device ID of device
{
Serial.print("Turn OFF first device with ID: ");
Serial.println(MyDeviceID);
}
}
//***********************************************************************************************
char minus = '-';
int n;
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length)
{
switch (type) {
case WStype_DISCONNECTED:
{ Serial.printf("[WSc] Webservice DISCONNECTED from sinric.com!\n");
} break;
case WStype_CONNECTED: {
Serial.printf("[WSc] Service connected to sinric.com at url: %s\n", payload);
Serial.printf("Waiting for commands from sinric.com ...\n");
}
break;
case WStype_TEXT: {
Serial.printf("[WSc] get text: %s\n", payload);
// Example payload for ON :
//{"deviceId":"5a2b908a74a6703928abf38b","powerState":"ON"}
DynamicJsonBuffer jsonBuffer (4000);
JsonObject& json = jsonBuffer.parseObject((char*)payload);
String deviceId = json ["deviceId"];
String action = json ["action"];
String value = json ["value"];
if (deviceId == "mysinric deviceid") // Device ID of first device
{
if (traffic_light == LOW)
{ if ( action == "setPowerState")
{ Serial.println ("entry from power");
if (value == "ON")
{ what_to_do = HIGH; //raise_up
do_something = HIGH;
}
if (value == "OFF")
{ what_to_do = LOW; //lower
do_something = HIGH;
}
} if (action == "SetBrightness" )
{ Serial.println ("entry from brightness"); // if below 50% lower otherwise raise
Serial.print (value );
int n = (value [0] - 48) * 10;
n = n + (value [1] - 48);
Serial.println (n );
Serial.print (" value 1 ");
Serial.println (value [1] );
if (n > 50 )
{
what_to_do = HIGH; //raise_up
do_something = HIGH;
Serial.println ("raise_up from brightness");
}
if (n <= 50 )
{ what_to_do = LOW; //lower
do_something = HIGH; Serial.println ("lower from brightness");
}
}
if ( action == "AdjustBrightness")
{ Serial.println ("entry from adjustbrightness");
Serial.print (value );
if ( value [0] != minus)
{
what_to_do = HIGH; //raise_up
do_something = HIGH;
Serial.println ("raise_up from brightness");
}
if ( value [0] == minus)
{ what_to_do = LOW; //lower
do_something = HIGH; Serial.println ("lower from brightness");
}
}
} else {
traffic_light = LOW;
digitalWrite(raise_up, LOW);// stop action
digitalWrite(lower, LOW);
}
}
} break;
case WStype_BIN:
{ Serial.printf("[WSc] get binary length: %u\n", length);
} break;
}
}
//****************************************************
void ActionTask (void * pvParameters)
{
while (1)
{
if (do_something == HIGH)
{ traffic_light = HIGH;
digitalWrite(LED, HIGH);
digitalWrite(status_on, HIGH);
{ if (what_to_do == HIGH) // raise_up curtain
{ digitalWrite(red, LOW);
digitalWrite(raise_up, HIGH); //funziona con logica inversa
actiontime ();
digitalWrite(raise_up, LOW);
digitalWrite(red, HIGH);
}
else // lower curtain
{
if (traffic_light == HIGH)
{ digitalWrite(green, LOW);
digitalWrite(lower, HIGH); //this depend on the relay board switch it could be low or high for operate
actiontime ();
}
digitalWrite(lower, LOW);
digitalWrite(green, HIGH);
}
}
digitalWrite(LED, LOW);
digitalWrite(status_on, LOW);
traffic_light = LOW;
do_something = LOW;
}
vTaskDelay(2);
}
}
//***********************************************************************************************
void actiontime ()
{ for (int i = 0; i < action_time; i++)
{ if (traffic_light == HIGH)
vTaskDelay(1000);
}
}
//***********************************************************************************************
[/code]
Comments
Please log in or sign up to comment.