Tag Archives: IoT

DIY IoT button

I’ve been looking for a project for a bunch of ESP-8266 ESP-01 boards I’ve had kicking around for a while.

The following describes a simple button that when pushed publishes a MQTT message that I can subscribe to with Node-RED to control different tasks.

It’s been done many times before, but I wanted to have a go at building my own IoT button.

Software

The code is pretty simple:

  • The MQTT PubSubClient (Thank’s Nick)
  • Some hard coded WiFi and MQTT Broker details
  • The setup function which connects to the network
  • The reconnect function that connects to the MQTT broker and publishes the message
  • The loop function which flashes the LED to show success then go into deep sleep

In order to get the best battery life you want the ESP8266 to be in deep sleep mode for as much as possible, so for this reason the loop function sends the message to signify the button has been pushed then indefinitely enters the deepest sleep state possible. This means the loop function will only run once on start up.

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

#define ESP8266_LED 1

const char* ssid = "WifiName";
const char* passwd = "GoodPassword";
const char* broker = "192.168.1.114";

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {

  Serial.begin(115200);
  delay(10);
  
  pinMode(ESP8266_LED, OUTPUT);

  WiFi.hostname("Button1");
  WiFi.begin(ssid, passwd);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  client.setServer(broker, 1883);
  reconnect();
}

void reconnect() {
  while(!client.connected()) {
    if (client.connect("button1")){
      client.publish("button1", "press");
    } else {
      delay(5000);
    }
  }
}

void loop() {

  if (client.connected()) {
    reconnect();
  }
  client.loop();
  
  // put your main code here, to run repeatedly:
  digitalWrite(ESP8266_LED, HIGH);
  delay(1000);
  digitalWrite(ESP8266_LED, LOW);
  delay(1000);
  ESP.deepSleep(0);
}

Hardware

By using a momentary push button wake the ESP-01 I bridged reset pin to ground the chip resets each time it’s pushed, this wakes it from the deep sleep state and runs the all the code, then drops back into the sleep state.

Button diagram

  • The green line is the Chip enable
  • The blue line is the the links reset to ground via the push button

Now I had the basic circuit and code working I needed to pick a power supply. The ESP-01 needs a 3.3v supply and most people seem to opt for using a small LiPo cell. A single cell has a nominal fully charged voltage of 3.7v which is probably close enough to use directly with the ESP-01, but the problem is you normally need to add a circuit to cut them out before the voltage gets too low as they discharge to prevent permanently damage them. You would normally add a charging circuit to allow recharging from a USB source.

This wasn’t what I was looking for, I wanted to use off the shelf batteries so I went looking for a solution using AAA batteries. The board will run directly from a fresh set of 2 AAA batteries, but the voltage can quickly drop too low. To help with this I found a part from Pololu that would take an input between 0.5v and 5v and generate a constant 3.3v. This meant that even as the batteries discharged I should be able to continue to run the device.

At first things didn’t look to work, because converter was not supplying enough current for the ESP-01 at start up, to get round this I added a 100uF capacitor across the outputs of the regulator. I don’t really know how properly to size this capacitor so I basically made a guess.

The final step was to use the soldering iron to remove the red power LED from the board as this was consuming way more power than the rest of the system.

Prototype

Next Steps

  • Make the MQTT topic based on the unique id of the ESP-01 so it isn’t hard coded
  • Look at adding Access Point mode to allow configuration of the WiFi details if the device can not connect to the existing configuration
  • Design a circuit board to hold the voltage converter, capacitor, button and the ESP-01
  • Create a case to hold it all
  • Work out just how long a set of batteries will last

Provisioning WiFi IoT devices

or

“How do you get the local WiFi details into a consumer device that doesn’t have a keyboard or screen?”

It’s been an on going problem since we started to put WiFi in everything. The current solution seams to be have the device behave like it’s own access point first and then connect a phone or laptop to this network in order to enter the details of the real WiFi network. While this works it’s a clunky solution that relies on a user being capable of disconnecting from their current network and connecting to the new device only network. It also requires the access point mode to be shutdown in order to try the supplied WiFi credentials which causes the phone/laptop to disconnect and normally reconnect to it’s normal network. This means if the user makes a typo then they have to wait for the device to realise the credentials are wrong and at best go back into access point mode or you have to manually reset the device to have it start over. This really isn’t a good solution.

I’ve been trying to come up with a better solution, specifically for my linear clock project. You may ask why a wall clock needs to be connected to the internet, but since it’s Raspberry Pi powered, which has no persistent real time clock it needs a way to set the time in the case of power outages. I also want a way to allow users to change the colours for the hours, mins and seconds and adjust brightness levels.

In order to add WiFi to the Raspberry Pi Zero I’m using the RedBear IoT pHat which as well as providing WiFi it includes Bluetooth 4.0 support. This opens up a new avenue to use for configuration. The idea is to have the device start as a Eddystone beacon broadcasting a URL. The URL will host a page that uses Web Bluetooth to connect to the device and allow the WiFi SSID and password to be entered. Assuming the credentials are correct the IP address can be pushed to the page allowing a link to be presented to a page served by the device to then configure the more day to day options.

RedBear IoT pHat

We had a hackday at the office recently and I had a go at implementing all of this.

Firstly the device comes up as an Eddystone Beacon that broadcasts the URL to the configuration page:

wpid-wp-1473775044897.png

When the page loads is shows a button to search for the devices with bluetooth. This is because the Web Bluetooth spec currently requires a user interaction to start a BLE session.

wpid-wp-1473775152699.png

Chrome then displays a list of matching devices to connect to.

wpid-wp-1473775152702.png

When the user selects a given device the form appears to allow the SSID and password to be entered and submitted.

wpid-wp-1473775152708.png

Once the details are submitted the page will wait until the device has bound to the WiFi network, it then displays a link directly to the device so any further configuration can be carried out.

The code for this is all up on GitHub here if anybody wants to play. The web front end needs a little work and I’m planning to add WiFi AP scanning and pre-population soon.

Now we just need Apple to get their finger out and implement Web Bluetooth

Tinkerforge Node-RED nodes

For a recent project I’ve been working on a collection of different Node-RED nodes. Part of this set is a group of nodes to interact with Tinkerforge Bricks and Bricklets.

Tinkerforge is a platform of stackable devices and sensors/actuators that can be connected to via USB or can be attached directly to the network via Ethernet or Wifi.

Tinkerforge Stack

Collections of sensors/actuators, known as bricklets, are grouped together round a Master Brick. Each Master Brick can host up to 4 sensors/actuators but multiple Master Brick’s can be stacked to add more capacity. The Master Brick also has a Micro USB socket which can be used to connect to a host machine running a deamon called brickd. The host runs a daemon that handles discovering the attached devices and exposes access to them via an API. There are also Ethernet (with and without PoE) and WiFi bricks which allow you to link the stack directly to the network.

As well as the Master Brick there is a RED Brick which contains a ARM Cortex A8 processor, SD card, USB socket and micro HDMI adapter. This runs a small Linux distribution (based on Debian) and hosts a copy of brickd.

There are bindings for the API in a number of languages including:

  • C/C++
  • C#
  • Delphi
  • Java
  • Javascript
  • PHP
  • Perl
  • Python
  • Ruby

For the Node-RED nodes I took the Javascript bindings and wrapped them as Node-RED nodes. So far the following bricklets are supported:

Adding others shouldn’t be hard, but these were the ones I had access to in order to test.

All the nodes share a config node which is configured to point to the instance of the brickd the sensors are linked and it then provides a filtered list of available bricklets for each node.

Node-RED - Google Chrome_004

The code for the nodes can be found here and is available on npmjs.org here

Node-Red – Delay Node (formally Pause Node)

