ESP8266-12F LinkNode R4 Relay board with Cayenne-MyDevices

I purchased the LinkNode R4 from amazon because it was cheap, looked fun, and useful. I haven’t really found anything I need to use this for yet but I hope this might help someone else get started with this inexpensive board.






It uses an ESP8266-12F for the controller. This is a very cool little microcontroller. It has 512k of flash, features list from the datasheet:

Features • 802.11 b / g / n • Built Tensilica L106 ultra-low power 32-bit micro MCU, clocked at 80 MHz and supports 160 MHz, support for RTOS • Built-in 10 bit precision ADC • Built-in TCP / IP protocol stack • Built TR switch, balun, LNA, power amplifier and matching network • Built-in PLL, voltage regulator and power management components, 802.11b mode +20 dBm output power The guard interval • A-MPDU, A-MSDU aggregation and 0.4 s of • WiFi @ 2.4 GHz, supports WPA / WPA2 security mode • Supports remote upgrade and cloud AT OTA upgrade • Support STA / AP / STA + AP mode • Support Smart Config function (including Android and iOS devices) • HSPI, UART, I2C, I2S, IR Remote Control, PWM, GPIO • Deep sleep holding current 10 uA, shutdown current of less than 5 uA • Within 2 ms of wake-up, connect and transfer data packets • Standby power consumption is less than 1.0 mW (DTIM3) • Operating temperature range: -40 ℃- 125 ℃

I like to use Cayenne with my IOT devices, so I am writing this with that in mind.

There no assembly required for this board. Just make sure you have a decent power supply. It uses 5 volts but,  I used a 5 volt 2000ma supply. You will also need a FTDI chip to flash it, or an arduino. I will cover how to flash it with the FTDI chip.

To make this board ready to program you must put the mode header across the first two pins. 






You will also need to apply power to the board to program it. You will not be able to power and flash it with just the FTDI chip.

Wire from the LinkNode to the FTDI TX to RX and RX to TX and GND to GND. Power on the LinkNode then plug in the FTDI to your computer. Open the Arduino IDE 1.6.8 or higher.

You will need to add the ESP8266 to your boards. To do this click on File-Preferences and add to the Additional Boards Manager URLs section. If you already have other boards here just seperate by a comma.






Now you can go to Tools-Board and select Generic ESP8266 Module. Change Flash Mode to QIO.








Now, if you don’t have a Cayenne account, you can create one for free at Cayenne. Continue to your Dashboard and click on Add New-Device-Arduino, and select a board. I chose the Mega but I don’t think it matters. Make a note of your auth token for this device. Now go back to the Arduino IDE and put this code in.

#define CAYENNE_DEBUG // Uncomment to show debug messages
#define CAYENNE_PRINT Serial // Comment this out to disable prints and save space

#include "CayenneDefines.h"
#include "BlynkSimpleEsp8266.h"
#include "CayenneWiFiClient.h"
#define VIRTUAL_PIN 1
#define RELAY_1 12
#define RELAY_2 13
#define RELAY_3 14
#define RELAY_4 16

// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = "your-token";
// Your network name and password.
char ssid[] = "your-wifi-name";
char password[] = "your wifi password";

void setup()
// set digital pin to output
pinMode(RELAY_1, OUTPUT);
pinMode(RELAY_2, OUTPUT);
pinMode(RELAY_3, OUTPUT);
pinMode(RELAY_4, OUTPUT);

Cayenne.begin(token, ssid, password);

// This function will be called every time a Dashboard widget writes a value to Virtual Pin 2.
CAYENNE_LOG("Got a value: %s", getValue.asStr());
int i = getValue.asInt();

if (i == 0)
digitalWrite(RELAY_1, HIGH);
digitalWrite(RELAY_1, LOW);
CAYENNE_LOG("Got a value: %s", getValue.asStr());
int i = getValue.asInt();

if (i == 0)
digitalWrite(RELAY_2, HIGH);
digitalWrite(RELAY_2, LOW);
CAYENNE_LOG("Got a value: %s", getValue.asStr());
int i = getValue.asInt();

if (i == 0)
digitalWrite(RELAY_3, HIGH);
digitalWrite(RELAY_3, LOW);
CAYENNE_LOG("Got a value: %s", getValue.asStr());
int i = getValue.asInt();

if (i == 0)
digitalWrite(RELAY_4, HIGH);
digitalWrite(RELAY_4, LOW);
void loop()

You can download the code Here

Make sure to select the COM port for your FTDI chip and click the upload button to flash the LinkNode. If it fails, make sure you have to pin on the program/run header right and reboot the LinkNode, then try again.

Once its flashed, set your Program/run pin to the run position and reboot. You can open the Serial monitor in the Arduino IDE to verify it has connected to Cayenne. Set the baud rate of the Serial Monitor to 9600. Once its connected you can return to Cayenne and click Done. Then Click on New-Widget-Actuator-Relay. Do this four times and make sure to uniquely name each relay so you can differentiate each one. Now you should be able to turn on and off each relay as you wish.


LinkNode R4 Wiki

ESP8266-12F Datasheet

Purchase LinkNode R4


LinkNode APK

Pine64 Linux with LCD and Touchscreen Enabled

Armbian has released an image that gives us a working LCD and touchscreen with Linux!
I have built it and you can download it here!
Armbian IMG with LCD and Touchscreen Working
Just make sure your uEnv.txt looks like this after writing the IMG to the SD card but before you remove it from your computer.

optargs=enforcing=0 cma=384M no_console_suspend

# Uncomment to enable LCD screen

For those of you that don’t know how to write this IMG to an SD card…
You will need SD Formatter and Win32 Disk Imager.
SD Formatter
Using SD formatter- Format your SD card with Option Format Size Adjustment enabled
Using win32diskimager – Write the IMG to the SD card
After the IMG hsa been written to the SD card, Open the SD card and edit the uEnv.txt to look like the section above. Insert the card in your Pine64 and power up. Make sure you are using a 5V 2A or larger power supply.

Nextbook Ares 11 NXA116QC164 Root, Remove Encryption, and Downgrade to 5.0

