Tutorial
Tutorial
When you purchase or use Issacnewton RFID Starter Kit for Raspberry Pi, please note the following:
This product contains small parts. Swallowing or improper operation can cause serious infections and death.
Seek immediate medical attention when the accident happened.
Do not allow children under 3 years old to play with or near this product. Please place this product in where
children under 3 years of age cannot reach.
Do not allow children lack of ability of safe to use this product alone without parental care.
Never use this product and its parts near any AC electrical outlet or other circuits to avoid the potential risk of
electric shock.
Never use this product near any liquid and fire.
Keep conductive materials away from this product.
Never store or use this product in any extreme environments such as extreme hot or cold, high humidity and
etc.
Remember to turn off circuits when not in use this product or when left.
Do not touch any moving and rotating parts of this product while they are operating.
Some parts of this product may become warm to touch when used in certain circuit designs. This is normal.
Improper operation may cause excessively overheating.
Using this product not in accordance with the specification may cause damage to the product.
About
Issacnewton is an open-source electronics platform. Issacnewton is committed to helping customer quickly realize
the creative idea and product prototypes, making it easy to get started for enthusiasts of programing and electronics
and launching innovative open source products. Our services include:
Electronic components and modules
Learning kits for Arduino
Learning kits for Raspberry Pi
Learning kits for Technology
Robot kits
Auxiliary tools for creations
References
The references for this product is named Issacnewton RFID Starter Kit for Raspberry Pi, which includes the following
folders and files:
Datasheet Datasheet of electronic components and modules
Code Code for project
Readme.txt Instructions
Support
Issacnewton provides free and quick technical support, including but not limited to:
Quality problems of products
Problems in using products
Questions for learning and technology
Opinions and suggestions
Ideas and thoughts
Copyright
Issacnewton reserves all rights to this book. No copies or plagiarizations are allowed for the purpose of commercial
use.
The code and circuit involved in this product are released as Creative Commons Attribution ShareAlike 3.0. This
means you can use them on your own derived works, in part or completely, as long as you also adopt the same
license. Issacnewton brand is copyright of Issacnewton Creative Technology Co., Ltd and cannot be used without
formal permission.
Contents I
Contents
Contents ........................................................................
.......... I
Preface ..........................................................................
.......... 1 Raspberry
Pi .......................................................................... 2
Install the
System ................................................................ 8
Component
List .........................................................................................................................................................................
8 Optional
Components ...........................................................................................................................................................
10 Raspbian
System ...................................................................................................................................................................
.. 12
Remote desktop &
VNC ....................................................................................................................................................... 15
Chapter 1
LED ................................................................... 42
Project 1.1
Blink ....................................................................................................................................................................... 42
Project 6.2
Alertor ................................................................................................................................................................... 84
What's
next? .................................................................... 271
Preface
Preface
If you want to become a maker, you may have heard of Raspberry Pi or Arduino before. If not, it doesn’t matter.
Through referencing this tutorial, you can be relaxed in using Raspberry Pi to create dozens of electronical interesting
projects, and gradually realize the fun of using Raspberry Pi to complete creative works.
Raspberry Pi and Arduino have a lot of fans in the world. They are keen to exploration, innovation and DIY and they
contributed a great number of high-quality open source code, circuit and rich knowledge base. So we can realize
our own creativity more efficiently by using these free resource. Of course, you can also contribute your own
strength to the resource.
Raspberry Pi, different from Arduino, is more like a control center with a complete operating system, which can deal
with more tasks at the same time. Of course, you can also combine the advantages of them to make something
creative.
Usually, a Raspberry Pi project consists of code and circuit. If you are familiar with computer language and very
interested in the electronic module. Then this tutorial is very suitable for you. It will, from easy to difficult, explain
the Raspberry Pi programming knowledge, the use of various types of electronic components and sensor modules
and their operation principle. And we assign scene applications for most of the module.
We provide code of both C and Python language versions for each project, so, whether you are a C language user or
a Python language user, you are able to easily grasp the code in this tutorial. The supporting kit, contains all the
electronic components and modules needed to complete these projects. After completing all projects in this tutorial,
you can also use these components and modules to achieve your own creativity, like smart home, smart car and
robot.
Additionally, if you have any difficulties or questions about this tutorial and the kit, you can always ask us for quick
and free technical support.
Raspberry Pi
Raspberry Pi (called RPi, RPI, RasPi, the text these words will be used alternately later), a micro-computer with size
of a card, quickly swept the world since its debut. It is widely used in desktop workstation, media center, smart
home, robots, and even the servers, etc. It can do almost anything, which continues to attract fans to explore it.
Raspberry Pi used to be running in Linux system and along with the release of windows 10 IoT. We can also run it in
Windows. Raspberry Pi (with interfaces USB, network, HDMI, camera, audio, display and GPIO), as a microcomputer,
can be running in command line mode and desktop system mode. Additionally, it is easy to operate just like Arduino,
and you can even directly operate the GPIO of CPU.
So far, Raspberry Pi has developed to the third generation. Changes in versions are accompanied by increase and
upgrades in hardware. A type and B type, the first generation of products, have been stopped due to various reasons.
Other versions are popular and active and the most important is that they are consistent in the order and number
of pins, which makes the compatibility of peripheral devices greatly enhanced between different versions.
Here are some practicality pictures and model diagrams of Raspberry Pi:
Practicality picture of Raspberry Pi 3 Model B+: Model diagram of Raspberry Pi 3 Model B+:
Practicality picture of Raspberry Pi 3 Model B: Model diagram of Raspberry Pi 3 Model B:
Practicality picture of Raspberry Pi 1 Model A+: Model diagram of Raspberry Pi 1 Model A+:
Practicality picture of Raspberry Pi Zero W: Model diagram of Raspberry Pi Zero W:
Component List
Required Components
Any Raspberry Pi 5V/2.5A Power Adapter. Different versions of
Raspberry Pi have different power requirements.
In addition, RPi also needs a network cable used to connect it to wide area network.
All of these components are necessary. Among them, the power supply is required at least 5V/2.5A, because lack of
power supply will lead to many abnormal problems, even damage to your RPi. So power supply with 5V/2.5A is highly
recommend. SD Card Micro (recommended capacity 16GB or more) is a hard drive for RPi, which is used to store the
system and personal files. In later projects, the components list with a RPi will contains these required components,
using only RPi as a representative rather than presenting details.
Optional Components
Under normal circumstances, there are two ways to login to Raspberry Pi: using independent monitor, or remote
desktop to share a monitor with your PC.
For different Raspberry Pi, the optional items are slightly different. But all of their aims are to convert the special
interface to standard interface of standard Raspberry Pi.
Micro-USB to USB-A
Receptacles
converter&wire (Micro Yes Yes No No No
USB OTG wire)
Selecting System
Visit RPi official website (https://www.RaspberryPi.org/), click “Downloads” and choose to download “RASPBIAN”.
RASPBIAN supported by RPI is an operating system based on Linux, which contains a number of contents required
for RPi. We recommended RASPBIAN system to beginners. All projects in this tutorial are operated under the
RASPBIAN system.
After download, extract file with suffix (.img). Preparation is ready to start making the system.
Under windows, Raspberry Pi can be generally accessed remotely through two applications. The first one is the
windows built-in application remote desktop, which corresponds to the Raspberry Pi xrdp service. The second one
is the free application VNC Viewer, which corresponds to the VNC interface of Raspberry Pi. Each way has its own
advantages. You can choose either one or two.
Windows Raspberry Pi
Remote Desktop Connection Xrdp
VNC Viewer VNC
VNC Viewer can not only run under Windows, but also under system MAC, Linux, IOS, Android and so on.
SSH
Under previous Raspbian system, SSH is opened by default. Under the latest version of Raspbian system, it is closed
by default. So you need to open it first.
Method: after the system is written. Create a folder named “ssh” under generated boot disk, then the SSH connection
will be opened.
And then, download the tool software Putty. Its official address: http://www.putty.org/
Or download it here: http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
Then use cable to connect your RPi to the routers of your PC LAN, to ensure your PC and your RPi in the same LAN.
Then put the system TF card prepared before into the slot of the RPi and turn on the power supply waiting for starting
RPi. Later, enter control terminal of the router to inquiry IP address named “raspberry pi”. For example, I have
inquired to my RPi IP address, and it is “192.168.1.108". Then open Putty, enter the address, select SSH, and then
click "OPEN", as shown below:
There will appear a security warning at first login. Just click “YES”.
Then there will be a login interface (RPi default user name: pi; the password: raspberry). When you enter the
password, there will be no display on the screen. This is normal. After the correct output, press “Enter” to confirm.
Then enter the command line of RPi, which means that you have successfully login to RPi command line mode.
If you think resolution ratio is not OK, you can set a proper resolution ratio on set interface of Raspberry Pi.
sudo raspi-config
Select 7 Advanced OptionsA5 Resolutionproper resolution ratio(set by yourself)OK. If it needs restart, just
restart.
In addition, your VNC Viewer window may zoom your Raspberry Pi desktop. You can change it. On your VNC View
control panel, click right key. And select Properties->Options label->Scaling. Then set proper scaling.
Here, you have logged in to Raspberry Pi successfully by using VNC Viewer and operated proper setting. Then
continue to do some preparation work: install a GPIO library wiringPi for your RPi.
Wi-Fi
Raspberry Pi 3B+/3B integrates a Wi-Fi adaptor. You can use it to connect to your Wi-Fi. Then you can use the wireless
remote desktop to control your RPi. This will be helpful for the following work. Raspberry Pi of other models can use
wireless remote desktop through accessing an external USB wireless card.
Chapter 0 Preparation
Why is “Chapter 0”? Because in the program code, all the counts are starting from 0. We choose to follow this rule
(just a joke). In this chapter, we will do some necessary preparation work: start your Pi Raspberry and install some
necessary libraries. If your Raspberry Pi can be started normally and used normally, you can skip this chapter.
Install WiringPi
WiringPi is a GPIO access library written in C for the BCM2835/BMC2836/ BMC2837 used in the Raspberry Pi. It’s
released under the GNU LGPLv3 license and is usable from C, C++ and many other languages with suitable wrappers
(See below) It’s designed to be familiar to people who have used the Arduino “wiring” system. (for more details,
please refer to http://wiringpi.com/ )
Chapter 0 Preparation
After the cloning operation is completed, go to the wiring folder and update the latest WiringPi.
cd wiringPi git
pull origin
The new build script will compile and install it all for you. It does use the sudo command at one point, so you may
wish to inspect the script before running it. Run the gpio command to check the installation:
gpio -v gpio
readall
That should give you some confidence that it's working well.
Now Python code of our kits can run on Python2 and Python3. Python3 is recommend. If you want to use python2,
please make sure your Python version is above 2.7. Python2 and Python3 is not fully compatible. However,
Python2.6 and Python2.7 are transition versions to python3. So you can also use Python2.6 and 2.7 to execute some
Python3 code.
You can type python2 and python3 respectively to check if python has been installed. Pree Ctrl-Z to exit.
If you want to set Python3 as default Python actuators. please follow the steps below.
1. Enter directory /usr/bin
cd /usr/bin
2. Delete the old python link.
sudo rm python
3. Creat new python links to python3.
sudo ln –s python3 python
4. Execute python to check whether the link succeeds.
python
If you want to set python2 as default python actuators, repeat above steps and just change the third command to the
following.
sudo ln –s python2 python
We will execute a same python file Hello.py with Python2 and Python3.
First, use Python2 to execute the code.
1. Use cd command to enter 00.0.0_Hello directory of Python code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/00.0.0_Hello
2. Use python2 command to execute python code Hello.py.
python2 Hello.py
Because the code for our kit supports Python2 and Python3. We just say python later, not specific Python2 or Python3.
You can shoose python version according to your situation.
Code Editor
Use the vi editor to open the file "Hello.c", then press ": q" and “Enter” to exit.
vi Hello.c
As is shown below:
Use the nano editor to open the file "Hello.c", then press " Ctrl+X " to exit.
nano Hello.c
As is shown below:
Use the following command to compile the code to generate the executable file “Hello”.
gcc Hello.c –o Hello
Use the following command to run the executable file “Hello”.
sudo ./Hello
After the execution, "Hello, World!" is printed out in terminal.
Next, learn to use the Geany editor. Use the following command to open the Geany in the sample file "Hello.c" file
directory path.
geany Hello.c
Or find and open Geany directly in the desktop main menu, and then click File->Open to open the "Hello.c", Or drag
"Hello.c" to Geany directly.
Generates an executable file by clicking menu bar Build->Build, then execute the generated file by clicking menu bar
Build->Execute.
After the execution, there will be a terminal printing out the characters “Hello, World!”, as shown below:
You can click Build->Set Build Commands to set compiler commands. In later projects, we will use various compiler
command options. If you choose to use Geany, you will need change the compiler command here. As is shown below:
Summary
Here we have introduced three code editors. There also many other good code editors, and you can choose any
one you like. In later projects, about the entry path and the compiler execute commands, we will operate the
contents in the terminal as examples. We won’t emphasize the code editing process, but will explain the contents
of the code in details.
GPIO
GPIO: General purpose input/output. We will introduce the specific future of the pins on the Raspberry Pi and what
you can do with them. You can use them for all sorts of purposes. Most of them can be used as either inputs or
outputs, depending on your program.
When programming the GPIO pins there are 3 different ways to refer to them: GPIO numbering, physical numbering,
WiringPi GPIO Numbering.
For more details about pin definition of GPIO, please refer to http://pinout.xyz/
PHYSICAL Numbering
Another way to refer to the pins is by simply counting across and down from pin 1 at the top left (nearest to the SD
card). This is 'physical numbering', as shown below:
WiringPi GPIO Numbering
Different from the previous mentioned two kinds of GPIO serial numbers, RPi GPIO serial number of the WiringPi
was renumbered. Here we have three kinds of GPIO number mode: based on the number of BCM chip, based on
the physical sequence number and based on wiringPi. The correspondence between these three GPIO numbers is
shown below:
You can also use the following command to view their correspondence.
gpio readall
For more details about wiringPi, please refer to http://wiringpi.com/ .
The connection between Breadboard Power Module and Breadboard is shown below:
Next
Here, all preliminary preparations have been completed. Next, we will combine the RPi and electronic components
to do a series of projects from easy to difficult and focus on explaining the relevant knowledge of electronic circuit.
Chapter 1 LED
This chapter is the starting point of the journey to explore RPi electronic projects. Let’s start with simple “Blink”.
Component List
Raspberry Pi 3B x1 GPIO Extension Board & Wire x1
BreadBoard x1
LED x1 Resistor 220Ω x1 Jumper
In the components list, 3B GPIO, Extension Shield Raspberry and Breadboard are necessary for each project. They
will be listed only in text form later.
Component knowledge
LED
LED is a kind of diode. LED will shine only if the long pin of LED is connected to the positive electrode and the short
pin is connected to negative electrode.
This is also the features of the common diode. Diode works only if the voltage of its positive electrode is higher than
its negative electrode.
The LED can not be directly connected to power supply, which can damage component. A resistor with certain
resistance must be connected in series in the circuit of LED.
Resistor
The unit of resistance(R) is ohm(Ω). 1mΩ=1000kΩ, 1kΩ=1000Ω.
Resistor is an electrical component that limits or regulates the flow of current in an electronic circuit. The left is
the appearance of resistor, and the right is the symbol of resistor represented in circuit.
Color rings attached to the resistor is used to indicate its resistance. For more details of resistor color code, please
refer to the appendix of this tutorial.
With the same voltage there will be less current with more resistance. And the links among current, voltage and
resistance can be expressed by the formula below: I=U/R.
In the following diagram, the current through R1 is: I=U/R=5V/10kΩ=0.0005A=0.5mA.
Do not connect the two poles of power supply with low resistance, which will make the current too high to damage
electronic components.
Circuit
Disconnect RPi from GPIO Extension Shield first. Then build the circuit according to the circuit diagram and the
hardware connection diagram. After the circuit is built and confirmed, connect RPi to GPIO Extension Shield. In
addition, short circuit (especially 5V and GND, 3.3V and GND) should be avoid, because short circuit may cause
abnormal circuit work, or even damage to RPi.
Schematic diagram
Hardware connection
Because Numbering of GPIO Extension Shield is the same as RPi GPIO, later Hardware connection diagram will only
show the part of breadboard and GPIO Extension Shield.
Code
According to the circuit, when the GPIO17 of RPi output high level, LED is turned on. Conversely, when the GPIO17
RPi output low level, LED is turned off. Therefore, we can let GPIO17 output high and low level in cycle to make LED
blink. We will use both C code and Python code to achieve the target.
C Code 1.1.1 Blink
First, observe the project result, and then analyze the code.
1. Use cd command to enter 01.1.1_Blink directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/01.1.1_Blink
2. Use the following command to compile the code “Blink.c” and generate executable file “Blink”.
gcc Blink.c –o Blink -lwiringPi
3. Then run the generated file “blink”.
sudo ./Blink
Now, LED start blink. You can press “Ctrl+C” to end the program. The
following is the program code:
1 #include <wiringPi.h>
2 #include <stdio.h>
3
4 #define ledPin 0
5 int
6 main(void)
7 { if(wiringPiSetup() == -1){ //when initialize wiring failed, print message to
8 screen printf("setup wiringPi failed !"); return 1;
9 }
10 //when initialize wiring successfully, print message to screen
11 printf("wiringPi initialize successfully, GPIO %d(wiringPi pin)\n",ledPin);
12 pinMode(ledPin,
13 OUTPUT);
14
15 while(1){
16 digitalWrite(ledPin, HIGH); //led on
17 printf("led on...\n"); delay(1000);
18 digitalWrite(ledPin, LOW); //led off
19 printf("...led off\n"); delay(1000);
20 }
21 return 0;
22 }
23
24
25
26
27
GPIO connected to ledPin in the circuit is GPIO17. And GPIO17 is defined as 0 in the wiringPi numbering. So ledPin
should be defined as 0 pin. You can refer to the corresponding table in Chapter 0.
#define ledPin 0
In the main function main(), initialize wiringPi first, and then print out the initial results. Once the initialization fails,
exit the program.
if(wiringPiSetup() == -1){ //when initialize wiring failed, print message to screen
printf("setup wiringPi failed !"); return 1;
}
//when initialize wiring successfully, print message to screen
printf("wiringPi initialize successfully, GPIO %d(wiringPi pin)\n",ledPin);
After the wiringPi is initialized successfully, set the ledPin to output mode. And then enter the while cycle, which is
an endless loop. That is, the program will always be executed in this cycle, unless it is ended outside. In this cycle,
use digitalWrite (ledPin, HIGH) to make ledPin output high level, then LED is turned on. After a period of time delay,
use digitalWrite(ledPin, LOW) to make ledPin output low level, then LED is turned off, which is followed by a delay.
Repeat the cycle, then LED will start blinking.
pinMode(ledPin, OUTPUT);
while(1){ digitalWrite(ledPin, HIGH); //led is
turned on printf("led on...\n");
delay(1000); digitalWrite(ledPin, LOW); //led
is turned off printf("...led off\n");
delay(1000);
}
Among them, the configuration function for GPIO is shown below as:
void pinMode(int pin, int mode);
This sets the mode of a pin to either INPUT, OUTPUT, PWM_OUTPUT or GPIO_CLOCK. Note that only output
wiringPi pin 1 (BCM_GPIO 18) supports PWMand only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK
output modes.
This function has no effect when in Sys mode. If you need to change the pin mode, then you can do it with your
the gpio program in a script before you start program
In subfunction setup(), GPIO.setmode (GPIO.BOARD) is used to set the serial number for GPIO based on physical
location of the pin. GPIO17 use pin 11 of the board, so define ledPin as 11 and set ledPin to output mode (output
low level).
ledPin = 11 # RPi Board pin11
def
setup():
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
GPIO.setup(ledPin, GPIO.OUT) # Set ledPin to output mode
GPIO.output(ledPin, GPIO.LOW) # Set ledPin to low level to turn off led
print ('using pin%d'%ledPin)
In loop(), there is a while cycle, which is an endless loop. That is, the program will always be executed in this cycle,
unless it is ended outside. In this cycle, set ledPin output high level, then LED is turned on. After a period of time
delay, set ledPin output low level, then LED is turned off, which is followed by a delay. Repeat the cycle, then LED
will start blinking.
def loop():
while True:
GPIO.output(ledPin, GPIO.HIGH) # led on
print ('...led on') time.sleep(1)
GPIO.output(ledPin, GPIO.LOW) # led off
print ('led off...') time.sleep(1)
Finally, when the program is terminated, subfunction will be executed, the LED will be turned off and then the IO
port will be released. If close the program terminal directly, the program will be terminated too, but destroy ()
function will not be executed. So, GPIO resources won’t be released, in the warning message may appear next time
you use GPIO. So, it is not a good habit to close the program terminal directly.
def destroy():
GPIO.output(ledPin, GPIO.LOW) # led is turned off
GPIO.cleanup() # Release resource
About RPi.GPIO:
RPi.GPIO
This is a Python module to control the GPIO on a Raspberry Pi. It includes basic output function and input
function of GPIO, and f unction used to generate PWM.
GPIO.setmode(mode)
Set the mode for pin ser ial number of GPIO. hich represents the GPIO pin serial number is based on
mode=GPIO.BOARD, w physical location of RPi. h represents the pin serial number is based on CPU of BCM
mode=GPIO.BCM, whic chip.
GPIO.setup(pin,mode) r output mode. “pin” for the GPIO pin, “mode” for INPUT or OUTPUT.
Set pin to input mode o
GPIO.output(pin,mode)
Set pin to output mode. “pin” for the GPIO pin, “mode” for HIGH (high level) or LOW (low level).
Next, we will build a simple control system to control LED through a button.
Component List
Raspberry Pi 3B x1 LED x1 Resistor 220Ω Resistor 10kΩ Push
GPIO Extension Board & Wire x1 x1 x2 button x1
BreadBoard x1
Jumper
Component knowledge
Push button
Push button has 4 pins. Two pins on the left is connected, and the right is similar as the left, which is shown in the
below:
When the push button is pressed, the circuit is turned on.
Circuit
Schematic diagram
Hardware connection
Code
This project is designed for learning how to use button to control LED. We first need to read the state of button, and
then determine whether turn on LED according to the state of the button.
C Code 2.1.1 ButtonLED
First, observe the project result, then analyze the code.
1. Use cd command to enter 02.1.1_ButtonLED directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/02.1.1_ButtonLED
2. Use the following command to compile the code “ButtonLED.c” and generate executable file “ButtonLED”
gcc ButtonLED.c –o ButtonLED -lwiringPi
3. Then run the generated file “ButtonLED”.
sudo ./ButtonLED
Later, the terminal window continues to print out the characters “led off…”. Press the button, then LED is turned on
and then terminal window prints out the "led on…". Release the button, then LED is turned off and then terminal
window prints out the "led off…". You can press "Ctrl+C" to terminate the program. The following is the program
code:
1 #include <wiringPi.h>
2 #include <stdio.h>
3
4 #define ledPin 0 //define the ledPin
5 #define buttonPin 1 //define the buttonPin
6 int main(void)
7 { if(wiringPiSetup() == -1){ //when initialization for wiring fails, print message
8 to screen printf("setup wiringPi failed !"); return 1;
9 }
1 pinMode(ledPin, OUTPUT);
0 pinMode(buttonPin, INPUT);
1 pullUpDnControl(buttonPin, PUD_UP); //pull up to high level
1 while(1){
1 if(digitalRead(buttonPin) == LOW){ //button has pressed down
2 digitalWrite(ledPin, HIGH); //led on printf("led
1 on...\n");
3 }
1 else { //button has released
4
digitalWrite(ledPin, LOW); //led off printf("...led
1
off\n");
5
}
1
} return
6
0;
1
}
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
In the circuit connection, LED and Button are connected with GPIO17 and GPIO18 respectively, which correspond to
0 and 1 respectively in wiringPI. So define ledPin and buttonPin as 0 and 1 respectively.
#define ledPin 0 //define the ledPin
#define buttonPin 1 //define the buttonPin
In the while cycle of main function, use digitalRead(buttonPin) to determine the state of Button. When the button
is pressed, the function returns low level, the result of “if” is true, and then turn on LED. Or, turn off LED.
if(digitalRead(buttonPin) == LOW){ //button has pressed down
digitalWrite(ledPin, HIGH); //led on
printf("led on...\n");
} else { //button has
released digitalWrite(ledPin, LOW);
//led off printf("...led off\n");
}
About digitalRead():
int digitalRead (int pin);
This function returns the value re ad at the given pin. It will be “HIGH” or “LOW”(1 or 0) depending on the
logic level at the pin.
In subfunction setup (), GPIO.setmode (GPIO.BOARD) is used to set the serial number of the GPIO, which is based on
physical location of the pin. So, GPIO17 and GPIO18 correspond to pin11 and pin12 respectively in the circuit. Then
set ledPin to output mode, buttonPin to input mode with a pull resistor.
ledPin = 11 # define the ledPin buttonPin
= 12 # define the buttonPin def setup():
print ('Program is starting...')
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
GPIO.setup(ledPin, GPIO.OUT) # Set ledPin's mode is output
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set buttonPin's mode is
input, and pull up to high level(3.3V)
In the loop function while dead circulation, continue to judge whether the key is pressed. When the button is pressed,
the GPIO.input(buttonPin) will return low level, then the result of “if” is true, ledPin outputs high level, LED is turned
on. Or, LED will be turned off.
def loop():
while True:
if GPIO.input(buttonPin)==GPIO.LOW:
GPIO.output(ledPin,GPIO.HIGH)
print ('led on ...') else :
GPIO.output(ledPin,GPIO.LOW)
print ('led off ...')
Execute the function destroy (), close the program and release the resource. About
function GPIO.input ():
GPIO.input()
This function returns the value read at the given pin. It will be “HIGH” or “LOW”(1 or 0) depending on the
Ideal state
Virtual state
Therefore, if we directly detect the state of Push Button, there may be multiple pressing and releasing action in one
pressing process. The buffeting will mislead the high-speed operation of the microcontroller to cause a lot of false
judgments. So we need to eliminate the impact of buffeting. Our solution is: to judge the state of the button several
times. Only when the button state is stable after a period of time, can it indicate that the button is pressed down.
This project needs the same components and circuits with the last section.
Code
In the project, we still detect the state of Button to control LED. Here we need to define a variable to save the state
of LED. And when the button is pressed once, the state of LED will be changed once. This has achieved the function
of the table lamp.
C Code 2.2.1 Tablelamp
First observe the project result, and then analyze the code.
1. Use cd command to enter 02.2.1_Tablelamp directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/02.1.1_Tablelamp
2. Use following command to compile “Tablelamp.c” and generate executable file “Tablelamp”.
gcc Tablelamp.c –o Tablelamp-lwiringPi
3. Tablelamp. Then run the generated file “Tablelamp”.
sudo ./Tablelamp
When the program is executed, press the Button once, then LED is turned on. Press the Button another time, then
LED is turned off.
1 #include <wiringPi.h>
2 #include <stdio.h>
3
4 #define ledPin 0 //define the ledPin #define buttonPin 1
5 //define the buttonPin int ledState=LOW; //store the
6 State of led int buttonState=HIGH; //store the State of
7 button int lastbuttonState=HIGH;//store the lastState of button
8 long lastChangeTime; //store the change time of button state
9 long captureTime=50; //set the button state stable time int
10 reading; int main(void)
11 { if(wiringPiSetup() == -1){ //when initialize wiring failed,print message to
12 screen printf("setup wiringPi failed !"); return 1;
13 }
14 printf("Program is starting...\n");
15 pinMode(ledPin, OUTPUT); pinMode(buttonPin,
16 INPUT);
17
18 pullUpDnControl(buttonPin, PUD_UP); //pull up to high level
19 while(1){
20 reading = digitalRead(buttonPin); //read the current state of button
21 if( reading != lastbuttonState){ //if the button state has changed ,record the time
22 point
23 lastChangeTime = millis();
24 }
25
26
27
28
29 //if changing-state of the button last beyond the time we set, we considered that
30 //the current button state is an effective change rather than a
31 buffeting if(millis() - lastChangeTime > captureTime){ //if
32 button state is changed ,update the data.
33 if(reading !=
34 buttonState){ buttonState =
35 reading;
36 //if the state is low ,the action is
37 pressing if(buttonState ==
38 LOW){ printf("Button is pressed!\n");
39 ledState = !ledState;
40 if(ledState){ printf("turn on
41 LED ...\n");
42 } else
43 { printf("turn off
44 LED ...\n");
45 }
46 }
47 //if the state is high ,the action is
48 releasing else
49 { printf("Button is released!\n");
50 }
51 } }
52 digitalWrite(ledPin,ledState);
53 lastbuttonState = reading;
54 }
55 return 0;
56 }
This code focuses on eliminating the buffeting of button. We define several variables to save the state of LED and
button. Then read the button state in while () constantly, and determine whether the state has changed. If it is,
record this time point.
reading = digitalRead(buttonPin); //read the current state of button
if( reading != lastbuttonState){ lastChangeTime = millis();
}
millis()
Returns the number of milliseconds since the Arduino board began running the current program.
Then according to just recorded time point, judge the duration of the button state change. If the duration exceeds
captureTime (buffeting time) we set, it indicates that the state of the button has changed. During that time, the
while () is still detecting the state of the button, so if there is a change, the time point of change will be updated.
Then duration will be judged again until the duration of there is a stable state exceeds the time we set.
if(millis() - lastChangeTime >
captureTime){ //if button state is
changed ,update the data.
if(reading !=
buttonState){ buttonState =
reading;
Finally, judge the state of Button. And if it is low level, the changing state indicates that the button is pressed, if the
state is high level, then the button is released. Here, we change the status of the LED variable, and then update the
state of LED.
if(buttonState ==
LOW){ printf("Button is
pressed!\n"); ledState
= !ledState;
if(ledState){ printf("turn
on LED ...\n");
} else
{ printf("turn off
LED ...\n");
}
}
//if the state is high ,the action is
releasing else
{ printf("Button is released!\n");
}
RPi.GPIO provides us with a simple and effective function to eliminate the jitter, that is GPIO.add_event_detect(). It
uses callback function. Once it detect that the buttonPin has a specified action FALLING, execute the specified
function buttonEvent(). In the function buttonEvent, each time the ledState is reversed, the state of the LED will be
updated.
def buttonEvent(channel):
global ledState print
'buttonEvent GPIO%d'%channel
ledState = not ledState if
ledState :
print ('Turn on LED ... ')
else :
print ('Turn off LED ... ')
GPIO.output(ledPin,ledState)
def
loop():
#Button detect
GPIO.add_event_detect(buttonPin,GPIO.FALLING,callback = buttonEvent,bouncetime=300)
while True: pass
Of course, you can also use the same programming idea of C code above to achieve this target.
Component List
Raspberry Pi 3B x1 LED bar graph x1 Resistor 220Ω x10
GPIO Extension Board & Wire x1
BreadBoard x1
Jumper
Component knowledge
Let us learn about the basic features of components to use them better.
LED bar graph
LED bar graph is a component Integration consist of 10 LEDs. There are two rows of pins at its bottom.
Hardware connection
In this circuit, the cathode of LED is connected to GPIO, which is the different from the front circuit. So, LED will be
turned on when GPIO output low level in the program.
In the program, first define 10 pins connected to LED, and set them to output mode in subfunction setup(). Then in
the loop() function, use two “for” cycles to realize flowing water light from right to left and from left to right. Among
them, ledPins[10:0:-1] is used to traverse elements of ledPins in reverse order.
def loop():
while True:
for pin in ledPins: #make led on from left to right
GPIO.output(pin, GPIO.LOW) time.sleep(0.1)
GPIO.output(pin, GPIO.HIGH)
for pin in ledPins[10:0:-1]: #make led on from right to left
GPIO.output(pin, GPIO.LOW) time.sleep(0.1)
GPIO.output(pin, GPIO.HIGH)
Chapter 4 Analog & PWM
In previous study, we have known that one button has two states: pressed and released, and LED has lighton/off
state, then how to enter a middle state? How to output an intermediate state to let LED "semi bright"? That's what
we're going to learn.
First, let’s learn how to control the brightness of a LED.
Component List
Raspberry Pi 3B x1 LED x1 Resistor 220Ω x1
GPIO Extension Board & Wire x1
BreadBoard x1
Jumper
Circuit knowledge
Analog & Digital
The analog signal is a continuous signal in time and value. On the contrary, digital signal is a discrete signal in time
and value. Most signals in life are analog signals, for example, the temperature in one day is continuously changing,
and will not appear a sudden change directly from 0█ to 10█, while the digital signal is a jump change, which can be
directly from 1 to 0.
Their difference can be illustrated by the following figure.
In practical application, we often use binary signal as digital signal, that is 0 and 1. The binary signal only has two
forms (0 or 1), so it has strong stability. And digital signal and analog signal can be converted to each other.
PWM
PWM, namely Width Modulation Pulse, is a very effective technique for using digital signals to control analog circuits.
The common processors can not directly output analog signals. PWM technology make it very convenient to achieve
this purpose.
PWM technology uses digital pins to send certain frequency of square waves, that is, the output of high level and
low level that last for a while alternately. The total time for each set of high level and low level is generally fixed,
which is called period (the reciprocal of the period is frequency). The time of high level outputting is generally called
pulse width, and the percentage of pulse width is called duty cycle.
The longer the output of high level last, the larger the duty cycle and the larger the corresponding voltage in analog
signal will be. The following figures show how the analog signals voltage vary between 0V-5V (high level is 5V)
corresponding to the pulse width 0%-100%:
The larger PWM duty cycle is, the lager the output power will be. So we can use PWM to control the brightness of
LED, the speed of DC motor and so on.
It is evident from the above that PWM is not real analog, and the effective value of the voltage is equivalent to the
corresponding analog. so, we can control the output power of the LED and other output modules to achieve
different effects.
In RPi, only GPIO18 has the ability to output PWM with a 10-bit accuracy, that is, 100% of the pulse width can be
divided into 210=1024 equal parts.
Circuit
Schematic diagram Hardware connection
Code
This project is designed to make PWM output GPIO18 with pulse width increasing from 0% to 100%, and then
reducing from 100% to 0% gradually.
C Code 4.1.1 BreathingLED
First observe the project result, and then analyze the code.
1. Use cd command to enter 04.1.1_BreathingLED directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/04.1.1_BreathingLED
2. Use following command to compile “BreathingLED.c” and generate executable file “BreathingLED”.
gcc BreathingLED.c –o BreathingLED -lwiringPi
3. Then run the generated file “BreathingLED”
sudo ./ BreathingLED
After the program is executed, you'll see that LED is turned from on to off and then from off to on gradually like
breathing.
The following is the program code:
1 #include <wiringPi.h>
2 #include <stdio.h>
3 #define ledPin 1 //Only GPIO18 can output PWM int
4 main(void)
5 { int i; if(wiringPiSetup() == -1){ //when initialize wiring failed,print
6 message to screen printf("setup wiringPi failed !");
7
8
9 return 1;
1 } pinMode(ledPin, PWM_OUTPUT);//pwm
0 output mode
1 while(1){ for(i=0;i<1024;i++){
1 pwmWrite(ledPin, i); delay(2);
1 } delay(300);
2 for(i=1023;i>=0;i-
1 -){ pwmWrite(ledPin,
3 i); delay(2);
1 }
4 delay(300);
1 }
5
return 0;
1
}
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
Since only GPIO18 of RPi has hardware capability to output PWM, the ledPin should be defined as 1 and set its
output mode to PWM_OUTPUT based on the corresponding chart for pins.
pinMode(ledPin, PWM_OUTPUT);//pwm output mode
There are two “for” cycles in the next endless “while” cycle. The first makes the ledPin output PWM from 0% to 100%
and the second makes the ledPin output PWM from 100% to 0%.
while(1){ for(i=0;i<1024;i+
+){ pwmWrite(ledPin,
i); delay(2);
} delay(300);
for(i=1023;i>=0;i-
-){ pwmWrite(ledPin,
i); delay(2);
}
delay(300);
}
You can also adjust the rate of the state change of LED by changing the parameters of the delay() function in the
“for” cycle.
void pwmWrite (int pin, int value) ;
Writes the value to the PWM register for the given pin. The Raspberry Pi has one on-board PWM pin, pin
1 (BCM_GPIO 18, Phys 12) and the range is 0- 1024. .
LED is connected to the IO port called GPIO18. And LedPin is defined as 12 and set to output mode according to the
corresponding chart for pins. Then create a PWM instance and set the PWM frequency to 1000HZ, the initial duty
cycle to 0%.
LedPin = 12 def
setup():
global p
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
GPIO.setup(LedPin, GPIO.OUT) # Set LedPin's mode is output
GPIO.output(LedPin, GPIO.LOW) # Set LedPin to low p =
GPIO.PWM(LedPin, 1000) # Set Frequency to 1KHz
p.start(0) # Duty Cycle = 0
There are two “for” cycles used to realize breathing LED in the next endless “while” cycle. The first makes the ledPin
output PWM from 0% to 100% and the second makes the ledPin output PWM from 100% to 0%.
def loop():
while True:
for dc in range(0, 101, 1): # Increase duty cycle: 0~100
p.ChangeDutyCycle(dc) # Change duty cycle
time.sleep(0.01) time.sleep(1) for dc in
range(100, -1, -1): # Decrease duty cycle: 100~0
p.ChangeDutyCycle(dc) time.sleep(0.01)
time.sleep(1)
p.stop()
To stop PWM.
For more details about usage method for PWM of RPi.GPIO, please refer to:
https://sourceforge.net/p/raspberry-gpio-python/wiki/PWM/
Chapter 5 RGBLED
Chapter 5 RGBLED
In this chapter, we will learn how to control a RGBLED.
RGB LED has integrated 3 LEDs that can respectively emit red, green and blue light. And it has 4 pins. The long pin
(1) is the common port, that is, 3 LED 's positive or negative port. The RGB LED with common positive port and its
symbol are shown below. We can make RGB LED emit various colors of light by controlling these 3 LEDs to emit light
with different brightness,
Red, green, and blue light are called 3 primary colors. When you combine these three primary-color light with
different brightness, it can produce almost all kinds of visible lights. Computer screens, single pixel of cell phone
screen, neon, and etc. are working under this principle.
RGB
If we use three 8 bit PWM to control the RGBLED, in theory, we can create 28*28*28=16777216 (16 million) color
through different combinations.
Next, we will use RGBLED to make a colorful LED.
Circuit
Schematic diagram
Hardware connection
Chapter 5 RGBLED
Code
Since this project requires 3 PWM, but in RPi, only one GPIO has the hardware capability to output PWM, we need
to use the software to make the ordinary GPIO output PWM.
C Code 5.1.1 ColorfulLED
First observe the project result, and then analyze the code.
1. Use cd command to enter 05.1.1_ColorfulLED directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/05.1.1_ColorfulLED
2. Use following command to compile “ColorfulLED.c” and generate executable file “ColorfulLED”. Note: in this
project, the software PWM uses a multi-threading mechanism. So “-lpthread” option need to be add the
compiler.
gcc ColorfulLED.c –o ColorfulLED -lwiringPi –lpthread
3. And then run the generated by “ColorfulLED”.
sudo ./ColorfulLED
After the program is executed, you will see that the RGBLED shows light of different color randomly. The
following is the program code:
1 #include <wiringPi.h>
2 #include <softPwm.h>
3 #include <stdio.h>
4
5 #define ledPinRed 0
6 #define ledPinGreen 1
7 #define ledPinBlue 2
8 void
9 ledInit(void)
10 { softPwmCreate(ledPinRed, 0, 100);
11 softPwmCreate(ledPinGreen,0, 100);
12 softPwmCreate(ledPinBlue, 0, 100);
13 }
14 void ledColorSet(int r_val, int g_val, int b_val)
15 {
16 softPwmWrite(ledPinRed, r_val);
17 softPwmWrite(ledPinGreen, g_val); softPwmWrite(ledPinBlue,
18 b_val);
19 }
20 int main(void)
21 { int
22 r,g,b;
23 if(wiringPiSetup() == -1){ //when initialize wiring failed,print message to screen
24 printf("setup wiringPi failed !");
25
26
27
28 return 1;
29 } printf("Program is
30 starting ...\n"); ledInit();
31 while(1){ r=random()%100;
32 g=random()%100; b=random()%100;
33 ledColorSet(r,g,b); printf("r=%d,
34 g=%d, b=%d \n",r,g,b); delay(300);
35 }
36 return 0;
37 }
38
39
40
41
42
First, in subfunction of ledInit(), create the software PWM control pins used to control the R G, RGBLED, B pin
respectively.
void ledInit(void)
{ softPwmCreate(ledPinRed, 0, 100);
softPwmCreate(ledPinGreen,0, 100);
softPwmCreate(ledPinBlue, 0, 100);
}
while(1){ r=random()%100
; g=random()%100;
b=random()%100;
ledColorSet(r,g,b);
printf("r=%d, g=%d, b=%d \n",r,g,b);
delay(300);
}
Chapter 5 RGBLED
The related function of Software PWM can be described as follws:
int softPwmCreate (int pin, int initialValue, int pwmRange) ;
This creates a software controlled PWM pin.
void softPwmWrite (int pin, int value) ;
This updates the PWM value on the given pin.
long random(); function will return a
This random number.
For more details about Software PWM, please refer to: http://wiringpi.com/reference/software-pwm-library/
In last chapter, we have learned how to use python language to make a pin output PWM. In this project, we let three
pins output PWM, and the usage is exactly the same as last chapter. In the “while” cycle of “loop” function, we first
obtain three random numbers, and then specify these three random numbers as the PWM value of the three pins.o
that the RGBLED switching of different colors randomly.
def loop():
while True :
r=random.randint(0,100)
g=random.randint(0,100)
b=random.randint(0,100) setColor(r,g,b)
print ('r=%d, g=%d, b=%d ' %(r ,g, b))
time.sleep(0.3)
Component List
Raspberry Pi 3B x1 Jumper
GPIO Extension Board & Wire x1
BreadBoard x1
NPN transistorx1 Active buzzer x1 Push button x1 Resistor 1kΩ x1 Resistor 10kΩ x2
(S8050)
Component knowledge
Buzzer
Buzzer is a sounding component, which is widely used in electronic devices such as calculator, electronic warning
clock, alarm. Buzzer has active and passive type. Active buzzer has oscillator inside, and it will sound as long as it is
supplied with power. Passive buzzer requires external oscillator signal (generally use PWM with different frequency)
to make a sound.
Active buzzer is easy to use. Generally, it can only make a specific frequency of sound. Passive buzzer requires an
external circuit to make a sound, but it can be controlled to make a sound with different frequency. The resonant
frequency of the passive buzzer is 2kHz, which means the passive buzzer is loudest when its resonant frequency is
2kHz.
Next, we will use an active buzzer to make a doorbell and a passive buzzer to make an alarm.
Transistor
Due to the current operating of buzzer is so large that GPIO of RPi output capability can not be satisfied, a transistor
of NPN type is needed here to amplify the current.
Transistor, the full name: semiconductor transistor, is a semiconductor device that controls current. Transistor can be
used to amplify weak signal, or works as a switch. It has three electrodes(PINs): base (b), collector (c) and emitter (e).
When there is current passing between "be", "ce" will allow several-fold current (transistor magnification) pass, at
this point, transistor works in the amplifying area. When current between "be" exceeds a certain value, "ce" will not
allow current to increase any longer, at this point, transistor works in the saturation area. Transistor has two types
shown below: PNP and NPN,
In our kit, the PNP transistor is marked with 8550, and the NPN transistor is marked with 8050.
According to the transistor's characteristics, it is often used as a switch in digital circuits. For micro-controller's
capacity of output current is very weak, we will use transistor to amplify current and drive large-current components.
When use NPN transistor to drive buzzer, we often adopt the following method. If GPIO outputs high level, current
will flow through R1, the transistor gets conducted, and the buzzer make a sound. If GPIO outputs low level, no
current flows through R1, the transistor will not be conducted, and buzzer will not sound.
When use PNP transistor to drive buzzer, we often adopt the following method. If GPIO outputs low level, current
will flow through R1, the transistor gets conducted, buzzer make a sound. If GPIO outputs high level, no current flows
through R1, the transistor will not be conducted, and buzzer will not sound.
Circuit
Schematic diagram
Hardware connection
Note: in this circuit, the power supply for buzzer is 5V, and pull-up resistor of the button connected to the power
3.3V. The buzzer can work when connected to power 3.3V, but it will reduce the loudness.
Code
In this project, buzzer is controlled by the button. When the button is pressed, the buzzer sounds. And when the
button is released, the buzzer stops sounding. In the logic, it is the same to using button to control LED.
C Code 6.1.1 Doorbell
First observe the project result, and then analyze the code.
1. Use cd command to enter 06.1.1_Doorbell directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/06.1.1_Doorbell
2. Use following command to compile “Doorbell.c” and generate executable file “Doorbell.c”.
gcc Doorbell.c –o Doorbell -lwiringPi
3. Then run the generated file “Doorbell”.
sudo ./Doorbell
After the program is executed, press the button, then buzzer sounds. And when the button is release, the buzzer will
stop sounding.
The following is the program code:
1 #include <wiringPi.h>
2 #include <stdio.h>
3
4 #define buzzeRPin 0 //define the buzzeRPin
5 #define buttonPin 1 //define the buttonPin
6 int
7 main(void)
8 { if(wiringPiSetup() == -1){ //when initialize wiring failed, print message to
9 screen printf("setup wiringPi failed !"); return 1;
10 }
11 pinMode(buzzeRPin, OUTPUT);
12 pinMode(buttonPin, INPUT);
13
14 pullUpDnControl(buttonPin, PUD_UP); //pull up to high level
15 while(1){ if(digitalRead(buttonPin) ==
16 LOW){ //button has pressed down digitalWrite(buzzeRPin,
17 HIGH); //buzzer on printf("buzzer on...\n");
18 }
19 else { //button has released
20 digitalWrite(buzzeRPin, LOW); //buzzer off
21 printf("...buzzer off\n");
22 }
23 }
24
25
26
27
28
29
30 return 0; }
31
The code is exactly the same to using button to control LED logically. You can try to use the PNP transistor to achieve
the function of his circuit once again.
Python Code 6.1.1 Doorbell
First observe the project result, then analyze the code.
1. Use cd command to enter 06.1.1_Doorbell directory of Python code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/06.1.1_Doorbell
2. Use python command to execute python code “Doorbell.py”.
python Doorbell.py
After the program is executed, press the button, then buzzer sounds. And when the button is released, the buzzer
will stop sounding.
The following is the program code:
1 import RPi.GPIO as GPIO
2 buzzerPin = 11 # define the
3 buzzerPin buttonPin = 12 # define
4 the buttonPin
5 def
6 setup():
7 print ('Program is starting...')
8 GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
9 GPIO.setup(buzzerPin, GPIO.OUT) # Set buzzerPin's mode is output
10 GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set buttonPin's mode is
11 input, and pull up to high level(3.3V)
12 def
13 loop():
14 while True: if
15 GPIO.input(buttonPin)==GPIO.LOW:
16 GPIO.output(buzzerPin,GPIO.HIGH)
17 print ('buzzer on ...') else :
18 GPIO.output(buzzerPin,GPIO.LOW)
19 print ('buzzer off ...')
20 def
21 destroy():
22 GPIO.output(buzzerPin, GPIO.LOW) # buzzer off
23 GPIO.cleanup() # Release resource
24 if __name__ == '__main__': # Program start from
25 here setup() try:
26 loop()
27
28
29
30
The code is the same to the active buzzer logically, but the way to control the buzzer is different. Passive buzzer
requires PWM of certain frequency to control, so you need to create a software PWM pin though softToneCreate
(buzzeRPin). Here softTone is dedicated to generate square wave with variable frequency and duty cycle fixed to
50%, which is a better choice for controlling the buzzer.
softToneCreate(buzzeRPin);
In the while cycle of main function, when the button is pressed, subfunction alertor() will be called and the alertor
will issue a warning sound. The frequency curve of the alarm is based on the sine curve. We need to calculate the
sine value from 0 to 360 degree and multiply a certain value (here is 500) and plus the resonant frequency of buzzer.
We can set the PWM frequency through softToneWrite (pin, toneVal).
void alertor(int
pin){ int x;
double sinVal, toneVal; for(x=0;x<360;x++){ //The
frequency is based on the sine curve.
sinVal = sin(x * (M_PI / 180));
toneVal = 2000 + sinVal * 500;
softToneWrite(pin,toneVal);
delay(1);
Chapter 6 Buzzer
}
}
If you want to close the buzzer, just set PWM frequency of the buzzer pin to 0.
void stopAlertor(int
pin){ softToneWrite(pin,0);
}
The related functions of softTone is described as follows:
int softToneCreate (int pin) ;
This creates a software controlled tone pin.
void softToneWrite (int pin, int freq) ;
This updates the tone frequency value on the given pin.
For more details about softTone, please refer to :http://wiringpi.com/reference/software-tone-library/
Python Code 6.2.1 Alertor
First observe the project result, and then analyze the code.
1. Use cd command to enter 06.2.1_Alertor directory of Python code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/06.2.1_Alertor
2. Use the python command to execute the Python code “Alertor.py”.
python Alertor.py
After the program is executed, press the button, then the buzzer sounds. When the button is released, the buzzer
will stop sounding.
The following is the program code:
1 import RPi.GPIO as GPIO
2 import time import math
3 buzzerPin = 11 # define the
4 buzzerPin buttonPin = 12 # define the
5 buttonPin
6 def
7 setup():
8 global p
9 print ('Program is starting...')
10 GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
11 GPIO.setup(buzzerPin, GPIO.OUT) # Set buzzerPin's mode is output
12 GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set buttonPin's mode is
13 input, and pull up to high level(3.3V) p = GPIO.PWM(buzzerPin, 1)
14 p.start(0);
15 def loop():
16 while True: if
17 GPIO.input(buttonPin)==GPIO.LOW:
18 alertor()
19 print ('buzzer on ...')
20 else :
21
22
23
24 stopAlertor()
25 print ('buzzer off ...') def
26 alertor():
27 p.start(50) for x in range(0,361): #frequency of the alarm along the sine
28 wave change sinVal = math.sin(x * (math.pi / 180.0)) #calculate the
29 sine value toneVal = 2000 + sinVal * 500 #Add to the resonant frequency with
30 a Weighted
31 p.ChangeFrequency(toneVal) #output PWM
32 time.sleep(0.001)
33 def
34 stopAlertor():
35 p.stop() def
36 destroy():
37 GPIO.output(buzzerPin, GPIO.LOW) # buzzer off
38 GPIO.cleanup() # Release resource if
39 __name__ == '__main__': # Program start from here
40 setup() try:
41 loop() except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child
42 program destroy() will be executed. destroy()
43
44
45
The code is the same to the active buzzer logically, but the way to control the buzzer is different. Passive buzzer
requires PWM of certain frequency to control, so you need to create a software PWM pin through softToneCreate
(buzzeRPin). The way to create PWM is also introduced before in the sections about BreathingLED and RGBLED.
def setup():
global p
print ('Program is starting...')
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
GPIO.setup(buzzeRPin, GPIO.OUT) # Set buzzeRPin's mode is output
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set buttonPin's mode is
input, and pull up to high level(3.3V) p = GPIO.PWM(buzzeRPin, 1)
p.start(0);
In the while cycle of main function, when the button is pressed, subfunction alertor() will be called and the alertor
will issue a warning sound. The frequency curve of the alarm is based on the sine curve. We need to calculate the
sine value from 0 to 360 degree and multiply a certain value (here is 500) and plus the resonant frequency of buzzer.
We can set the PWM frequency through p.ChangeFrequency(toneVal).
Chapter 6 Buzzer
p.ChangeFrequency(toneVal)
time.sleep(0.001)
When the button is released, the buzzer will be closed.
def stopAlertor():
p.stop()
def alertor():
p.start(50) for x
in range(0,361):
sinVal = math.sin(x * (math.pi / 180.0))
toneVal = 2000 + sinVal * 500
Chapter 7 PCF8591
We have learned how to control the brightness of LED through PWM and understood that PWM is not the real
analog before. In this chapter, we will learn how to read analog quantities through PCF8591, convert it into digital
quantity and convert the digital quantity into analog output. That is, ADC and DAC.
Component List
Raspberry Pi 3B x1 Jumper
GPIO Extension Board & Wire x1
BreadBoard x1
Rotary potentiometer x1 PCF8591 x1 Resistor 10kΩ x2 Resistor 220Ω x1 LED x1
Circuit knowledge
ADC
ADC, Analog-to-Digital Converter, is a device used to convert analog to digital. The range of the ADC on PCF8591 is
8 bits, that means the resolution is 2^8=256, and it represents the range (here is 3.3V) will be divided equally to 256
parts. The analog of each range corresponds to one ADC values. So the more bits ADC has, the denser the partition
of analog will be, also the higher precision of the conversion will be.
Component knowledge
Potentiometer
Potentiometer is a resistive element with three Terminal part and the resistance can be adjusted according to a
certain variation. Potentiometer is often made up by resistance and removable brush. When the brush moves along
the resistor body, there will be resistance or voltage that has a certain relationship with displacement on the output
side (3). Figure shown below is the linear sliding potentiometer and its symbol.
What
between
potentiometer pin 1 and pin 2 is the resistor body, and pins 3 is connected to brush. When brush moves from pins
1 to pin 2, the resistance between pin 1, and pin 3 will increase up to body resistance linearly, and the resistance
between pin 2 and pin 3 will decrease down to 0 linearly.
In the circuit. The both sides of resistance body are often connected to the positive and negative electrode of the
power. When you slide the brush pin 3, you can get a certain voltage in the range of the power supply.
Rotary potentiometer
Rotary potentiometer and linear potentiometer have similar function; the only difference is: the resistance is adjusted
through rotating the potentiometer.
PCF8591
The PCF8591 is a single-chip, single-supply low power 8-bit CMOS data acquisition device with four analog inputs, one
analog output and a serial I2C-bus interface.
FEATURES
Single power supply Auto-incremented channel selection
Operating supply voltage 2.5 V to 6 V Analog voltage ranges from VSS to VDD
Low standby current On-chip track and hold circuit
Serial input/output via I2C-bus 8-bit successive approximation A/D conversion Address by 3
hardware address pins Multiplying DAC with one analog output.
Sampling rate given by I2C-bus speed 4 analog inputs programmable as single-ended
differential inputs or
PINNING
SYMBOL PIN DESCRIPTION TOP VIEW
AIN0 1
AIN1 2
Analog inputs (A/D converter)
AIN2 3
AIN3 4
A0 5 Hardware address
A1 6
A2 7
Hardware connection
Configure I2C
Enable I2C
The I2C interface raspberry pie is closed in default. You need to open it manually. You can enable the I2C interface in
the following way.
Type command in the terminal:
sudo raspi-config
Then open the following dialog box:
Choose “5 Interfacing Options”“P5 I2C”“Yes”“Finish” in order and restart your RPi later. Then the I2C module
is started.
Type a command to check whether the I2C module is started:
lsmod | grep i2c
If the I2C module has been started, the following content will be shown:
Install I2C-Tools
Type the command to install I2C-Tools.
sudo apt-get install i2c-tools
I2C device address detection:
i2cdetect –y 1
For more detailed instructions about PCF8591 of wiringPi, please refer to: http://wiringpi.com/extensiones/i2c-
pcf8591/
First, define the I2C address and control byte of PCF8591, and then instantiate object bus of SMBus, which can be
used to operate ADC and DAC of PCF8591.
address = 0x48 # default address of
PCF8591 bus=smbus.SMBus(1) cmd=0x40
# command
This subfunction is used to read the ADC. Its parameter “chn” represents the input channel number: 0, 1, 2, 3. Its
return value is the read ADC value.
def analogRead(chn):# read ADC value,chn:0,1,2,3
value = bus.read_byte_data(address,cmd+chn) return
value
This subfunction is used to write DAC. Its parameter “value” represents the digital quality to be written, between 0-
255.
def analogWrite(value):# write DAC value
bus.write_byte_data(address,cmd,value)
In the “while” cycle, first read the ADC value of channel 0, and then write the value as the DAC digital quality and
output corresponding voltage in the out pin of PCF8591. Then calculate the corresponding voltage value and print
it out.
def loop():
while True:
value = analogRead(0) #read the ADC value of channel 0
analogWrite(value) # write ADC value
voltage = value / 255.0 * 3.3 # calculate voltage value
print ('ADC Value : %d, Voltage : %.2f'%(value,voltage))
time.sleep(0.01)
Component List
Raspberry Pi 3B x1 Jumper
GPIO Extension Board & Wire x1
BreadBoard x1
Rotary potentiometer x1 PCF8591 x1 Resistor 10kΩ x2 Resistor 220Ω x1 LED x1
Circuit
The circuit of this project is similar to the one in last chapter. The only difference is that the pin used to control LED
is different.
Schematic diagram
Hardware connection
Code
C Code 8.1.1 Softlight
First observe the project result, and then analyze the code.
1. Use cd command to enter 08.2.1_Softlight directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/08.1.1_Softlight
2. Use following command to compile “Softlight.c” and generate executable file “Softlight”.
gcc Softlight.c –o Softlight–lwiringPi –lpthread
3. Then run the generated file “Softlight”.
sudo ./Softlight
After the program is executed, shift the potentiometer, then the terminal window will print out the voltage value of
the potentiometer and the converted digital quantity. And brightness of LED will be changed consequently.
The following is the code:
1 #include <wiringPi.h>
2 #include <pcf8591.h>
3 #include <stdio.h>
4 #include <softPwm.h>
5
6 #define address 0x48 //pcf8591 default address
7 #define pinbase 64 //any number above 64
8 #define A0 pinbase + 0
9 #define A1 pinbase + 1
10 #define A2 pinbase + 2
11 #define A3 pinbase + 3
12
13 #define ledPin 0
14 int
15 main(void){ int
16 value; float
17 voltage;
18 if(wiringPiSetup() == -1){ //when initialize wiring failed,print message to screen
19 printf("setup wiringPi failed !"); return 1;
20 }
21 softPwmCreate(ledPin,0,100);
22 pcf8591Setup(pinbase,address);
23
24 while(1){
25 value = analogRead(A0); //read A0 pin
26 softPwmWrite(ledPin,value*100/255); voltage = (float)value /
27 255.0 * 3.3; // calculate voltage printf("ADC
28 value : %d ,\tVoltage : %.2fV\n",value,voltage); delay(100);
29
Chapter 8 Potentiometer & LED
30 }
31 return 0; }
32
In the code, read ADC value of potentiometers and map it to duty cycle of PWM to control LED brightness.
Python Code 8.1.1 Softlight
First observe the project result, and then analyze the code.
1. Use cd command to enter 08.2.1_Softlight directory of Python code
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/08.1.1_Softlight
2. Use the python command to execute the Python code “Softlight.py”.
python Softlight.py
After the program is executed, shift the potentiometer, then the terminal window will print out the voltage value of
the potentiometer and the converted digital quantity. And brightness of LED will be changed consequently.
The following is the code:
1 import RPi.GPIO as GPIO
2 import smbus import
3 time
4 address = 0x48
5 bus=smbus.SMBus(1)
6 cmd=0x40 ledPin =
7 11
8 def
9 analogRead(chn):
10 value = bus.read_byte_data(address,cmd+chn)
11 return value
12 def
13 analogWrite(value):
14 bus.write_byte_data(address,cmd,value)
15 def
16 setup():
17 global p
18 GPIO.setmode(GPIO.BOARD)
19 GPIO.setup(ledPin,GPIO.OUT)
20 GPIO.output(ledPin,GPIO.LOW)
21
22 p = GPIO.PWM(ledPin,1000)
23 p.start(0)
24 def loop():
25 while True:
26 value = analogRead(0) #read A0 pin
27 p.ChangeDutyCycle(value*100/255) #Convert ADC value to duty cycle of PWM
28 voltage = value / 255.0 * 3.3 #calculate voltage
29
30
31 print ('ADC Value : %d, Voltage : %.2f'%(value,voltage))
32 time.sleep(0.01)
33 def destroy():
34 bus.close()
35 GPIO.cleanup()
36 if __name__ ==
37 '__main__':
38 print ('Program is starting ... ')
39 setup() try:
40 loop() except
41 KeyboardInterrupt:
42 destroy()
43
44
In the code, read ADC value of potentiometers and map it to duty cycle of PWM to control LED brightness.
Chapter 9 Potentiometer & RGBLED
Component List
Raspberry Pi 3B x1 Jumper
GPIO Expansion Board & Wire x1
BreadBoard x1
Rotary potentiometer x3 PCF8591 x1 Resistor 10kΩ x2 Resistor 220Ω x3 RGBLED x1
Circuit
Component List
Raspberry Pi 3B x1 Jumper
GPIO Extension Board & Wire x1
BreadBoard x1
Photoresistor x1 PCF8591 x1 Resistor 10kΩ x3 Resistor 220Ω x1 LED x1
Component knowledge
Photoresistor
Photoresistor is a light sensitive resistor. When the strength that light casts onto the photoresistor surface is not the
same, resistance of photoresistor will change. With this feature, we can use photoresistor to detect light intensity.
Photoresistor and symbol are as follows.
The circuit below is often used to detect the change of photoresistor resistance:
In the above circuit, when photoresistor resistance changes due to light intensity, voltage between photoresistor
and resistor R1 will change, so light's intensity can be obtained by measuring the voltage.
Circuit
The circuit of this project is similar to the one in last chapter. The only difference is that the input signal of the AIN0
pin of PCF8591 is changed from a potentiometer to combination of a photoresistor and a resistor.
Schematic diagram
Hardware connection
Component List
Raspberry Pi 3B x1 Jumper
GPIO Extension Board & Wire x1
BreadBoard x1
Chapter 11 Thermistor
Component knowledge
Thermistor
Thermistor is a temperature sensitive resistor. When the temperature changes, resistance of thermistor will change.
With this feature, we can use thermistor to detect temperature intensity. Thermistor and symbol are as follows.
We can use the value measured by the analog pin of UNO to obtain resistance value of thermistor, and then can use
the formula to obtain the temperature value.
Consequently, the temperature formula can be concluded:
T2 = 1/(1/T1 + ln(Rt/R)/B)
Circuit
The circuit of this project is similar to the one in last chapter. The only difference is that the photoresistor is replaced
by the thermistor.
Schematic diagram
Hardware connection
Chapter 11 Thermistor
Code
In this project code, the ADC value is still needed to be read, and the difference is that a specific formula is used to
calculate the temperature value.
C Code 11.1.1 Thermometer
First observe the project result, and then analyze the code.
Use cd command to enter 11.1.1_Thermometer directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/11.1.1_Thermometer
1. Use following command to compile “Thermometer.c” and generate executable file “Thermometer”. “-lm”
option is needed.
gcc Thermometer.c –o Thermometer –lwiringPi –lm
2. Then run the generated file “Thermometer”.
sudo ./Thermometer
After the program is executed, the terminal window will print out the current ADC value, voltage value and
temperature value. Try to pinch the thermistor (do not touch pin) with hand lasting for a while, then the temperature
value will be increased.
In the code, read the ADC value of PCF8591 A0 port, and then calculate the voltage and the resistance of thermistor
according to Ohms law. Finally, calculate the current temperature. according to the front formula.
Python Code 11.1.1 Thermometer
First observe the project result, and then analyze the code.
1. Use cd command to enter 11.1.1_Thermometer directory of Python code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/11.1.1_Thermometer
2. Use python command to execute python code “Thermometer.py”.
python Thermometer.py
After the program is executed, the terminal window will print out the current ADC value, voltage value and
temperature value. Try to pinch the thermistor (do not touch pin) with hand lasting for a while, then the temperature
value will be increased.
In the code, read the ADC value of PCF8591 A0 port, and then calculate the voltage and the resistance of thermistor
according to Ohms law. Finally, calculate the current temperature. according to the front formula.
Chapter 12 Joystick
In the previous chapter, we have learned how to use rotary potentiometer. Now, let's learn a new electronic module
Joystick which working on the same principle as rotary potentiometer.
Component List
Raspberry Pi 3B x1 Jumper
GPIO Expansion Board & Wire x1
BreadBoard x1
PCF8591 x1 Resistor 10kΩ x2 Joystick x1
Component knowledge
Joystick
Joystick is a kind of sensor used with your fingers, which is widely used in gamepad and remote controller. It can
shift in direction Y or direction X at the same time. And it can also be pressed in direction Z.
Two rotary potentiometers inside the joystick are set to detect the shift direction of finger, and a push button in
vertical direction is set to detect the action of pressing.
When read the data of joystick, there are some different between axis: data of X and Y axis is analog, which need
to use ADC. Data of Z axis is digital, so you can directly use the GPIO to read, or you can also use ADC to read.
Circuit
Schematic diagram
Hardware connection
Code
In this project code, we will read ADC value of X and Y axis of Joystick, and read digital quality of Z axis, then print
these data out.
C Code 12.1.1 Joystick
First observe the project result, and then analyze the code.
1. Use cd command to enter 12.1.1_Joystick directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/12.1.1_ Joystick
2. Use following command to compile "Joystick.c" and generate executable file "Joystick.c". "-lm" option is needed.
gcc Joystick.c –o Joystick –lwiringPi –lm
3. Then run the generated file "Joystick".
sudo ./Joystick
After Program is executed, the terminal window will print out the data of 3 axes X, Y, Z. And shifting the Joystick or
pressing it will make those data change.
Component List
Raspberry Pi 3B x1 Jumper
GPIO Extension Board & Wire x1
BreadBoard x1
Breadboard power module x1 9V Battery (provided by yourself) & battery cable
Component knowledge
Motor
Motor is a device that converts electrical energy into mechanical energy. Motor consists of two parts: stator and
rotor. When motor works, the stationary part is stator, and the rotating part is rotor. Stator is usually the outer case
of motor, and it has terminals to connect to the power. Rotor is usually the shaft of motor, and can drive other
mechanical devices to run. Diagram below is a small DC motor with two pins.
When motor get connected to the power supply, it will rotate in one direction. Reverse the polarity of power supply,
then motor rotates in opposite direction.
+ - - +
L293D
L293D is a chip integrated with 4-channel motor drive. You can drive a unidirectional motor with 4 ports or a bi-
directional motor with 2 port or a stepper motor.
Following connection uses two channels: one channel outputs PWM wave, and another channel connects GND, so
you can control the speed of motor. When these two channel signals are exchanged, the current direction of the
motor can be reversed, and the motor will rotate in reverse direction. This can not only control the speed of
motor, but also can control the steering of motor.
In actual use, motor is usually connected to the channel 1 and 2, output different level to in1 and in2 to control
the rotation direction of the motor, and output PWM wave to Enable1 port to control the motor rotation speed.
Or, get motor connected to the channel 3 and 4, output different level to in3 and in4 to control the motor's
rotation direction, and output PWM wave to Enable2 pin to control the motor rotation speed.
Circuit
When connecting the circuit, pay attention to that because the motor is a high-power component, do not use the
power provided by the RPi, which may do damage to your RPi. the logic circuit can be powered by RPi power or
external power supply which should have the common ground with RPi.
3.3
Code
In this project code, first read the ADC value, and then control the rotation direction and speed of the motor
according to the value of the ADC.
C Code 13.1.1 Motor
First observe the project result, and then analyze the code.
1. Use cd command to enter 13.1.1_Motor directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/13.1.1_Motor
2. Use following command to compile “Motor.c” and generate executable file “Motor”. “-lm” and “-lpthread”
option is needed.
gcc Motor.c –o Motor–lwiringPi –lm -lpthread
3. Then tun the generated file ”Motor”.
sudo ./Motor
After the program is executed, shift the potentiometer, then the rotation speed and direction of the motor will
change with it. And when the potentiometer is turned to midpoint position, the motor stops running. When away
from the middle position, the motor speed will increase. When to both ends, motor speed reach to maximum. When
the potentiometer is turned to different side of the middle position, the motor will run with different direction.
Meanwhile, the terminal will print out ADC value of the potentiometer, the motor direction and the PWM duty cycle
used to control motor speed.
Component List
Raspberry Pi 3B x1 Jumper
GPIO Expansion Board & Wire x1
BreadBoard x1
9V battery (prepared by yourself) & battery line
Component knowledge
Relay
Relay is a safe switch which can use low power circuit to control high power circuit. It consists of electromagnet and
contacts. The electromagnet is controlled by low power circuit and contacts is used in high power circuit. When the
electromagnet is energized, it will attract contacts.
The following is a principle diagram of common relay and the feature and circuit symbol of 5V relay used in this
project:
Diagram Feature: Symbol
Pin 5 and pin 6 are connected to each other inside. When the coil pin3 and 4 get connected to 5V power supply, pin
1 will be disconnected to pin 5&6 and pin 2 will be connected to pin 5&6. So pin 1 is called close end, pin 2 is called
open end.
Inductor
The unit of inductance(L) is the henry (H). 1H=1000mH, 1mH=1000μH.
Inductor is an energy storage device that converts electrical energy into magnetic energy. Generally, it consists of
winding coil, with a certain amount of inductance. Inductor will hinder the changing current passing through the
inductor. When the current passing through inductor increases, it will attempt to hinder the increasing trend of
current; and when the current passing through the inductor decreases, it will attempt to hinder the decreasing trend
of current. So the current passing through inductor is not transient.
The reference circuit for relay is as follows. The coil of relay can be equivalent to inductor, when the transistor
disconnects power supply of the relay, the current in the coil of the relay can't stop immediately, causing an impact
on power supply. So a parallel diode will get connected to both ends of relay coil pin in reversing direction, then the
current will pass through diode, avoiding the impact on power supply.
Circuit
Pay attention to the power supply voltage needed for the components in circuit, in which the relay needs power
supply voltage 5V, and the motor needs 3.3V. Additionally, a LED is used as an indicator for the relay (turned on or
turned off).
3.3
Code
The project code is in the same logic as TableLamp. Press the button to driver the transistor conducted. Because the
relay and LED are connected in parallel, they will be opened at the same time. And if you press the button again,
they will be closed.
C Code 14.1.1 Relay
First observe the project result, and then analyze the code.
1. Use cd command to enter 14.1.1_Relay directory of C code.
cd ~/Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/14.1.1_Relay
2. Use following command to compile "Relay.c" and generate executable file "Relay".
gcc Relay.c –o Relay –lwiringPi
3. Run the generated file "Relay".
sudo ./Relay
After the program is executed, press the button, then the relay is opened, the Motor starts to rotate and LED is
turned on. If you press the button again, the relay is closed, the Motor stops running, and the LED is turned off.
The following is the program code:
1 #include <wiringPi.h>
2 #include <stdio.h>
3
4 #define relayPin 0 //define the relayPin #define buttonPin
5 1 //define the buttonPin int relayState=LOW; //store
6 the State of relay int buttonState=HIGH; //store the State of
7 button int lastbuttonState=HIGH;//store the lastState of button
8 long lastChangeTime; //store the change time of button state
9 long captureTime=50; //set the button state stable time int
10 reading; int main(void)
11 {
12 if(wiringPiSetup() == -1){ //when initialize wiring fairelay,print message to screen
13 printf("setup wiringPi fairelay !"); return 1;
14 } printf("Program is
15 starting...\n"); pinMode(relayPin,
16 OUTPUT); pinMode(buttonPin,
17 INPUT);
18 pullUpDnControl(buttonPin, PUD_UP); //pull up to high level
19 while(1){ reading = digitalRead(buttonPin); //read the current state of button
20 if( reading != lastbuttonState){ //if the button state has changed ,record the time
21 point lastChangeTime = millis();
22
23
24
25
26
27 }
28 //if changing-state of the button last beyond the time we set,we considered that
29 //the current button state is an effective change rather than a
30 buffeting if(millis() - lastChangeTime > captureTime){ //if
31 button state is changed ,update the data.
32 if(reading !=
33 buttonState){ buttonState =
34 reading;
35 //if the state is low ,the action is
36 pressing if(buttonState ==
37 LOW){ printf("Button is pressed!\n");
38 relayState = !relayState;
39 if(relayState){ printf("turn on
40 relay ...\n");
41 } else
42 { printf("turn off
43 relay ...\n");
44 }
45 }
46 //if the state is high ,the action is
47 releasing else
48 { printf("Button is released!\n");
49 }
50 } }
51 digitalWrite(relayPin,relayState);
52 lastbuttonState = reading;
53 }
54 return 0;
55 }
56
The code is in the same logic as TableLamp code above.
Component List
Raspberry Pi 3B x1 Jumper
GPIO Expansion Board & Wire x1
BreadBoard x1
Servo x1
Component knowledge
Servo
Servo is an auto-control system, consisting of DC motor, reduction gear, sensor and control circuit. Usually, it can
rotate in the range of 180 degrees. Servo can output larger torque and is widely used in model airplane, robot and
so on. It has three lines, including two for electric power line positive (2-VCC, red), negative (3GND, brown), and the
signal line (1-Signal, orange).
We use 50Hz PWM signal with a duty cycle in a certain range to drive the servo. The lasting time 0.5ms-2.5ms of
PWM single cycle high level corresponds to the servo angle 0 degrees - 180 degree linearly. Part of the corresponding
values are as follows:
High level time Servo angle
0.5ms 0 degree
1ms 45 degree
1.5ms 90 degree
2ms 135 degree
2.5ms 180 degree
When you change the servo signal, servo will rotate to the designated position.
Circuit
Pay attention to the power supply for stepping motor is 5v, and don't confuse the line sequence.
Schematic diagram
Hardware connection
Code
In this project, we make the servo rotate from 0 degrees to 180 degrees, and then from 180 degrees to 0 degrees.
C Code 15.1.1 Sweep
First observe the project result, and then analyze the code.
1. Use cd command to enter 15.1.1_Sweep directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/15.1.1_Sweep
2. Use following command to compile "Sweep.c" and generate executable file "Sweep".
gcc Sweep.c –o Sweep –lwiringPi
3. Run the generated file "Sweep".
sudo ./Sweep
After the program is executed, the servo will rotate from 0 degrees to 180 degrees, and then from 180 degrees to 0
degrees, circularly.
The following is the program code:
1 #include <wiringPi.h>
2 #include <softPwm.h>
3 #include <stdio.h>
4 #define OFFSET_MS 3 //Define the unit of servo pulse offset: 0.1ms
5 #define SERVO_MIN_MS 5+OFFSET_MS //define the pulse duration for minimum angle of
6 servo
7 #define SERVO_MAX_MS 25+OFFSET_MS //define the pulse duration for maximum angle of
8 servo
9
10 #define servoPin 1 //define the GPIO number connected to servo long
11 map(long value,long fromLow,long fromHigh,long toLow,long
12 toHigh){ return (toHigh-toLow)*(value-fromLow) / (fromHigh-fromLow) +
13 toLow;
14 } void servoInit(int pin){ //initialization function for servo PWM
15 pin softPwmCreate(pin, 0, 200);
16 }
17 void servoWrite(int pin, int angle){ //Specif a certain rotation angle (0-180) for the
18 servo
19 if(angle > 180)
20 angle = 180;
21 if(angle < 0)
22 angle = 0;
23 softPwmWrite(pin,map(angle,0,180,SERVO_MIN_MS,SERVO_MAX_MS));
24 } void servoWriteMS(int pin, int ms){ //specific the unit for pulse(5-25ms)
25 with specific duration output by servo pin: 0.1ms if(ms > SERVO_MAX_MS)
26 ms = SERVO_MAX_MS;
27
28
29 if(ms < SERVO_MIN_MS)
30 ms = SERVO_MIN_MS;
31 softPwmWrite(pin,ms);
32 } int
33 main(void)
34 { int i; if(wiringPiSetup() == -1){ //when initialize wiring faiservo,print
35 message to screen printf("setup wiringPi faiservo !"); return 1;
36 } printf("Program is starting ...\n"); servoInit(servoPin);
37 //initialize PWM pin of servo
38 while(1){ for(i=SERVO_MIN_MS;i<SERVO_MAX_MS;i++){ //make servo rotate from
39 minimum angle to maximum angle servoWriteMS(servoPin,i);
40 delay(10);
41 } delay(500); for(i=SERVO_MAX_MS;i>SERVO_MIN_MS;i--){ //make
42 servo rotate from maximum angle to minimum angle
43
44 servoWriteMS(servoPin,i);
45 delay(10);
46 }
47 delay(500);
48 }
49 return 0;
50 }
51
52
53
54
55
56
57
58
59
50 Hz pulse, namely cycle for 20ms, is required to control Servo. In function softPwmCreate (int pin, int initialValue,
int pwmRange), the unit of third parameter pwmRange is 100US, namely 0.1ms. In order to get the PWM with cycle
of 20ms, the pwmRange shoulde be set to 200. So in subfunction of servoInit (), we create a PWM pin with
pwmRange 200.
void servoInit(int pin){ //initialization function for servo PWM pin
softPwmCreate(pin, 0, 200);
}
As 0-180 degrees of servo corresponds to PWM pulse width 0.5-2.5ms, with PwmRange 200 and unit 0.1ms. So, in
function softPwmWrite (int pin, int value), the scope 5-25 of parameter value corresponds to 0-180 degrees of servo.
What’s more, the number writen in subfunction servoWriteMS () should be within the range of 5-25. However, in
practice, due to the manufacture error of each servo, pulse width will also have deviation. So we define a minimum
pulse width and a maximum one and an error offset.
#define OFFSET_MS 3 //Define the unit of servo pulse offset: 0.1ms
#define SERVO_MIN_MS 5+OFFSET_MS //define the pulse duration for minimum angle of
servo
#define SERVO_MAX_MS 25+OFFSET_MS //define the pulse duration for maximum angle of
servo
……
void servoWriteMS(int pin, int
ms){ if(ms > SERVO_MAX_MS)
ms = SERVO_MAX_MS; if(ms <
SERVO_MIN_MS) ms =
SERVO_MIN_MS;
softPwmWrite(pin,ms);
}
In subfunction servoWrite (), input directly angle (0-180 degrees), and map the angle to the pulse width and then
output it.
void servoWrite(int pin, int angle){ //Specif a certain rotation angle (0-180) for
the servo if(angle > 180) angle = 180; if(angle < 0) angle = 0;
softPwmWrite(pin,map(angle,0,180,SERVO_MIN_MS,SERVO_MAX_MS)); }
Finally, in the "while" cycle of main function, use two "for" cycle to make servo rotate from 0 degrees to 180 degrees,
and then from 180 degrees to 0 degrees.
while(1){ for(i=SERVO_MIN_MS;i<SERVO_MAX_MS;i++){ //make servo rotate
from minimum angle to maximum angle
servoWriteMS(servoPin,i);
delay(10);
}
delay(500);
for(i=SERVO_MAX_MS;i>SERVO_MIN_MS;i--){ //make servo rotate from maximum
angle to minimum angle servoWriteMS(servoPin,i); delay(10);
}
delay(500);
}
50 Hz pulse, namely cycle for 20ms, is required to control Servo. So we need set PWM frequency of servoPin to 50Hz.
p = GPIO.PWM(servoPin, 50) # Set Frequency to 50Hz
As 0-180 degrees of servo corresponds to PWM pulse width 0.5-2.5ms within cycle 20ms and to duty cycle 2.5%-
12.5%. In subfunction servoWrite (angle), map the angle to duty cycle to output the PWM, then the servo will rotate
a specific angle. However, in practice, due to the manufacture error of each servo, pulse width will also have
deviation. So we define a minimum pulse width and a maximum one and an error offset.
OFFSE_DUTY = 0.5 #define pulse offset of servo
SERVO_MIN_DUTY = 2.5+OFFSE_DUTY #define pulse duty cycle for minimum angle of servo
SERVO_MAX_DUTY = 12.5+OFFSE_DUTY #define pulse duty cycle for maximum angle of servo
……
def servoWrite(angle): #make the servo rotate to specific angle (0-180 degrees)
if(angle<0): angle = 0 elif(angle > 180): angle = 180
p.ChangeDutyCycle(map(angle,0,180,SERVO_MIN_DUTY,SERVO_MAX_DUTY))
Finally, in the "while" cycle of main function, use two "for" cycle to make servo rotate from 0 degrees to 180 degrees,
and then from 180 degrees to 0 degrees.
def loop():
while True:
for dc in range(0, 181, 1): #make servo rotate from 0°to 180°
servoWrite(dc) # Write to servo time.sleep(0.001)
time.sleep(0.5) for dc in range(180, -1, -1): #make servo rotate
from 180°to 0° servoWrite(dc) time.sleep(0.001)
time.sleep(0.5)
Chapter 16 Stepping Motor
Component List
Raspberry Pi 3B x1 Jumper
GPIO Expansion Board & Wire x1
BreadBoard x1
Stepping Motor x1 ULN2003 Stepping motorDriver x1
Component knowledge
Stepping Motor
Stepping motor is an open-loop control device which converts the electric pulse signal into angular displacement or
linear displacement. In non-overload condition, the speed of the motor and the location of the stop depends only
on the pulse signal frequency and pulse number, and not affected by the load changes. A small four-phase
deceleration stepping motor is shown as follows:
The schematic diagram of four-phase stepping motor is shown below:
The outside piece is the stator and the inside is the rotor of the motor. There are a certain number of coils, usually
integer multiple of phases number, in the stator and when powered on, an electromagnet will be formed to attract
a convex part (usually iron or permanent magnet) of the rotor. Therefore, the electric motor can be driven by
conducting the coils on stator orderly.
The stator of stepping motor we use has 32 magnetic poles, so a circle needs 32 steps. The output shaft of the
stepping motor is connected with a reduction gear set, and the reduction ratio is 1/64. So the final output shaft
rotates a circle requiring a 32*64=2048 step.
Subfunction moveOnePeriod ((int dir,int ms) will drive the stepping motor rotating four step clockwise or
anticlockwise, four step as a cycle. Where parameter "dir" indicates the rotation direction, if "dir" is 1, the servo will
rotate forward, otherwise it rotates to reverse direction. Parameter "ms" indicates the time between each two steps.
The "ms" of stepping motor used in this project is 3ms (the shortest time), less than 3ms will exceed the speed limit
of stepping motor resulting in that motor can not rotate.
void moveOnePeriod(int dir,int ms){ int i=0,j=0; for
(j=0;j<4;j++){ //cycle according to power supply order for
(i=0;i<4;i++){ //assign to each pin, a total of 4 pins if(dir == 1)
//power supply order clockwise
digitalWrite(motorPins[i],(CCWStep[j] == (1<<i)) ? HIGH : LOW); else
//power supply order anticlockwise
digitalWrite(motorPins[i],(CWStep[j] == (1<<i)) ? HIGH : LOW);
printf("motorPin %d, %d \n",motorPins[i],digitalRead(motorPins[i]));
} printf("Step cycle!\n"); if(ms<3) //the delay can
not be less than 3ms, otherwise it will exceed speed limit of the motor
ms=3; delay(ms);
}
}
Subfunction moveSteps (int dir, int ms, int steps) is used to specific cycle number of stepping motor.
void moveSteps(int dir, int ms, int steps){ int
i;
for(i=0;i<steps;i++){ moveOnePeriod(dir,ms);
}
}
Finally, in the while cycle of main function, rotate one circle clockwise, and then one circle anticlockwise. According
to the previous knowledge of the stepping motor, it can be known that the stepping motor rotation for one circle
requires 2048 steps, that is, 2048/4=512 cycle.
while(1){
moveSteps(1,3,512); //rotating 360° clockwise, a total of 2048 steps in a
circle, namely, this function(four steps) will be called 512 times.
delay(500); moveSteps(0,3,512);
//rotating 360° anticlockwise delay(500);
}
Python Code 16.1.1 SteppingMotor
First observe the project result, and then analyze the code.
1. Use cd command to enter 16.1.1_SteppingMotor directory of Python code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/16.1.1_ SteppingMotor
2. Use python command to execute code "SteppingMotor.py".
python SteppingMotor.py
After the program is executed, the stepping motor will rotate 360° clockwise and then 360° anticlockwise, circularly.
The following is the program code:
1 import RPi.GPIO as GPIO import
2 time
3 motorPins = (12, 16, 18, 22) #define pins connected to four phase ABCD of
4 stepper motor
5 CCWStep = (0x01,0x02,0x04,0x08) #define power supply order for coil for rotating
6 anticlockwise
7 CWStep = (0x08,0x04,0x02,0x01) #define power supply order for coil for rotating clockwise
8 def
9 setup():
10 print 'Program is starting...'
11 GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
12 for pin in motorPins: GPIO.setup(pin,GPIO.OUT)
13 #as for four phase stepping motor, four steps is a cycle. the function is used to
14 drive the stepping motor clockwise or anticlockwise to take four steps def
15 moveOnePeriod(direction,ms):
16 for j in range(0,4,1): #cycle for power supply order
17 for i in range(0,4,1): #assign to each pin, a total of 4 pins
18 if (direction == 1):#power supply order clockwise
19 GPIO.output(motorPins[i],((CCWStep[j] == 1<<i) and GPIO.HIGH orGPIO.LOW))
20 else : #power supply order anticlockwise
21 GPIO.output(motorPins[i],((CWStep[j] == 1<<i) and GPIO.HIGH or GPIO.LOW))
22 if(ms<3): #the delay can not be less than 3ms, otherwise it will exceed speed limit
23 of the motor ms = 3 time.sleep(ms*0.001)
24 #continuous rotation function, the parameter steps specifies the rotation cycles,
25 every four steps is a cycle def moveSteps(direction, ms, steps): for i in
26 range(steps):
27 moveOnePeriod(direction, ms)
28 #function used to stop rotating def
29 motorStop():
30
31
32
33
34
35
36 for i in range(0,4,1):
37 GPIO.output(motorPins[i],GPIO.LOW)
38 def
39 loop():
40 while True:
41 moveSteps(1,3,512) #rotating 360° clockwise, a total of 2048 steps in a
42 circle, namely, 512 cycles.
43 time.sleep(0.5) moveSteps(0,3,512)
44 #rotating 360° anticlockwise time.sleep(0.5)
45 def
46 destroy():
47 GPIO.cleanup() # Release resource
48 if __name__ == '__main__': # Program start from
49 here setup() try:
50 loop() except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child
51 program destroy() will be executed. destroy()
52
53
54
55
56
In the code, define four pins of stepping motor and coil power supply order of four steps rotation mode.
motorPins = (12, 16, 18, 22) #define pins connected to four phase ABCD of stepper
motor
CCWStep = (0x01,0x02,0x04,0x08) #define power supply order for coil for rotating
anticlockwise
CWStep = (0x08,0x04,0x02,0x01) #define power supply order for coil for rotating
clockwise
Subfunction moveOnePeriod (direction, ms) will drive the stepping motor rotating four step clockwise or
anticlockwise, four step as a cycle. Where parameter "dir" indicates the rotation direction, if "dir" is 1, the servo will
rotate forward, otherwise it rotates to reverse direction. Parameter "ms" indicates the time between each two steps.
The "ms" of stepping motor used in this project is 3ms (the shortest time), less than 3ms will exceed the speed limit
of stepping motor resulting in that motor can not rotate.
def moveOnePeriod(direction,ms):
for j in range(0,4,1): #cycle for power supply order
for i in range(0,4,1): #assign to each pin, a total of 4 pins
if (direction == 1):#power supply order clockwise
GPIO.output(motorPins[i],((CCWStep[j] == 1<<i) and GPIO.HIGH orGPIO.LOW))
else : #power supply order anticlockwise
GPIO.output(motorPins[i],((CWStep[j] == 1<<i) and GPIO.HIGH or GPIO.LOW))
if(ms<3): #the delay can not be less than 3ms, otherwise it will exceed speed limit
of the motor ms = 3
time.sleep(ms*0.001)
Subfunction moveSteps (direction, ms, steps) is used to specific cycle number of stepping motor.
def moveSteps(direction, ms, steps):
for i in range(steps):
moveOnePeriod(direction, ms)
Component List
Raspberry Pi 3B x1 Jumper
GPIO Extension Board & Wire x1
BreadBoard x1
74HC595 x1 LEDBar Graph x1 Resistor 220Ω x8
Component knowledge
74HC595
74HC595 chip is used to convert serial data into parallel data. 74HC595 can convert the serial data of one byte to 8
bits, and send its corresponding level to the corresponding 8 ports. With this feature, 74HC595 can be used to
expand the IO port of Arduino board. At least 3 ports on the RPI board are need to control 8 ports of 74HC595.
The ports of 74HC595 are described as follows:
Pin name Pin number Description
Q0-Q7 15, 1-7 Parallel data output
VCC 16 The positive electrode of power supply, the voltage is 2~6V
GND 8 The negative electrode of power supply
DS 14 Serial data Input
OE 13 Enable output,
When this pin is in high level, Q0-Q7 is in high resistance state
When this pin is in low level, Q0-Q7 is in output mode
ST_CP 12 Parallel update output: when its electrical level is rising, it will update the parallel
data output.
SH_CP 11 Serial shift clock: when its electrical level is rising, serial data input register will do
a shift.
MR 10 Remove shift register: When this pin is in low level, the content in shift register will
be cleared .
Q7' 9 Serial data output: it can be connected to more 74HC595 in series.
For more detail, please refer to the datasheet.
Circuit
Schematic diagram
Hardware connection
Code
In this project, make a flowing water light with 74HC595 to learn its usage.
C Code 17.1.1 LightWater02
First observe the project result, and then analyze the code.
1. Use cd command to enter 17.1.1_LightWater02 directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/17.1.1_LightWater02
2. Use following command to compile “LightWater02.c” and generate executable file “LightWater02”.
gcc LightWater02.c –o LightWater02 –lwiringPi
3. Then run the generated file “LightWater02”.
sudo ./LightWater02
After the program is executed, LEDBar Graph begin to display flowing water light from left to right, then from right
to left.
The following is the program code:
1 #include <wiringPi.h>
2 #include <stdio.h>
3 #include <wiringShift.h>
4
5 #define dataPin 0 //DS Pin of 74HC595(Pin14)
6 #define latchPin 2 //ST_CP Pin of 74HC595(Pin12) #define clockPin 3
7 //CH_CP Pin of 74HC595(Pin11)
8 void _shiftOut(int dPin,int cPin,int order,int val){ int i;
9 for(i = 0; i < 8; i++){ digitalWrite(cPin,LOW);
10 if(order == LSBFIRST){
11 digitalWrite(dPin,((0x01&(val>>i)) == 0x01) ? HIGH : LOW); delayMicroseconds(10
12 }
13 else {//if(order == MSBFIRST){
14 digitalWrite(dPin,((0x80&(val<<i)) == 0x80) ? HIGH : LOW); delayMicroseconds(10
15 } digitalWrite(cPin,HIGH);
16 delayMicroseconds(10);
17 }
18 } int main(void)
19 { int i; unsigned char x;
20
21
22
23
24
25
26
27
28
29
30 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen printf("setup
31 wiringPi failed !"); return 1;
32 } pinMode(dataPin,OUTPUT); pinMode(latchPin,OUTPUT); pinMode(clockPin,OUTPUT);
33 while(1){ x=0x01; for(i=0;i<8;i++){ digitalWrite(latchPin,LOW); //
34 Output low level to latchPin _shiftOut(dataPin,clockPin,LSBFIRST,x);// Send serial data to
35 74HC595 digitalWrite(latchPin,HIGH); // Output high level to latchPin, and 74HC595 will
36 update the data to the parallel output port.
37 x<<=1; // make the variable move one bit to left once, then the bright LED move one step to
38 left once.
39 delay(100);
40 } x=0x80;
41 for(i=0;i<8;i++){ digitalWrite(latchPin,LOW);
42 _shiftOut(dataPin,clockPin,LSBFIRST,x);
43 digitalWrite(latchPin,HIGH); x>>=1;
44 delay(100);
45 } } return 0;
46 }
47
48
49
50
51
52
53
54
55
56
57
58
In the code, we configure three pins to control the 74HC595. And define a one-byte variable to control the state of
8 LEDs through the 8 bits of the variable. The LED lights on when the corresponding bit is 1. If the variable is assigned
to 0x01, that is 00000001 in binary, there will be only one LED on.
x=0x01;
In the “while” cycle of main function, use “for” cycle to send x to 74HC595 output pin to control the LED. In “for”
cycle, x will be shift one bit to left in one cycle, then in the next round when data of x is sent to 74HC595, the LED
turned on will move one bit to left once.
for(i=0;i<8;i++){
digitalWrite(latchPin,LOW); // Output low level to latchPin
_shiftOut(dataPin,clockPin,LSBFIRST,x);// Send serial data to 74HC595
digitalWrite(latchPin,HIGH); // Output high level to latchPin, and 74HC595 will update
the data to the parallel output port.
x<<=1; // make the variable move one bit to left once, then the bright LED
move one step to the left once.
delay(100);
}
In second “for” cycle, the situation is the same. The difference is that x is shift from 0x80 to right in order.
<< operator
is the
"<<" and left0 shift
add on operator, which can make all bits of 1 byte shift by several bits to the left (high) direction right
the byte x = 1 (low). For example, shift binary 00000001 by 1 bit to left:
<< 1;
← ← ← ← ← ← ←
The result of x is ← 0 0 0 0 0 0 0 1 ← 0
2(binary 00000010).
0 0 0 0 0 0 1 0
There is another similar operator" >>". For example, shift binary 00000001 by 1 bit to right:
>>x1;= 1
byte
→ → → → → → →
0 0 0 0 0 0 0 0 1
The result of x is 0 (00000000) .
0 0 0 0 0 0 0 0
void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ;
void _shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ;
e data
This is used to shift an 8-bit data value out with th out on the being
cPin. sent
order is asout on dPin
above. Dataand the clock being sent
is clocked out on the rising or falling edge cPin is taken high then low – repeated for the 8 – ie. dPin is set, then
bits.
For more details about shift function, please refer to: http://wiringpi.com/reference/shift-library/
Python Code 17.1.1 LightWater02
First observe the project result, and then analyze the code.
1. Use cd command to enter 17.1.1_LightWater02 directory of Python code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/17.1.1_LightWater02
2. Use python command to execute python code “LightWater02.py”.
python LightWater02.py
After the program is executed, LEDBar Graph begin to display flowing water light from left to right, then from right
to left.
The following is the program code:
1 import RPi.GPIO as GPIO import
2 time
3 # Defines the data bit that is transmitted preferentially in the shiftOut function.
4 LSBFIRST = 1
5 MSBFIRST = 2
6 #define the pins connect to 74HC595 dataPin =
7 11 #DS Pin of 74HC595(Pin14) latchPin = 13
8 #ST_CP Pin of 74HC595(Pin12) clockPin = 15
9 #SH_CP Pin of 74HC595(Pin11)
10 def
11 setup():
12 GPIO.setmode(GPIO.BOARD) # Number GPIOs by its physical location
13 GPIO.setup(dataPin, GPIO.OUT)
14 GPIO.setup(latchPin, GPIO.OUT)
15 GPIO.setup(clockPin, GPIO.OUT)
16 # shiftOut function, use bit serial transmission.
17 def shiftOut(dPin,cPin,order,val): for i in
18 range(0,8):
19 GPIO.output(cPin,GPIO.LOW);
20 if(order == LSBFIRST):
21 GPIO.output(dPin,(0x01&(val>>i)==0x01) and GPIO.HIGH or GPIO.LOW)
22 elif(order == MSBFIRST):
23 GPIO.output(dPin,(0x80&(val<<i)==0x80) and GPIO.HIGH or GPIO.LOW)
24 GPIO.output(cPin,GPIO.HIGH);
25 def loop(): while True:
26 x=0x01 for i in
27 range(0,8):
28 GPIO.output(latchPin,GPIO.LOW) #Output low level to latchPin
29 shiftOut(dataPin,clockPin,LSBFIRST,x)#Send serial data to 74HC595
30 GPIO.output(latchPin,GPIO.HIGH)#Output high level to latchPin, and 74HC595
31 will update the data to the parallel output port.
32 x<<=1# make the variable move one bit to left once, then the bright LED move
33 one step to the left once. time.sleep(0.1) x=0x80 for i in
34 range(0,8):
35 GPIO.output(latchPin,GPIO.LOW)
36 shiftOut(dataPin,clockPin,LSBFIRST,x)
37 GPIO.output(latchPin,GPIO.HIGH) x>>=1
38 time.sleep(0.1)
39 def destroy(): # When 'Ctrl+C' is pressed, the function is
40 executed. GPIO.cleanup()
41
if __name__ == '__main__': # Program starting from
42 here
43
44
45
46
47
48
49 print ('Program is starting...')
50 setup() try:
51 loop() except
52 KeyboardInterrupt:
53 destroy()
54
In the code, we define a shiftOut() function, which is used to output value with bit in order. And where the dPin for
the data pin, cPin for the clock and order for the priority bit flag (high or low). This function conforms to the
operation mode of 74HC595.
def shiftOut(dPin,cPin,order,val):
for i in range(0,8):
GPIO.output(cPin,GPIO.LOW);
if(order == LSBFIRST):
GPIO.output(dPin,(0x01&(val>>i)==0x01) and GPIO.HIGH or GPIO.LOW)
elif(order == MSBFIRST):
GPIO.output(dPin,(0x80&(val<<i)==0x80) and GPIO.HIGH or GPIO.LOW)
GPIO.output(cPin,GPIO.HIGH);
In the loop () function, we use two “for” cycle to achieve the target. First, define a variable x=0x01, binary 00000001.
When it is transferred to the output port of 74HC595, the low bit outputs high level, then a LED is turned on. Next,
x is shifted one bit, when x is transferred to the output port of 74HC595 once again, the LED turned on will be shifted.
Repeat the operation, the effect of flowing water light will be formed. If the direction of the shift operation for x is
different, the flowing direction is different.
def loop(): while True:
x=0x01 for i in
range(0,8):
GPIO.output(latchPin,GPIO.LOW) #Output low level to latchPin
shiftOut(dataPin,clockPin,LSBFIRST,x)#Send serial data to 74HC595
GPIO.output(latchPin,GPIO.HIGH)#Output high level to latchPin, and 74HC595
will update the data to the parallel output port.
x<<=1# make the variable move one bit to left once, then the bright LED
move one step to the left once. time.sleep(0.1) x=0x80 for
i in range(0,8):
GPIO.output(latchPin,GPIO.LOW)
shiftOut(dataPin,clockPin,LSBFIRST,x)
GPIO.output(latchPin,GPIO.HIGH) x>>=1
time.sleep(0.1)
Chapter 18 74HC595 & 7-segment display.
In this chapter, we will learn a new component, 7-segment display.
Component List
Raspberry Pi 3B x1 Jumper
GPIO Extension Board & Wire x1
BreadBoard x1
74HC595 x1 7-segment display x1 Resistor 220Ω x8
Component knowledge
7-segment display
7-segment display is a digital electronic display device. There is a figure of "8" and a decimal point, which consist of
8 LED. According to the difference about common cathode and anode. its internal structure and pins diagram is
shown below:
As is known from the above circuit diagram that we can control the state of each LED separately. So, through
combining LED with different state, we can display different numbers. For example, display figure 0: we need to turn
on LED segment A, B, C, D, E, F, and turn off LED segment G and DP.
In this project, we use a display 7-segment (common anode). Therefore, when the input low level to a LED segment,
the LED will be turned on. Define segment “A” as the lowest level, the segment “DP” as the highest level, that is,
from high to low: “DP”, “G”, “F”, “E”, “D”, “C”, “B”, “A”. And character "0" corresponds to the code:
1100 0000b=0xc0.
Circuit
Schematic diagram
Hardware connection
Code
In this code, uses 74HC595 to control the 7-segment display. The usage of 74HC595 is generally the same to last
section. The content 74HC595 outputs is different. We need code character “0”- “F” one by one, and then output
them with 74HC595.
C Code 18.1.1 SevenSegmentDisplay
First observe the project result, and then analyze the code.
1. Use cd command to enter 18.1.1_SevenSegmentDisplay directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/18.1.1_SevenSegmentDisplay
2. Use following command to compile “SevenSegmentDisplay.c” and generate executable file
“SevenSegmentDisplay”.
gcc SevenSegmentDisplay.c –o SevenSegmentDisplay –lwiringPi
3. Then run the generated file “SevenSegmentDisplay”.
sudo ./SevenSegmentDisplay
After the program is executed, SevenSegmentDisplay starts to display the character “0”- “F” successively. The
following is the program code:
1 #include <wiringPi.h>
2 #include <stdio.h>
3 #include <wiringShift.h>
4
5 #define dataPin 0 //DS Pin of 74HC595(Pin14)
6 #define latchPin 2 //ST_CP Pin of 74HC595(Pin12)
7 #define clockPin 3 //CH_CP Pin of 74HC595(Pin11)
8 //encoding for character 0-F of common anode SevenSegmentDisplay.
9 unsigned char num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
10
11 void _shiftOut(int dPin,int cPin,int order,int val){ int i; for(i = 0; i < 8;
12 i++){ digitalWrite(cPin,LOW); if(order == LSBFIRST){
13 digitalWrite(dPin,((0x01&(val>>i)) == 0x01) ? HIGH : LOW); delayMicroseconds(10
14 }
15 else {//if(order == MSBFIRST){
16 digitalWrite(dPin,((0x80&(val<<i)) == 0x80) ? HIGH : LOW); delayMicroseconds(10
17 } digitalWrite(cPin,HIGH); delayMicroseconds(10);
18 }
19 }
20
21
22
23
24
25
26
27
28 int main(void)
29 { int i; if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
30 failed !"); return 1;
31 } pinMode(dataPin,OUTPUT); pinMode(latchPin,OUTPUT);
32 pinMode(clockPin,OUTPUT);
33 while(1){ for(i=0;i<sizeof(num);i++){ digitalWrite(latchPin,LOW);
34 _shiftOut(dataPin,clockPin,MSBFIRST,num[i]);//Output the figures and the highest level is t
35 digitalWrite(latchPin,HIGH); delay(500);
36 } for(i=0;i<sizeof(num);i++){ digitalWrite(latchPin,LOW);
37 _shiftOut(dataPin,clockPin,MSBFIRST,num[i] & 0x7f);//Use the "&0x7f" to display the decimal
38 digitalWrite(latchPin,HIGH); delay(500);
39 } } return 0;
40 }
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
First, put encoding of “0”-“F” into the array.
unsigned char
num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
In the “for” cycle of loop() function, use 74HC595 to output contents of array “num” successively.
SevenSegmentDisplay can correctly display the corresponding characters. Pay attention to that in shiftOut function,
the transmission bit, flag bit highest bit will be transmitted preferentially.
for(i=0;i<sizeof(num);i++){ digitalWrite(latchPin,LOW);
_shiftOut(dataPin,clockPin,MSBFIRST,num[i]);//Output the figures and the highest
level is transfered preferentially. digitalWrite(latchPin,HIGH);
delay(500);
}
If you want to display the decimal point, make the highest bit of each array become 0, which can be implemented
easily by num[i]&0x7f.
_shiftOut(dataPin,clockPin,MSBFIRST,num[i] & 0x7f);
If you want to display the decimal point, make the highest bit of each array become 0, which can be implemented
easily by num[i]&0x7f.
shiftOut(dataPin,clockPin,MSBFIRST,num[i]&0x7f)# Use “&0x7f”to display the decimal
point.
Chapter 18 74HC595 & 7
Component List
Raspberry Pi 3B x1 Jumper
GPIO Expansion Board & Wire x1
BreadBoard x1
74HC595 x1 PNP 4-Digit 7-segment display x1 Resistor 220Ω Resistor 1KΩ x4
transistor x4 x8
Component knowledge
4 Digit 7-Segment Display
4 Digit 7-segment display integrates four 7-segment display, so it can display more numbers. According to the
difference about common cathode and anode. its internal structure and pins diagram is shown below:
The internal circuit is shown below, and all 8 LED cathode pins of each 7-segment display are connected together.
Display method of 4 Digit 7-segment display is similar to 1 Digit 7-segment display. The difference between them is
that 4-Digit display in turn, one by one, not together. First send high level to common end of the first tube, and send
low level to the rest of the three common end, and then send content to 8 LED cathode pins of the first tube. At this
time, the first 7-segment display will display content and the rest three one in closed state.
Similarly, the second, third, fourth 7-segment display the content in turn, namely, scan display. Although the four
numbers are displayed in turn separately, but this process is very fast, and due to the optical afterglow effect and
people in vision persistence effect, we can see all 4 numbers at the same time. On the contrary, if each figure is
displayed for a long time, you can see that the numbers are displayed separately.
Circuit
Chapter 18 74HC595 & 7
Code
In this code, we use 74HC595 to control 4-Digit 7-segment display, and use dynamic scanning way to show the
changing numbers.
C Code 18.2.1 StopWatch
First observe the project result, and then analyze the code.
Subfunction timer (int sig) is the timer function, wich will set a alarm signal. This function wil be ececuted once at
set intervals. Accompanied by the execution, the variable counter will be added 1, and then reset the time of timer
to 1s.
void timer(int sig){ //timer function if(sig == SIGALRM){ //If the signal
is SIGALRM, the value of counter plus 1, and update the number displayed by 7-segment
display counter ++;
alarm(1); //set the next timer time
}
}
Finally, in the main function, configure all the GPIO, and set the timer function.
pinMode(dataPin,OUTPUT); //set the pin connected to74HC595 for output
mode pinMode(latchPin,OUTPUT); pinMode(clockPin,OUTPUT);
//set the pin connected to 7-segment display common end to output mode
for(i=0;i<4;i++){ pinMode(digitPin[i],OUTPUT);
digitalWrite(digitPin[i],LOW);
}
signal(SIGALRM,timer); //configure the timer
alarm(1); //set the time of timer to 1s
In the while cycle, make the digital display variable counter value. The value will change in function timer (), Chapter
18 74HC595 & 7
so the content displayed by 7-segment display will change accordingly.
while(1){ display(counter); //display
number counter
}
Python Code 18.2.1 StopWatch
This code use four step four pat mode to drive the stepping motor forward and reverse direction.
1. Use cd command to enter 16.1.1_SteppingMotor directory of Python code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/18.2.1_StopWatch
2. Use python command to execute code "StopWatch.py".
python StopWatch.py
After the program is executed, 4-Digit 7-segment start displaying a four-digit number dynamically, and the will plus
1 in each successive second.
Subfunction selectDigit (digit) function is used to open one of the 7-segment display and close the other 7segment
display, where the parameter digit value can be 1,2,4,8. Using "|" can open a number of 7-segment display.
def selectDigit(digit): #Open one of the 7-segment display and close the remaining three,
the parameter digit is optional for 1,2,4,8
GPIO.output(digitPin[0],GPIO.LOW if ((digit&0x08) == 0x08) else GPIO.HIGH)
GPIO.output(digitPin[1],GPIO.LOW if ((digit&0x04) == 0x04) else GPIO.HIGH)
GPIO.output(digitPin[2],GPIO.LOW if ((digit&0x02) == 0x02) else GPIO.HIGH)
GPIO.output(digitPin[3],GPIO.LOW if ((digit&0x01) == 0x01) else GPIO.HIGH)
Subfunction outData (data) is used to make the 74HC595 output a 8-bit data immediately.
def outData(data): #function used to output data for 74HC595
GPIO.output(latchPin,GPIO.LOW) shiftOut(dataPin,clockPin,MSBFIRST,data)
GPIO.output(latchPin,GPIO.HIGH)
Subfunction display (dec) is used to make 4-Digit 7-segment display a 4-bit integer. First open the common end of
first 7-segment display and close to the other three, at this time, it can be used as 1-Digit 7-segment display. The
first is used for displaying single digit of "dec", the second for tens digit, third for hundreds digit and fourth for
thousands digit respectively. Each digit will be displayed for a period of time through using delay (). The time in this
code is set very short, so you will see different digit is in a mess. If the time is set long enough, you will see that
every digit is display independent.
def display(dec): #display function for 7-segment display
outData(0xff) #eliminate residual display
selectDigit(0x01) #Select the first, and display the single
digit outData(num[dec%10]) time.sleep(0.003) #display
duration
Chapter 18 74HC595 & 7
outData(0xff) selectDigit(0x02) #Select the second, and display
the tens digit outData(num[dec%100/10]) time.sleep(0.003)
outData(0xff) selectDigit(0x04) #Select the third, and display the
hundreds digit outData(num[dec%1000/100]) time.sleep(0.003)
outData(0xff) selectDigit(0x08) #Select the fourth, and display the
thousands digit outData(num[dec%10000/1000]) time.sleep(0.003)
Subfunction timer () is the timer callback function. When the time is up, this function will be executed. Accompanied
by the execution, the variable counter will be added 1, and then reset the time of timer to 1s. 1s later, the function
will be executed again.
def timer(): #timer function global counter global
t t = threading.Timer(1.0,timer) #reset time of timer to
1s
t.start() #Start timing
counter+=1 print
("counter : %d"%counter)
Subfunction setup(), configure all input output modes for the GPIO pin used.
Finally, in loop function, make the digital tube display variable counter value in the while cycle. The value will change
in function timer (), so the content displayed by 7-segment display will change accordingly.
def loop():
global t
global counter
t = threading.Timer(1.0,timer) # set the timer
t.start() #Start timing
while True:
display(counter) #display the number counter
After the program is executed, press "Ctrl+C", then subfunction destroy() will be executed, and GPIO resources and
timers will be released in this subfunction.
def destroy(): # When 'Ctrl+C' is pressed, the function is executed.
global t
GPIO.cleanup()
t.cancel() # cancel the timer
Chapter 19 74HC595 & LED Matrix
We have learned how to use 74HC595 to control LEDBar Graph and Seven-SegmentDisplay. And we will continue to
use the 74HC595 to control more LED, LEDMatrix.
Component List
Raspberry Pi 3B x1 Jumper
GPIO Extension Board & Wire x1
BreadBoard x1
74HC595 x2 8*8 LEDMatrix x1 Resistor 220Ω x8
Component knowledge
LED matrix
LED matrix is a rectangular display module that consists of several LEDs. The following is an 8*8 monochrome LED
matrix with 64 LEDs (8 rows and 8 columns).
In order to facilitate the operation and save the ports, positive pole of LEDs in each row and negative pole of LEDs
in each column are respectively connected together inside LED matrix module, which is called Common Anode.
There is another form. Negative pole of LEDs in each row and positive pole of LEDs in each column are respectively
connected together, which is called Common Cathode.
The one we use in this project is a common anode LEDMatrix.
Connection mode of common anode Connection mode of common cathode
Let us learn how connection mode of common anode works. Choose 16 ports on RPI board to connect to the 16
ports of LED Matrix. Configured one port in columns for low level, which make the column of the port selected.
Then configure the eight ports in row to display content in the selected column. Delay for a moment. And then
select the next column and outputs the corresponding content. This kind of operation to column is called scan. If
you want to display the following image of a smiling face, you can display it in 8 columns, and each column is
represented by one byte.
12345678
0 0 0 0 0 0 0 0
0 0 1 1 1 1 0 0
0 1 0 0 0 0 1 0
1 0 1 0 0 1 0 1
1 0 0 0 0 0 0 1
1 0 0 1 1 0 0 1
0 1 0 0 0 0 1 0
0 0 1 1 1 1 0 0
Circuit
In this project circuit, the power pin of 74HC595 is connected to 3.3V. It can also be connected to 5V to make
LEDMatrix brighter.
Code
Two 74HC595 are used in this project used, one for controlling columns of LEDMatrix, another for lines. And two
74HC595 are connected in cascade way (series) and has 16 output port. Because shiftOut () function output 8-bit
data once, twice shiftOut () function are required and data of second stage 74HC595 should be transmitted
preferentially. There are two 74HC595 in this project circuit, A (first stage) and B (second stage). When the RPi uses
shiftOut() function to send data "data1", data of A port will be "data1", and data of B will be 0. Next, use shiftOut()
to send "data2", then data "data1" of A will be moved to B and new data "data2" will be moved to A. According to
the circuit connection, line data should be sent first, then send column data. The following code will make LEDMatrix
display a smiling face, and then display scrolling character "0-F".
C Code 19.1.1 LEDMatrix
First observe the project result, and then analyze the code.
1. Use cd command to enter 19.1.1_LEDMatrix directory of C language.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/19.1.1_LEDMatrix
2. Use following command to compile “LEDMatrix.c” and generate executable file “LEDMatrix”.
gcc LEDMatrix.c –o LEDMatrix –lwiringPi
3. Then run the generated file “LEDMatrix”.
sudo ./LEDMatrix
After the program is executed, LEDMatrix will display a smiling face, and then the display scrolling character "0-F",
circularly.
The following is the program code:
1 #include <wiringPi.h>
2 #include <stdio.h>
3 #include <wiringShift.h>
4
5 #define dataPin 0 //DS Pin of 74HC595(Pin14)
6 #define latchPin 2 //ST_CP Pin of 74HC595(Pin12)
7 #define clockPin 3 //SH_CP Pin of 74HC595(Pin11)
8 // data of smiling face unsigned char
9 pic[]={0x1c,0x22,0x51,0x45,0x45,0x51,0x22,0x1c}; unsigned char
10 data[]={ // data of "0-F"
11 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // " "
12 0x00, 0x00, 0x3E, 0x41, 0x41, 0x3E, 0x00, 0x00, // "0"
13 0x00, 0x00, 0x21, 0x7F, 0x01, 0x00, 0x00, 0x00, // "1"
14 0x00, 0x00, 0x23, 0x45, 0x49, 0x31, 0x00, 0x00, // "2"
15 0x00, 0x00, 0x22, 0x49, 0x49, 0x36, 0x00, 0x00, // "3"
16 0x00, 0x00, 0x0E, 0x32, 0x7F, 0x02, 0x00, 0x00, // "4"
17 0x00, 0x00, 0x79, 0x49, 0x49, 0x46, 0x00, 0x00, // "5"
18 0x00, 0x00, 0x3E, 0x49, 0x49, 0x26, 0x00, 0x00, // "6"
19 0x00, 0x00, 0x60, 0x47, 0x48, 0x70, 0x00, 0x00, // "7"
20 0x00, 0x00, 0x36, 0x49, 0x49, 0x36, 0x00, 0x00, // "8"
21 0x00, 0x00, 0x32, 0x49, 0x49, 0x3E, 0x00, 0x00, // "9"
22 0x00, 0x00, 0x3F, 0x44, 0x44, 0x3F, 0x00, 0x00, // "A"
Chapter 19 74HC595 & LED Matrix
23 0x00, 0x00, 0x7F, 0x49, 0x49, 0x36, 0x00, 0x00, // "B"
24 0x00, 0x00, 0x3E, 0x41, 0x41, 0x22, 0x00, 0x00, // "C"
25 0x00, 0x00, 0x7F, 0x41, 0x41, 0x3E, 0x00, 0x00, // "D"
26 0x00, 0x00, 0x7F, 0x49, 0x49, 0x41, 0x00, 0x00, // "E"
27 0x00, 0x00, 0x7F, 0x48, 0x48, 0x40, 0x00, 0x00, // "F"
28 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // " "
29 }; void _shiftOut(int dPin,int cPin,int order,int val){ int i;
30 for(i = 0; i < 8; i++){ digitalWrite(cPin,LOW);
31 if(order == LSBFIRST){ digitalWrite(dPin,((0x01&(val>>i))
32 == 0x01) ? HIGH : LOW); delayMicroseconds(10);
33 } else {//if(order ==
34 MSBFIRST){ digitalWrite(dPin,((0x80&(val<<i)) == 0x80) ?
35 HIGH : LOW); delayMicroseconds(10);
36 }
37 digitalWrite(cPin,HIGH);
38 delayMicroseconds(10);
39 } } int
40 main(void)
41 { int i,j,k;
42 unsigned char x;
43 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
44 printf("setup wiringPi failed !"); return 1;
45 }
46 pinMode(dataPin,OUTPUT);
47 pinMode(latchPin,OUTPUT);
48 pinMode(clockPin,OUTPUT); while(1){
49 for(j=0;j<500;j++){// Repeat enough times to display the smiling face a period of
50 time
51 x=0x80;
52 for(i=0;i<8;i++){
53 digitalWrite(latchPin,LOW);
54 _shiftOut(dataPin,clockPin,MSBFIRST,pic[i]);// first shift data of line
55 information to the first stage 74HC959
56 _shiftOut(dataPin,clockPin,MSBFIRST,~x);//then shift data of column
57 information to the second stage 74HC959
58
59
60
61
62
63
64
65
66
67 digitalWrite(latchPin,HIGH);//Output data of two stage 74HC595 at the
68 same time x>>=1;// display the next column delay(1);
69 } } for(k=0;k<sizeof(data)-8;k++){ //sizeof(data) total
70 number of "0-F" columns for(j=0;j<20;j++){// times of repeated displaying
71 LEDMatrix in every frame, the bigger the “j”, the longer the display time
72 x=0x80; // Set the column information to start from the first column
73 for(i=k;i<8+k;i++){ digitalWrite(latchPin,LOW);
74 _shiftOut(dataPin,clockPin,MSBFIRST,data[i]);
76 _shiftOut(dataPin,clockPin,MSBFIRST,~x);
77 digitalWrite(latchPin,HIGH); x>>=1;
78 delay(1);
79 }
80 }
81 } }
82 return 0;
83 }
84
85
86
87
88
89
90
91
The first “for” cycle in the “while” cycle is used to display a static smile. Display column information from left to right,
one column by one column, totally 8 columns. Repeat 500 times to ensure display time enough.
for(j=0;j<500;j++){// Repeat enough times to display the smiling face a period
of time x=0x80;
for(i=0;i<8;i++){ digitalWrite(latchPin,LOW);
shiftOut(dataPin,clockPin,MSBFIRST,pic[i]);
shiftOut(dataPin,clockPin,MSBFIRST,~x);
digitalWrite(latchPin,HIGH); x>>=1;
delay(1);
}
}
The second “for” cycle is used to display scrolling characters "0-F", totally 18*8=144 columns. Display the 08 column,
1-9 column, 2-10 column...... 138-144 column in turn to achieve scrolling effect. The display of each frame is
repeated a certain number of times, and the more times the number of repetitions, the longer the single frame
display, the slower the rolling.
Chapter 19 74HC595 & LED Matrix
The second “for” cycle is used to display scrolling characters "0-F", totally 18*8=144 columns. Display the 08 column,
1-9 column, 2-10 column...... 138-144 column in turn to achieve scrolling effect. The display of each frame is
repeated a certain number of times, and the more times the number of repetitions, the longer the single frame
display, the slower the rolling.
for k in range(0,len(data)-8):#len(data) total number of “O-F” columns.
for j in range(0,20):# times of repeated displaying LEDMatrix in every frame,
the bigger the “j”, the longer the display time x=0x80 # Set the
column information to start from the first column for i in range(k,k+8):
GPIO.output(latchPin,GPIO.LOW)
shiftOut(dataPin,clockPin,MSBFIRST,data[i])
shiftOut(dataPin,clockPin,MSBFIRST,~x)
GPIO.output(latchPin,GPIO.HIGH)
time.sleep(0.001) x>>=1
Chapter 20 LCD1602
In this chapter, we will learn a display screen, LCD1602.
I2C LCD1602 integrates a I2C interface, which connects the serial-input ¶llel-output module to LCD1602. We just
use 4 lines to the operate LCD1602 easily.
The serial-to-parallel chip used in this module is PCF8574(PCF8574A), and its default I2C address is 0x27(0x3F), and
you can view all the RPI bus on your I2C device address through command "i2cdetect –y 1" to. (refer to the
"configuration I2C" section below) below is the PCF8574 pin schematic diagram and the block pin diagram:
PCF8574 chip pin diagram: PCF8574 module pin diagram
PCF8574 module pin and LCD1602 pin are corresponding to each other and connected with each other:
So, we can use just 4 pins to control LCD1602 with 16 pins easily through I2C interface.
In this project, we will use I2CLCD1602 to display some static characters and dynamic variables.
Component List
Raspberry Pi 3B x1 Jumper
GPIO Extension Board & Wire x1
BreadBoard x1
I2C LCD1602 Module x1
Circuit
Note that the power supply for I2CLCD1602 in this circuit is 5V.
Schematic diagram
Hardware connection
Code
This code will get the CPU temperature and system time of RPi, display them on LCD1602.
C Code 20.1.1 I2CLCD1602
First observe the project result, and then analyze the code.
1. Use cd command to enter 20.1.1_ I2CLCD1602 directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/20.1.1_I2CLCD1602
2. Open the file I2CLCD1602.c, and find the macro definition "pcf8574_address". If your serial-to-parallel module
uses chip PCF8574, set the macro "pcf8574_address" value to 0x27.If your serial-to-parallel module uses chip
PCF8574A, set the macro "pcf8574_address" value to 0x3F.
3. Use following command to compile “I2CLCD1602.c” and generate executable file “I2CLCD1602”.
gcc I2CLCD1602.c –o I2CLCD1602 –lwiringPi –lwiringPiDev
4. Then run the generated file “I2CLCD1602”.
sudo ./ I2CLCD1602
After the program is executed, LCD1602 screen will display current CPU temperature and system time. If there is no
display or the display is not clear, adjust potentiometer of PCF8574 module to adjust the contrast of LCD1602 until
the screen can display clearly. The following is the program code:
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <wiringPi.h>
4 #include <pcf8574.h>
5 #include <lcd.h>
6 #include <time.h>
7
8 //#define pcf8574_address 0x27 // default I2C address of Pcf8574
9 #define pcf8574_address 0x3F // default I2C address of Pcf8574A
10 #define BASE 64 // BASE is not less than 64
11 //////// Define the output pins of the PCF8574, which are directly connected to the
12 LCD1602 pin.
13 #define RS BASE+0
14 #define RW BASE+1
15 #define EN BASE+2
16 #define LED BASE+3
17 #define D4 BASE+4
18 #define D5 BASE+5
19 #define D6 BASE+6
20 #define D7 BASE+7
21
22 int lcdhd;// used to handle LCD void printCPUTemperature(){//
23 subfunction used to print CPU temperature
2 FILE *fp; char
4 str_temp[15]; float
2 CPU_temp;
5 // CPU temperature data is stored in this directory.
2 fp=fopen("/sys/class/thermal/thermal_zone0/temp","r"); fgets(str_temp,15,fp);
6 // read file temp
2 CPU_temp = atof(str_temp)/1000.0; // convert to Celsius degrees
7 printf("CPU's temperature : %.2f \n",CPU_temp); lcdPosition(lcdhd,0,0);
2 // set the LCD cursor position to (0,0)
8 lcdPrintf(lcdhd,"CPU:%.2fC",CPU_temp);// Display CPU temperature on LCD
2 fclose(fp);
9
} void printDataTime(){//used to print system time time_t rawtime; struct tm
3
*timeinfo; time(&rawtime);// get system time timeinfo = localtime(&rawtime);//
0
convert to local time printf("%s \n",asctime(timeinfo)); lcdPosition(lcdhd,0,1);//
3
set the LCD cursor position to (0,1)
1
lcdPrintf(lcdhd,"Time:%d:%d:%d",timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);
3
//Display system time on LCD
2
} int
3
main(void){ i
3
nt i;
3
4 if(wiringPiSetup() == -1){ //when initialize wiring failed, print message to screen
3 printf("setup wiringPi failed !"); return 1;
5 }
3 pcf8574Setup(BASE,pcf8574_address);// initialize PCF8574
6 for(i=0;i<8;i++){
3 pinMode(BASE+i,OUTPUT); // set PCF8574 port to output mode
7 }
3 digitalWrite(LED,HIGH); // turn on LCD backlight
8 digitalWrite(RW,LOW); // allow writing to LCD
3 lcdhd = lcdInit(2,16,4,RS,EN,D4,D5,D6,D7,0,0,0,0);// initialize LCD and return “handle”
9 used to handle LCD if(lcdhd == -1){
4 printf("lcdInit failed !");
0 return 1;
4 }
1 while(1){
4 printCPUTemperature();// print CPU temperature
2 printDataTime(); // print system time
4
3
4
4
4
5
4
6
4
7
4
8
4
9
5
0
5
1
5
2
5
3
5
4
5
5
5
6
5
7
5
8
5
9
6
0
6
1
6
2
6
3
6
4
6
5
6
6
6
7
6 delay(1000);
8 } return
6 0;
9 }
7
0
It can be seen from the code that PCF8591 and PCF8574 have a lot of similarities, they are through the I2C interface
to expand the GPIO RPI. First defines the I2C address of the PCF8574 and the Extension of the GPIO pin, which is
connected to the GPIO pin of the LCD1602.
//#define pcf8574_address 0x27 // default I2C address of Pcf8574 #define
pcf8574_address 0x3F // default I2C address of Pcf8574A
#define BASE 64 // BASE is not less than 64
//////// Define the output pins of the PCF8574, which are directly connected to the
LCD1602 pin.
#define RS BASE+0
#define RW BASE+1
#define EN BASE+2
#define LED BASE+3
#define D4 BASE+4
#define D5 BASE+5
#define D6 BASE+6
#define D7 BASE+7
Then, in main function, initialize the PCF8574, set all the pins to output mode, and turn on the LCD1602 backlight.
pcf8574Setup(BASE,pcf8574_address);// initialize PCF8574
for(i=0;i<8;i++){ pinMode(BASE+i,OUTPUT); // set PCF8574
port to output mode
} digitalWrite(LED,HIGH); // turn on LCD
backlight
Then use lcdInit() to initialize LCD1602 and set the RW pin of LCD1602 to 0 (namely, can be write ) according to
requirements of this function. The return value of the function called "Handle" is used to handle LCD1602" next.
lcdhd = lcdInit(2,16,4,RS,EN,D4,D5,D6,D7,0,0,0,0);// initialize LCD and return
“handle” used to handle LCD
Details about lcdInit():
int lcdInit (int rows, int cols, int bits, int rs, int strb,
int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ;
This is the main initialization function and must be called before you use any other LCD functions. Rows
and cols are the rows and columns on the display (e.g. 2, 16 or 4,20).
on the interface (4 or 8). The rs and strb pin. The parameters d0 through
d7 are the pin numbers of display. Only the first 4 are used if you are Bits is the number of bits wide
running the display in 4- represent the pin numbers of the displays RS pin and Strobe (E) the
The return value is the ‘handle’ to be used for all subsequent calls8 to thepins
data lcd library whenfrom
connected dealing
thewith that
Pi to theLCD,
bit
or -1 to indicate a fault. (Usually incorrect parameters) For moremode.
details about LCD Library, please refer to:
library/
https://projects.drogon.net/raspberry-pi/wiringpi/lcd-
In the next “while”, two subfunctions are called to display the CPU temperature and the time. First look at subfunction
printCPUTemperature(). The CPU temperature data is stored in the
"/sys/class/thermal/thermal_zone0/temp " file. We need read contents of the file, and converts it to temperature
value stored in variable CPU_temp, and use lcdPrintf() to display it on LCD.
void printCPUTemperature(){//subfunction used to print CPU temperature
FILE *fp; char
str_temp[15];
float CPU_temp;
// CPU temperature data is stored in this directory.
fp=fopen("/sys/class/thermal/thermal_zone0/temp","r"); fgets(str_temp,15,fp);
// read file temp
CPU_temp = atof(str_temp)/1000.0; // convert to Celsius degrees
printf("CPU's temperature : %.2f \n",CPU_temp); lcdPosition(lcdhd,0,0);
// set the LCD cursor position to (0,0)
lcdPrintf(lcdhd,"CPU:%.2fC",CPU_temp);// Display CPU temperature on LCD
fclose(fp);
}
These output a single ASCII character, a string or a formatted string using the usual printf formatting
commands.
Next is subfunction printDataTime() used to print system time. First, got the standard time and store it into variable
rawtime, and then converted it to the local time and tore it into timeinfo, and finally display the time information on
LCD1602.
void printDataTime(){//used to print system
time time_t rawtime; struct tm
*timeinfo;
time(&rawtime);// get system time
timeinfo = localtime(&rawtime);// convert to local time
printf("%s \n",asctime(timeinfo)); lcdPosition(lcdhd,0,1);//
set the LCD cursor position to (0,1)
lcdPrintf(lcdhd,"Time:%d:%d:%d",timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);
//Display system time on LCD
}
Component List
Raspberry Pi 3B x1 DHT11 x1 Resistor 10kΩ x1
GPIO Expansion Board & Wire x1
BreadBoard x1
Jumper
Component knowledge
Temperature & Humidity Sensor DHT11 is a compound temperature & humidity sensor, and the output digital signal
has been calibrated inside.
It has 1S's initialization time after powered up. The operating voltage is within the range of 3.3V-5.5V.
Hardware connection
Code
The code is used to read the temperature and humidity data of DHT11, and print them out.
C Code 21.1.1 DHT11
First observe the project result, and then analyze the code.
1. Use cd command to enter 21.1.1_DHT11 directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/21.1.1_DHT11
2. Code of this project contains a custom header file. Use the following command to compile the code DHT11.cpp
and DHT.cpp and generate executable file DHT11. And the custom header file will be compiled at the same time.
gcc DHT.cpp DHT11.cpp –o DHT11 –lwiringPi
3. Run the generated file "DHT11".
sudo ./DHT11
After the program is executed, the terminal window will display the current total number of reading times, the read
state, as well as the temperature and humidity value. As is shown below:
Component List
Raspberry Pi 3B x1 4x4 Matrix Keypad x1
GPIO Expansion Board & Wire x1
BreadBoard x1
Jumper
Component knowledge
4x4 Matrix Keypad
Keypad is a device that integrates a number of keys. As is shown below, a 4x4 Keypad integrates 16 keys:
Like the integration of LED matrix, in 4x4 Keypad each row of keys is connected in with one pin and it is the same as
each column. Such connection can reduce the occupation of processor port. Internal circuit is shown below.
The usage method is similar to the Matrix LED, namely, uses a row scan or column scanning method to detect the
state of key on each column or row. Take column scanning method as an example, send low level to the first 1
column (Pin1), detect level state of row 5, 6, 7, 8 to judge whether the key A, B, C, D are pressed. And then send low
level to column 2, 3, 4 in turn to detect whether other keys are pressed. Then, you can get the state of all keys.
Code
This code is used to obtain all key code of 4x4 Matrix Keypad, when one of keys is pressed, the key code will be
printed out in the terminal window.
C Code 22.1.1 MatrixKeypad
First observe the project result, and then analyze the code.
1. Use cd command to enter 22.1.1_MatrixKeypad directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/22.1.1_MatrixKeypad
2. Code of this project contains a custom header file. Use the following command to compile the code
MatrixKeypad.cpp, Keypad.cpp and Key.cpp generate executable file MatrixKeypad. And the custom header file
will be compiled at the same time.
gcc MatrixKeypad.cpp Keypad.cpp Key.cpp –o MatrixKeypad –lwiringPi
3. Run the generated file "MatrixKeypad".
sudo ./MatrixKeypad
After the program is executed, press any key on the MatrixKeypad, the terminal will print out the corresponding key
code. As is shown below:
The library Keypad used for RPi is transplanted from the Arduino library Keypad. And the source files can be obtained
by visiting http://playground.arduino.cc/Code/Keypad. As for transplanted function library, the function and
method of all classes, functions, variables, etc. are the same as the original library. Partial contents of the Keypad
library are described below:
class Keypad
Keypad(char , byte *row, byte *col, byte numRows, byte numCols);
*userKeymap
Constructor, the parameters are : key code of keyboard, row pin, column pin, the number of rows, the
number of columns.
char getKey(); Get the
code of the pressed key. If no key is pressed, the return value is NULL.
key void setDebounceTime
Set the debounce time.(uint);
void And the default time is 10ms.
setHoldTime(uint
);
Set the time when the key
bool isPressed(char holds stable state after pressed.
keyChar);
Judge char waitForKey();
Wait forwether thebekey
a key to p with code "keyChar" is pressed.
KeyState getState();
Get state of the keys.ressed, and return key code of the pressed key.
bool keyStateChanged
Judge whether there is a change of
(); key state, then return True or False.
For More information about Keypad, please visit: http://playground.arduino.cc/Code/Keypad or through the
opening file "Keypad.hpp".
In this project code, we use two custom module "Keypad.py", which is located in the same directory with program
file "MatrixKeypad.py". And this library file, which is transplanted from Arduino function library Keypad, provides a
method to read the keyboard. By using this library, we can easily read the matrix keyboard. First, import module
Keypad. Then define the information of the matrix keyboard used in this project: the number of rows and columns,
code of each key and GPIO pin connected to each column and each row.
import Keypad #import module Keypad ROWS =
4 #number of rows of the Keypad COLS = 4
#number of columns of the Keypad keys =
[ '1','2','3','A', #key code
'4','5','6','B',
'7','8','9','C', '*','0','#','D' ] rowsPins =
[12,16,18,22] #connect to the row pinouts of the keypad colsPins =
[19,15,13,11] #connect to the column pinouts of the keypad
And then, based on the above information, instantiate a Keypad class object to operate the matrix keyboard.
keypad = Keypad.Keypad(keys,rowsPins,colsPins,ROWS,COLS)
Set the debounce time to 50ms, and this value can be set based on the actual use of the keyboard flexibly, with
default time 10ms.
keypad.setDebounceTime(50)
In the "while" cycle, use the function key= keypad.getKey () to read the keyboard constantly. If there is a key pressed,
its key code will be stored in the variable "key", and then be printed out.
while(True):
key = keypad.getKey() #get the state of keys
if(key != keypad.NULL): # if a key is pressed, print out its key code
print ("You Pressed Key : %c "%(key))
The library Keypad used for RPi is transplanted from the Arduino library Keypad. The source files is written by
language C++ and translated to Python can be obtained by visiting
http://playground.arduino.cc/Code/Keypad. As for transplanted function library, the function and method of all
classes, functions, variables, etc. are the same as the original library. Partial contents of the Keypad library are
described below:
class Keypad
def __init__( Constructed
function the number of
self,usrKeyMap,row_Pins,col_Pins,num_Rows,num_Cols):
columns. , the parameters are: key code of keyboard, row pin, column pin, the number of rows,
def getKey(self Get a
pressed ):defkey. If no key is pressed, the return value is
setDebounceTime keypad NULL.
(self,ms):
def setHoldTime Set time. And the default time is 10ms.
Set the debounce
the def(self,ms):
isPressed( Judge def the key holds stable state after pressed.
time when
waitForKey keyChar):
wether the key with code "keyChar" is
def getState(): pressed. ():
Get state
Waitofforthe to bedef
a keykeys. pressed, and return key code of the pressed key.
keyStateChanged
():
Judge whether there is a change of key state, then return True or False.
For More information about Keypad, please visit: http://playground.arduino.cc/Code/Keypad or through the
opening file "Keypad.py".
Chapter 23 Ultrasonic Ranging
In this chapter, we learn a module which use ultrasonic to measure distance, HC SR04.
In this project, we use ultrasonic ranging module to measure distance, and print out the data in the terminal.
Component List
Raspberry Pi 3B x1 HC SR501 x1
GPIO Expansion Board & Wire x1
BreadBoard x1
Jumper
Component Knowledge
Ultrasonic ranging module use the principle that ultrasonic will reflect when it encounters obstacles. Start counting
the time when ultrasonic is transmitted. And when ultrasonic encounters an obstacle, it will reflect back. The
counting will end after ultrasonic is received, and the time difference is the total time of ultrasonic from transmitting
to receiving. Because the speed of sound in air is constant, and is about v=340m/s. So we can calculate the distance
between the model and the obstacle: s=vt/2.
Ultrasonic module integrates a transmitter and a receiver. The transmitter is used to convert electrical signals
(electrical energy) into sound waves (mechanical energy) and the function of the receiver is opposite. The object
picture and the diagram of HC SR04 ultrasonic module are shown below:
Pin description:
VCC power supply pin
Trig trigger pin
Echo Echo pin
GND GND
Technical specs:
Working voltage: 5V
Working current: 12mA
Minimum measured distance: 2cm
Maximum measured distance: 200cm
Size: 45mm*20mm*15mm
Instructions for use: output a high-level pulse in Trig pin lasting for least 10uS. Then the module begins to transmit
ultrasonic. At the same time, the Echo pin will be pulled up. When the module receives the returned ultrasonic, the
Echo pin will be pulled down. The duration of high level in Echo pin is the total time of the ultrasonic from
transmitting to receiving, s=vt/2.
Circuit
Note that the voltage of ultrasonic module is 5V in the circuit.
Schematic diagram
Hardware connection
Code
C Code 23.1.1 UltrasonicRanging
First observe the project result, and then analyze the code.
1. Use cd command to enter 23.1.1_UltrasonicRanging directory of C code.
cd ~/Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/23.1.1_UltrasonicRanging
2. Use following command to compile "UltrasonicRanging.c" and generate executable file
"UltrasonicRanging".
gcc UltrasonicRanging.c –o UltrasonicRanging –lwiringPi
3. Then run the generated file "UltrasonicRanging".
sudo ./UltrasonicRanging
After the program is executed, make the detector of ultrasonic ranging module aim at the plane of an object, then
the distance between the ultrasonic module and the object will be displayed in the terminal. As is shown below:
If the module does not return high level, we can not wait forever. So we need to calculate the lasting time over
maximum distance, that is, time Out. timOut= 2*MAX_DISTANCE/100/340*1000000. The constant part behind is
approximately equal to 58.8.
#define timeOut MAX_DISTANCE*60
Subfunction getSonar () function is used to start the ultrasonic module for a measurement, and return the measured
distance with unit cm. In this function, first let trigPin send 10us high level to start the ultrasonic module. Then use
pulseIn () to read ultrasonic module and return the duration of high level. Finally calculate the measured distance
according to the time.
float getSonar(){ // get the measurement results of ultrasonic module, with unit: cm
long pingTime; float distance; digitalWrite(trigPin,HIGH); //trigPin send
10us high level delayMicroseconds(10); digitalWrite(trigPin,LOW);
pingTime = pulseIn(echoPin,HIGH,timeOut); //read plus time of echoPin
distance = (float)pingTime * 340.0 / 2.0 / 10000.0; // the sound speed is 340m/s, and
calculate distance return distance;
}
Finally, in the while loop of main function, get the measurement distance and print it out constantly.
while(1){ distance = getSonar();
printf("The distance is : %.2f cm\n",distance);
delay(1000);
}
long).
If the module does not return high level, we can not wait forever. So we need to calculate the lasting time over
maximum distance, that is, time Out. timOut= 2*MAX_DISTANCE/100/340*1000000. The constant part behind is
approximately equal to 58.8.
timeOut = MAX_DISTANCE*60
Subfunction getSonar () function is used to start the ultrasonic module for a measurement, and return the measured
distance with unit cm. In this function, first let trigPin send 10us high level to start the ultrasonic module. Then use
pulseIn () to read ultrasonic module and return the duration of high level. Finally calculate the measured distance
according to the time.
def getSonar(): #get the measurement results of ultrasonic module, with unit: cm
GPIO.output(trigPin,GPIO.HIGH) #make trigPin send 10us high level
time.sleep(0.00001) #10us GPIO.output(trigPin,GPIO.LOW) pingTime =
pulseIn(echoPin,GPIO.HIGH,timeOut) #read plus time of echoPin distance =
pingTime * 340.0 / 2.0 / 10000.0 # the sound speed is 340m/s, and calculate
distance return distance
Finally, in the while loop of main function, get the measurement distance and print it out constantly.
while(True):
distance = getSonar() print ("The
distance is : %.2f cm"%(distance)) time.sleep(1)
long).
Chapter 24 RFID
In this chapter, we will learn how to use RFID.
Component List
Raspberry Pi 3B x1 Breadboard power module x1
GPIO Extension Board & Wire x1
BreadBoard x1
Jumper M/F x7
Chapter 24 RFID
Component Knowledge
RFID
RFID(Radio Frequency Identification)is a wireless communication technology. A complete RFID system is generally
composed of the responder and reader. Generally, we use tags as responders, and each tag has a unique code, which
is attached to the object to identify the target object. The reader is a device for reading (or writing) tag information.
Products derived from RFID technology can be divided into three categories: passive RFID products, active RFID
products and semi active RFID products. And Passive RFID products are the earliest, the most mature and most
widely used products in the market among others. It can be seen everywhere in our daily life such as, the bus card,
dining card, bank card, hotel access cards, etc., and all of these belong to close-range contact recognition. The main
operating frequency of Passive RFID products are: 125KHZ (low frequency), 13.56MHZ (high frequency), 433MHZ
(ultrahigh frequency), 915MHZ (ultrahigh frequency). Active and semi active RFID products work at higher
frequencies.
The RFID module we use is a passive RFID product with the operating frequency of 13.56MHz.
MFRC522
The MFRC522 is a highly integrated reader/writer IC for contactless communication at 13.56MHz.
The MFRC522’s internal transmitter is able to drive a reader/writer antenna designed to communicate with ISO/IEC
14443 A/MIFARE cards and transponders without additional active circuitry. The receiver module provides a robust
and efficient implementation for demodulating and decoding signals from ISO/IEC 14443 A/MIFARE compatible
cards and transponders. The digital module manages the complete ISO/IEC 14443A framing and error detection
(parity and CRC) functionality
This RFID Module uses MFRC522 as the control chip, and SPI (Peripheral Interface Serial) as the reserved interface.
Technical specs:
Operating Voltage 13-26mA(DC)\3.3V
Idle current 10-13mA(DC)\3.3V
Sleep current in the <80uA
Peak current <30mA
Operating frequency 13.56MHz
Mifare1 S50、Mifare1 S70、Mifare
Supported card type
Ultralight、Mifare Pro、Mifare Desfire
Size 40mmX60mm
Operation temperature 20-80 degrees(Celsius)
Storage temperature 40-85 degrees (Celsius)
Operation humidity 5%-95%(Relative humidity)
Mifare1 S50 Card
Mifare S50 is often called Mifare Standard with the capacity of 1K bytes. And each card has a 4-bytes global unique
identifier number (USN/UID), which can be rewritten 100 thousand times and read infinite times. Its storage period
can last for 10 years. The ordinary Mifare1 S50 Card and non-standard Mifare1 S50 Card equipped for Freenove RFID
Kit are shown below.
The Mifare S50 capacity (1K byte) is divided into 16 sectors (Sector0-Sector15). Each sector contains 4 data block
(Block0-Block3. 64 blocks of 16 sectors will be numbered according absolute address, from 0 to 63). And each block
contains 16 bytes (Byte0-Byte15), 64*16=1024. As is shown in the following table:
Sector No. Block No. Storage area Block type Absolute
block No.
sector 0 block 0 vendor code vendor block 0
block 1 data block 1
block 2 data block 2
block 3 Password A-access control-password B control block 3
sector 1 block 0 data block 4
block 1 data block 5
block 2 data block 6
block 3 Password A-access control-password B control block 7
…… …… …… ……
sector 15 block 0 data block 60
block 1 data block 61
block 2 data block 62
block 3 Password A-access control-password B control block 63
Each sector has a set of independent password and access control which are put in the last block of each sector, and
the block is also known as sector trailer, that is Block 3 in each sector. Sector 0, block 0 (namely absolute address 0)
of S50 is used to store the vendor code, which has been solidified and can’t be changed, and the card serial number
is stored here. In addition to the manufacturer and the control block, the rest of the cards are data blocks, which can
be used to store data. Data block can be used for two kinds of applications:
(1) used as general data storage and can be operated for reading and writing.
(2) used as data value, and can be operated for initializing the value, adding value, subtracting and reading the value.
The sector trailer block in each sector is the control block, including a 6-byte password A, 4-byte access control and
6-byte password B. For example, the control block of a brand new card is as follows:
A0 A1 A2 A3 A4 A5 FF 07 80 69 B0 B1 B2 B3 B4 B5
password A access control password B
The default password of a brand new card is generally 0A1A2A3A4A5 for password A, B0B1B2B3B4B5 for password
B, or both the password A and password B are 6 FF. Access control is used to set the access conditions for each block
(including the control block itself) in a sector.
Blocks of S50 are divided into data blocks and control blocks. There are four operations, "read", "write", "add value",
"subtract value (including transmission and storage)" for data blocks, and there are two operations, "read" and
"write" for control blocks.
For more details about how to set data blocks and control blocks, please refer to Datasheet.
By default, after verifying password A or password B, we can do reading or writing operation to data blocks. And
after verifying password A, we can do reading or writing operation to control blocks. But password A can never be
read. If you choose to verify password A and then you forget the password A, the block will never be able to read
again. It is highly recommended that beginners should not try to change the contents of control blocks.
For Mifare1 S50 card equipped for RFID Kit, the default password A and B is FFFFFFFFFFFF.
Chapter 24 RFID
Circuit
Schematic diagram:
Hardware connection:
Configure SPI
Enable SPI
The SPI interface raspberry pie is closed in default. You need to open it manually. You can enable the SPI interface in
the following way.
Type command in the terminal:
sudo raspi-config
Then open the following dialog box:
Choose “5 Interfacing Options”“P4 SPI”“Yes”“Finish” in order and restart your RPi later. Then the SPI module
is started.
Type the following command to check whether the module SPI is loaded successfully:
ls /dev/sp*
The following result indicates that the module SPI has been loaded successfully:
Chapter 24 RFID
Code
The project code use human-computer interaction command line mode to read and write the M1-S50 card.
C Code 24.1.1 RFID
First observe the running result, and then analyze the code.
1. Use cd command to enter 24.1.1_RFID directory of C code.
cd Freenove_RFID_Starter_Kit_for_Raspberry_Pi/Code/C_Code/24.1.1_RFID
2. Use following command to compile and generate executable file "RFID".
sudo ./build.sh
3. Then run the generated file "RFID".
sudo ./RFID
After the program is executed, the following contents will be displayed in the terminal:
Here, type the command “quit” to exit the program.
Type command "scan", then the program begins to detect whether there is a card close to the sensing area of
MFRC522 reader. Place an M1-S50 card in the sensing area. The following results indicate that the M1-S50 card has
been detected, the UID of which is E6CF5C8EFB (HEX).
When the Card is placed in the sensing area, you can read and write the card through the following command.
In the command read<blockstart>, the parameter blockstart is the address of the data block, and the range is 0-63.
This command is used to display all the data from blockstart address to the end of the sector. For example, sector 0
contains data block 0,1,2,3. Using the command read 0 can display all contents of data block 0,1,2,3. Using the
command read 1 can display all contents of data block 1,2,3. As is shown below:
Command dump is used to display the content of all data blocks in all sectors.
Command <address> <data> is used to write “data" to data block with address “address”. Where the address range
is 0-63 and the data length is 0-16. For example, if you want to write the string "Freenove" to the data block with
address “1”, you can type the following command.
write 1 Freenove
Read the contents of this sector and check the data just written.
read 0
The following results indicate that the string "Freenove" has been written successfully into the data block 1.
Command clean <address> is used remove the contents of the data block with address "address". For example, if
you want to clear the contents of the data block 1 that has just been written, you can type the following command.
clean 1
Read the contents of data blocks in this sector again to test whether the data is erased. The following results indicate
that the contents of data block 1 have been erased.
10 } return
4 0;
10 } int tag_select(uint8_t *CardID)
5 { int ret_int; printf(
10 "Card detected 0x%02X 0x%02X 0x%02X 0x%02X, Check Sum = 0x%02X\r\n",
6
10
7
10
8
10
9
11
0
11
1
11
2
11
3
11
4
11
5
11
6
11
7
11 CardID[0], CardID[1], CardID[2], CardID[3], CardID[4]);
8 ret_int = MFRC522_SelectTag(CardID); if (ret_int == 0)
11 { printf("Card Select Failed\r\n"); return -1; }
9 else {
12 printf("Card Selected, Type:%s\r\n",
0 MFRC522_TypeToString(MFRC522_ParseType(ret_int)));
12 } ret_int =
1 0; return
12 ret_int;
2
}
12
3
12
4
12
5
12
6
12
7
12
8
12
9
In the code, first initialize the MFRC522. If the initialization fails, the program will exit.
ret = MFRC522_Init('A'); if
(ret < 0) { perror("Failed to
initialize"); exit(-1);
}
In the main function, wait for the command input. If command "scan" is received, the function will begin to detect
whether there is a card close to the sensing area. If a card is detected, the card will be selected and card UID will be
acquired. Then enter the function scan_loop (). If command "quit" or "exit" is received, the program will exit.
scanf("%s", command_buffer); if
(strcmp(command_buffer, "scan") == 0)
{ puts("Scanning"); while
(1) { ret = MFRC522_Check(CardID);
if (ret != MI_OK)
{ printf(".");
fflush(stdout); continue;
}
ret |= tag_select(CardID);
if (ret == MI_OK) { ret
= scan_loop(CardID); if
(ret < 0) { goto
END_SCAN; } else if (ret
== 1) { goto HALT;
}
}
}
END_SCAN: printf("Card error...");
HALT: puts("Halt");
The function scan_loop() will detect command read, write, clean, halt, dump and do the corresponding processing
to each command. The function of each command and the method have been introduced before.
int scan_loop(uint8_t *CardID) {
while (1) {
char input[32]; int block_start; DISP_COMMANDLINE();
printf("%02X%02X%02X%02X>", CardID[0], CardID[1], CardID[2], CardID[3]);
scanf("%s", input); puts((char*)input); if (strcmp(input, "halt")
== 0) { return 1;
} else if (strcmp(input, "dump") == 0)
{ if (MFRC522_Debug_CardDump(CardID) <
0) return -1;
} else if (strcmp(input, "read") == 0)
{ scanf("%d", &block_start);
if (MFRC522_Debug_DumpSector(CardID, block_start) < 0)
{ return -1;
}
} else if(strcmp(input, "clean") ==
0){ char c; scanf("%d",
&block_start);
while ((c = getchar()) != '\n' && c != EOF)
;
if (MFRC522_Debug_Clean(CardID, block_start))
{ return -1;
}
The header file "mfrc522.h" contains the associated operation method for the MFRC522. You can open the file to
view all the definitions and functions.
In the command read<blockstart>, the parameter blockstart is the address of the data block, and the range is 0-63.
As is shown below:
In the command read<blockstart>, the parameter blockstart is the address of the data block, and the range is 0-63.
This command is used to read the data of data block with address “blockstart”. For example, using command read 0
can display the content of data block 0. Using the command read 1 can display the content of data block 1. As is
shown below:
Command dump is used to display the content of all data blocks in all sectors.
Command <address> <data> is used to write “data" to data block with address “address”. Where the address range
is 0-63 and the data length is 0-16. In the process of writing data to the data block, both the contents of data block
before written and after written will be displayed. For example, if you want to write the string "Freenove" to the
data block with address “1”, you can type the following command.
write 1 Freenove
Command clean <address> is used remove the contents of the data block with address "address". For example, if
you want to clear the contents of the data block 1 that has just been written, you can type the following command.
clean 1
The function cmdloop() will detect command read, write, clean, halt, dump and do the corresponding processing to
each command. The function of each command and the method have been introduced before.
def cmdloop(cardID):
pass
while(True):
dis_ConmandLine()
dis_CardID(cardID)
inCmd = raw_input()
cmd = inCmd.split(" ")
print cmd if(cmd[0] ==
"read"): …………
elif cmd[0] ==
"dump": …………
elif cmd[0] ==
"write": …………
elif cmd[0] == "clean":
…………
elif cmd[0] == "halt":
return 0
else :
print "Usage:\r\n" "\tread <blockstart>\r\n" "\tdump\r\n" "\thalt\r\n"
"\tclean <blockaddr>\r\n" "\twrite <blockaddr> <data>\r\n"
The file "MFRC522.py" contains the associated operation method for the MFRC522. You can open the file to view all
the definitions and functions.
Chapter 25 WebIOPi & IOT
Component List
Raspberry Pi 3B x1 LED x1 Resistor 220Ω x1
GPIO Extension Board & Wire x1
BreadBoard x1
Jumper M/M x2
Hardware connection
Options:
-h, --help Display this help
-c, --config file Load config from file
-l, --log file Log to file
-s, --script file Load script from file
-d, --debug Enable DEBUG
Arguments:
port Port to bind the HTTP Server
For instance, to start with verbose output and the default config file :
sudo webiopi -d -c /etc/webiopi/config
The Port is 8000 in default.
Until now, WebIOPi has been launched, and you can press "Ctrl+C" to terminate service.
Access WebIOPi over local network
Under the same network, use mobile phone or PC browser to open your RPi IP address, and add port number like
8000. For example, my raspberry pi IP address is 192.168.1.109. Then, in the browser, should input:
http://192.168.1.109:8000/
Default user is "webiopi" and password is "raspberry"。 Then,
enter the main control interface:
Chapter 25 WebIOPi & IOT
Click on GPIO Header to enter the GPIO control interface.
About WebIOPi
The reason for changing file in the configuration process is that the model of new generation of RPi CPU is different
form old one, which result in some of the issues during using.
WebIOPi has not provide corresponding installation package for latest RPi timely. Therefore, there are two changes
in the configuration, and some BUG may exist to cause some problems to WebIOPi function. We look forward to
that the author of WebIOPi to provide a complete set of the latest version of installation package to fit with RPi.
WebIOPi can achieve far more than this, so we also look forward to learning and exploring with the funs.
What's next?
What's next?
Thanks for your reading.
This tutorial is all over here. If you find any mistakes, missions or you have other ideas and questions about
contents of this tutorial or the kit and etc, please feel free to contact us, and we will check and correct it as soon
as possible.
If you want to learn more about Arduino, Raspberry Pi, smart cars, robots and other interesting products in
science and technology, please continue to focus on our website. We will continue to launch cost-effective,
innovative and exciting products.