Posted on Leave a comment

Connecting the IoT Remote Gate Opener to MQTT

Now that we have a reasonable understanding about MQTT, we can connect our IoT Gate Remote from the previous post to the MQTT broker.

The idea is to have our Remote Gate opener listen to the message in the MQTT broker. Looking at our previous example, we have setup 2 topics in the message broker, “/homeautomation” and “/hello”, we can expand the “/homeautomation” into

/homeautomation/gate

When a message is send to “/homeautomation/gate” topic, our ESP8266 will get the message and we can act on it, which mean we can open or close the gate.

So we need to modify the code so that we can subscribe to this topic. This can be done with the following:

MQTTClient client; 
// MQTT info
 const char* thehostname = "broker.shiftr.io";
 const char* user = "tokenusername";
 const char* user_password = "tokenpassword";
 const char* id = "ESP8266";

Serial.print("\nconnecting…");
   while (!client.connect(id, user, user_password)) {
     Serial.print(".");
     delay(1000);
   }
Serial.println("\nconnected!");
client.subscribe("/homeautomation/gate");

Once this you had subscribe to the topic, we need to modify the code to perform the action when we received the message. In this example let us assume the message that we are going to receive is “OPEN”. Assuming we have the following code in the Setup() section:

void setup() {  
...
  client.begin(thehostname, net);
  client.onMessage(messageReceived);
...
}

And to act on the message, we need to process the message in the messageReceived() function as below:

void messageReceived(String &topic, String &payload) {
   Serial.println("incoming: " + topic + " - " + payload);
if (payload == "OPEN"){
// open the door
digitalWrite(LEDpin,LOW); //LED ON
} else if (payload == "CLOSE") {
// close the door
digitalWrite(LEDpin,HIGH);
}
}

Now you should be able to control the Remove Gate from the internet. We can test this by posting the “OPEN” and “CLOSE” message to the topic.

I hope you enjoy this post, if you have any questions please don’t hesitate to ask and subscribe to my blog to get more frequent update on projects that I am currently working on.

Posted on Leave a comment

IoT Remote Gate Opener

I am helping my brother to make a remote Gate opener. He have a remote that can open the gate, but being in this day and age, we would like to connect everything to the Internet. So the concept can be seen in the following picture:

IoT Remote Gate Opener circuit
Remote Gate Opener

The brain consist of ESP8266, which is connected to relay that will trigger the remote. The original idea is to have some sort of sensor (magnetic) that can be detected using Hall Effect sensor to detect when the gate had been closed or opened. Then to be able to access this remotely from anywhere in the world, we can connect this to Node-RED and subsequently able to access this via Apple Homekit.

To start off as the proof of concept and to reduce the complexity, we revert back to the basics, by just connecting the ESP8266 to a relay that will activate the remote to open and close the Gate door. To start off follow the following steps:

Step 1. Gather the components

Components for ESP8266 with Relay

We will need ESP8266, Relay module, and PCB to connect the two together. You can connect the two module together by soldering it on to the PCB. Connect the 3.3 Volt pin from ESP8266 to VCC of the Relay module, and GND from the ESP8266 to the GND of the Relay module, and finally for this example, I am connecting the pin D5 to the IN pin of the Relay module. Note that the Relay IN is active LOW, this means that the relay will be activated (Green LED on Relay board turn ON) when IN is LOW. The fully assembled board looks like the following picture.

Fully assembled ESP8266 with Relay module

Step 2. Modify the Remote

Remote Modification
Remote Wiring

In the image above, we solder 2 wire across the button that can activate the Gate. This two wire will be connected by the Relay module later on.

Step 3. Uploading the Arduino Code

The idea is to use ESP8266 as a webserver. This will allow us to show a setting page to connect the ESP8266 to the WiFi without having to hardcode the WiFi access points in the code. The website will also serve as the command to turn the Relay ON and OFF. Thanks for the handy work of Martyn Currey on how to create JavaScipt and AJAX within the ESP8266, and also some AJAX code to update ESP8266 from Circuits4you, I was able to massage the AJAX code into my previous Arduino code for the Temperature sensor. The final result looks like the following picture.

ESP8266 Webserver
ESP8266 Webserver

Once the ESP8266 is connected to the WiFi, only then the “Switch” button will appear in the webserver interface. When the ESP8266 is not connected to the WiFi, by default it will revert to be an Access Point, this will allow you to connect and configure the WiFi settings.

When you click on the “Switch” it will turn the relay ON, and thus simulating the press of the remote button to open the gate. Because we don’t have any feedback from the Gate in this solution, we will need to turn the “Switch” off manually, otherwise the button on the gate remote will be pressed and the battery will drain.