I’ve just been updating my Pause node for Node-Red after a request to support message rate limiting as well as pausing individual messages.

To help make it a little clearer the node has also been renamed to Delay (thanks to deldrid1 for the suggestion)

Delay Mode

In this mode the node allows you to delay any message passing through it by a given number of milliseconds, seconds, hours or days.

Rate Limit Mode

This time the node ensures that no more than the given number of messages are delivered per millisecond, second, hour or day.

All the code is in my fork of the original project for now and soon to be rolled up in to the main stream.

Node-Red – Pause Node

Two guys from my team (Nick O’Leary and Dave Conway-Jones) at IBM released a very cool tool for wiring up IoT last week called Node-Red.

Node-Red lets you wire together a selection of inputs, things like MQTT messages, Twitter feeds, serial port and a whole lot more, perform transforms on them with Javascript functions before outputting them to a similar collection of options.

I’ve been playing with it to replace a couple things that used to be standalone scripts, but one of the things that was missing was the way to delay an action happening until a certain time after a message has arrived. For example if I want to set my Blink(1) clone to green when somebody mentions me in the tweet I may want to reset it to off 20 seconds later

To help with this I have written a new node called pause that delays passing on a given message by a configurable amount of time. Nodes are made up of 2 files and are placed in the node-red/nodes directory. As well as all the built in nodes there is a example node (99-sample) which you can use to

Each node is made up of 2 parts, the first is javascript file which controls how the node should behave and a html file which contains the descriptive text,

99-pause.js

...
// Simple node to introduce a pause into a flow

//Require main module
var RED = require("../red/red");

function PauseNode(n) {
   RED.nodes.createNode(this,n);
   
   this.timeout = n.timeout * 1000;
   
   this.on("input", function(msg) {
       var node= this;
       setTimeout(function(){node.send(msg);}, node.timeout);
   });
}

RED.nodes.registerType("pause",PauseNode);

You can see in the code above I’ve attached a small function to the ‘input’ event for the pause node, all it does setup a callback after the timeout expires to send the passed in message object to the next node in the flow.

99-pause.html

...
<!-- First, the content of the edit dialog is defined.                       -->
<script type="text/x-red" data-template-name="pause">
  <div class="form-row">
     <label for="node-input-topic"><i class="icon-tasks"></i> Pause</label>
    <input type="text" id="node-input-timeout" placeholder="Time">
  </div>
    
  <div class="form-row">
    <label for="node-input-name"><i class="icon-tag"></i> Name</label>
    <input type="text" id="node-input-name" placeholder="Name">
  </div>
</script>

<!-- Next, some simple help text is provided for the node.                   -->
<script type="text/x-red" data-help-name="pause">
    <p>Introduces a pause into a flow</p>
    <p>Default pause is 5 seconds but can be configured</p>
</script>

<!-- Finally, the node type is registered along with all of its properties   -->
<script type="text/javascript">
    RED.nodes.registerType('pause',{
        category: 'function',      // the palette category
        color:"#E6E0F8",
        defaults: {             // defines the editable properties of the node
            name: {value:""},   //  along with default values.
            timeout: {value:"5", required:true, validate:RED.validators.number()}
        },
        inputs:1,                // set the number of inputs - only 0 or 1
        outputs:1,               // set the number of outputs - 0 to n
        icon: "arrow-in.png",    // set the icon (held in public/icons)
        label: function() {      // sets the default label contents
            return this.name||this.topic||"pause";
        },
        labelStyle: function() { // sets the class to apply to the label
            return this.name?"node_label_italic":"";
        }
    });
</script>

The HTML sets up configuration dialog for the node, the help text, the nodes look and behaviour and the default values for any properties the node has.

The configuration dialog for the pause node looks like this:

I’ve checked this new node into my fork of the Node-Red project here, but I’ll be submitting a pull request to get it included in the main project as soon as I get a chance to have a chat with Nick and Dave.

EDIT:
This is now a core node called delay and is also capable of rate limiting messages