In the previous tutorial, FTP protocol and file transfer over it between a Client and Server was discussed. The FTP protocol can really useful in many IoT applications. Many IOT devices are installed in places like nuclear plant, electrical grids and other industrial setups where these types of devices can get some bugs and need application software updates to fix them. On standard IoT protocols like MQTT, CoAP, etc, it is hard to update and reinstall application software because most of the IoT protocols are designed for IoT communication between devices and network but not for tasks like application updates. The application update on an IoT device is only possible over TCP/IP stack. The FTP protocol is the specifically designed protocol over TCP/IP stack for file transfer between a client and a server. So, it can be used by an IoT device to download updated application software and reinstall it once downloaded.
In this project, a Raspberry Pi is used as an IoT device which is running a simple python application to blink an LED. So, the IoT device designed in this project is a Raspberry Pi interfaced with an LED. One another python application also keeps running on the daughter board which keeps looking for an update of the LED blinking code from a FTP server. The Update seeking application connects with the FTP server and tracks the version number of the LED blinking code available at the FTP server. If the version number of the LED blinking code is changed, the update seeking code downloads the updated code and reinstall it on the Raspberry Pi. The update process takes place automatically and does not require any human intervention. So, uploading and downloading files from FTP is reliable and fast that many applications uses FTP in update severs.
Components Required –
1) Raspberry Pi 3
2) LED
3) 1K Ω Resistor
4) Jumper Wires
Software Required –
1) Raspbian OS
2) Leafpad/GNU Nano/Python 3 IDLE (for writing python scripts)
Block Diagram –
Fig. 1: Block Diagram of Raspberry Pi 3 based IoT FTP Client
Circuit Connections –
A simple IOT device is designed in this project. It has an LED interfaced with the Raspberry Pi 3. The device is designed by assembling the following components together.
Raspberry Pi 3 – Raspberry Pi 3 is the third generation Raspberry Pi. It is a miniature marvel, packing considerable computing power into a footprint no larger than a credit card. The processor at the heart of the Raspberry Pi system is a Broadcom BCM2837 system-on-chip (SoC) which houses a 1.2 GHz Quad Core ARM Cortex-A53 processor. The vast majority of the system’s components, including its central and graphics processing units along with the audio and communications hardware, are built onto that single component along with 1 GB LPDDR2 memory chip at the centre of the board. It is not just this SoC design that makes the BCM2837 different to the processor found in a typical desktop or laptop, however, it also uses a different instruction set architecture (ISA), known as ARM.
The Pi comes equipped with on-board 10/100 BaseT Ethernet Socket, HDMI and Composite RCA port for video, 3.5 mm audio output jack, 15-pin MIPI Camera Serial Interface (CSI-2), Display Serial Interface, Bluetooth 4.1, 802.11 b/g/n Wireless LAN, Micro SDIO for Micro SD Card, 4 USB 2.0 Connectors, 40 pin header containing 27 GPIO pins and Micro USB socket for power supply.
The Raspberry Pi is a single board computer and is designed to run an operating system called GNU/Linux Raspbian. Hereafter referred to simply as Linux. Unlike Windows or OS X, Linux is open source, so it is possible to download the source code for the entire operating system and make whatever changes desired. The Raspberry Pi 3 can also run Windows 10 IoT and many other embedded operating systems most of which are Linux derivatives. The operating system should be loaded in a MicroSD card and boot from it. With powerful computing resources, large number of multimedia interfaces and GPIO pins, Raspberry Pi 3 is a suitable choice to run a software oriented complex IoT or Embedded project that requires sufficient computing power as well as large scale sensor connectivity. With on-board Bluetooth and Wi-Fi, this 3rd generation Pi can be easily deployed in an IoT network. The key specifications of the Raspberry Pi 3 are summarized in the following table –
Fig. 2: Table listing technical specifications of Raspberry Pi 3
The 40-pin header on Raspberry Pi 3 has the following pin configuration –
Fig. 3: Table listing pin configuration of 40-pin header of Raspberry Pi
Fig. 4: Table listing pin configuration of 40-pin header of Raspberry Pi
In this project, an LED is interfaced to GPIO18 pin of the Raspberry Pi. The board is powered by an USB adapter.
LED – An LED is connected at GPIO18 of the Raspberry Pi. Its anode is connected to Raspberry Pi pin and cathode is cathode is connected to ground. The LED is connected to Pi via a 1K ohm pull-up resistor in series.
Power Supply – The power source is connected to the Raspberry Pi. The Pi should be powered by a 5V adapter with 2.5 A current output. The adaptor can be connected at Micro USB socket.
How the circuit works –
The IoT device designed here is simply a Raspberry Pi 3 controlling an LED. For controlling the LED and keeping the Pi connected to a FTP server, two separate python scripts need to be run on the daughter board. One python script controls the LED blinking and another python script manages to automatically update the LED blinking script. First of all, the Raspberry Pi needs to loaded with an operating system. Here the official operating system for the Raspberry Pi – Linux Raspbian is installed on it. While installing the operating system, the Raspberry Pi should be connected to a display monitor using HDMI cable and a keyboard and mouse through USB ports.
For installing the Raspbian Operating System on MicroSD card, first download the latest image of Raspbian OS from Raspberry Pi website from the following link –
Copy the image of the latest Raspbian OS in the MicroSD card. If the MicroSD card used is 32 GB or below, it must be formatted to FAT32 (file system) before copying the image or if the MicroSD card is more than 32 GB, it should be formatted to exFAT before copying the image. Extract the OS Zip and copy it to the MicroSD card. The image can be written to the card by connecting the card to a laptop or PC using a MicroSD card reader. After copying the extracted image, insert the card in the MicroSD slot as shown below –
Fig. 5: Typical Image of Raspberry Pi 3 MicroSD Card Slot
Connect the Raspberry Pi with a display monitor using HDMI Cable, a keyboard and a mouse. Power on the board by connecting to a power adaptor. The red LED on the board will start blinking and the OS will start booting from the MicroSD card. The boot process will display on the monitor and once the boot is complete, green LED will light up on the Raspberry Pi. After successfully installing Raspbian OS on Raspberry Pi, it is recommended to perform software update. It can be done by running the following Linux commands in the Linux Terminal –
$ sudo apt-get update
$ sudo apt-get upgrade
After installing the Raspbian, it’s time to write and run the python scripts on Raspbian. A python script can be written on Raspbian using a text editor like Leafpad or GNU Nano. The python script can also be written using the default python IDE like Python 2 IDLE or Python 3 IDLE. Open the Python 3 IDLE by navigating through Menu -> Programming -> Python 3 IDLE. A window called Python 3.4.2 Shell will open up. Write the python scripts and save them to a directory.
The python script written for this project should run at the startup as the Pi 3 is powered on. The script runs an infinite loop so it never ends. There are some methods by which the Raspberry Pi can be configured to run a python script on start up. Any of the following methods can be used –
1) Editing rc.local –
The commands can be added to the file /etc/rc.local to run a program or command when the raspberry Pi boots up. This is especially useful if the Pi has to plug in to power headless, and have it run a program without configuration or a manual start. The file should be edited with root by running the following commands in the Linux Terminal –
sudo nano /etc/rc.local
Now add commands to execute the python script using complete file path and add an ampersand at the end of the command so that the script runs in a separate process and booting could continue. The following command should be added where the python scripts are saved as FTP.py and CODE.py-
sudo python /home/pi/FTP.py &
exit 0
The command should be added just before the line exit 0 in the rc.local file.
2) Editing .bashrc –
The .bashrc is a hidden file in the home folder that contains user configuration options. Open the .bshrc file by running the following commands in the Linux terminal –
sudo nano /home/pi/.bashrc
Add the following lines after the last line in the file –
echo Running at boot
sudo python /home/pi/FTP.py
3) Adding script to init.d directory –
The init.d directory contains the scripts which are started during the boot process (in addition, all programs here are executed when Pi is shutdown or rebooted). Add the script to be run at startup to the init.d directory using the following commands –
sudo cp /home/pi/securitysystem.py /etc/init.d/
Move to the init directory and open the python script by running the following commands –
cd /etc/init.d
sudo nano FTP.py
Add the following lines to the python script to make it a Linux Standard Base (LSB) –
# /etc/init.d/sample.py
### BEGIN INIT INFO
# Provides: sample.py
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time
# Description: Enable service provided by daemon.
### END INIT INFO
Make the python script in the init directory executable by changing its permission by running the following command –
sudo chmod +x FTP.py
Then run the following command –
sudo update-rc.d FTP.py defaults
Next reboot the Pi by running the following command –
sudo reboot
Any of the above methods can be used to make the python script run on startup. Now the Pi 3 can be disconnected with the display monitor, keyboard and mouse. Interface the LED with the Raspberry Pi and power it up.
Now when the Pi will power up, it will run both the scripts on start up. The main script (CODE.py) controls the blinking of LED. It let the LED blink over a period of few seconds. The other script (FTP.py) keeps checking for file on FTP server for version of the main file. The file checked by the script and containing version number is named as ‘Readme.txt’ and simply contains version number of the LED Blinking script as plain text. If update script (FTP.py) finds any changes in the version indication file (Readme.txt) on FTP server, which means the application file is changed, (in which case the period of blinking led could have been changed in CODE.py uploaded to FTP server), it indicates that new version of the main file is available. Now the updated version of the main file is downloaded from FTP server. After downloading, the main script is restarted so the changes can take effect and thus the led blink duration is then changed.
The FTP.py runs on the startup and checks for the application code (CODE.py) from the FTP server. The FTP.py itself manages to download, install and run the main code i.e. CODE.py.
Programming Guide –
There are two python scripts written which run on the startup. One of the python script simply blinks LED connected to the Raspberry Pi and it is saved as CODE.py. This script begins with importing required libraries – RPi.GPIO library for handing digital input and output and time library for time delays. RPi.GPIO is a module to control Raspberry Pi GPIO channels. There may be more than one script/circuit on the GPIO of the Raspberry Pi. As a result of this, if RPi.GPIO detects that a pin has been configured to something other than the default (input), it may give a warning when the Pi tries to configure the script. To disable these warnings, false argument is passed to setwarning() method. A variable is initialized which is set to 24. The GPIO numbering system is set to BCM which refers to the channel numbers on Broadcom SoC. The BCM channel number 24 is configured as GPIO output using the setup() method and it is set to LOW using output() method. An infinite loop is run in which the GPIO output is set to HIGH and LOW alternatively using output() method and time delay is provided using sleep() method of time module which accepts delay interval as parameter in milliseconds.
The second file (FTP.py) is the update script. The application file can be any script file which in this case is CODE.py. The update script is divided into four parts –
1. Setting FTP server
2. Connecting to FTP server
3. Downloading Version file and comparing
4. Downloading the Application File and restarting the Application
1. Setting Server: The FTP server must contain two files, readme.txt (Which contains the version information) and code.py (Containing Main application code file). Any open FTP server like www.biz.nf can be used for web hosting. Create an account there and just upload those two files.
2. Connecting to FTP server: To connect to FTP server a python library that supports FTP commands “ftplib” is imported. It should be imported into top of the update script.
import ftplib as ftp
To connect to ftp server, the connection is started on a session variable. The server address and its username and password are provided to the variable.
session = ftp.FTP(‘192.168.1.100′,’iot_user’,’123123123′)
3. Downloading the Version File and Comparing: The readme file on server contains information about the current version of the Application code. Also in the update script, current version is defined with a variable.
c_version = “1”
The readme file from FTP server is downloaded and stored into a variable “version”. The file is opened and read to detect version number.
with open(‘README.txt’, ‘r’) as myfile:
version=myfile.read().replace(‘n’, ”)
After storing, the version variables are compared and if changes are found, the downloading process of Application code from FTP server is initiated.
if(version != c_version):
global c_version
c_version = version
4. Downloading the Application File and restarting the Application: After the comparison between version and detection of version change, the download of updated Code.py from FTP server is initiated.
session.retrbinary(‘RETR CODE.py’, open(‘CODE.py’, ‘wb’).write)
The file is retrieved and stored as the same name as the main Application file. First the running application is killed.
check_kill_process(“CODE.py”)
Then, a separate thread is started to restart the application.
start = ‘sudo python CODE.py’
proc = subprocess.Popen(start, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
So, this is how the FTP protocol can be used in an IOT application for automatic application update. Check out the python scripts from the code section and try them out. In the next tutorial, learn about SFTP Protocol. SFTP is a secure variant of FTP protocol.
Project Source Code
### //Program to import ftplib as ftp import time import os,signal import subprocess version = "" c_version = "1" session = ftp.FTP('192.168.1.100','iot_user','123123123') #stop = 'sudo kill $(ps aux | grep CODE.py | awk '{{print $2}}')' start = 'sudo python CODE.py' def update(): #ftp.cwd('debian') #session.retrlines('LIST') session.retrbinary('RETR README.txt', open('README.txt', 'wb').write) with open('README.txt', 'r') as myfile: version=myfile.read().replace('n', '') if(version != c_version): global c_version session.retrbinary('RETR CODE.py', open('CODE.py', 'wb').write) c_version = version time.sleep(1) check_kill_process("CODE.py") print "STOP pass" time.sleep(1) proc = subprocess.Popen(start, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) print "START Pass" time.sleep(3) print "UPDATED!" else: time.sleep(5) print "NO UPDATES" def check_kill_process(pstring): for line in os.popen("ps ax | grep " + pstring + " | grep -v grep"): fields = line.split() pid = fields[0] os.kill(int(pid), signal.SIGKILL) while True: try: update() except Exception as e: session.quit() print e ###
Circuit Diagrams
Filed Under: Featured Contributions, IoT tutorials, Tutorials