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.


1 comment: