This project aims at showing the step-by-step method to create you very own DIY remote wifi switch for your electrical appliances using the RAK DashButton board.
The purpose of creating these small wifi based switches is to allow small kids to control lights and other electrical appliances without actual having to go near the electrical outlets. Appliances that are controlled via the sonoff tasmota based relays (using mqtt) are supported but I will also be showing you how to control via HTTP/s as well. SO lets jump in
Hardware:1) The hardware is pretty straight forward. Get yourself a RAK dash button (links in this tutorial):
The button comes with a nice cover as well. and four sets of buttons along with four sets of RGB leds.
2) RAK creator pro, base board: This is required to program the DASH button with your own custom hardware:
3) Some jumper wires and a breadboard if required.
Software:For setting up the software, do the following:
Development environment
Installing Driver
First, connect CREATOR pro to the computer via Micro USB:
If this is the first time you connect CREATOR pro to your computer, you have to install the USB driver for CREATOR pro. CREATOR pro uses the standard ARM MBED CMSIS DAP driver, you can get the installation file and related information in the following website:
https://developer.mbed.org/handbook/Windows-serial-configuration
In "Download latest driver" download and install mbedWinSerial_16466.exe". Afterwards, you will see "mbed Serial Port" in Device Manager of your computer: If you are using the WIN10 system, when installing the mbed Serial Port driver, the installation fails. Please re-power the module and install the mbed Serial Port driver again. If the device driver does not display the mbed Serial Port driver after installing the driver, update the module DAP firmware.
Set up Arduino IDE
From version 1.6.5, Arduino IDE supports third-party hardware. Therefore, we can use Arduino IDE to develop applications on CREATOR pro, and the examples of Arduino can run on CREATOR pro too. Arduino IDE can be downloaded in the Arduino website:
https://www.arduino.cc/en/Main/Software
When the installation is finished, open up Arduino IDE. To set up Realtek Ameba correctly in Arduino IDE, go to "File" -> "Preferences" And paste the following URL into "Additional Boards Manager URLs" field:
https://github.com/RAKWireless/CREATOR-Arduino-SDK/raw/master/release/package_rakwireless.com_creator_index.json
Next, go to "Tools" -> "Board" -> "Boards Manager": The "Boards Manager" requires about 10~20 seconds to refresh all hardware files (if the network is in bad condition, it may take longer). Every time the new hardware is connected, we need to reopen the Board Manager. So, we close the Boards Manager, and then open it again. Find "RAK CREATOR Boards" in the list, click "Install", then the Arduino IDE starts to download required files for CREATOR pro.
Finally, we select CREATOR pro as current connected board in "tools" -> "Board" -> "CREATOR RTL8711A":
NOTE:RTL8195 and RTL8711 are compatible
Your Arduino environment is setup. I would love if you can go through the Examples present for the RTL8711 board and hack around till your comfortable with the IDE.
A little introduction to AMEBA SDK:The awesome little RAK Dash board is powered by the RAK 473 wifi module which is powerful module running the AMEBA SDK. The RT8711 supports a plethora of peripherals and is very easy to develop using the MBED development environment.
The official AMEBA site:
https://www.amebaiot.com/en/ameba-sdk-intro/
Link to the SDK:
https://www.amebaiot.com/en/ameba-sdk-release-plan/
Getting the dash button board hooked upThe dash button board needs a RAK creator pro base board to hook up to it. Also keep a 10 pin jtag cable nearby, just in case you would like to switch between the DAP and JTAG methods of uploading the software
Hookup guide:
The connection shown below is for those who have the second revision of the Dash button board.
Once hooked up, power the button and the base board. On windows/linux the board will show up as a mass storage with some files in it. The board will also show up as a mbed serial port in the device manager (windows) or as a serial port in /dev/ttyAMCx (linux).
Getting your sonoff switch readyThe sonoff switches are smart relays that can control electrical applliance over wifi and support and wide range of MQTT/HTTP command set.
Sonoff switches:
https://www.itead.cc/sonoff-wifi-wireless-switch.html
Sonoff Tasmota firmware:
https://github.com/arendst/Sonoff-Tasmota
If you would like to know how to setup your Sonoff switches please have a look through my project on home automation with Alexa where i have covered a detailed step-by-step instruction on getting your sonoff switches connected to the electrical appliance and flashing with the Tasmota firmware:
https://www.hackster.io/naresh-krish/home-automation-using-wiscore-and-openhab-1ec6e4
Once setup, the tasmota firmware has a set of MQTT commands that can be used to power on and power off the board: HUGEEE list of mqtt commands for the tasmota switches:
https://github.com/arendst/Sonoff-Tasmota/wiki/Commands
Our of the list we are interested in two of them:
Power<x> 0 / off Turn relay<x> power Off
Power<x> 1 / on Turn relay<x> power On
Power<x> 2 / toggle Toggle power of relay<x>
Here Power is the command to power on/off the switch. it can take on,. off or toggle as the command.
So for example if you have setup your tasmota siwtch to listen to the topic "sonoffswitch" then the mqtt topic and command will be:
topic: tasmota/sonoffswitch/cmnd/Power1
command: on OR off OR toggle
Now with this idea in mind. lets start writing the fimware:
FirmwareThis is where things get exciting. The firmware i am going to write is for sending the above mqtt command to the sonoff switch locally. So for this project make sure:
1) both the sonoff tasmota and the dash button connect to the same mqtt broken
2) The sonoff switch is successfully connected to the internet and able to ping the mqtt broker you want to user.
For this project we will use the free mqtt broker at broker.hivemq.com port 1883
Arduino Code:
//#include <HttpClient.h>
#include <WiFi.h>
//#include <WiFiClient.h>
#include <PubSubClient.h>
#define LED1 0
#define LED2 1
#define LED3 2
#define LED4 3
#define RED 0
#define GREEN 1
#define BLUE 2
#define OFF 3
char mqttServer[] = "broker.hivemq.com";
char clientId[] = "amebaClient";
char publishTopic[] = " tasmota/sonoff-mylight/cmnd/Power1";
char publishPayload[] = "hello world";
char subscribeTopic[] = "inTopic";
WiFiClient wifiClient;
PubSubClient client(wifiClient);
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i=0;i<length;i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(clientId)) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish(publishTopic, publishPayload);
// ... and resubscribe
client.subscribe(subscribeTopic);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void printWifiStatus();
void led_off();
void led_ctrl(uint8_t led_num, uint8_t rgb);
char ssid[] = "xxxx"; // your network SSID (name)
char pass[] = "xxxx"; // 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;
/* power enable */
int pwr_en = 15;
/* leds */
int led1_r = 25;
int led1_g = 24;
int led1_b = 19;
int led2_r = 0;
int led2_g = 2;
int led2_b = 6;
int led4_r = 12;
int led4_g = 11;
int led4_b = 13;
int led3_r = 22;
int led3_g = 21;
int led3_b = 1;
/* keys */
int key1 = 23;
int key2 = 14;
int key3 = 10;
int key4 = 20;
void setup()
{
Serial.begin(9600);
//connect to the mqtt broken and set the connection callback
client.setServer(mqttServer, 1883);
client.setCallback(callback);
pinMode(pwr_en, OUTPUT);
digitalWrite(pwr_en, 1);
pinMode(led2_r, OUTPUT);
pinMode(led2_g, OUTPUT);
pinMode(led2_b, OUTPUT);
pinMode(led1_b, OUTPUT);
pinMode(led3_r, OUTPUT);
pinMode(led3_g, OUTPUT);
pinMode(led3_b, OUTPUT);
pinMode(led4_b, OUTPUT);
pinMode(key2, INPUT_PULLUP);
pinMode(key3, INPUT_PULLUP);
pinMode(key4, INPUT_PULLUP);
#if 1
/*
* Pin D21-D25 can not be used as digital IO ,when in debug mode(Enable JTAG).
* D21-D25 can be used as digital IO when in factory mode.(Disable JTAG)
*/
//D21-D25
pinMode(led4_g, OUTPUT);
pinMode(led4_r, OUTPUT);
pinMode(led1_g, OUTPUT);
pinMode(led1_r, OUTPUT);
pinMode(key1, INPUT_PULLUP);
#endif
led_off();
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to wifi");
printWifiStatus();
}
void loop()
{
if (!client.connected()) {
reconnect();
}
client.loop();
led_off();
if (digitalRead(key1) == 0) {
delay(50);
if (digitalRead(key1) == 0) {
led_ctrl(LED1,BLUE);
toggleSwitch();
delay(500);
Serial.print("key1");
//http_get("1");
}
}
if (digitalRead(key2) == 0) {
delay(50);
if (digitalRead(key2) == 0) {
led_ctrl(LED2,BLUE);
delay(500);
Serial.print("key2");
//http_get("2");
}
}
if (digitalRead(key3) == 0) {
delay(50);
if (digitalRead(key3) == 0) {
led_ctrl(LED3,BLUE);
delay(500);
Serial.print("key3");
//http_get("3");
}
}
if (digitalRead(key4) == 0) {
delay(50);
if (digitalRead(key4) == 0) {
led_ctrl(LED4,BLUE);
delay(500);
Serial.print("key4");
//http_get("4");
}
}
delay(100);
}
// function toggle the switch 1 of a sonoff switch
void toggleSwitch(){
if(client.connected()){
client.publish(outTopic, "toggle");
}else{
Serial.println("client is not connected...")
}
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
led_ctrl(LED1,RED);
led_ctrl(LED2,RED);
led_ctrl(LED3,RED);
led_ctrl(LED4,RED);
delay(500);
}
void led_off() {
led_ctrl(LED1,OFF);
led_ctrl(LED2,OFF);
led_ctrl(LED3,OFF);
led_ctrl(LED4,OFF);
}
void led_ctrl(uint8_t led_num, uint8_t rgb)
{
switch (led_num) {
case LED1:
if (rgb == RED) {
digitalWrite(led1_r, 0);
digitalWrite(led1_g, 1);
digitalWrite(led1_b, 1);
}
else if (rgb == GREEN) {
digitalWrite(led1_r, 1);
digitalWrite(led1_g, 0);
digitalWrite(led1_b, 1);
}
else if (rgb == BLUE) {
digitalWrite(led1_r, 1);
digitalWrite(led1_g, 1);
digitalWrite(led1_b, 0);
}
else if (rgb == OFF) {
digitalWrite(led1_r, 1);
digitalWrite(led1_g, 1);
digitalWrite(led1_b, 1);
}
break;
case LED2:
if (rgb == RED) {
digitalWrite(led2_r, 0);
digitalWrite(led2_g, 1);
digitalWrite(led2_b, 1);
}
else if (rgb == GREEN) {
digitalWrite(led2_r, 1);
digitalWrite(led2_g, 0);
digitalWrite(led2_b, 1);
}
else if (rgb == BLUE) {
digitalWrite(led2_r, 1);
digitalWrite(led2_g, 1);
digitalWrite(led2_b, 0);
}
else if (rgb == OFF) {
digitalWrite(led2_r, 1);
digitalWrite(led2_g, 1);
digitalWrite(led2_b, 1);
}
break;
case LED3:
if (rgb == RED) {
digitalWrite(led3_r, 0);
digitalWrite(led3_g, 1);
digitalWrite(led3_b, 1);
}
else if (rgb == GREEN) {
digitalWrite(led3_r, 1);
digitalWrite(led3_g, 0);
digitalWrite(led3_b, 1);
}
else if (rgb == BLUE) {
digitalWrite(led3_r, 1);
digitalWrite(led3_g, 1);
digitalWrite(led3_b, 0);
}
else if (rgb == OFF) {
digitalWrite(led3_r, 1);
digitalWrite(led3_g, 1);
digitalWrite(led3_b, 1);
}
break;
case LED4:
if (rgb == RED) {
digitalWrite(led4_r, 0);
digitalWrite(led4_g, 1);
digitalWrite(led4_b, 1);
}
else if (rgb == GREEN) {
digitalWrite(led4_r, 1);
digitalWrite(led4_g, 0);
digitalWrite(led4_b, 1);
}
else if (rgb == BLUE) {
digitalWrite(led4_r, 1);
digitalWrite(led4_g, 1);
digitalWrite(led4_b, 0);
}
else if (rgb == OFF) {
digitalWrite(led4_r, 1);
digitalWrite(led4_g, 1);
digitalWrite(led4_b, 1);
}
break;
default:
break;
}
}
The code is very simple:
char mqttServer[] = "broker.hivemq.com";
char clientId[] = "amebaClient";
char publishTopic[] = " tasmota/sonoff-mylight/cmnd/Power1 ";
char publishPayload[] = "hello world";
char subscribeTopic[] = "inTopic";
This section sets up you mqtt broker and the in and out topics for you to subscribe and publish to. Here we are more concerned with the outTopic.
WiFiClient wifiClient;
PubSubClient client(wifiClient);
Here we create the wificlient and the PubSubClient that will help us communicate with the mqtt server
void callback(char* topic, byte* payload, unsigned int length) { }
void reconnect() { }
These two function do the following:
1) callback() acts as the function that is called when the pubsubclient gets an incoming message
2) reconnect() tried to reconnect to the broker if the connection is lost due to some reason (power outage, WiFi router issues etc)
Serial.begin(9600);
//connect to the mqtt broken and set the connection callback
client.setServer(mqttServer, 1883);
client.setCallback(callback);
Here we start the serial port with 9600 baud rate and also init the pubsubclient with connect to the given server along with registering the message callback function
The loop function is simple and whenever you press any of the button 1, you will have the pubsubclient object send a message to the outTopic with toggle as the payload.
Since the button control is like a normal Arduino code: wait for the button to pull the GPIO high and if the GPIO pin is digital high or a 1, execute some code. in our case send the toggle command to the sonoff switch
Click the upload button in the Arduino IDE and in a few seconds the firmware will be flashed to the dash button board and you can use the button labeled one to control the sonoff switch appliance connected to relay 1.
Fairly easy right guys. There are certain modifications you can do to connect to the Sonoff switch via HTTP or connect the dash button to OpenHab (a software to control your smart home) to extend the functionalities of the dashbutton board
We will cover that in a future project.
Comments
Please log in or sign up to comment.