Arduino ESP2866, cloud and websocket based gate opener

Arduino ESP2866, cloud and websocket based gate opener
31/03/2019 Ernestas Konopliovas
In Arduino
Short description

My goal of this project was to make gate and garage opening process more convenient. I thought that it would be nice if I could open them using just my voice, in Siri, for instance. Take a look how I managed to bring it into life.

For hardware part, I have chosen Wemos D1 R2 WiFi board because it already had an integrated ESP2866 module in it.

For software, I decided to use Python web server as soon as it works with Web Sockets, and to use some simple html and js for a tiny website.

Note: This project is based on my similar creation Attention notifier. Please look for a source code there.

How it looks like inside

I believed, that reprogramming garage and gate remote will be too massive work, so i decided to find another, less technological but way more reliable solution. This is quite funny but I decided to just put two servos, which will be pushing gate and garage buttons on my remote. So I deconstructed my regular remote and placed it all together as shown on photos. And guess what? It works perfectly.

Then, I connected my web server to Heroku, created some Siri shortcuts and here is what I achieved:

Code, I used

Board code:

#include <ESP8266WiFi.h>
#include <WebSocketsClient.h>
#include <Servo.h>

Servo servo;

// Connecting to the internet
char * ssid = "Your Wifi SSID";
char * password = "Your Wifi password";

bool garageClosed = "false";
bool gateClosed = "false";
int servo_position = 165;

const unsigned long period = 1000 * 165; //2,5min
unsigned long startMillis;
unsigned long currentMillis;
bool gatePushed = false;

// Controlling the WS2812B

// Setting up the websocket client
WebSocketsClient webSocket;
WebSocketsClient webSocket2;
WebSocketsClient webSocket3;

void setup() {

  pinMode(BUILTIN_LED, OUTPUT);
// put your setup code here, to run once:
Serial.begin(115200);
// WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while(WiFi.status()!=WL_CONNECTED) {
Serial.print(".");
delay(500);
}
servo.attach(D6);
servo.write(servo_position);
servo.detach();

  servo.attach(D7);
servo.write(servo_position);
servo.detach();

  Serial.println("");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());

  // Initializing the websocket communication
//webSocket.begin("192.168.2.224", 8000, "/subscribe");

  webSocket.begin("Your project name.herokuapp.com", 80, "/subscribe");
webSocket.onEvent(webSocketEvent);
webSocket.setReconnectInterval(50); 

  //gate voice control cloud websocket listener
webSocket2.begin("Your project name.herokuapp.com", 80, "/subscribe");
webSocket2.onEvent(webSocketEvent);
webSocket2.setReconnectInterval(50); 

  //garage voice control cloud websocket listener
webSocket3.begin("Your project name.herokuapp.com", 80, "/subscribe");
webSocket3.onEvent(webSocketEvent);
webSocket3.setReconnectInterval(50); 

  startMillis = millis();
}

void loop() {
// put your main code here, to run repeatedly:
webSocket.loop();
webSocket2.loop();
webSocket3.loop();

     if(gatePushed == true){
currentMillis = millis();
if (currentMillis - startMillis >= period)  //test whether the period has elapsed
{
performAction('1');
gatePushed = false;
startMillis = currentMillis;
}
}

} 

void webSocketEvent(WStype_t type, uint8_t *payload, size_t length) {
switch(type) {
case WStype_DISCONNECTED:
Serial.printf("[WSc] Disconnected!n");
break;
case WStype_CONNECTED:
Serial.printf("[WSc] Connected to url: %sn", payload);
blinkTheLed(3);
break;
case WStype_TEXT:
if((char)payload[0] == '0' || (char)payload[0] == '1' || (char)payload[0] == '2' || (char)payload[0] == '3' || (char)payload[0] == '4'){
blinkTheLed(1);
performAction((char)payload[0]);
}
break;
}
}

void performAction(char actionNumber){
switch(actionNumber){

     case '0':
Serial.println("Gate action received!");
if(!gateClosed){
webSocket.sendTXT("gate closing");
gatePush();
webSocket.sendTXT("gate closed");
gateClosed = true;
}
else{
webSocket.sendTXT("gate opening");
gatePush();
webSocket.sendTXT("gate opened");
gateClosed = false;
}
break;

    case '1':
Serial.println("Gate action received!");
gatePushed = true;
if(!gateClosed){
webSocket.sendTXT("gate closing");
gatePush();
webSocket.sendTXT("gate closed");
gateClosed = true;
}
else{
webSocket.sendTXT("gate opening");
gatePush();
webSocket.sendTXT("gate opened");
gateClosed = false;
}
break;

    case '2':
Serial.println("Garage action received!");
if(!garageClosed){
webSocket.sendTXT("garage closing");
garagePush();
webSocket.sendTXT("garage closed");
garageClosed = "true";
}
else{
webSocket.sendTXT("garage opening");
garagePush();
webSocket.sendTXT("garage opened");
garageClosed = false;
}
break;

     case '3':
webSocket.sendTXT("ready");
webSocket2.sendTXT("ready");
webSocket3.sendTXT("ready");
checkStatus();
break;

     case '4':
gateClosed = true;
garageClosed = true;
checkStatus();
blinkTheLed(5);
break;
}
}

void checkStatus(){
if(garageClosed){
webSocket.sendTXT("garage closed");
}
if(!garageClosed){
webSocket.sendTXT("garage opened");
}
if(gateClosed){
webSocket.sendTXT("gate closed");
}
if(!gateClosed){
webSocket.sendTXT("gate opened");
}
}

void gatePush(){
servo1rotate(1);
delay(1000);
}

void garagePush(){
servo2rotate(1);
delay(1000);
}

void blinkTheLed(int times){
for(int i = 0; i < times; i++){
digitalWrite(BUILTIN_LED, HIGH);
delay(100);
digitalWrite(BUILTIN_LED, LOW);
delay(100);
}
}

  void servo1rotate(int howManyTimes){
servo.attach(D6);

    for(int i = 0; i < howManyTimes; i++){ for (servo_position=165; servo_position >= 0; servo_position -=1){
servo.write(servo_position);
delay(3);
}

    for (servo_position = 0; servo_position <=165; servo_position +=1){
servo.write(servo_position);
delay(3);
}
}
servo.detach();
}

  void servo2rotate(int howManyTimes){
servo.attach(D7);

  for(int i = 0; i < howManyTimes; i++){ for (servo_position=165; servo_position >= 0; servo_position -=1){
servo.write(servo_position);
delay(3);
} 

  for (servo_position = 0; servo_position <=165; servo_position +=1){
servo.write(servo_position);
delay(3);
}
}
servo.detach();
}

Comments (0)

Leave a reply