In the next section we will dive in a bit deeper into the Arduino code. If you are not interested in the code, you can skip this section and just upload the code straight away into the ESP8266. When the ESP8266 load up the first time you will be able to see the AP as coded in “settings.h” file. The AP name is “ESP-Gate” with the default password defined in the file. You can change this to make sure it is much more secure.

define CLOCK_NAME "ESP-Gate"
define WIFI_AP_NAME CLOCK_NAME
define WIFI_APPSK "DefaultAPPassword" // default AP password

Step 4. Arduino Code deep dive

The Arduino code comes in 5 files, and here are the list of the files:

  1. ESP8266GateSwitchV2: This is the main file where the magic happens. Pay special attention to the following sections (void setup(), void handleLED(), void handleRoot(), void loop()).
  2. Clock.h: This file is the header file for the CLOCK
  3. mainPage.h: This file is the webserver html file which get served when you connect to the ESP8266 web server
  4. ntp: This file consist of the function to connect to the ntp server to synchronise the clock
  5. settings.h: This file contain most of the settings for the project.

Void setup() section

#include <ESP8266WebServer.h>
// Create an instance of the server
// specify the port to listen on as an argument
ESP8266WebServer server(80);

void setup() {
DebugStart();
timer = 200;
pinMode(LED_BUILTIN, OUTPUT);
pinMode(LEDpin, OUTPUT); // setup LED
digitalWrite(LEDpin, HIGH); // Relay Active LOW
setupWiFi(1); // SetupAP mode
setupTime();
server.on("/", handleRoot);
server.on("/form", handleForm);
server.on("/setLED", handleLED);
server.begin();
}

This section will initialise the LEDpin, which is the trigger connected to the IN input of the Relay module. We will need to set the LEDpin to HIGH, because the relay module is active LOW. Initially setupWiFi will be called to try to connect to the WiFi, if this fail the program will defaulted to AP mode. SetupTime() will attempt to setup the time by synchonising the time with ntp server. The next couple of line define what function will be called when the webserver is being invoked. For example, handleRoot function will be called when the root of the webserver is being accessed. The handleForm function will be callled when the “/form” is being called, this is called when we setting up the Wifi parameter as well a a few other settings of the clock, daylight savings, etc. Finally “/setLED” will be called when we “button” is being pressed to activate the Relay.

void handleLED() section

void handleLED() {
String ledState = "OFF";
String t_state = server.arg("LEDstate"); //Refer xhttp.open("GET", "setLED?LEDstate="+led, true);
Serial.println(t_state);
if(t_state == "1"){
digitalWrite(LEDpin,LOW); //LED ON
ledState = "ON"; //Feedback parameter
}
else {
digitalWrite(LEDpin,HIGH); //LED OFF
ledState = "OFF"; //Feedback parameter
}
server.send(200, "text/plane", ledState); //Send web page
}

If we look at the handleLED function above, this is where the Relay is being activated. When the AJAX code post the LEDstate parameters back to the webserver, this section will check whether the LEDState parameter value is equal to 1 or 0, if it is 1, the code will write LEDpin output to LOW, and activate the Relay, and if the parameter value is 0, the code will write LEDpin output to HIGH, and deactivated the Relay. The ledState feedback parameter is just to make our life easier when debugging the code, this will show on the website whether the ledState is ON or OFF via AJAX return code.

void loop() section

void loop() {
server.handleClient();
if (timeStatus() != timeNotSet){
time_t t = now();
}
}

This section of the code is very simple, all it needs to do is to make sure the server.handleClient() function is called, to ensure that ESP8266 will allow client to connect to it’s webserver.

void handleRoot() section

void handleRoot() {
DebugLn("handleRoot");
String s = MAIN_page;
if (WiFi.status() == WL_CONNECTED) {
s += ButtonControl;
// check led state
boolean pinStatus = digitalRead(LEDpin);
if (pinStatus==LOW) {
s.replace("@@NA@@", "ON");
s.replace("@@SW@@", "ON");
s.replace("@@Checked@@", "checked");
}
else {
s.replace("@@NA@@", "OFF");
s.replace("@@SW@@", "OFF");
s.replace("@@Checked@@", "");
}
}
s+= WifiSetting;
time_t t = now();
s.replace("@@SSID@@", settings.ssid);
s.replace("@@PSK@@", settings.psk);
s.replace("@@TZ@@", String(settings.timezone));
s.replace("@@USDST@@", settings.usdst?"checked":"");
s.replace("@@HOUR@@", String(adjustedHour(t)));
s.replace("@@MIN@@", String(minute(t)));
s.replace("@@NTPSRV@@", settings.timeserver);
s.replace("@@NTPINT@@", String(settings.interval));
s.replace("@@SYNCSTATUS@@", timeStatus() == timeSet ? "OK" : "Overdue");
s.replace("@@CLOCKNAME@@", settings.name);
s.replace("@@UPDATERESPONSE@@", httpUpdateResponse);
httpUpdateResponse = "";
server.send(200, "text/html", s);
}

