Thursday, 2 February 2017

HOME AUTOMATION: ESP8266, Blynk and OTA Updates

I previously used Blynk to set up remote access to my house via my phone and a electric door strike. Since then I learned of the Arduino Over The Air (OTA) update library that would allow me to remotely update the firmware of my device so naturally I immediately wanted to add this feature.

Arduino OTA Library:

You can read about the library on the Arduino github site here, but basically there are three ways you can implement the OTA update:

  1. Arduino IDE
  2. Web Browser
  3. HTTP Server
I've decided to go for the Arduino IDE scenario that is described here.
The requirements for this process are:
  • Arduino IDE (tested with 1.6.8)
  • Python 2.7


Arduino IDE OTA Update:

Basically all you really is the command "ArduinoOTA.begin();" in the setup routine and the command "ArduinoOTA.handle();" in the loop function. This is the bare minimum you need to get it working, but we'll add some more things like error handling and some basic security.

EDIT: I couldn't get the Arduino IDE security feature working on my windows 10 machine, it seems there are a few bugs still being worked out 


Blynk and OTA Code:


/**************************************************************
 * Blynk is a platform with iOS and Android apps to control
 * Arduino, Raspberry Pi and the likes over the Internet.
 * You can easily build graphic interfaces for all your
 * projects by simply dragging and dropping widgets.
 *
 *   Downloads, docs, tutorials: http://www.blynk.cc
 *   Blynk community:            http://community.blynk.cc
 *   Social networks:            http://www.fb.com/blynkapp
 *                               http://twitter.com/blynk_app
 *
 * Blynk library is licensed under MIT license
 * This example code is in public domain.
 *
 **************************************************************
 * This example runs directly on ESP8266 chip.
 *
 * WARNING! ESP8266 SSL support is still experimental.
 *          More info here: https://github.com/esp8266/Arduino/issues/43
 *
 * Note: This requires ESP8266 support package:
 *   https://github.com/esp8266/Arduino
 *
 * Please be sure to select the right ESP8266 module
 * in the Tools -> Board menu!
 *
 * Change WiFi ssid, pass, and Blynk auth token to run :)
 *
 **************************************************************/

#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#define RELAY_PIN D1

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266_SSL.h>
#include <Ticker.h>
#include <ArduinoOTA.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "XXXX";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "XXXX";
char pass[] = "XXXX";
char hostOTA[] = "DoorLock";
char passOTA[] = "XXXX";

bool vPinState = false;               // Set the default virtual pin state
int maxRelayOnTime = 10;              // Set the max on time of the relay 
int minRelayOnTime = 1;               // Set the minimum on time of the relay
int vDelayTime = minRelayOnTime;      // Set the initial delay time value
Ticker doorLatch;                     // Callback fuction instance

void setPinLow()
{
  digitalWrite(RELAY_PIN, 0);
  doorLatch.detach();
}

void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);

  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, 0);

  ArduinoOTA.setHostname(hostOTA);
  //ArduinoOTA.setPassword(passOTA);
  ArduinoOTA.onStart([]() {
    Serial.println("OTA: Start");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nOTA: End");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("OTA: Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("OTA: Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("OTA: Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("OTA: Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("OTA: End Failed");
  });
  ArduinoOTA.begin();
  Serial.println("OTA: Ready");
}

void loop()
{
  ArduinoOTA.handle();
  Blynk.run();
}

BLYNK_WRITE(V0)
{
  // Get the virtual input state
  vPinState = param.asInt();

  // If the virtual input went high
  if(vPinState)
  {
    // Open the relay
    digitalWrite(RELAY_PIN, 1);
    // Turn off the relay after the defined delay time
    doorLatch.attach(vDelayTime, setPinLow);
  }
}

BLYNK_WRITE(V1)
{
  // Get the input from the virtual input slider
  vDelayTime = param.asInt();

  // Constrain the virtual slider input to within the preset bounds
  vDelayTime = constrain(vDelayTime, minRelayOnTime, maxRelayOnTime);
}


How to update your device OTA:

Once you get the code loaded on to your device you should see the unit appear in your list of ports under the 'Tools' heading.
I had to reboot my machine to get this to work for me. Now you can upload code to your device over the network as if it was connected via USB.


No comments:

Post a Comment