[go: up one dir, main page]

0% found this document useful (0 votes)
269 views39 pages

Iot Hardware: Raspberry Pi 3 Model B

The document provides instructions for several common IoT hardware projects using a Raspberry Pi including: 1) Blinking an LED, controlling a traffic light, and using PWM to control LED brightness. 2) Interfacing a push button to turn an LED on and off and using a switch to control an LED. 3) Interfacing ultrasonic and DC motors and providing example programs to measure distance and drive the motor. 4) Accessories and programs are listed for each project to help replicate the circuits and code.

Uploaded by

bbmathi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
269 views39 pages

Iot Hardware: Raspberry Pi 3 Model B

The document provides instructions for several common IoT hardware projects using a Raspberry Pi including: 1) Blinking an LED, controlling a traffic light, and using PWM to control LED brightness. 2) Interfacing a push button to turn an LED on and off and using a switch to control an LED. 3) Interfacing ultrasonic and DC motors and providing example programs to measure distance and drive the motor. 4) Accessories and programs are listed for each project to help replicate the circuits and code.

Uploaded by

bbmathi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 39

IoT Hardware

Raspberry pi 3 Model B

1
1. LED Blinking
Objective:

To Make LED to blink in periodic Time.

Accessories Quantity
1.Bread Board 1

2.LED 1

3.Resistance 230Ω – 1kΩ

4.Jumper cable 2

Program: Program:

import RPi.GPIO as GPIO from gpiozero import LED


import time from time import sleep
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT) red = LED(17)

while (True): while True:


GPIO.output(18, True) red.on()
time.sleep(0.5) sleep(1)
GPIO.output(18, False) red.off()
time.sleep(0.5) sleep(1)

DIY:
1. Make LED to Blink alternatively.
2
2. TRAFFIC LIGHT CONTROL
Objective:
To control the Traffic light with constant Delay.

Accessories Unit
1.Bread Board 1

2.LED 3

3.Resistance 230Ω – 1kΩ

4.Jumper cable 6

Program:
import time print '--------------------'
import RPi.GPIO as GPIO time.sleep(13)
RUNNING = True trafficState(0,1,0)
GPIO.setmode(GPIO.BCM) print 'Green light is OFF'
GPIO.setup(18, GPIO.OUT) print 'Yellow light is ON'
GPIO.setup(23, GPIO.OUT) print '--------------------'
GPIO.setup(24, GPIO.OUT) time.sleep(10)
def trafficState(red, yellow, green): trafficState(1,0,0)
GPIO.output(18, red) print 'Yellow light is OFF'
GPIO.output(23, yellow) print 'red light is ON'
GPIO.output(24, green) print '--------------------'
print "Traffic Light Simulation. time.sleep(10)
Press CTRL + C to quit" except KeyboardInterrupt:
try: RUNNING = False
while RUNNING: print "\Quitting"k
trafficState(0,0,1) finally:
print 'Green light is ON' GPIO.cleanup()

DIY: Control the traffic light using Push Button


3
3. PWM with LED
Objective:
To control the brightness of the LED using PWM.

Program: GPIO.setmode(GPIO.BOARD)
import RPi.GPIO as GPIO GPIO.setup(12, GPIO.OUT)
GPIO.setmode(GPIO.BOARD) p = GPIO.PWM(12, 50) #
GPIO.setup(12, GPIO.OUT) channel=12 frequency=50Hz
p.start(0)
p = GPIO.PWM(12, 0.5) try:
p.start(1) while 1:
input('Press return to stop:') for dc in range(0, 101, 5):
# use raw_input for Python 2 p.ChangeDutyCycle(dc)
p.stop() time.sleep(0.1)
GPIO.cleanup() for dc in range(100, -1, -5
p.ChangeDutyCycle(dc)
An example to brighten/dim an time.sleep(0.1)
LED: except KeyboardInterrupt:
import time pass
import RPi.GPIO as GPIO p.stop()
GPIO.cleanup()

4
4. PUSH BUTTON with LED
Objective:
To make a LED to turn ON and Turn OFF using push button.

Accessories Unit
2.Bread Board 1

3.LED 1

4.PushButton 1

5.Jumper cable 5

Program:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(25, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(24, GPIO.OUT) try:
while True
if GPIO.input(25):
print "LED ON"
GPIO.output(24, 1)
else:
print "LED OFF"
GPIO.output(24, 0
sleep(0.1)
finally:
GPIO.cleanup()
5
4. a. LED with SWITCH
Objective:
To make a LED to ON and OFF controlled by 2 way switch.

Accessories Unit
2.Bread Board 1

3.LED 1

4.Switch 1

5.Jumper cable 3

Program: if i==0:
print "SWITCH OFF"
import RPi.GPIO as GPIO GPIO.output(3, 0)
import time time.sleep(0.1)
else:
GPIO.setwarnings(False) print "SWITCH ON"
GPIO.setmode(GPIO.BOARD) GPIO.output(3, 1)
GPIO.setup(11, GPIO.IN) time.sleep(0.1)
GPIO.setup(3, GPIO.OUT)
while True:
i=GPIO.input(11)

DIY:
1. Burglar alarm Using PIR Motion Sensor.
6
Accessories Quantity
1.Raspberry pi 2 Model 1
B

2.LED 1

3.PIR Sensor 1

3.Resistance 230Ω – 1kΩ

4.Jumper cable 3

2. Moisture Level Monitoring in Agricultural land.

5. ULTRASONIC SENSOR INTERFACING


Objective:

To measure the distance of object using HC-SR04 ultrasonic sensor.

Accessories Quantity
1.Raspberry Pi 1

2.LED 1

3.Ultrasonic Sensor 1

4.Jumper cable 4

7
Program:
import RPi.GPIO as GPIO StopTime = time.time()
import time TimeElapsed = StopTime -
GPIO.setmode(GPIO.BCM) StartTime
GPIO_TRIGGER = 18 # multiply with the sonic speed
GPIO_ECHO = 24 (34300 cm/s)
GPIO.setup(GPIO_TRIGGER, # and divide by 2, because there
GPIO.OUT) and back
GPIO.setup(GPIO_ECHO, distance = (TimeElapsed *
GPIO.IN) 34300) / 2
return distance
def distance():
GPIO.output(GPIO_TRIGGER, if __name__ == '__main__':
True) try:
while True:
# set Trigger after 0.01ms to dist = distance()
LOW print ("Measured Distance
time.sleep(0.00001) = %.1f cm" % dist)
GPIO.output(GPIO_TRIGGER, time.sleep(1)
False) # Reset by pressing CTRL +
StartTime = time.time() C
StopTime = time.time() except KeyboardInterrupt:
while GPIO.input(GPIO_ECHO) print("Measurement stopped
== 0: by User")
StartTime = time.time() GPIO.cleanup()
while GPIO.input(GPIO_ECHO)
== 1:
DIY:
Design and Implement an Obstacle Indicator using Ultrasonic Sensor and
Buzzer or LED
Note: Distance <=xx cm ; Buzzer On

8
6. DC MOTOR INTERFACING

Objective:

To make drive and stop the DC motor using Raspberry pi and L293D IC.

Accessories Unit
1.Raspberry Pi 1

2.ICL293D 1

3.DC Motor 1

4.Jumper cable 5

5.Battery – 9v 1

Program:
import RPi.GPIO as GPIO GPIO.setup(Motor1E,GPIO.OUT)
from time import sleep print "Turning motor on"
GPIO.setmode(GPIO.BOARD) GPIO.output(Motor1A,GPIO.HIGH)
Motor1A = 16 GPIO.output(Motor1B,GPIO.LOW)
Motor1B = 18 GPIO.output(Motor1E,GPIO.HIGH)
Motor1E = 22 sleep(2)
GPIO.setup(Motor1A,GPIO.OUT) print "Stopping motor"
GPIO.setup(Motor1B,GPIO.OUT) GPIO.output(Motor1E,GPIO.LOW)

9
GPIO.cleanup()
7. ANALOG TEMPERATURE SENSOR
INTERFACING
Objective
To measure the Temperature Value using LM35 Sensor.

Program:
import RPi.GPIO as GPIO temp = ((data *330)/float(1023))-5
import spidev temp = round(temp,places)
import time return temp
import os temp_channel = 1
GPIO.setwarnings(False) delay = 2
spi = spidev.SpiDev() while True:
spi.open(0,0) temp_level =
def ReadChannel(channel): ReadChannel(temp_channel)
adc = temp_volts =
spi.xfer2([1,(8+channel)<<4,0]) ConvertVolts(temp_level,2)
data= ((adc[1]&3) << 8) + adc[2] temp = ConvertTemp(temp_level,2)
return data print
def ConvertVolts(data,places): "_______________________________
volts = (data * 3.3) / float(1023) _____________"
volts = round(volts,places) print ("Temp : {} ({}V) {} deg
return volts C".format(temp_level,temp_volts,temp))
def ConvertTemp(data,places): time.sleep(delay)
10
8. POTENTIOMETER/LDR INTERFACING
About the Project:

To measure the analog Value using Potentiometer.

CODING:
import RPi.GPIO as GPIO return volts
import spidev light_channel = 0
import time delay = 2
import os while True:
GPIO.setwarnings(False) light_level =
spi = spidev.SpiDev() ReadChannel(light_channel)
spi.open(0,0) light_volts =
def ReadChannel(channel): ConvertVolts(light_level,2)
adc =
spi.xfer2([1,(8+channel)<<4,0]) print"_______________________
data= ((adc[1]&3) << 8) + adc[2] _____________________"
return data print ("Light: {}
({}V)".format(light_level,light_volts)
def ConvertVolts(data,places): )
volts = (data * 3.3) / float(1023)
volts = round(volts,places) time.sleep(delay)

11
9. ACCELEROMETER INTERFACING
Objective:

To measure the X,Y,and Z axis value using ADXL335 and MCP3008

Program:
import RPi.GPIO as GPIO adc_out=((r[1]&3)<<8)+r[2]
import spidev return adc_out
import time while True:
import os X = ReadChannel(0)
GPIO.setwarnings(False) Y = ReadChannel(1)
spi = spidev.SpiDev() Z = ReadChannel(2)
spi.open(0,0)
def ReadChannel(channel): print("X=%d\ty=%d\tZ=%d"%(X,Y,
Z))
r=spi.xfer2([1,(8+channel)<<4,0]) time.sleep(delay)

DIY:

1. Design a system to direct the robot to Right, Left, Forward, Back.

12
11. SERVOMOTOR INTERFACING

Objective:

To Control the angle moment using Servomotor.

Program:
import RPi.GPIO as GPIO ck=0
import time while ck<=5:
GPIO.setmode(GPIO.BOARD) pwm.ChangeDutyCycle(duty1)
GPIO.setup(22, GPIO.OUT) time.sleep(0.8)
pwm=GPIO.PWM(22,100) pwm.ChangeDutyCycle(duty2)
pwm.start(5) time.sleep(0.8)
angle1=20 ck=ck+1
duty1=float(angle1)/10+2.5 time.sleep(1)
angle2=160 GPIO.cleanup()
duty2=float(angle2)/10+2.5

13
IoT Implementations
1. HOME AUTOMATION USING RASPBERRY PI
Objective:

To control the Devices Interfaced with Rpi over Web or App.

Program
#!/usr/bin/python
import RPi.GPIO as GPIO
import urllib2
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(5,GPIO.OUT)
while True:
try:

response=urllib2.urlopen('http://uxbusinesssolutions.com//buttonStatu
s.php')
status=response.read()
except urllib2.HTTPError, e:
print e.code
except urllib2.URLError, e:
print e.args

print status
if status=='ON':
GPIO.output(5,True)
print "ON"
elif status=='OFF':
GPIO.output(5,False)
print "OFF"

DYI: Design and Implement a Smart Home Application for Controlling Home
Appliances like Lights, Fans or any AC Devices
14
2. Temperature Data Logging Using Ultrasonic
Sensor
Objective:
Acquire data from a Switch and update it in thingspeak.com
Program:

import RPi.GPIO as GPIO


import urllib,httplib
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
TRIG = 16
ECHO = 18
GPIO.setup(TRIG, GPIO.OUT)
GPIO.setup(ECHO, GPIO.IN)
GPIO.output(TRIG, False)
while True:
print "waiting for sensor to settle"
time.sleep(2)
GPIO.output(TRIG, True)
time.sleep(0.00001)
GPIO.output(TRIG, False)
while GPIO.input(ECHO)==0:
pulse_start = time.time()
while GPIO.input(ECHO)==1:
pulse_end = time.time()
pulse_duration = pulse_end - pulse_start
distance = pulse_duration * 17150
distance=round(distance, 2)
params =
urllib.urlencode({'field1':distance,'key':'BE502C47YYZ0SYIG'})
headers = {"Content-typZZe": "application/x-www-form-
urlencoded","Accept": "text/plain"}
15
conn = httplib.HTTPConnection("api.thingspeak.com:80")
try:
conn.request("POST", "/update", params, headers)
response = conn.getresponse()
conn.close()
print "distance:",distance,"cm"
except:
print "connection failed"

3. UPLOAD DIGITAL SENSOR DATA IN


THINGSPEAK USING NodeMCU
Note:
1. Create Account in Thingspeak.com
2. Write a program to upload sensor data in thingspeak using Arduino IDE.
Collect the Sensor Data from thingspeak.com

Program:
#include <ESP8266WiFi.h> Serial.println("");
String apiKey = "0LUFJSN3W1YA19IG"; Serial.println("WiFi conected");
const char* ssid = "xxxxxxxxxxx"; }
const char* password = "xxxxxxxxx"; void loop() {
const char* server = // put your main code here, to run
"api.thingspeak.com"; repeatedly:
int buttonState = 0; buttonState = digitalRead(2);
WiFiClient client; if (buttonState==HIGH)
void setup() { {
pinMode(2, INPUT); Serial.print("Switch ON");}
Serial.begin(115200); else
delay(10); { Serial.print("Switch OFF");
WiFi.begin(ssid, password); }
Serial.println();
Serial.println(); if (client.connect(server,80)){
Serial.print("Connecting to"); String postStr = apiKey;
Serial.println(ssid); postStr +="&field2=";
WiFi.begin(ssid, password); postStr += String(buttonState);
while (WiFi.status() != postStr += "\r\n\r\n";
WL_CONNECTED){ client.print("POST /update
delay(500); HTTP/1.1\n");
Serial.print("."); client.print("Host:
} api.thingspeak.com\n");
16
client.print("Connection: close\n"); Serial.print(buttonState);
client.print("X-THINGSPEAKAPIKEY: Serial.println("% send to Thingspeak");
"+apiKey+"\n"); }
client.print("Content-Type: client.stop();
application/x-www-form-urlencoded\n"); Serial.println("waiting...");
client.print("Content-Length: "); delay(5);
client.print(postStr.length()); }
client.print("\n\n");
client.print(postStr);

4. UPLOAD ANALOG SENSOR DATA IN


THINGSPEAK USING Node MCU
Note:
1. Create Account in Thingspeak.com
2. Write a program to upload sensor data in thingspeak using Arduino IDE.
3. Collect the Sensor Data from thingspeak.com

Program:
#include <ESP8266WiFi.h> while (WiFi.status() != WL_CONNECTED){
// replace with your channel's thingspek API delay(500);
key Serial.print(".");
String apiKey = "SLMSXB6DU4NV3C2L"; }
const char* ssid = "xxxxxxxxxx"; Serial.println("");
const char* password = "xxxxxxxxxxx"; Serial.println("WiFi conected");
}
const char* server = "api.thingspeak.com";
float temp = 0;
int analog = 0;
WiFiClient client; void loop() {
void setup() { // put your main code here, to run
// put your setup code here, to run once: repeatedly:
Serial.begin(115200); analog = analogRead(17);
delay(10); float temp = analog * 0.2785;
WiFi.begin(ssid, password); if (client.connect(server,80)){
Serial.println(); String postStr = apiKey;
Serial.println(); postStr +="&field1=";
Serial.print("Connecting to"); postStr += String(temp);
Serial.println(ssid); postStr += "\r\n\r\n";
WiFi.begin(ssid, password); client.print("POST /update HTTP/1.1\n");

17
client.print("Host: api.thingspeak.com\n"); Serial.print(temp);
client.print("Connection: close\n"); Serial.println("% send to Thingspeak");
client.print("X-THINGSPEAKAPIKEY: }
"+apiKey+"\n"); client.stop();
client.print("Content-Type: application/x- Serial.println("waiting...");
www-form-urlencoded\n"); delay(5);
client.print("Content-Length: "); }
client.print(postStr.length());
client.print("\n\n");
client.print(postStr);
Serial.print("Temperature");

Setting up Raspberry Pi as WIFI Access Point


Setting up Rpi as server:
• ifconfig –a
• Install software:
– sudo apt-get update
– sudo apt-get install hostapd isc-dhcp-server
– Enter y
– sudo apt-get install iptables-persistent
– Enter y ………………… Enter yes
• Set up DHCP server:
– sudo nano /etc/dhcp/dhcpd.conf
– Find the lines that say
– option domain-name "example.org";
– option domain-name-servers ns1.example.org, ns2.example.org;
and change them to add a # in the beginning so they say
• #option domain-name "example.org";
#option domain-name-servers ns1.example.org, ns2.example.org;
• Find the lines that say
– # If this DHCP server is the official DHCP server for the local
– # network, the authoritative directive should be uncommented.
– #authoritative;
– and remove the # so it says
– # If this DHCP server is the official DHCP server for the local
– # network, the authoritative directive should be uncommented.
– authoritative;
18
– Then scroll down to the bottom and add the following lines
subnet 192.168.42.0 netmask 255.255.255.0 {
range 192.168.42.10 192.168.42.50;
option broadcast-address 192.168.42.255;
ption routers 192.168.42.1;
default-lease-time 600;
max-lease-time 7200;
option domain-name "local";
option domain-name-servers 8.8.8.8, 8.8.4.4;
• }
• Control X -Y
• Run sudo nano /etc/default/isc-dhcp-server
• scroll down to INTERFACES="" and update it to say INTERFACES="wlan0“
• Close and save
• Set up wlan0 for static IP
• run sudo ifdown wlan0
• Run sudo nano /etc/network/interfaces
• to edit the file
Find the line auto wlan0 and add a # in front of the line, and in front of every line
afterwards.
auto lo
iface lo inet loopback
iface eth0 inet dhcp
allow-hotplug wlano
iface wlan0 inet static
address 192.168.42.1
netmask 255.255.255.0
Control X-Y
• Assign a static IP address to the wifi adapter by running
sudo ifconfig wlan0 192.168.42.1
• Configure Access Point
• Now we can configure the access point details. We will set up a password-protected
network so only people with the password can connect.
Create a new file by running sudo nano /etc/hostapd/hostapd.conf

19
• Paste the following in, you can change the text after ssid= to another name, that will be
the network broadcast name. The password can be changed with the text
after wpa_passphrase=
interface=wlan0
#driver=rtl871xdrv
ssid=Pi_AP
country_code=US
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=Raspberry
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
wpa_group_rekey=86400
ieee80211n=1
wme_enabled=1
• If you are using the Raspberry Pi 3's internal WiFi adapter, comment out
the driver=rtl871xdrv line altogether:
• Now we will tell the Pi where to find this configuration file. Run sudo nano
/etc/default/hostapd
Find the line #DAEMON_CONF="" and edit it so it
says DAEMON_CONF="/etc/hostapd/hostapd.conf"
Don't forget to remove the # in front to activate it!
Likewise, run sudo nano /etc/init.d/hostapd and find the line
DAEMON_CONF=
and change it to
DAEMON_CONF=/etc/hostapd/hostapd.conf
• Configure Network Address Translation
– Run sudo nano /etc/sysctl.conf
• Scroll to the bottom and add
net.ipv4.ip_forward=1
• on a new line. Save the file. This will start IP forwarding on boot up

20
• Also run
• sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
• to activate it immediately
• Run the following commands to create the network translation between the ethernet
port eth0 and the wifi port wlan0
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state
RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT
• You can check to see whats in the tables with
• sudo iptables -t nat -S
sudo iptables -S
• To make this happen on reboot (so you don't have to type it every time) run
sudo sh -c "iptables-save > /etc/iptables/rules.v4“
• First test!
• Finally we can test the access point host! Run
• sudo /usr/sbin/hostapd /etc/hostapd/hostapd.conf
• Removing WPA-Supplicant
• Depending on your distro, you may need to remove WPASupplicant. Do so by running
this command:
• sudo mv /usr/share/dbus-1/system
services/fi.epitest.hostap.WPASupplicant.service ~/
and then rebooting (sudo reboot) and retrying running hostapd
• Finishing up!
• OK now that we know it works, time to set it up as a 'daemon' - a program that will start
when the Pi boots.
Run the following commands
• sudo service hostapd start
sudo service isc-dhcp-server start
• you can always check the status of the host AP server and the DHCP server with
• sudo service hostapd status
• To start the daemon services. Verify that they both start successfully (no 'failure' or
'errors')
Then to make it so it runs every time on boot
• sudo update-rc.d hostapd enable
sudo update-rc.d isc-dhcp-server enable
21
5. WIFI SENSOR MODULE IMPLEMENTATION
Note:
1. Set ting up Raspberrypi as a Router(Access Point)
2. Choose NODE MCU ESP8266 wifi as Sensor node.
3. Write the program to make TCP Communication establishment between the
Rpi and Sensor using arduino IDE.
4. Give thefollowing command in Raspberrypi LXterminal:
nc –l –k portnumber
ex: nc –l –k 5001

Program :

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h> if (!client.connect(host, port)) {
Serial.println("connection failed");
ESP8266WiFiMulti WiFiMulti; Serial.println("wait 5 sec...");
void setup() { delay(5000);
Serial.begin(115200); return;
delay(10); }
WiFiMulti.addAP("Pi_AP", int analog = analogRead(17);
"Raspberry"); float temp = analog*(285.0/1024.0);
Serial.print("Wait for WiFi... "); client.print("Sensor Node : ");
while(WiFiMulti.run() != client.print(temp);
WL_CONNECTED) client.print("C");
{ String line = clie
Serial.print("."); nt.readStringUntil('\r');
delay(500); client.println(line);
} Serial.println("closing connection\n");
Serial.println(""); client.stop();
Serial.println("WiFi connected"); delay(1000);
Serial.println("IP address: "); }
Serial.println(WiFi.localIP());
delay(500);
}
void loop() {

const uint16_t port = 5001;


const char * host = "192.168.42.1";
Serial.print("connecting to ");
Serial.println(host);
WiFiClient client;
22
Raspbery pi publishing MQTT Messages to Node MCU
Step 1:
How to Install Mosquitto Broker on Raspberry Pi
Installing Mosquitto Broker on Raspbian Stretch

pi@raspberry:~ $ sudo apt update


pi@raspberry:~ $ sudo apt install -y mosquitto mosquitto-clients

You’ll have to type Y and press Enter to confirm the installation. To make Mosquitto auto start
on boot up enter:
pi@raspberry:~ $ sudo systemctl enable mosquitto.service

Testing Installation
Send the command:
pi@raspberry:~ $ mosquitto -v
This returns the Mosquitto version that is currently running in your Raspberry Pi. It should be
1.4 or above.

Note: sometimes the command mosquitto -v prompts a warning message saying “1484326030: Error:
Address already in use”. That warning message means that your Mosquitto Broker is already running,
so don’t worry about that.

Wrapping up
Testing Mosquitto Broker and Client on Raspbbery Pi
Subscribing to testTopic Topic
To subscribe to an MQTT topic with Mosquitto Client open a terminal Window #1 and enter the
command:
23
pi@raspberry:~ $ mosquitto_sub -d -t testTopic

Publishing “Hello World!” Message to testTopic Topic


To publish a sample message to testTopic, open a terminal Window #2 and run this command:
pi@raspberry:~ $ mosquitto_pub -d -t testTopic -m "Hello world!"

The message “Hello World!” is received in Window #1 as illustrated in the figure above.

24
Publishing a Message to Multiple Clients
Having Window #1 still subscribed to topic testTopic, open a new terminal Window #3 and run
this command to subscribe to testTopic topic:
pi@raspberry:~ $ mosquitto_sub -d -t testTopic
On Window #2 publish the “Hello World!” message:
pi@raspberry:~ $ mosquitto_pub -d -t testTopic -m "Hello world!"

25
Since two clients are subscribed to testTopic topic, they will both receive “Hello
world!”message.
This simple example shows how MQTT works and how your devices (for example: ESP8266)
could be subscribed to the same topic to receive messages or a device could publish messages
to multiple devices. We’ll explore this concept further in future blog posts.
Python web server with Flask
We’re going to use a Python microframework called Flask to turn the Raspberry Pi into web
server.
To install Flask, you’ll need to have pip installed. Run the following commands to update your Pi
and install pip:
pi@raspberrypi ~ $ sudo apt-get update
pi@raspberrypi ~ $ sudo apt-get upgrade
pi@raspberrypi ~ $ sudo apt-get install python-pip python-flask
Then, you use pip to install Flask and its dependencies:
pi@raspberrypi ~ $ sudo pip install flask

Installing Python Paho-MQTT

The Paho-MQTT package provides a client class which enable applications to connect to an
MQTT broker to publish messages, and to subscribe to topics and receive published messages.
In this example, the Python web server is going to publish messages to the ESP8266 to turn the
GPIOs on and off.
To install paho-mqtt run the following command:
pi@raspberrypi ~ $ sudo pip install paho-mqtt

Creating the Python Script

This is the core script of our application. It sets up the web server and when these buttons are
pressed it publishes an MQTT message to the ESP8266.
To keep everything organized, start by creating a new folder:
pi@raspberrypi ~ $ mkdir web-server
pi@raspberrypi ~ $ cd web-server
pi@raspberrypi:~/web-server $
26
Create a new file called app.py.
pi@raspberrypi:~/web-server $ nano app.py
Copy and paste the following script to your Raspberry Pi

#
# Created by Rui Santos
# Complete project details: http://randomnerdtutorials.com
#
import paho.mqtt.client as mqtt
from flask import Flask, render_template, request
app = Flask(__name__)

mqttc=mqtt.Client()
mqttc.connect("localhost",1883,60)
mqttc.loop_start()
# Create a dictionary called pins to store the pin number, name, and
pin state:
pins = {
4 : {'name' : 'GPIO 4', 'board' : 'esp8266', 'topic' : 'esp8266/4',
'state' : 'False'},
5 : {'name' : 'GPIO 5', 'board' : 'esp8266', 'topic' : 'esp8266/5',
'state' : 'False'}
}
# Put the pin dictionary into the template data dictionary:
templateData = {
'pins' : pins
}
27
@app.route("/")
def main():
# Pass the template data into the template main.html and return it
to the user
return render_template('main.html', **templateData)
# The function below is executed when someone requests a URL with the
pin number and action in it:
@app.route("/<board>/<changePin>/<action>")
def action(board, changePin, action):
# Convert the pin from the URL into an integer:
changePin = int(changePin)
# Get the device name for the pin being changed:
devicePin = pins[changePin]['name']
# If the action part of the URL is "on," execute the code indented
below:
if action == "1" and board == 'esp8266':
mqttc.publish(pins[changePin]['topic'],"1")
pins[changePin]['state'] = 'True'

if action == "0" and board == 'esp8266':


mqttc.publish(pins[changePin]['topic'],"0")
pins[changePin]['state'] = 'False'
# Along with the pin dictionary, put the message into the template
data dictionary:
templateData = {

28
'pins' : pins
}
return render_template('main.html', **templateData)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=8181, debug=True)

Creating the HTML File

Keeping HTML tags separated from your Python script is how you keep your project organized.

Flask uses a template engine called Jinja2 that you can use to send dynamic data from your
Python script to your HTML file.
Create a new folder called templates:

pi@raspberrypi:~/web-server $ mkdir templates


pi@raspberrypi:~/web-server $ cd templates
pi@raspberrypi:~/web-server/templates $
Create a new file called main.html.
pi@raspberrypi:~/web-server/templates $ nano main.html
Copy and paste the following template to your Pi:

Copy and paste the following template to your Pi:

<!DOCTYPE html>
<head>
<title>RPi Web Server</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/boot

29
strap.min.css" integrity="sha384-
1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkz
s7" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/boot
strap-theme.min.css" integrity="sha384-
fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En
5r" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootst
rap.min.js" integrity="sha384-
0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7
xS" crossorigin="anonymous"></script>
<meta name="viewport" content="width=device-width, initial-
scale=1">
</head>

<body>
<h1>RPi Web Server - ESP8266 MQTT</h1>
{% for pin in pins %}
<h2>{{ pins[pin].name }}
{% if pins[pin].state == 'True' %}
is currently <strong>on</strong></h2><div
class="row"><div class="col-md-2">
30
<a href="/esp8266/{{pin}}/0" class="btn btn-block btn-lg
btn-default" role="button">Turn off</a></div></div>
{% else %}
is currently <strong>off</strong></h2><div
class="row"><div class="col-md-2">
<a href="/esp8266/{{pin}}/1" class="btn btn-block btn-lg
btn-primary" role="button">Turn on</a></div></div>
{% endif %}
{% endfor %}
</body>
</html>

Programming the ESP8266


For the ESP8266 to interact with the Raspberry Pi web server, you need to
install PubSubClient library. This library provides a client for doing simple
publish/subscribe messaging with a server that supports MQTT (basically allows
your ESP8266 to talk with Python web server).

Installing the Library


1) Click here to download the PubSubClient library. You should have a .zip folder in your
Downloads folder
2) Unzip the .zip folder and you should get pubsubclient-master folder
3) Rename your folder from pubsubclient-master to pubsubclient
4) Move the pubsubclient folder to your Arduino IDE installation libraries folder
5) Then, re-open your Arduino IDE
The library comes with a number of example sketches.
See File > Examples > PubSubClient within the Arduino IDE software.

31
Uploading sketch
Finally, you can upload the full sketch to your ESP8266 (replace with your SSID, password and
RPi IP address):

/*****

All the resources for this project:


https://randomnerdtutorials.com/

*****/

// Loading the ESP8266WiFi library and the PubSubClient


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

// Change the credentials below, so your ESP8266 connects to


your router
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";

// Change the variable to your Raspberry Pi IP address, so it


connects to your MQTT broker
const char* mqtt_server = "YOUR_RPi_IP_Address";

// Initializes the espClient

32
WiFiClient espClient;
PubSubClient client(espClient);

// Connect an LED to each GPIO of your ESP8266


const int ledGPIO5 = 5;
const int ledGPIO4 = 4;

// Don't change the function below. This functions connects


your ESP8266 to your router
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("WiFi connected - ESP IP address: ");
Serial.println(WiFi.localIP());
}

// This functions is executed when some device publishes a


33
message to a topic that your ESP8266 is subscribed to
// Change the function below to add logic to your program, so
when a device publishes a message to a topic that
// your ESP8266 is subscribed you can actually do something
void callback(String topic, byte* message, unsigned int
length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;

for (int i = 0; i < length; i++) {


Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();

// Feel free to add more if statements to control more GPIOs


with MQTT

// If a message is received on the topic


home/office/esp1/gpio2, you check if the message is either 1
or 0. Turns the ESP GPIO according to the message
if(topic=="esp8266/4"){
Serial.print("Changing GPIO 4 to ");
if(messageTemp == "1"){
34
digitalWrite(ledGPIO4, HIGH);
Serial.print("On");
}
else if(messageTemp == "0"){
digitalWrite(ledGPIO4, LOW);
Serial.print("Off");
}
}
if(topic=="esp8266/5"){
Serial.print("Changing GPIO 5 to ");
if(messageTemp == "1"){
digitalWrite(ledGPIO5, HIGH);
Serial.print("On");
}
else if(messageTemp == "0"){
digitalWrite(ledGPIO5, LOW);
Serial.print("Off");
}
}
Serial.println();
}

// This functions reconnects your ESP8266 to your MQTT broker


// Change the function below if you want to subscribe to more
topics with your ESP8266
void reconnect() {
35
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
/*
YOU NEED TO CHANGE THIS NEXT LINE, IF YOU'RE HAVING
PROBLEMS WITH MQTT MULTIPLE CONNECTIONS
To change the ESP device ID, you will have to give a
unique name to the ESP8266.
Here's how it looks like now:
if (client.connect("ESP8266Client")) {
If you want more devices connected to the MQTT broker,
you can do it like this:
if (client.connect("ESPOffice")) {
Then, for the other ESP:
if (client.connect("ESPGarage")) {
That should solve your MQTT multiple connections problem

THE SECTION IN loop() function should match your device


name
*/
if (client.connect("ESP8266Client")) {
Serial.println("connected");
// Subscribe or resubscribe to a topic
// You can subscribe to more topics (to control more
LEDs in this example)
36
client.subscribe("esp8266/4");
client.subscribe("esp8266/5");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}

// The setup function sets your ESP GPIOs to Outputs, starts


the serial communication at a baud rate of 115200
// Sets your mqtt broker and sets the callback function
// The callback function is what receives messages and
actually controls the LEDs
void setup() {
pinMode(ledGPIO4, OUTPUT);
pinMode(ledGPIO5, OUTPUT);

Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
37
// For this project, you don't need to change anything in the
loop function.
// Basically it ensures that you ESP is connected to your
broker
void loop() {
if (!client.connected()) {
reconnect();
}
if(!client.loop())
/*
YOU NEED TO CHANGE THIS NEXT LINE, IF YOU'RE HAVING
PROBLEMS WITH MQTT MULTIPLE CONNECTIONS
To change the ESP device ID, you will have to give a
unique name to the ESP8266.
Here's how it looks like now:
client.connect("ESP8266Client");
If you want more devices connected to the MQTT broker,
you can do it like this:
client.connect("ESPOffice");
Then, for the other ESP:
client.connect("ESPGarage");
That should solve your MQTT multiple connections problem

THE SECTION IN recionnect() function should match your


device name
38
*/
client.connect("ESP8266Client");
}

Launching the Web Server


To launch your Raspberry Pi web server move to the folder that contains the file app.py:
pi@raspberrypi:~/web-server/templates $ cd ..
Then, run the following command:

pi@raspberrypi:~/web-server $ sudo python app.py


Your web server should start immediately on port : 8181!

Demonstration
Open your Raspberry Pi address in your browser by entering its IP address, in my
case: http://192.168.1.98:8181

39

You might also like