This section deals on how the root of the webserver should look like. It will first get the MAIN_page content from mainPage.h file, and then substitute the checkbox status based on the reading of the LEDpin. If the currently the LEDpin is LOW, that means the switch is active, so it will need to show the “switch” as on. And if the reading is HIGH, this means that the switch is not active, so it will need to show the “switch” as off. Then the rest of the code is to display the WiFi SSID, time zone, ntp server, update interval, device name.

I hope you like this post, and please subscribe if you haven’t done so. And let me know if you have any questions.

Posted on Leave a comment

Connecting ESP8266 to MQTT broker

So what is MQTT, according to mqtt.org, it is a connectivity protocol used to connect machine to machine, used for Internet of Things (IoT). It was designed as an extremely light weight publish/subscribe messaging transport. In short it is the messaging designed for Internet of Things devices to allow robust connectivity when faced with challenged bandwidth limitation, and power consumption. It stands for Message Queuing Telemetry Transport.

MQTT how it works

The concept of MQTT is a Publish/Subscribe system. This means that there is at least one system that publish a message on a topic and there is at least one system that subscribe to the “topic” to receive “messages”. The “Messages” are information that are being exchange between the devices. “Topic” are series of strings separated by a forward slash (/), each topic is separated by the forward slash.

MQTT Broker

MQTT Broker is responsible for receiving messages and forwarding the messages to the devices that are interested (Subscribed) to the topic. There are a few MQTT Broker that you can use. In this example we will use the one called https://shiftr.io/try.

You can also installed your own message broker (Mosquitto broker) into Raspberry Pi to relay all the messages for your home automation projects.

Getting Started with MQTT Broker

Start by getting a free account with shiftr.io, then follow the documentation to create the Namespace and Token. The Token is username and password pair that will be used to authenticate the client, the one that will publish or subscribe to the messages. The token will be used in the following section of the code:

const char* user = "tokenusername";
const char* user_password = "tokenpassword";

You will need to download the MQTT library to send the message to the MQTT broker. The initialisation is done using the following code:

#include <MQTT.h>
MQTTClient client;

During the setup you will need to connect the onMessage event to the function that be executed when the message is received, this is done with the following code:

void setup() {  
...
client.begin(thehostname, net);
client.onMessage(messageReceived);
...
}

In the loop section of the code, you will need to execute the client.loop() function and the following code will try to connect to the message broker and at the same it will publish “Alive” message to the “/hello” topic.

void loop() {
client.loop();
if (!client.connected()) {
connect();
}
// publish a message roughly every second.
if (millis() - lastMillis > 1000) {
lastMillis = millis();
client.publish("/hello", "Alive");
}

}

Here are the connect() function, which will attempt to connect to the WiFi and upon connection will subscribe to the “/hello” topic.

void connect() {
Serial.print("checking wifi…");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.print("\nconnecting…");
while (!client.connect(id, user, user_password)) {
Serial.print(".");
delay(1000);
}
Serial.println("\nconnected!");
client.subscribe("/hello");
// client.unsubscribe("/hello");
}

Here are the full source code from the example above:

// MQTT Test client
//
// 128x64 OLED pinout:
// GND goes to ground
// Vin goes to 3.3V
// Data to I2C SDA (GPIO 4)
// Clk to I2C SCL (GPIO 2)
// Add MQTT
#include <TimeLib.h>
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <SSD1306.h>
#include <SSD1306Wire.h>
#include <MQTT.h>

char ssid[] = "ssidname"; // your network SSID (name)
char pass[] = "ssidpassword"; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS;
WiFiClient net;
MQTTClient client;
unsigned long lastMillis = 0;
// MQTT info
const char* thehostname = "broker.shiftr.io";
const char* user = "tokenusername";
const char* user_password = "tokenpassword";
const char* id = "ESP8266";
SSD1306 display(0x3c, 4, 2); //0x3d for the Adafruit 1.3" OLED, 0x3C being the usual address of the OLED
void connect() {
Serial.print("checking wifi…");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.print("\nconnecting…");
while (!client.connect(id, user, user_password)) {
Serial.print(".");
delay(1000);
}
Serial.println("\nconnected!");
client.subscribe("/hello");
// client.unsubscribe("/hello");
}
void messageReceived(String &topic, String &payload) {
Serial.println("incoming: " + topic + " - " + payload);
}
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(115200);
//Setup Rest Client
WiFi.begin(ssid, pass);
Wire.pins(4, 2); // Start the OLED with GPIO 4 and 2 on ESP-01
Wire.begin(4, 2); // 4=sda, 2=scl
display.init();
display.flipScreenVertically();
display.drawString(0, 24, "Connected.");
display.display();
client.begin(thehostname, net);
client.onMessage(messageReceived);
connect();
delay(1000);
}
int timer =0;
void loop() {
client.loop();
if (!client.connected()) {
connect();
}
// publish a message roughly every second.
if (millis() - lastMillis > 1000) {
lastMillis = millis();
client.publish("/hello", "Alive");
}
//delay(1000);
}

If everything goes well, you should be able to see the message being published to the topic that you are monitoring. In the example above the message will go from the ESP8266 device to the /hello topic.

The message being published is “Alive” message, as shown at the top left hand corner. This will keep being published every seconds.

That’s all for now, I hope this post is useful as an introduction to the MQTT. Please share this if you like, or provide some comments. The next step from here is to modify the Temperature sensor to use the MQTT, stay tune if you would like to know about this.

Posted on Leave a comment

3 Way to use a button using OneButton Library

I stumble across a “OneButton” library by Matthias Hertel which allows you to use one button and expanding it’s uses without blocking the program. The code allows setting up a Normal LOW button (button connected to VCC 5V when pressed) or Normal HIGH button (button connected to GND when pressed).

If we look at the state diagram above, we start with state 0. When a button is pressed, the program will jump to state 1 and waiting for the button goes up, if this sequence happened and the timeout occur (state 2), the click() function will be called. If another button down event happened (state 3) followed by button up the doubleclick() function will be called. Then the state machine will go back to start state 0. If the button was pressed initially a bit longer than the press timeout, the press() event will fire, and then the state machine will jump to state 6 and detecting the button up before go back to initial state 0.

So in summary by using this library, we can allow 3 function call for a single button:

  1. Single click
  2. Double click
  3. Long click

Installation

To install the OneButton library you can just go from the Arduino interface and select the menu Sketch->Include Library->ManageLibraries…

You can search for the OneButton Library by Matthias Hertel. At the time of the writing the version 1.3.0 is the latest. You can Click the “install” button to install the library. Now you are ready to use the OneButton Library.

How to use the OneButton Library

To use the library, you will have to include the library at the beginning of your code as shown below:

#include "OneButton.h"

Then initialise the the OneButton variable using the following code:

// setup a new OneButton on pin 2
OneButton button(2, false); // normal LOW, set to true for normal HIGH

The first parameter “2” is telling the code which pin is connected to the button. In this example it is connected to Digital pin 2. You can also connect it to Analog pin, and you have to pass in “A1” if the button is connected to pin Analog 1.

The second parameter “false” is telling the code that the button is normally connected to the GND (LOW) and when it is pressed it will send a HIGH signal to the input pin D2. To illustrate this you can have a look at the following schematic diagram:

The Normal LOW button on the left is connected to the input D2 via pull down resistor R1, and Normal HIGH button is connected to input D3 via pull up resistor R2.

Once this is done, it is time to setup the call back function for in the Setup() section of the Arduino code.

void setup() {
Serial.begin(9600); // Serial begin
// link myClickFunction to a click event
button.attachClick(myClickFunction);
// link myDoubleClickFunction to a doubleclick event
button.attachDoubleClick(myDoubleClickFunction);
// link to long press stop event
button.attachLongPressStop(wipeOutFunction);
// set debouncing time default 50ms
button.setDebounceTicks(80);
}

You will notice at the code above the call back function for Click is called myClickFunction, the call back function for DoubleClick is called myDoubleClickFunction and the call back function for long press is called wipeOutFunction. As also shown above you can also set the debounce time to 80ms, if this is not set the default will be at 50ms.

Now I am applying this to my previous Game Of Life circuit, with the following additional function:

  1. Double click to randomly start the game 8×8 life form
  2. Single click to pause so that we can observe
  3. Long click to wipe out half or life form (the same way Thanos would have done)

To achieve the above, here are the modification to the setup function:

void setup() {
Serial.begin(9600); // Serial begin
pinMode(latchPin, OUTPUT); // Pin configuration
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
for (int i = 0; i < 8; i++) { // for loop is used to configure common cathodes
pinMode(pins[i], OUTPUT);
digitalWrite(pins[i], HIGH);
}
// link myClickFunction to a click event
button.attachClick(myClickFunction);
// link myDoubleClickFunction to a doubleclick event
button.attachDoubleClick(myDoubleClickFunction);
// link to long press stop event
button.attachLongPressStop(wipeOutFunction);
// set debouncing time
button.setDebounceTicks(debounce);
randomSeed(analogRead(0));
}

The Loop function is now much simplified to the code to display the matrix as follows:

void loop() {
// keep watching the push button
button.tick();
if (started){
// calculate next field
if (millis() - 1000 > lastMillis) {// delay each iteration by 1000 ms
fillNextField();
for (int x = 0; x<8; x++){
for (int y = 0; y<8; y++) {
field[x][y] = nextfield[x][y];
}
}
lastMillis = millis();
}
}
// display output to 8x8 matrix
refreshScreen();
}

The myClickFunction call back is also quite simple to pause and continue the sequence

// this function will be called when the button was pressed 1 time and them some time has passed.
void myClickFunction(){
started = !started;
}

The double click function call back will be used to reset the game by randomly reassigning the 8×8 LEDs

// this function will be called when the button was pressed 2 times in a short timeframe.
void myDoubleClickFunction(){
started = false;
for (int i = 0; i<8; i++) {
for (int j = 0; j<8; j++){
field[i][j] = random(2);
Serial.print("field["); Serial.print(i); Serial.print("]["); Serial.print(j);
Serial.print("]:");
Serial.println(field[i][j]);
}
}
delay(200);
started = !started;
}

The long press will be used to wipe out half of the life form, Thanos would be so proud.

// this function will be called when the long press is finished
void wipeOutFunction(){
started = false;
bool alive = random(2); //dead or alive
for (int i = 0; i<8; i++) {
for (int j = 0; j<8; j++){
if (field[i][j]){
field[i][j] &= alive;
alive = !alive;
}
}
}
}

You can see the result in the following video.

Please let me know what do you think, and please share if you like or drop me a comments and don’t forget to subscribe for more simple Arduino circuits.

Posted on Leave a comment

ESP8266 Secure AP mode

Quite often we take shortcut to make things simple. That that sometimes will come and bite you back. To make sure you always consider security in mind at everything you do. Password is to keep something secure, and not to be forgotten.

In this post, I am trying to show how simple the security can be implemented to ensure that we always have security in mind. There is nothing worse than having a fully working system and then get hacked. This will cause unnecessary stress later.

If you are using ESP8266 in AP mode to setup the WIFI configuration, don’t forget to set the password and make sure you keep it secure by remembering it and not tell anyone.

In order to do this you can set the password when setting the ESP as and AP, this is done using the following code:

WiFi.softAP(WIFI_AP_NAME, AP_PASS);

The second line in the above code passed in “AP_PASS” variable, this will ensure that you can connect to the ESP using the password. You can also leave the second parameter blank to leave it open, but then anyone can connect to it and messed up with your setting. Things to note, the password will need to be more than 8 Characters, otherwise, the function call will fail. The best way to check this is to check the Serial Monitor and modify the above code to be as follow:

Serial.print("Starting AP mode:");
Serial.println(WiFi.softAP(WIFI_AP_NAME, AP_PASS)? "Ready": "Failed!");

When the AP is started, you can see in the Serial monitor window whether the function call WiFi.softAP is success or not. The simple code describing the above can be found below.

/*
   Copyright (c) 2015, Majenko Technologies
   All rights reserved.
   Redistribution and use in source and binary forms, with or without modification,
   are permitted provided that the following conditions are met:
 * * Redistributions of source code must retain the above copyright notice, this
     list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice, this
     list of conditions and the following disclaimer in the documentation and/or
     other materials provided with the distribution.
 * * Neither the name of Majenko Technologies nor the names of its
     contributors may be used to endorse or promote products derived from
     this software without specific prior written permission.
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
   ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
   ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/* Create a WiFi access point and provide a web server on it. */

#include 
#include 
#include 

#ifndef APSSID
#define APSSID "ESPap"
#define APPSK  "thereisnospoon"
#endif

/* Set these to your desired credentials. */
const char *ssid = APSSID;
const char *password = APPSK;

ESP8266WebServer server(80);

/* Just a little test message.  Go to http://192.168.4.1 in a web browser
   connected to this access point to see it.
*/
void handleRoot() {
  server.send(200, "text/html", "You are connected");
}

void setup() {
  delay(1000);
  Serial.begin(115200);
  Serial.println();
  Serial.print("Configuring access point...");
  /* You can remove the password parameter if you want the AP to be open. */
  WiFi.softAP(ssid, password);

  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  server.on("/", handleRoot);
  server.begin();
  Serial.println("HTTP server started");
}

void loop() {
  server.handleClient();
}

Hopefully you will find this article useful to secure your IoT devices and saving you the headache of being hacked in the future. If you like this post, please share and don’t forget to subscribe the blog for more article about IoT and Arduino.

Posted on Leave a comment

Arduino LED Matrix “Game of Life”

I was reading a post about someone making a Thanos Gauntlet and simulating wiping off half of the population randomly. So I thought about the “Game of Life” simulation. If you want to know more about “Game of Life” you can read it all up here. So why not trying to make this simulation based on my previous build of the 8×8 LED Matrix. The circuit can be found below:

Using the previous build, I made a few adjustment to the code to simulate the game of life. The first thing to note is to initialise the 8×8 variable to hold the initial life form, the next variable is the next stage after the life form evolved, this is shown as below:

bool field[8][8] = {};
bool nextfield[8][8] = {};

When the program start, we randomly assign the 8×8 matrix with zeros and ones to simulate the initial stage, this is shown in the following code. The code will only be executed when the button is pressed longer than the threshold defined by variable debounce. I define this to be 50ms.

if (buttonpressed == HIGH && millis() - time > debounce){ // set random life
time = millis();
started = false;
for (int i = 0; i<8; i++) {
for (int j = 0; j<8; j++){
field[i][j] = random(2);
Serial.print("field["); Serial.print(i); Serial.print("]["); Serial.print(j);
Serial.print("]:");
Serial.println(field[i][j]);
}
}
delay(200);
started = !started; // start the Game of Life simulation
}

Right after the initialisation, the code will set the started variable to true. The program will calculate the next field at every iteration this is done by calling the fillNextField() function, shown in the following code.

}else if (started){
// calculate next field
if (millis() - 1000 > lastMillis) {// delay each iteration by 1000 ms
fillNextField();
for (int x = 0; x<8; x++){
for (int y = 0; y<8; y++) {
field[x][y] = nextfield[x][y];
}
}
lastMillis = millis();
}
}

The rule of Game of Life is as below. Each cell’s existence depends on all the other 8 cells that are surrounding it.

  1. Any live cell with fewer than 2 live neighbours dies, as if by underpopulation
  2. Any live cell with two or three live neighbours lives on to the next generation (cycle)
  3. Any live cell with more than three live neighbours dies, as if by overpopulation.
  4. Any dead cell with exactly 3 live neighbours becomes a live cell, as if by reproduction.

Based on the logic above the getCellsNextState(int x, int y) function is being developed as shown below:

//returns the cell's next state, true if alive, false otherwise
bool getCellsNextState(int x, int y) {
bool shouldBeAlive = false;
shouldBeAlive |= (!field[y][x] && countAliveNeighbours(x, y) == 3);
shouldBeAlive |= (field[y][x] && countAliveNeighbours(x, y) == 3);
shouldBeAlive |= (field[y][x] && countAliveNeighbours(x, y) == 2);
return shouldBeAlive;
}

As you can see the CountAliveNeighbours(x,y) function will count the number of alive neighbours around the cell. This is done by simply iterating from the one cell before and after in x coordinate and one cell before and after in y coordinate. Then we define the boundary condition as per our LED matrix boundary, which is 8 cells x 8 cells. And finally we count how many live cells as per below function.

// counts the alive neighbours this step
int countAliveNeighbours(int x, int y) {
int retVal = 0;
for (int row = y - 1; row <= y + 1; row++) { for (int col = x - 1; col <= x + 1; col++) { if ((row == y && col == x) || (row < 0) || (row > 7) || (col < 0) || (col > 7)) continue;
if (field[row][col]) retVal++;
}
}
return retVal;
}

If all goes well, you should see the following Game of Life simulation similar to the following video.

Congratulations, how you are able to simulate this classic Game of Life and you can modify this to your heart’s content. What you can do next is to stop the simulation and wipe off half of the live form like what Thanos did, and feel the power of the Infinity Gauntlet.

Please share or comments if you like this post, and let me know if you have any questions related to this.

Posted on Leave a comment

Light Saber Build Part 2

This is the continuation of the Light Saber Build Part 1. You can check the previous post to see where I am up to. Just a quick recap from Part 1. I am connecting the DPPlayer to the Arduino Nano and also the saber on-off switch which is connected to D3 and ground as shown in the following circuit.

The next part is to connect the Gyro MPU6050 and the LED strip WS2811. My LED strip consist of 20 controller, each controller is controlling 3 LEDs. Before putting everything together in the case, we are testing to make sure the strip are lighting up properly and also when there is a sudden movement or “a hit” the hit sound effects are being played.

You can see the test result in the following video.

Things to note about the feature of the light saber:

  • Sound effect for saber on and off
  • Switching lightsaber colour when the button are pressed 3 times when the lightsaber is on
  • Toggle the humming sound effect on and off when the button are pressed 5 times when the lightsaber is on
  • Humming sound and special effects when the lightsaber hit an object or there is a change in the angle

Once we tested that the lightsaber are functioning correctly, as per the feature that we want, it is time that we put the case together. I found that this is the most difficult part to get the right combination for the part. I am a big believer in recycling, so I am trying hard to find some spare parts that are lying around that can be used to build the lightsaber. Stay tune for the next write up on the lightsaber case.

If you like this post, please share it, and don’t forget to subscribe and please let me know if you have any questions and I will try to answer them.

Posted on Leave a comment

Light Saber build part 1

Today is May Day, so I though to prepare and finish off my Light Saber build that had been sitting in my shelf for quite sometime. The idea is not new and the circuit is a modification of an existing circuit build by someone else. So it is not by any means original but still fun to build.

So here is the circuit, it is using Arduino nano as the “brain” and MPU6050 gyroscope to detect the movement. It also being equipped with DFPlayer mini for the light Saber effect. The light is using addressable LED strip (WS2811).

I had manage to wire up the circuit by recycling my previous build of Frankenbot. I have not wire up the LED and the gyroscope just yet, this is to ensure that everything is working before moving on to the next part.

Here are the Video of the special effects turning on and off. Stay tune for the part. If you like this, please subscribe and share the content.

Posted on Leave a comment

3 Step to use External Interrupt on ESP8266

I was in the middle of replicating my 433 MHz remote control using Arduino. The receiver circuit is quite simple and it is using Arduino pin 2 (interrupt) to detect the data signal from the receiver.

I was wondering whether I can do the same thing with ESP8266. After a short google, I found some information about Interrupt pin D3 (GPIO0) and also D0 (GPIO16). At a glance it seems do able.

Here are the steps to use the interrupt.

  1. Initialise IO pin as input
  2. Initialise IO with Interrupt Subroutine definition
  3. Interrupt Subroutine.

Here are the code that I stumble upon from the Circuits4you.com website.

const int interruptPin = 0; //GPIO 0 (Flash Button) STEP 1
const int LED=2; //On board blue LED
 
void setup() {
  Serial.begin(115200);
  pinMode(LED,OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, CHANGE); // STEP 2
}
 
void loop()
{
    digitalWrite(LED,HIGH); //LED off
    delay(1000);
    digitalWrite(LED,LOW); //LED on
    delay(1000);
}
 
//This program get executed when interrupt is occurs i.e.change of input state - STEP 3
void handleInterrupt() {
    Serial.println("Interrupt Detected");
}

I will try this tonight and report back whether the Interrupt detection works or not.

The Remote.

BAUHN Remote Control

The remote consist of 4 ON button and 4 OFF buttons, each one is labelled A, B, C and D.It works independently controlling the remote power point switch.

The power point needs to be sync against one of the button pair (A, B, C or D). In this experiment I am detecting button B.

Below are the connection between ESP8266 to the 433 MHz receiver. As you can see I only connected 3 cables. 3.3V Vcc for Power (red cable), GND (green cable) and Data (Yellow) connected to GPIO0 of ESP8266 (D3).

I had used a slightly different sketch which is utilising the rc-switch library, and it also can provide the same detection that I had done using Arduino Uno. Here are the sketch that I had used to detect the remote.

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();

void setup() {
Serial.begin(9600);
mySwitch.enableReceive(0); // Receiver on interrupt 0 => that is pin GPIO0 or D3 in ESP8266

pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
if (mySwitch.available()) {
Serial.print("Received ");
output(mySwitch.getReceivedValue(), mySwitch.getReceivedBitlength(), mySwitch.getReceivedDelay(), mySwitch.getReceivedRawdata(),mySwitch.getReceivedProtocol());
mySwitch.resetAvailable();
}
}

I had connect the receiver to Pin D3 on ESP8266, and getting the following result when I press the B-ON button.

Received Decimal: 9085236 (24Bit) Binary: 100010101010000100110100 Tri-State: not applicable PulseLength: 500 microseconds Protocol: 5
Raw data: 7036,1061,455,589,934,607,918,613,952,1071,454,575,955,1065,457,565,971,1033,509,509,1021,1022,506,526,995,542,981,548,977,543,979,1055,482,561,1057,466,1080,942,548,980,540,486,1067,956,552,484,1071,564,966,
Received Decimal: 9085236 (24Bit) Binary: 100010101010000100110100 Tri-State: not applicable PulseLength: 500 microseconds Protocol: 5
Raw data: 6969,1116,407,629,907,553,987,554,928,1085,445,593,924,1123,405,623,912,1122,403,625,901,1049,489,537,988,546,974,556,965,565,970,1045,483,561,944,559,969,1070,453,1073,453,578,949,1066,460,577,946,545,1021,

So I can conclude that the Interrupt definitely working ok. The next step would be to capture a few more data and trying to send it back via the 433MHz transmitter to try to replicate each of the button. Given that the ESP8266 can be connected to WIFI and also can server as a webserver this will make it possible to control the remote via internet as an IoT device.

Stay tune for the next article. Please share or subscribe if you like to see more of this article and feel free to drop me a comment.

Posted on Leave a comment

Connecting IoT Sensors data to Node-RED

This is the continuation of the Temperature sensor project in the previous post. The concept is to allow the data from sensors (temperature, motion) can be displayed in Apple Homekit, so that the user can interact with the information and control the IoT connected devices (Lights, Fan, etc). It is best described in the following picture.

The following instruction shows how to install Node-RED on a linux computer running Debian OS.

sudo npm install -g --unsafe-perm node-red

You will also need to install the mosquitto MQTT message broker, here are the command required

sudo apt-key add mosquitto-repo.gpg.key
sudo wget http://repo.mosquitto.org/debian/mosquitto-jessie.list
sudo apt-get update
sudo apt-get install mosquitto

You will also need the latest Python library, so grab them using the following instruction

sudo apt-get install python-dev

Test the installation. In this example I was using Linux Debian, so typing the command node if you get the following in the command prompt, that means the installation is successful. So then you can exit node by typing .exit command in the prompt >.

If all goes well, you can run the node-red command in the command prompt. You should get the following message. This shows that the node-red is now running at http://127.0.0.1:1880.

Node-RED Settings

Node-RED setting file called settings.js, on Linux it is located in the /usr/lib/node-modules/node-red folder. You will have another settings.js file in the .node-red folder in your home folder. This setting will be loaded by default.

Creating the flow in Node-RED

Now that you have a running Node-RED, it is time to create the flow. In this example we will create a simple flow to read temperature posted by our ESP8266. Let’s start by firing up your favourite browser and point to the following URL: http://127.0.0.1:1880/

You will be presented with a blank screen similar to the following picture. Now to start creating a flow, drop an “Inject” node from input section. We will use this as a trigger to get the temperature reading. Once you dropped it in, double click to set the property. We call the node “timestamp” and we set the interval to repeat every 4 minutes.

The next step is to connect this with an “http” node, so drop an “http” node and configure this as http GET to call a server side script in the webserver. What the script needs to return is the temperature in JSON format as below:

{"CurrentTemperature":25}

So my data_store2.php script does exactly that, as shown in the following code:

 /* readtemperature file from temp.txt file    return the value back in JSON format for HomeKit  */ 
$theparam = $_GET;
$file = './temp.txt';
$temperature = file_get_contents($file);
echo '{"CurrentTemperature":'.$temperature.'}';

Now the final step is to connect to the “Homekit” node from the Advance nodes menu. Once you drop the “Homekit” node, you can double click to configure the property as below.

Once all had been connected, it is time to deploy the node. You can do this by clicking on the “Deploy” button at the top of the Node-RED window. You will need to click the “Deploy” button whenever you make any changes to the node. Sometime the deployment might stop the Node-RED server, so you just have to run the node-red command again in the command prompt.

If all goes well, you can now test this node by clicking on the button next to “timestamp” node, the temperature should be read from the webserver and displayed in Homekit, similar to the following picture.

That conclude this session on how to configure the Node-RED to work with our temperature sensor data from ESP8266. Please let me know if you have any questions related to this and don’t forget to subscribe for update on the similar projects. The next session we are going to connect this to the Apple homekit in IPhone or IPad.