This is for the NXA116QC164. Not the 264 model. The 264 model has firmware updated to 6.0 on the site. Proceed at your own risk.

I bought an Ares 11 from Walmart and found out in short order that even though this tablet has good specs it is slow and with Android 5.1 installed it has a memory leak causing instability. After a bit of research I found that we can get root access, install a better recovery, downgrade to Android 5.0, and remove the encryption. After doing this, my tablet is much more responsive and stable. This also works for the Ares 8. Just use ares-8-boot.img instead of boot_noencrypt.img. everything else is the same.

This is just a more consolidated version of the information from HERE.

If you choose to continue following this tutorial, you acknowledge that performing these tasks may cause your tablet not to boot properly and that is your responsibility, not mine. All data on the tablet will be erased. You should backup anything you do not want to lose. With that being said, I have done this on two NextBook Ares 11’s without issue. So as long as you follow the instructions you should be fine.

What You Will Need

Concerning Linux

If you don’t have Ubuntu on a computer you can use a live disk. Download Ubuntu and burn it to a disk with imgburn.

Lets Get To It 

  • Make sure your tablet is charged
  • Turn off your tablet
  • Boot into Linux
  • Connect to the internet
  • Download
  • Extract to the Desktop
  • Copy to your micro SD card
  • Install the SD card to your tablet
  • Connect your tablet to the linux computer with the micro USB data cable
  • Open Terminal in linux
  • Install ADB sudo apt-get install android-tools-adb
  • cd /home/*user*/Desktop/ares11
  • (Tablet) Boot the tablet into the bootloader by pressing the Power button and the Volume Down until you see the boot logo then release the Power button and continue to hold the Volume Down until you see the bootloader.
  • (Terminal) sudo ./trigger 4 This will cause your tablets screen to look funny, just wait till its done.
  • (Tablet) Reboot to the bootloader
  • (Terminal) sudo ./fastboot flash recovery ./twrp_recovery.img
  • (Tablet) Reboot to recovery by powering off the tablet. Once the tablet is off, press and hold the Power button and the Volume Up buttons until you see the logo, then release the Power button and continue holding the Volume Up button till you see the recovery menu.
  • (Tablet) Using the touchpad on the attached keyboard click on Wipe
  • Click on Format Data
  • Type yes
  • Click Go
  • Click the Home Icon on the bottom left
  • Click on Install
  • Select
  • Swipe to Confirm Flash
  • Reboot to the bootloader
  • (Terminal) sudo ./fastboot flash boot ./boot_noencrypt.img
  • (Tablet) Reboot to recovery
  • (Tablet) Click on Wipe
  • (Tablet) Swipe to Factory Reset
  • (Tablet) Power off and then power on normally
  • Enjoy!

Arduino nrf24 dual drive motor remote controlled car.

This is a work in progress but, there is plenty of very useful code  and information here. With the motor controller and Arduino code in this article you should be able to produce a remote controlled car that drives and turns using two drive motors. One on the left and one on the right.

My end goal is to use a motorized wheelchair and convert it to use tracked tread and haul loads of up to 300 pounds.

For now I have just been playing with a seeedstudio motor controller to control two hobby motors on an Arduino mega. I went with the mega due to spi pin constraints. Since I am using the nrf24 as the wireless interface, I was unable to use the motor controller and the nrf24 on the Uno since they both required the use of the same pins. The mega allows for the use of both modules and still leaves plenty of extra I/O for future expansion.  On the transmitter side, I am using an Uno, a joystick shield and an nrf24.

There are a couple of important notes to make when working with the nrf24. First and most importantly, is that they can only be powered by 3.3 volts. If you try to power them with 5 volts you will fry them. Second, is that they have higher peak power requirements than the Arduino boards can supply. If you want to power them from the Arduino, you will need to add a 10uf – 100uf capacitor from power to ground on the nrf24 modules ( pins 1 & 2 ). Make sure you have the capacitor polorized with the ground of the capacitor going to the ground ( pin 1 ) of the nrf24 module.

Also, I would like to mention that I had a great deal of help from gpop1 in the Arduino forums on this. He had a great attitude and helped me clean the code up and make it much more readable and efficient. Without him I would have working but slow and messy code. Thanks gpop1!

Items used for this project

  • Arduino Mega 2560
  • Arduino Uno
  • Joystick Shield
  • Seeedstudio Motor Controller
  • 2 Hobby Motors
  • 2 100uf Capacitors

Tools used in this project

  • Soldering iron
  • Wire stripper/cutter

NRF24 Versions, and Ranges

Amplified Version                                                                                                         The amplified version hooks up the same but, I would not suggest running it using the 3.3 volts from the Arduino. The module is already using all the power it can from the Arduino without being amplified. If you decide that you need or want the amplified version, then you need to consider how you are going to power it.

Low Powered Version                                                                                                     If you are going to continue to use the non amplified version, you can add a single piece of cat5 wire that is 83.33 mm (3.279528 inches) long to it to extend the range by as much as 60 meters. Without the extra length of wire you will only get about 15 meters out of it.  Here is a video explaining the antenna mod. Antenna Mod Video

Choosing a power source


  • Maximum sustainable voltage the motors can take
  • Is your voltage within the acceptable input range for the Arduino
  • Is your voltage within the acceptable input range for the motor controller
  • How long do you want to be able to use it for
  • How is the battery weight going to effect your performance and run time

For the car: I would suggest something like you find in most hobby cars. Typically 7.2 or 9.6 volt battery pack with a charger. From there you can pigtail right off of the input to the motor controller with a standard barrel plug for the Arduino.( NOTE: this is only if you have bought a quality motor shield or used the one I outlined earlier in the post since they have protection circuitry built in to protect from voltage spikes that come from the motors.)

For the controller: I would suggest using a large booster battery like the ones for cell phones. I found some at the 5 and Below Store for $5 that are 6600 ma and is capable of an output of 5 volts at 1 amp. It already has the necessary circuitry for charging all you need is a cell phone charger and cable to charge it. Then, just use a standard USB cable and plug it into your Arduino controller. Very convenient.













Car Side                                                                                                                                       If you are using the low powered nrf24 and are going to directly connect power to the Arduino Mega, you will need to solder the power and ground from the nrf24 directly to the 3.3 volt pin on the bottom of the Mega since the motor controller likely wont break out the 3.3 volts. You should be able to just use the female breakouts for the rest. The power will be supplied from the motor controller.

NRF24 Uno Mega
2 3.3v 3.3v
3 9 49
4 10 53
5 13 52
6 11 51
7 12 50

Controller Side                                                                                                                             Connect the joystick shield and solder each nrf24 connection to the pins on the top of the shield or bottom of the arduino. Unless your shield has breakouts on the top, then you can just plug them in.

The TX (Controller) Code from arduino-info

/* YourDuinoStarter Example: nRF24L01 Transmit Joystick values
- WHAT IT DOES: Reads Analog values on A0, A1 and transmits
them over a nRF24L01 Radio Link to another transceiver.
- SEE the comments after "//" on each line below
- CONNECTIONS: nRF24L01 Modules See:
1 - GND
2 - VCC 3.3V !!! NOT 5V
3 - CE to Arduino pin 9
4 - CSN to Arduino pin 10
5 - SCK to Arduino pin 13
6 - MOSI to Arduino pin 11
7 - MISO to Arduino pin 12
Analog Joystick or two 10K potentiometers:
GND to Arduino GND
VCC to Arduino +5V
X Pot to Arduino A0
Y Pot to Arduino A1

– V1.00 11/26/13
Based on examples at
Questions: */

/*—–( Import needed libraries )—–*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
/*—–( Declare Constants and Pin Numbers )—–*/
#define CE_PIN 9
#define CSN_PIN 10
#define JOYSTICK_X A0
#define JOYSTICK_Y A1

// NOTE: the “LL” at the end of the constant is “LongLong” type
const uint64_t pipe = 0xE8E8F0F0E1LL; // Define the transmit pipe

/*—–( Declare objects )—–*/
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
/*—–( Declare Variables )—–*/
int joystick[2]; // 2 element array holding Joystick readings

void setup() /****** SETUP: RUNS ONCE ******/
}//–(end setup )—

void loop() /****** LOOP: RUNS CONSTANTLY ******/
joystick[0] = analogRead(JOYSTICK_X);
joystick[1] = analogRead(JOYSTICK_Y);

radio.write( joystick, sizeof(joystick) );

}//–(end main loop )—

/*—–( Declare User-written Functions )—–*/

//*********( THE END )***********


The RX (Car) Code from seeedstudio, gpop1, and Me.
//. Motor driver shield- 2012 Copyright (c) Seeed Technology Inc.
// Original Author: Jimbo.we
// Contribution: LG
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
/*—–( Declare Constants and Pin Numbers )—–*/
#define CE_PIN 49
#define CSN_PIN 53

// NOTE: the “LL” at the end of the constant is “LongLong” type
const uint64_t pipe = 0xE8E8F0F0E1LL; // Define the transmit pipe

/*—–( Declare objects )—–*/
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

int pinI1 = 8; //define I1 interface
int pinI2 = 11; //define I2 interface
int speedpinA = 9; //enable motor A
int pinI3 = 12; //define I3 interface
int pinI4 = 13; //define I4 interface
int speedpinB = 10; //enable motor B
int fspead = 0; //define the forward spead of motor
int bspead = 0; //define the backward spead of motor
int rspead = 0; //define the right turn only spead of motor
int lspead = 0; //define the left turn only spead of motor
int joystick[2]; // 2 element array holding Joystick readings
byte flagStop = 0;

void setup()
pinMode(pinI1, OUTPUT);
pinMode(pinI2, OUTPUT);
pinMode(speedpinA, OUTPUT);
pinMode(pinI3, OUTPUT);
pinMode(pinI4, OUTPUT);
pinMode(speedpinB, OUTPUT);
Serial.println(“Nrf24L01 Receiver Starting”);
radio.openReadingPipe(1, pipe);

void forward()
{//if (joystick[1] >= 510)//ok
fspead = map(joystick[1], 510, 1023, 0, 255);
Serial.print(“A: “);
Serial.print(“B: “);
digitalWrite(pinI4, HIGH); //turn DC Motor B move clockwise
digitalWrite(pinI3, LOW);
digitalWrite(pinI2, LOW); //turn DC Motor A move anticlockwise
digitalWrite(pinI1, HIGH);
analogWrite(speedpinA, fspead); //input a simulation value to set the speed
analogWrite(speedpinB, fspead);
void backward()//if (joystick[1] <= 505) { bspead = map(joystick[1], 506, 0, 0, 255); Serial.print(“Backward: “); Serial.print(“A: “); Serial.print(bspead); Serial.print(“B: “); Serial.print(bspead); Serial.println(“”); digitalWrite(pinI4, LOW); //turn DC Motor B move anticlockwise digitalWrite(pinI3, HIGH); digitalWrite(pinI2, HIGH); //turn DC Motor A move clockwise digitalWrite(pinI1, LOW); analogWrite(speedpinA, bspead); //input a simulation value to set the speed analogWrite(speedpinB, bspead); } void left()//if (joystick[0] >= 516)

lspead = map(joystick[0], 517, 1023, 0, 255);
Serial.print(“Left Only: “);
Serial.print(“A: “);
Serial.print(“B: “);
digitalWrite(pinI4, HIGH); //turn DC Motor B move clockwise
digitalWrite(pinI3, LOW);
digitalWrite(pinI2, HIGH); //turn DC Motor A move clockwise
digitalWrite(pinI1, LOW);
analogWrite(speedpinA, lspead); //input a simulation value to set the speed
analogWrite(speedpinB, lspead);
void right()//if (joystick[0] <= 508) { rspead = map(joystick[0], 517, 0, 0, 255); Serial.print(“Right Only: “); Serial.print(“A: “); Serial.print(rspead); Serial.print(“B: “); Serial.print(rspead); Serial.println(“”); digitalWrite(pinI4, LOW); //turn DC Motor B move anticlockwise digitalWrite(pinI3, HIGH); digitalWrite(pinI2, LOW); //turn DC Motor A move clockwise digitalWrite(pinI1, HIGH); analogWrite(speedpinA, rspead); //input a simulation value to set the speed analogWrite(speedpinB, rspead); } void forandright()//if (joystick[1] >= 516)

//not perfect but useable
fspead = map(joystick[1], 513, 1023, 0, 255);
Serial.print(“Forward and Right: “);
Serial.print(“A: “);
Serial.print(“B: “);
Serial.print(fspead / 2);
digitalWrite(pinI4, HIGH); //turn DC Motor B move clockwise
digitalWrite(pinI3, LOW);
digitalWrite(pinI2, LOW); //turn DC Motor A move anticlockwise
digitalWrite(pinI1, HIGH);
analogWrite(speedpinA, fspead); //input a simulation value to set the speed
analogWrite(speedpinB, fspead / 2);

void forandleft()//if (joystick[1] >= 516)
fspead = map(joystick[1], 513, 1023, 0, 255);
Serial.print(“Forward and Left: “);
Serial.print(“A: “);
Serial.print(fspead / 2);
Serial.print(“B: “);
digitalWrite(pinI4, HIGH); //turn DC Motor B move clockwise
digitalWrite(pinI3, LOW);
digitalWrite(pinI2, LOW); //turn DC Motor A move anticlockwise
digitalWrite(pinI1, HIGH);
analogWrite(speedpinA, fspead / 2); //input a simulation value to set the speed
analogWrite(speedpinB, fspead);

void backandright()//
bspead = map(joystick[1], 517, 0, 255, 0);
Serial.print(“Back and Right: “);
Serial.print(“A: “);
Serial.print(“B: “);
Serial.print(bspead / 2);
digitalWrite(pinI4, LOW); //turn DC Motor B move anticlockwise
digitalWrite(pinI3, HIGH);
digitalWrite(pinI2, HIGH); //turn DC Motor A move clockwise
digitalWrite(pinI1, LOW);
analogWrite(speedpinA, bspead); //input a simulation value to set the speed
analogWrite(speedpinB, bspead / 2);

void backandleft()//
bspead = map(joystick[1], 517, 0, 0, 255);
Serial.print(“Back and Left: “);
Serial.print(“A: “);
Serial.print(bspead / 2);
Serial.print(“B: “);
digitalWrite(pinI4, LOW); //turn DC Motor B move anticlockwise
digitalWrite(pinI3, HIGH);
digitalWrite(pinI2, HIGH); //turn DC Motor A move clockwise
digitalWrite(pinI1, LOW);
analogWrite(speedpinA, bspead / 2); //input a simulation value to set the speed
analogWrite(speedpinB, bspead);

void stop()//
Serial.println(“ALL STOP”);
digitalWrite(speedpinA, LOW); // Unenble the pin, to stop the motor. this should be done to avid damaging the motor.
digitalWrite(speedpinB, LOW);


void loop()
if ( radio.available() )
// Read the data payload until we’ve received everything
bool done = false;, sizeof(joystick));
// Serial.print(“X = “);
// Serial.print(joystick[0]);
// Serial.print(” Y = “);
// Serial.println(joystick[1]);
flagStop = 0;
} else {
flagStop = 1;
Serial.println(“No radio available”);

if (joystick[1] > 502 && joystick[1] < 510 && joystick[0] >= 509 && joystick[0] <= 510)
flagStop = 1;
else {
flagStop = 0;

if (flagStop == 0) {//if the flag is 1 then skip this code until its not

if (joystick[0] <= 508 && joystick[1] >= 516)// J0 center stick 509 to 510. j1 center stick 503 to 509.

else if (joystick[0] >= 513 && joystick[1] >= 516)// J0 center stick 509 to 510. j1 center stick 503 to 509.

else if (joystick[0] <= 508 && joystick[1] <= 502)// J0 center stick 509 to 510. j1 center stick 503 to 509. { backandright(); } else if (joystick[0] >= 513 && joystick[1] <= 502)// J0 center stick 509 to 510. j1 center stick 503 to 509.

else if (joystick[1] <= 505 && joystick[0] >= 509 && joystick[0] <= 513)// J0 center stick 509 to 510. j1 center stick 503 to 509. { backward(); } else if (joystick[1] >= 510 && joystick[0] <= 513 && joystick[0] >= 509)// J0 center stick 509 to 510. j1 center stick 503 to 509.

else if (joystick[0] >= 516)// J0 center stick 509 to 510. j1 center stick 503 to 509.

else if (joystick[0] <= 508)// J0 center stick 509 to 510. j1 center stick 503 to 509.

{ // no harm as a back up

Download the code here

Raspberry Pi Appliance Timer

Disclaimer:  Working with mains current is dangerous. Use the information provided in this article/post at your own risk. Always turn off power and confirm no voltage is present on the wires you are going to work with, with a volt meter before beginning work with mains power.

This is an On/Off timer based on the Raspberry Pi. After some really high electric bills I decided I needed to do something to help reduce my burden. The first thing that came to mind that likely runs much more than necessary is the electric water heater.  The water heater is designed to constantly retain a certain temperature. However, we only use hot water one to two times daily, once in the morning and again at night.

I needed something that would give me an AM and a PM On/Off schedule. I could have bought a ready made product but I have been looking for a good project for the Raspberry Pi and since it is so much easier to use the Pi for timed projects due to the built in NTP client over the Arduino it was a no brainer.

There are  couple of different ways of writing a script to turn on and off the appliance. One way and probably the easiest is to turn on the GPIO pins based on time and then set a delay for the duration you want it on for followed by turning the GPIO pin back off. Another, the way I did it here, is to turn the GPIO pin on and off based on times rather than setting a delay. I feel like making the on and off based on the clock is more elegant and dependable.

Now, on to the Hardware I used and why.

Raspberry Pi (any model) – $35 – Where to purchase

Raspberry Pi case – $8.99 – Where to purchase – This is for the pi B+ or Pi 2. You will need a different case for the other Pi models.

240 volt to 24 volt AC transformer – $14 – Where to purchase

240 volt contactor – $21 – Where to purchase – Steps 240 volts down to 24 volts for the contactor relay.

NPN transistor – $0.12 – Where to purchase – This switches the 24 volt relay.

24 volt relay – $0.64 – Where to purchase – This switches the contactor.

3 position screw down terminal – $0.20 – Where to purchase – 5 volt and grounds terminal block.

2 position screw down terminal – $0.10 – Where to purchase – 24 volt relay terminal for switching the contactor.

Prototyping board – $0.99 – Where to purchase – To solder our components to.

LED (any color) – $0.05 – Where to purchase – To indicate whether the appliance is switched on or off.

Momentary button – $0.25 – Where to purchase – Manual timed on switch

Enclosure – $10.89 – Where to purchase – This is not the enclosure I used but it is the type you should use. Mine is one I had around from Radio Shack.

Wire – $0.00 – You should be able to find appropriate wire laying around. Cat 5 (Ethernet), Cat 3 (Phone Wire), HVAC Thermostat Wire), all will work well for the contactor control board, but just about any wire larger than 24 gauge will be fine. Just make sure that you have a few different colors so you don’t make mistakes by getting confused about what goes where. I use Cat 5 wire because you can find it everywhere these days and because there are 8 differently color coded wires in it.

Wire nuts – $10.96 – Where to purchase – Use wire nuts appropriate for the size of the wire and amount of current.

Wire Terminals – $2.98 – Where to purchase – Use wire terminals appropriate for the size of your wire and amount of current.

Crude Schematic of Contactor Control Board

Click pictures to show larger view.

These pictures are showing the bottom of the board where the pins come through.









Semi complete Project


WP_20150806_003 WP_20150814_004[1] WP_20150806_002 WP_20150806_004 WP_20150806_001 WP_20150805_005














Make the Contactor Control Board

Since the 24 volt relay is the largest component on the controller board, it should be the component you structure the rest of the components around. I placed the transistor close enough to the relay that I was able to solder it directly to the relay pin. You can use wire to connect each point on the board or make solder traces connecting it all together. You should be able to follow my crude schematic to put together the control board, but if you need further instruction please leave a comment or email me at modsbyus ‘at’ I will be more than happy to give further assistance.


Putting Together The Mains Components

The 240/24 Volt AC Transformer

This transformer has 4 wires for connecting to the mains. The black and white ones are for 120 volts and the orange and red ones are for 240 volts. Use the pair that is appropriate for your usage. The 24 volt wires are blue and yellow.

The yellow wire is going to connect to the relay terminal on the control board and then you make a connection from the other position on the relay terminal to one side of the contactor. The blue wire goes directly to the other side of the contactor.

The Enclosure

Depending on the enclosure you choose for your project, mounting will be different. You need to make sure that your Raspberry Pi is mounted in its own case outside of the enclosure for the mains components. The EMD (electro magnetic discharge) from the contactor opening and closing can cause damage to your Raspberry Pi and can also cause unexpected unclean shut downs.  You can put the timed override switch and status LED mounted through the enclosure.

The Raspberry Pi

I highly recommend using a Pi case for your Raspberry Pi. It will protect your Pi from all sorts of damage and it looks nicer.

We are going to use GPIO pins 17, 24, and 27 and 3 ground pins.

17 and one ground pin is wired to the timed override switch.

24 and one ground pin is wired to the LED. The long leg of the LED goes to the GPIO 24 pin.

27 goes to the control position on the 3 position terminal block which is connected to pin 1 of the transistor.

A third ground goes to the ground position of the 3 position terminal block which is connected to pin 2 of the transistor.

You will need a constant 5 volt supply for the relay which goes to the 5VDC position of the 3 position terminal block. You can use a 5 volt pin from the Raspberry Pi but I don’t recommend it for this project. Whenever you turn off a coil or motor it sends back high voltage spikes that can damage your Raspberry Pi. I suggest finding a 5 volt power supply to use. The positive line of the 5 volts goes to the 5VDC position of the 3 position terminal block and the ground or negative of the power supply goes to the ground position of the 3 position terminal block.


The Python Program That Runs it

You can download it Download

?View Code PYTHON
# Raspberry Pi custom appliance timer
# import GPIO module
import RPi.GPIO as GPIO
# set up GPIO pins as outputs
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Button
GPIO.setup(27, GPIO.OUT) # Appliance 5/25 volt relay
GPIO.setup(24, GPIO.OUT)# LED
state = 0
button = GPIO.input(17)
# import date and time modules
import datetime
import time
# Enter the times you want the appliance to turn on and off for
# each day of the week.
MonAMOn  = datetime.time(hour=5)
MonAMOff = datetime.time(hour=7)
MonPMOn  = datetime.time(hour=16)
MonPMOff = datetime.time(hour=22)
TueAMOn  = datetime.time(hour=5)
TueAMOff = datetime.time(hour=7)
TuePMOn  = datetime.time(hour=16)
TuePMOff = datetime.time(hour=22)
WedAMOn  = datetime.time(hour=5)
WedAMOff = datetime.time(hour=7)
WedPMOn  = datetime.time(hour=16)
WedPMOff = datetime.time(hour=22)
ThuAMOn  = datetime.time(hour=5)
ThuAMOff = datetime.time(hour=7)
ThuPMOn  = datetime.time(hour=16)
ThuPMOff = datetime.time(hour=22)
FriAMOn  = datetime.time(hour=5)
FriAMOff = datetime.time(hour=7)
FriPMOn  = datetime.time(hour=16)
FriPMOff = datetime.time(hour=22)
SatAMOn  = datetime.time(hour=5)
SatAMOff = datetime.time(hour=7)
SatPMOn  = datetime.time(hour=16)
SatPMOff = datetime.time(hour=22)
SunAMOn  = datetime.time(hour=5)
SunAMOff = datetime.time(hour=7)
SunPMOn  = datetime.time(hour=16)
SunPMOff = datetime.time(hour=22)
# Store these times in an array for easy access later.
OnTimeAM = [MonAMOn, TueAMOn, WedAMOn, ThuAMOn, FriAMOn, SatAMOn, SunPMOn]
OnTimePM = [MonPMOn, TuePMOn, WedPMOn, ThuPMOn, FriPMOn, SatPMOn, SunPMOn]
OffTimeAM = [MonAMOff, TueAMOff, WedAMOff, ThuAMOff, FriAMOff, SatAMOff, SunAMOff]
OffTimePM = [MonPMOff, TuePMOff, WedPMOff, ThuPMOff, FriPMOff, SatPMOff, SunAMOff]
# Start the loop that will run until you stop the program or turn off your Raspberry Pi.
while True:
    button = GPIO.input(17)
    global state
    if button == 0:
        #print('button', button)
        state = 1
        #print('state', state)
    if state == 1:
        GPIO.output(24, True)
        GPIO.output(27, True)
        time.sleep(3600) #3600
        state = 0
        GPIO.output(24, False)
        GPIO.output(27, False)
    # get the current time in hours, minutes and seconds
    currTime =
    # get the current day of the week (0=Monday, 1=Tuesday, 2=Wednesday...)
    currDay =
        #Check to see if it's time to run the appliance for the AM hours
    while (currTime.hour &gt;= OnTimeAM[currDay].hour and currTime.hour &lt;= OffTimeAM[currDay].hour): # set the GPIO pin to HIGH GPIO.output(24, True) GPIO.output(27, True) time.sleep(60) currTime = currDay = else: if (currTime.hour &gt;= OffTimeAM[currDay].hour - 1):
            GPIO.output(24, False)
            GPIO.output(27, False)
    #Check to see if it's time to run the appliance for the PM hours
    while (currTime.hour &gt;= OnTimePM[currDay].hour and currTime.hour &lt;= OffTimePM[currDay].hour): GPIO.output(24, True) GPIO.output(27, True) time.sleep(60) currDay = currTime = else: if (currTime.hour &gt;= OffTimePM[currDay].hour - 1):
            GPIO.output(24, False)
            GPIO.output(27, False)

Disconnected Testing

You should run a dry test without the mains connected to the contactor. You don’t want to damage anything or hurt yourself. As long as you can push the override switch and it stays on for the expected amount of time and it comes on and goes off properly for a specified time period then you are good to go.

Bringing it All Together

Its time to hook up the mains (240 or 110 Volts) to the contactor. The feed lines go to one side and the lines to your appliance go to the other side. Use the pictures above as a reference. As always you should follow all safety procedures for dealing with main current and if you don’t know what you are doing then you have no business messing with it. YOU CAN KILL YOURSELF OR OTHERS!

Live Testing

After hooking in the mains and your appliance its time to give it a real test. Set and AM and a PM time for short durations during a time you can monitor it. Turn everything on, boot up the PI, test out the override switch and the timed functions.

Set it and Forget it

The easiest way I have found to set a python script to start when you boot the Pi is to set it as a Cron job using Webmin.

HARDWARE_HACKS has a great tutorial on how to setup Webmin. Follow that then return here for the Cron Job how to.

If you have Webmin setup and you are logged in click on System then Scheduled Cron Jobs







Now click on Create a New Scheduled Cron Job.

It should look like this. The only difference is that for the Command that you put in the path for your python script.

python /home/pi/Desktop/








Now Just

sudo reboot

and you are all done! It should come on and go off based on the schedule you set.

Special Note:

The Raspberry Pi does not do well with improper shutdowns. It will cause system corruption. For the sake of all the hard work you just went through, run this on a UPS or some type of reliable battery system.

Getting Started with the Raspberry Pi

I Got My Raspberry Pi, Now What?

This is a great platform to work with. You have many options when choosing a micro computer. The Raspberry Pi has a large community that makes it easy to work with this hardware. If you have trouble with the hardware or with the scripting or programming for the Pi you can head over to the Raspberry Pi Forum where there is always someone happy to help without being rude and condescending. Unlike most other forums I have encountered, the atmosphere there is refreshing and full of welcome.

What you Need

  • Raspberry Pi
  • Class 10 Micro SD Card (Others will work but this is recommended.)
  • 5 Volt 2 Amp with a Micro USB 5pin Male
  • A computer
  • A Micro SD Adapter and maybe a USB to SD Adapter as well depending on your needs.
  • SD Formatter – Get it at
  • Win32 Disk Imager – Get it at
  • Raspbian (The Operating System) – Get it at
  • Adafruit Pi Finder – Get it at GitHub
  • WinRAR – Get it at
  • Putty – Get it at
  • AngryIPScanner – Get it at (Optional)
  • A Ethernet connection to your network (internet access)

Install WINRAR

You will need this or some other archive tool to extract everything you have downloaded. I suggest that you extract everything to a familiar place like your Desktop to make it easy to find. You should create a folder to extract the Adafruit Pi Finder to since there are a lot of files.


Preparing the SD Card

Open SD Formatter










It should find your SD card automatically but you need to verify that the drive letter shown is in fact the drive letter of your SD card. If you format the wrong drive you will erase EVERYTHING. Go to your explorer and verify drive letters there.

Choose the Option button and select Format Size Adjustment to ON. Then click OK then Format. Say OK to the two warnings to Format your SD card.

Install the OS to the SD Card

Open Win32 Disk Imager.





Browse to and select the img file you extracted from the file you downloaded from

Click on Write and wait for it to complete. After its finished safely eject the SD card and insert it into the Pi.

First Boot

Plug in your Ethernet (internet) cable to the Pi then the power cable.

Wait a moment for the Pi to boot, then open the Adafruit Pi Finder by double clicking the PiBootstrap.exe file. Then click on Find My Pi!.

PiFinder PiFinderAfterFind








Once it finds your Pi open Putty and type in the IP address of your Pi. I don’t suggest using this tool for anything other than finding the IP address of your Pi. Terminal works most of the time but its frustrating when it doesn’t. The webide is still in beta and has some bugs in the installation.











The default username is ‘pi’ and the default password is ‘raspberry’. You will not see any characters being printed on the screen when you are inputting the password, this is normal.

Now run

sudo raspi-config

This will take to a window like this.








There is no mouse support in this menu. Use the Up,Down,Left,Right,TAB, and Enter keys of your keyboard to navigate.

Press enter on the first option to Expand Filesystem.

After that has finished you will be returned to this menu. Now choose Change User Password. You don’t want your project bamboozled by the internet bullies.

If you wish to automatically go straight to the desktop or to Scratch then make your selection in Enable Boot to Desktop/Scratch.

Next, Set your timezone and keyboard options in Internationalisation Options.

Now If you have the Raspberry Pi Camera module choose Enable Camera. If you are going to use a webcam there is no need to do this step.

If you wish to get the full potential out of your Pi then go to Overclock and choose the option you want for your Pi.

We’re getting close to the end now.

Go to Advanced Options.








Here you are going to set options that are specific to you individual needs. To have continued access using SSH (Putty) you need to enable SSH. Without SSH you must have an HDMI display hooked up to your PI. After each edit in this menu you will likely be returned to the main menu, just go back to Advance options to get back and finsh your optional configurations. Once you are done and back to the main menu select Finish. You should be prompted to reboot. Go ahead and do that now.

Once your Pi has rebooted restart your Putty session and log in.

Now is a good time to make sure that your Raspberry Pi is up to date.



sudo apt-get update


sudo apt-get upgrade

This will take a while. Once it is done reboot your Pi again.

sudo reboot

Once your Pi has rebooted restart your Putty session and log in again.

Static Network Config (OPTIONAL)

You may wish to configure a static IP configuration on your Pi to make it easier to find and work on in the future.

First you need to determine a suitable IP address to use. If you know how to find this out by logging into your router then do that.


Install and open Angry IP Scanner and click on Start.

This will return a list of all the IP addresses on your network, active and inactive.

Typically your router will only give out up to 50 addresses by DHCP. The rest can be used for static assignment. You need to choose an inactive IP outside of you DHCP range. This can be determined by examining the results of the IP Scanner results. Usually your DHCP will either start at 2 and end somewhere around 50 or start around 100 and go to 150 or 200. If your results have IP addresses in the lower range then use something above 100. Otherwise use something between 2 and 49. Examples:,, ect..

Now that you know what IP address you are going to use.
Go back to your Putty session and type in

route -n

This will give an output something like this.
This shows us the Gateway, and netmask. Take note of these.

Example:  Netmask: Gateway:

So now you have an IP address, Gateway address, and a  Netmask.

Now we have the information we need to configure a static IP address.
Now type in

sudo nano /etc/network/interfaces

You will see something like this.









Change it to look like this using your IP information.

auto lo

iface lo inet loopback
iface eth0 inet static

allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp








Then hit Ctrl+o to save it and Ctrl+x to exit

Now reboot

sudo reboot

If you would like to be able to log into your Pi’s desktop remotely See my Post Raspberry Pi VNC Server Setup.

Raspberry Pi VNC Server Setup

Seeting up Remote Access With Tight VNC

Open a terminal if you are logged into your Pi with a connected display or Use Putty to SSH into your Pi if you are working on it over the network or remotely.

Type in

Sudo apt-get update

Now type in

Sudo apt-get install tightvncserver

When asked

After this operation, 9,988 kB of additional disk space will be used.
Do you want to continue [Y/n]?

answer with ‘y’


Sudo vncserver

It will ask you for a password to use for the VNC access twice. Just type in the same password both times. This will be the password you will have to enter each time you access your Pi over VNC.
It will also ask if you want to enter a view only password. I don’t use that so I always say no, but if you want to be able to view without control you do it then.
When its done you should see something like this.








Now you will need to download and install the Tight VNC Viewer on your computer.

Get it at

Once installed open it up and type the IP address of your Pi succeeded by :1 and hit Enter


You should be prompted for your password and after entering your password you will be greeted with the view and control of your Pi’s desktop.

VNC-Access VNC-desktop

Playing with the Raspberry Pi

So, I have been holding off on getting the Raspberry Pi for quite a while. Why? Well honestly, it was because I was a bit intimidated by it. I have been using and programming on the Arduino platform for a couple of years. I made a few projects like a wireless temperature monitor, a thermostat, and a couple of other tidbits. I struggled my way through a good bit of it since I haven’t had any proper training in programming. With a lot of help and criticism from the guys in the Arduino forum I made it through each one of my projects less one.

You can see why moving to a more complicated and more powerful platform would be a little scary. Alas, I decided it was time to try something new. I was bored with struggling  through the same things and figured that if I’m going to struggle any way why not do it the next step up.

I bought the Raspberry Pi a couple of weeks ago and I have been surprised at every turn! Not only is it much easier to program in python but this tiny computer is so incredibly versatile.  I have written a basic program to flash and LED as well as a “Hello World” and built an HTPC with RaspBMC.

The Raspberry Pi isn’t powerful enough to run Windows but there are custom Linux images that run great. This little computer even has an HDMI output built right in and it is pretty much no fuss to use it.

My next step is to work through all the learning material on and grasp as much understanding about writing in python as possible. There are other sites to learn from as well. There are huge online communities and plenty of published guides and tutorials to follow. I am really looking forward to working with this platform in the coming year!

I will document each of my projects on here and hope that you get the most out of it. I am anxious to see what we can come up with and hope to hear your thoughts on each progressive project I make.

433 MHz Wireless temperature Monitor with I2C LCD

Using a 433 MHz transmitter and receiver ,  a Dallas DS18B20, and a 16×2 LCD with an  i2c / SPI character LCD backpack we can make a simple wireless temperature monitor. I’m not going to go into the construction of the hardware here since there is plenty of resources out there for that already.


Antennas are a big deal! There is a ton of antenna theory and math out there for you to figure it out but it would be difficult for anyone not already involved in antennas. So, I’m going to tell you what I did.

I got 2 stainless steel whips and magnetic bases from a local 2-way radio supplier and cut the whips to 13 1/4 inches. No coil is needed for this. I get about 60 feet through walls and floors. On the transmitter I am using 12 volts so that I can transmit at full power. I am just using one of the 5 volt pins of the Uno to power the receiver.


Transmitter Code

#include <OneWire.h> //This temperature sensor requires a 4.7k Ohm resistor across its pins 2 and three!!!!
#include <DallasTemperature.h>
#include <Wire.h>
#include <VirtualWire.h>
int ledPin = 13;//Set up the TX indicator pin 13 as LedPin
int Sensor1Data;//initialize the use of the variable Sensor1Data
//int sensorValue = 0;  // variable to store the value coming from the sensor If using analog sensor
float currentTemp = 0;//to store decimal value coming from the temp sensor
// RF Transmission container
//char Sensor1CharMsg[4]; 
// Trying to use 5 instead to fit trailing null char 
// go back to 4 if this does not work. 
char Sensor1CharMsg[5]; 

//This temperature sensor requires a 4.7k Ohm resistor across its pins 2 and three!!!! Thats the middle pin and the GND pin
// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

DeviceAddress insideThermometer = { 0x28, 0xE4, 0x10, 0x74, 0x03, 0x00, 0x00, 0xD5 };
// DeviceAddress outsideThermometer = { 0x28, 0x20, 0x04, 0xA8, 0x02, 0x00, 0x00, 0x4D };

void setup()
  pinMode(ledPin, OUTPUT);//Set the ledPin as an output
  Serial.begin(9600);//initialize serial communication
  Serial.print("TX Start");//Print TX Start in the serial terminal
  // VirtualWire 
    // Initialise the IO and ISR
    // Required for DR3100
    // Bits per sec
    vw_setup(300);	//Set VirtualWire communication speed
// Start up the library
// set the resolution to 9 bit (good enough?)
sensors.setResolution(insideThermometer, 9);
// sensors.setResolution(outsideThermometer, 9);

void loop(void)

sensors.requestTemperatures();  //Get temperature from the temp Sensor

float tempC = sensors.getTempC(insideThermometer);
if (tempC == -127.00) {
Serial.print("Error");//Print Error if we read -127else {
// lcd.print(tempC);
// lcd.print("/");
Sensor1Data = (DallasTemperature::toFahrenheit(tempC));//Set Sensor1Data as the Celcius to Fahrenheit Conversion
Serial.print(Sensor1Data); //Print the converted temp in the serial terminal
// Integer to ASCII
digitalWrite(13, true); // Turn on a light to show transmitting
 vw_send((uint8_t *)Sensor1CharMsg, strlen(Sensor1CharMsg));//Send the data collected

 vw_wait_tx(); // Wait until the whole message is gone
 digitalWrite(13, false); // Turn off a light after transmission
 delay(200);//Wait 200 Milliseconds and then go back to program start


Receiver Code


#include <Wire.h>

#include <Adafruit_MCP23008.h>
#include <LiquidCrystal.h>


Sensor Receiver 
By Markus Ulfberg 2012-07-06

Gets a sensor reading 0-1023 in a char array
from RF Transmitter unit via VirtualWire 
converts char array back to integer


#include <VirtualWire.h>

// LED's
int ledPin = 13;//Set up pin 13 as the recieve indicator
int ActionLED = 4;//Set up pin for LED 

// Connect via i2c, default address #0 (A0-A2 not jumpered)
LiquidCrystal lcd(0);
// Sensors 
int Sensor1Data;//initialize the variable Sensor1Data for use

// RF Transmission container
 char Sensor1CharMsg[4]; 
// Trying to use 5 instead to fit trailing null char 
// go back to 4 if this does not work. 
//char Sensor1CharMsg[5]; 

void setup() {
  lcd.begin(16, 2);
  Serial.begin(9600);//Initialize serial communication
  Serial.print("RX Start");//Print RX Start in the Serial Terminal 

  // sets the digital pin as output
  pinMode(ledPin, OUTPUT);//Set the ledPin as an Output
  pinMode(ActionLED, OUTPUT);//Se up the ActionLED pin as an Output
  digitalWrite(ActionLED, LOW);//Set the ActionLED LOW 'off'

    // VirtualWire 
    // Initialise the IO and ISR
    // Required for DR3100
    // Bits per sec
    vw_setup(300);//Set up VirualWire Communication Speed	 

    // Start the receiver PLL running

} // END void setup

void loop(){
  //Unsigned Integer of 8 bit length buffer Max Message Length
    uint8_t buf[VW_MAX_MESSAGE_LEN];
  //Unsigned Integer of 8 bit length buffer length Max Message Length
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

    // Non-blocking
    if (vw_get_message(buf, &buflen)) 
	int i;//initialize the variable i
        // Turn on a light to show received good message 
        digitalWrite(13, true); 
        lcd.setCursor(1, 0);
	lcd.print("Remote Temp: ");//Print Remote Temp: in the serial terminal
        // Message with a good checksum received, dump it. 
        for (i = 0; i < buflen; i++)//Use the variable i to store bytes from message and if i is less than the buffer length then increase byte storage.
          // Fill Sensor1CharMsg Char array with corresponding 
          // chars from buffer.   
         Sensor1CharMsg[i] = char(buf[i]);//Senso1CharMsg[i] is the variable to represent char(buf[i]);, char(buf[i]); is charactor buffer storage

        // Null terminate the char array
        // This needs to be done otherwise problems will occur
        // when the incoming messages has less digits than the
        // one before. 
        Sensor1CharMsg[buflen] = '\0';//clear it to fill again.

        // Sensor1Data is atoi (ASCII to Integer) from Sensor1CharMsg
        Sensor1Data = atoi(Sensor1CharMsg);

        // DEBUG 

        lcd.println(Sensor1Data); //Print Sensor1Data in the serial Terminal

        // END DEBUG

        // Turn off light to and await next message 
        digitalWrite(13, false);
        //If Sensor1Data (temp) is less than 75 degrees turn on the ActionLED
        if (Sensor1Data < 75)
          digitalWrite(ActionLED, HIGH);
    } //If Sensor1Data (temp)is more than 75 degrees turn off ActionLE
        else if (Sensor1Data > 75)
          digitalWrite(ActionLED, LOW);


Bread board power wires


This may seem a little trivial for a post, but I did it so I thought I would share.

I took a regulated 12 volt power supply and added a regulated 5 volt and adjustable supplies to it. I used some old speaker terminals I had around for the facing connections on the power supply. I wanted to have some wires that I didn’t have to screw down so I got some banana clips and male header pins to make my own wires that will work with the bread board and the power supply easily.

I got the banana clips and male headers from Tayda Electronics.



Helping Others With What We Know

%d bloggers like this: