0% found this document useful (0 votes)
221 views

Ibrahim D. Learning Python With Raspberry Pi for..Engineers 2019

The document describes a resistive potential divider circuit program designed for electronics engineers, which calculates resistance values to achieve a desired output voltage from a given input voltage. The program prompts users for input voltage, desired output voltage, and resistance values, and then calculates the necessary resistance values. It also includes instructions for setting up and using a Raspberry Pi, along with various chapters covering Python programming and command line usage.

Uploaded by

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

Ibrahim D. Learning Python With Raspberry Pi for..Engineers 2019

The document describes a resistive potential divider circuit program designed for electronics engineers, which calculates resistance values to achieve a desired output voltage from a given input voltage. The program prompts users for input voltage, desired output voltage, and resistance values, and then calculates the necessary resistance values. It also includes instructions for setting up and using a Raspberry Pi, along with various chapters covering Python programming and command line usage.

Uploaded by

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

# RESISTIVE POTENTIAL DIVIDER

# ---------------------------
#

For Electronics Engineers


# This is a resistive potential divider circuit program.
# The program calculates the resistance values that will

Learning Python with


# lower the input voltage to the desired value
#
# Program: divider.py

Raspberry Pi
# Date : July, 2019
# Author : Dogan Ibrahim
#=======================================================
print("RESISTIVE POTENTIAL DIVIDER")
print("===========================")
R1flag = 1
R2flag = 0

while R1flag == 1:
Vin = float(raw_input("\nInput voltage (Volts): "))
Vo = float(raw_input("Desired output voltage (Volts): "))
R2 = float(raw_input("Enter R2 (in Ohms): "))
#
# Calculate R1
#
R1 = R2 * (Vin - Vo) / Vo
print("\nR1 = %3.2f Ohms R2 = %3.2f Ohms" %(R1, R2))
#
# Read chosen physical R1 and display actual Vo
#
NewR1 = float(raw_input("\nEnter chosen R1 (Ohms): "))

#
# Display and print the output voltage with chosen R1
#
print("\nWith the chosen R1,the results are:")
Vo = R2 * Vin / (NewR1 + R2)
print("R1 = %3.2F R2 = %3.2f Vin = %3.2f Vo = %3.3f" %(NewR1,R2,Vin,Vo))
#
# Check if happy with the values ?
#
happy = raw_input("\nAre you happy with the values? ")
happy = happy.lower()
if happy == 'y':
break
else:
mode = raw_input("Do you want to try again? ")
mode = mode.lower()
if mode == 'y':
R1flag = 1
Dogan Ibrahim
else:
R1flag = 0 LEARN DESIGN SHARE
break
GN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DE
HARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ●
LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE
GN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DE
HARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN
Learning Python with
Raspberry Pi
for electronic engineers

Dogan Ibrahim

LEARN DESIGN SHARE


● This is an Elektor Publication. Elektor is the media brand of
Elektor International Media B.V.
78 York Street, London W1H 1DP, UK
Phone: (+44) (0)20 7692 8344

● All rights reserved. No part of this book may be reproduced in any material form, including
photocopying, or storing in any medium by electronic means and whether or not transiently or incidentally
to some other sue of this publication, without the written permission of the copyright holder except in
accordance with the provisions of the Copyright Designs and Patents Act 1988 or under the terms of a
licence issued by the Copyright Licencing Agency Ltd., 90 Tottenham Court Road, London, England W1P
9HE. Applications for the copyright holder's permission to reproduce any part of the publication should be
addressed to the publishers.

● Declaration
The author and publisher have used their best efforts in ensuring the correctness of the information
contained in this book. They do not assume, or hereby disclaim, any liability to any party for any loss or
damage caused by errors or omissions in this book, whether such errors or omissions result from negligence,
accident or any other cause..

● Acknowledgements
The author would like to express his thanks to Ferdinand te Walvaart of Elektor for the valuable suggestions
he made throughout the duration of the preparation of this book. The author would like to thank also to his
wife Nadire for her encouragement, motivation, and for being patient with me while working on this book.

● British Library Cataloguing in Publication Data


A catalogue record for this book is available from the British Library

● ISBN 978-1-907920-80-6

© Copyright 2019: Elektor International Media b.v.


Prepress Production: D-Vision, Julian van den Berg
First published in the United Kingdom 2019
Printed in the Netherlands by Wilco

Elektor is part of EIM, the world's leading source of essential technical information and electronics products for pro
engineers, electronics designers, and the companies seeking to engage them. Each day, our international team develops
and delivers high-quality content - via a variety of media channels (including magazines, video, digital media, and social
media) in several languages - relating to electronics design and DIY electronics. www.elektormagazine.com

LEARN DESIGN SHARE


Contents

Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

Chapter 1 • Raspberry Pi 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

1.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

1.2 Parts of the Raspberry Pi 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

1.3 Requirements of the Raspberry Pi 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

1.3.1 Setup Option 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

1.3.2 Setup Option 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

1.4 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

Chapter 2 • Setting Up the Raspberry Pi 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

2.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

2.2 Installation Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

2.3 Powering Up your Raspberry Pi 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

2.4 Remote Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

2.4.1 Configuring the Putty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

2.5 Remote Access of the Desktop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

2.6 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

Chapter 3 • Using the Command Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

3.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

3.2 The Raspberry Pi Directory Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

3.3 File Permissions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

3.4 Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

3.5 Date, Time, and Calendar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

3.6 File Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

3.7 System and User Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

3.8 Resource Monitoring on Raspberry Pi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

3.9 Shutting Down . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

Chapter 4 • Using a Text Editor in Command Mode . . . . . . . . . . . . . . . . . . . . . . . . 44

4.1 nano Text Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

4.2 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

Chapter 5 • Creating and Running a Python Program . . . . . . . . . . . . . . . . . . . . . . 48

5.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

5.2 Method 1 – Interactively from Command Prompt . . . . . . . . . . . . . . . . . . . . . . . . 48

●5
Learning Python with Raspberry Pi

5.3 Method 2 – Create a Python File in Command Mode . . . . . . . . . . . . . . . . . . . . . . 49

5.4 Method 3 – Create a Python File in GUI mode . . . . . . . . . . . . . . . . . . . . . . . . . . 49

5.5 Which Method? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

5.6 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

Chapter 6 • Python Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

6.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

6.2 Variable Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

6.3 Reserved Words . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

6.4 Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

6.5 Line Continuation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

6.6 Blank Lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

6.7 More Than One Statement on a Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

6.8 Indentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

6.9 Python Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

6.10 Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

6.11 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

6.11.1 String Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

6.11.2 Escape Sequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

6.12 Print Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

6.13 List Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

6.13.1 List Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

6.14 Tuple Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

6.15 Dictionary Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

6.15.1 Dictionary Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

6.16 Keyboard Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

6.17 Comparison Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

6.18 Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

6.19 Assignment Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

6.20 Control of Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

6.20.1 if, if-else, and elif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

6.20.2 for Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

6.20.3 while Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

●6


6.20.4 continue Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

6.20.5 break Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

6.20.6 pass Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

6.21 Case Study 1 – 4 Band Resistor Colour Code Identifier . . . . . . . . . . . . . . . . . . . 70

6.22 Case Study 2 – 4 Band Resistor Colour Code Identifier Including Small Resistors . 72

6.23 Case Study 3 – Series or Parallel Resistors . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

6.24 Case Study 4 – Resistive Potential Divider . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

6.25 Trigonometric Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

6.26 User-defined Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

6.27 Example Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

6.28 Case Study 5 - Resistive Attenuator Design – Equal Source &

Load Resistances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

6.29 Case Study 6 - Resistive Attenuator Design – Unequal Source &

Load Resistances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

6.30 Recursive Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

6.31 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

6.31.1 try/finally Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

6.32 Case Study 7 – Zener Diode Based Voltage Regulator . . . . . . . . . . . . . . . . . . . 109

6.33 Date and Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

6.34 Creating Our Own Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

6.35 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116

Chapter 7 • Plotting Graphs With Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

7.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

7.2 The Matplotlib Graph Plotting Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

7.3 Case Study 8 – RC Transient Circuit Analysis - Charging . . . . . . . . . . . . . . . . . . 130

7.4 Case Study 9 – RC Transient Circuit Analysis - Discharging . . . . . . . . . . . . . . . . 132

7.5 Transient RL Circuits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

7.6 Case Study 10 – RCL Transient Circuit Analysis . . . . . . . . . . . . . . . . . . . . . . . . 136

7.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

Chapter 8 • Files in Python With the Raspberry Pi . . . . . . . . . . . . . . . . . . . . . . . . 140

8.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140

8.2 Python File Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140

●7
Learning Python with Raspberry Pi

8.3 Case Study 11 – RC Circuit Frequency Response . . . . . . . . . . . . . . . . . . . . . . . 146

8.4 Case Study 12 – Save Raspberry Pi 4 CPU Temperature in a File . . . . . . . . . . . . 148

8.5 Saving Data on an External USB Memory Stick . . . . . . . . . . . . . . . . . . . . . . . . 150

8.6 Case Study 13 – Save Raspberry Pi 4 CPU Temperature on Memory Stick . . . . . . 152

8.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

Chapter 9 • Array and Matrix Operations With Python . . . . . . . . . . . . . . . . . . . . . 155

9.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

9.2 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

9.2.1 Array Operations and Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156

9.2.2 Array Multiplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156

9.2.3 Copying Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

9.3 Systems of Linear Algebraic Equations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

9.4 Case Study 14 – DC Circuits Mesh Analysis 1 . . . . . . . . . . . . . . . . . . . . . . . . . . 160

9.5 Case Study 15 – DC Circuits Mesh Analysis 2 . . . . . . . . . . . . . . . . . . . . . . . . . . 163

9.6 Case Study 16 – DC Circuits Mesh Analysis 3 . . . . . . . . . . . . . . . . . . . . . . . . . . 164

9.7 Case Study 17 – DC Circuits Node Analysis 1 . . . . . . . . . . . . . . . . . . . . . . . . . . 165

9.8 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168

Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python . . . . . . 169

10.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169

10.2 GUI with the Tkinter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169

10.2.1 Label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170

10.2.2 Button . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173

10.2.3 Message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178

10.2.4 Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179

10.2.5 Grid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180

10.2.6 Radio Button . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181

10.2.7 Checkbox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185

10.2.8 Dialogs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187

10.2.9 Scale (Slider) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190

10.2.10 Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192

10.2.11 Binding to Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194

10.3 Case Study 18 – Resonance in Series RLC Circuits . . . . . . . . . . . . . . . . . . . . . 196

●8


10.4 Case Study 19 – Inductance of a Single Layer Coil . . . . . . . . . . . . . . . . . . . . . 200

10.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202

Chapter 11 • BJT Transistor Circuit Analysis and Design . . . . . . . . . . . . . . . . . . . 203

11.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203

11.2 BJT Transistor DC Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203

11.2.1 Collector Feedback Biasing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203

11.3 Case Study 20 – Analyzing Collector Feedback Biasing . . . . . . . . . . . . . . . . . . 203

11.4 Voltage Divider Biasing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205

11.5 Case Study 21 – Analyzing Voltage Divider Biasing . . . . . . . . . . . . . . . . . . . . . 206

11.6 Case Study 22 – Designing Transistor Amplifier Circuit . . . . . . . . . . . . . . . . . . 208

11.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213

Chapter 12 • Active Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214

12.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214

12.2 Case Study 23 – Designing Low-Pass Active Filters . . . . . . . . . . . . . . . . . . . . . 214

12.3 High-Pass Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219

12.4 Band-Pass Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219

12.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220

Chapter 13 • Accessing
 Raspberry Pi 4 Hardware and Peripheral
Devices From Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221

13.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221

13.2 GPIO – Parallel Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222

13.2.1 The GPIO Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222

13.2.2 Pin Numbering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223

13.2.3 Channel (I/O port pin) Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223

13.2.4 Case Study 24 – Flashing an LED . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226

13.3 PWM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227

13.3.1 Case Study 25 – Changing the Brightness of an LED . . . . . . . . . . . . . . . . . . 228

13.4 I2C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229

13.4.1 Case Study 26 – Using I2C LCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230

13.5 SPI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233

13.5.1 Case Study 27 – Using SPI – Analog Temperature Sensor . . . . . . . . . . . . . . . 234

13.6 The serial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239

●9
Learning Python with Raspberry Pi

13.6.1 Case Study 28 – Using Serial Communication – Serial Loopback . . . . . . . . . . 239

13.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241

Chapter 14 • Python and the Internet on Raspberry Pi 4 . . . . . . . . . . . . . . . . . . . 242

14.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242

14.2 Internet Communication Protocols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242

14.3.1 Case Study 29 – Sending a Text Message to a Mobile Phone Using TCP/IP . . . 243

14.3.2 Case Study 30 – Communicating with a PC Using TCP/IP . . . . . . . . . . . . . . . 246

14.3.3 Case Study 31 – Controlling an LED Connected to Raspberry Pi


From Mobile Phone Using TCP/IP . . . . . . . . . . . . . . . . . . . . 249

14.4 UDP Based Communication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251

14.4.1 Case Study 32 – Sending a Text Message to a Mobile Phone Using UDP . . . . . 252

14.4.2 Case Study 33 – Controlling an LED Connected to Raspberry Pi From


Mobile Phone Using UDP . . . . . . . . . . . . . . . . . . . . . . . . . . 254

14.5 U
 sing Flask to Create a Web Server to Control Raspberry Pi GPIO Ports
From the Internet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255

14.5.1 Case Study 34 – Web Server - Controlling an LED Connected to


Raspberry Pi Using Flask . . . . . . . . . . . . . . . . . . . . . . . . . . 257

14.6 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261

Chapter 15 • B
 luetooth Communication on Raspberry Pi 4
Using Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262

15.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262

15.2 Case Study 35 – Bluetooth Control of LED From a Mobile Phone . . . . . . . . . . . . 262

15.3 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268

Appendix A • Using wxPython Graphical User Interface . . . . . . . . . . . . . . . . . . . 269

A.1 wxPython Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269

A.2 Some Example Widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270

A.3 Case Study 36 – Display the Raspberry Pi 4 CPU Temperature Using wxPython . . 276

Appendix B • Object-oriented Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279

B.1 Classes and Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279

B.2 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280

B.3 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281

● 10
Preface

Preface

Python is an interpreted high-level language created in The 1990s by Guido van Rossum.
The language is procedural and object-oriented. Python is a general purpose language
which can be used for web development, general software development, mathematics and
system scripting. The latest version of Python is Python 3. However, Python 2.7 still seems
to be very popular and is used extensively. Python has some similarities to the English lan-
guage and relies on indentation to define the scope of loops, functions and classes. Other
programming languages (e.g. C) use curly-brackets for this purpose.

Python is currently the most popular teaching language. It is used as the first programming
language in most colleges and universities around the world. Most software development
companies (e.g. Google, Dropbox, Spotify, Netflix, PayPal, Reddit, etc) prefer Python lan-
guage because of its versatile features and fewer programming codes to accomplish a task.
Some of the advantages of Python can be summarized as:

• Interpreted
• Interactive
• Dynamic
• Modular
• Object-oriented
• Portable (available on Raspberry Pi as well as on the PC)
• Easy to learn
• Machine learning and artificial intelligence support
• Extensive support libraries
• Support of multitasking
• Well supported and maintained
• Free of charge

Perhaps the strongest point of Python is that it supports extensive support libraries that
include string operations, web tools, Wi-Fi and Bluetooth support, and operating system
interfaces.

Python is available on many operating systems, including Linux, Windows, MAC, and many
others. Python has recently become more popular since it is the most commonly used
programming language on the Raspberry Pi family of single-board computers. For exam-
ple, students can purchase a $50 rather powerful Raspberry Pi computer with the Python
programming language already installed. They can learn Python by experimenting on the
Raspberry Pi.

This book is about teaching the Python programming language using the Raspberry Pi 4
computer. The book is aimed for beginners, students, practicing engineers, hobbyists, and
for anyone else who may want to learn to program in Python. The book includes many ex-
ample programs and case studies. All the example programs and case studies have been
tested fully by the author and are all working. Most of the programs in the book have been
developed using Python 2.7, but they will work on Python 3 with minor changes. The graph-

● 11
Learning Python with Raspberry Pi

ics programs (tkinter) have been developed using Python 3. The example programs are
general in the sense that they aim to teach the various programming concepts of Python.
The case studies cover the use of Python in the analysis and design of electronic circuits.
Electronic engineers and readers interested in electronic circuit analysis and design will
find the case studies very useful. The following sub-headings are used while describing the
example programs and case studies:

• Title
• Description
• Aim
• Background Information
• Program Listing

Full program listings of all the programs used in the book are available at the Elektor web
site of the book. Readers should be able just to copy and use these programs in their Rasp-
berry Pi projects without any modifications. The operation of all the programs given in the
book are fully described in the book and therefore readers should find it easy to develop
these programs further, or to modify them for their own needs.

I hope you enjoy reading the book and use Python in your next Raspberry Pi project.

Dogan Ibrahim
September, 2019
London

● 12
Chapter 1 • Raspberry Pi 4

Chapter 1 • Raspberry Pi 4

1.1 Overview
Raspberry Pi has recently become one of the most popular and most powerful single-board
computers used by students, hobbyists, and professional engineers. Raspberry Pi 4 is the
latest and the most powerful version of the Raspberry Pi. In this chapter, we shall be look-
ing at the basic specifications and requirements of the Raspberry Pi 4 computer. What is
included in this chapter, can easily be applied to other models in the Raspberry Pi family.

1.2 Parts of the Raspberry Pi 4


Just like its earlier versions, Raspberry Pi 4 is a single-board computer having the following
basic specifications:

• 1.5GHz 64-bit quad-core CPU


• 1GB, 2GB, or 4GB RAM
• 2.4GHZ and 5.0GHz IEEE 802.11ac Wi-Fi
• Bluetooth 5.0 BLE
• Gigabit Ethernet
• 2 x USB 3.0, 2 x USB 2.0 and 1 x USB-C ports
• 2 x micro-HDMI ports for dual display, supporting up to 4K resolution
• DSI display and CSI camera ports
• micro SD card slot for the operating system and data storage
• 4-pole stereo audio and composite video port
• 40-pin GPIO header
• Power over Ethernet (PoE) enabled with the PoE HAT
• OpenGL ES 3.0 graphics

Figure 1 shows the Raspberry Pi 4 board with its major components identified.

● 13
Learning Python with Raspberry Pi

A brief description of the various components on the board is given below:

Processor: the processor is enclosed in a metal cap and it is based on Broadcom


BCM2711B0, which consists of a Cortex A-72 core, operating at 1.5GHz.

RAM: There are 3 versions of Raspberry Pi 4 depending on the amount of DDR4 RAM re-
quired: 1GB, 2GB, and 4GB.

USB Ports: Raspberry Pi 4 includes 2 x USB 3.0, 2 x USB 2.0, and 1 x USB-C ports. USB
3.0 data transfer rate is 4,800 Mbps (megabits per second), while USB 2.0 can transfer at
up to 480Mbps, i.e. 10 times slower than the USB 2.0. The USB-C port enables the board
to be connected to a suitable power source.

Ethernet: The Ethernet port enables the board to be connected directly to an Ethernet port
on a router. The port supports Gigabit connections (125Mbps).

HDMI: Two micro HDMI ports are provided that support up to 4K screen resolutions. HDMI
adapters can be used to interface the board to standard size HDMI devices.

GPIO: A 40-pin header is provided as the GPIO (General Purpose Input Output). This is
compatible with the earlier GPIO ports.

Audio and Video Port: A 3.5mm jack type socket is provided for stereo audio and com-
posite video interface. Headphones can be connected to this port. External amplifier de-
vices will be required to connect speakers to this port. This port also supports composite
video, enabling TVs, projectors, and other composite video compatible display devices to
be connected to the port.

CSI Port: This is the camera port (Camera Serial Interface), allowing a compatible camera
to be connected to the Raspberry Pi.

DSI Port: This is the display port (Display Serial Interface), allowing a compatible display
(e.g. 7 inch Raspberry Pi display) to be connected to the Raspberry Pi.

PoE Port: This is a 4-pin header, allowing the Raspberry Pi to receive power from a net-
work connection.

Micro SD Card: This card is mounted on the cardholder placed at the bottom of the board
and it holds the operating system software as well as the operating system and user data.

1.3 Requirements of the Raspberry Pi 4


As listed below, a number of external devices are required before the Raspberry Pi can be
used:

● 14
Chapter 1 • Raspberry Pi 4

• Power supply
• Micro SD card
• Operating system software
• USB keyboard and mouse
• Micro HDMI cable to receive sound and video signals
• HDMI compatible display or TV (you may also need to have micro HDMI to DVI-D
or VGA adapters. A 3.5mm TRRS type cable and plug will be required if you will
be using an old TV with composite video)

Power Supply: A 5V 3A power supply with USB-C type connector is required. You may ei-
ther purchase the official Raspberry Pi 4 power supply (Figure 1.2), or use a USB-C adapter
to provide power from an external source.

Figure 1.2 Official Raspberry Pi 4 power supply

Micro SD Card: It is recommended to use a micro SD card with a capacity of at least 8GB,
although higher capacity (e.g. 16GB or 32GB) is better as there will be room to grow in the
future. A Class 10 (or faster) card is recommended.

Operating System: You can purchase the operating system pre-loaded on a micro SD
card, known as NOOBS (New Out Of Box Software) which require minimum configuration
before it is fully functional. The alternative is to purchase a blank micro SD card and upload
the operating system on this card. The steps to prepare a new micro SD card with the op-
erating system is given in the next chapter.

USB Keyboard and Mouse: You can either use a wireless or wired keyboard and mouse
pair. If using a wired pair, you should connect the keyboard to one of the USB ports and the
mouse to another USB port. If using a wireless keyboard and mouse, you should connect
the wireless dongle to one of the USB ports.

Display: A standard HDMI compatible display monitor with a micro HDMI to standard HDMI
adapter can be used. Alternatively, a VGA type display monitor with a micro HDMI to VGA
adapter or DVI-D adapter can be used. If you have an old TV with composite video inter-

● 15
Learning Python with Raspberry Pi

face, then you can connect it to the Raspberry Pi 3.5mm port with a TRRS type connector.
You may also consider purchasing additional parts, such as a case, CPU fan, and so on. A
case is very useful as it protects your Raspberry Pi electronics. The working temperature of
the CPU can go as high as 80 degrees Centigrade. Using a fan (see Figure 1.3) makes the
CPU more efficient as it can lower its temperature by about 50%.

Figure 1.3 Raspberry Pi 4 CPU fan (www.seeedstudio.com)

1.3.1 Setup Option 1


As shown in Figure 1.4, in this option various devices are connected directly to the Raspber-
ry Pi 4. Depending on what type of display monitor we have, we can use an HDMI display,
VGA monitor, DVI-D monitor, or TV. Notice that depending on the external USB devices
used, you can use either the USB 2.0 or the USB 3.0 ports.

● 16
Chapter 1 • Raspberry Pi 4

Figure 1.4 Raspberry Pi 4 setup - option 1

1.3.2 Setup Option 2


In this option, as shown in Figure 1.5, a powered hub is used to connect the USB devices.

Figure 1.5 Raspberry Pi 4 setup – option 2

● 17
Learning Python with Raspberry Pi

1.4 Summary
In this chapter we have learned the main parts and their functions on the Raspberry Pi 4
board. In addition, we have learned how to setup the Raspberry Pi 4.

In the next chapter we shall be installing the operating system on a new blank micro SD
card.

● 18
Chapter 2 • Setting Up the Raspberry Pi 4

Chapter 2 • Setting Up the Raspberry Pi 4

2.1 Overview
In this chapter we shall be learning how to install the Raspberry Pi 4 operating system
Raspbian on a new blank micro SD card. If you have purchased a pre-installed micro SD
card with NOOBS, you do not need to do anything else other than plug it into your Rasp-
berry Pi.

2.2 Installation Steps


The instructions to install the operating system on a blank micro SD card using the NOOBS
are given below. You will need a micro SD card with a capacity of at least 8GB, although
16GB is recommended for future expansion and installing new applications and programs.
You might need a standard size SD card adapter to insert the micro SDcard into your com-
puter's card slot. The steps are as follows:

• Activate the following link to select the operating system as shown in Figure 2.1,
and click NOOBS.

https://www.raspberrypi.org/downloads/

Figure 2.1 Operating system selection

• As shown in Figure 2.2, there are two versions of the software: NOOBS and
NOOBS Lite. You should select to download NOOBS as it contains the Raspbian
operating system and other products. Click Download ZIP under NOOBS and
save the file in a folder (e.g. C:\RPI).

● 19
Learning Python with Raspberry Pi

Figure 2.2 Click Download ZIP under NOOBS

• We should now format our micro SD card using SD Card Association Card For-
matter tool. Install this tool from the following site (see Figure2.3):

https://www.sdcard.org/downloads/formatter/

Figure 2.3 Install the SD card formatter

• Insert your micro SD card into the card reader of your PC and run the card for-
matter application. Give a volume name (e.g. RPI or NOOBS) and select Quick
Format and click Format (see Figure 2.4) after making sure that you have se-
lected the card. The formatting process should take only a few seconds.

● 20
Chapter 2 • Setting Up the Raspberry Pi 4

Figure 2.4 Format the micro SD card

• We can now install the operating system on the card. Double click the operating
system file in folder C:\RPI and unzip it into the same directory.

• Select all the files (except unzipped file NOOBS_v3_1_1) in folder C:\RPI and
drag them to your micro SD card (Figure2.5).

Figure 2.5 Select files and drag to the SD card

• When the files are all copied, remove the SD card from your PC and insert into
your Raspberry Pi.

2.3 Powering Up your Raspberry Pi 4


Connect the power supply cable, keyboard, mouse, and display to your Raspberry Pi and
apply power. After a short while you will see the startup menu on the display as shown in
Figure 2.6. Select the Raspbian operating system and click the Install button. Click YES to

● 21
Learning Python with Raspberry Pi

confirm to install the Raspbian operating system. You should see the message Raspbian
Full: Creating filesystem at the bottom of the display (Figure 2.7). Wait for 5 to 10 min-
utes until the operating system has been installed and ready on the SD card (See Figure
2.8). You should see a progress bar at the bottom of the display as the installation process
continues.

Figure 2.6 Raspberry Pi 4 installation startup menu

Figure 2.7 Installing the operating system

● 22
Chapter 2 • Setting Up the Raspberry Pi 4

Figure 2.8 End of installation

At this point, you are given the option of selecting a Wi-Fi network. In Figure 2.9, BTHome-
Spot-XNH is selected as the Wi-Fi network and the password id entered.

Figure 2.9 Select a Wi-Fi network

Move the mouse pointer over the blue Wi-Fi icon at the top right-hand side of the display
and you should see the IP address assigned to the Raspberry Pi. As shown in Figure 2.10,
the address 192.168.1.202 was assigned to the Raspberry Pi.

Figure 2.10 Raspberry Pi IP address

The IP address of the Raspberry Pi could also be displayed by entering command ifconfig
to a terminal session as shown in Figure 2.11.

● 23
Learning Python with Raspberry Pi

Figure 2.11 Result of command ifconfig

2.4 Remote Access


It is much easier to access the Raspberry Pi remotely over the Internet, for example using
a PC rather than connecting a keyboard, mouse, and display to it. Before being able to
access the Raspberry Pi remotely, we have to enable the SSH and the VNC by entering the
following command at a terminal session:

pi$raspberrypi:~ $ sudo raspi-config

Go to the configuration menu and select Interface Options. Go down to P2 SSH (see
Figure 2.12) and enable SSH. Click <Finish> to exit the menu.

Figure 2.12 Enable SSH

You should also enable VNC so that the Raspberry Pi can be accessed graphically over the
Internet. This can be done by entering the following command at a terminal session:

pi$raspberrypi:~ $ sudo raspi-config

Go to the configuration menu and select Interface Options. Go down to P3 VNC and
enable VNC. Click <Finish> to exit the menu.

● 24
Chapter 2 • Setting Up the Raspberry Pi 4

At this stage, you may want to shutdown your Raspberry Pi by clicking the Applications
Menu on Desktop and selecting the Shutdown option as shown in Figure 2.13.

Figure 2.13 Shutting down the Raspberry Pi

The program we will be using on our PC to access the Raspberry Pi is called Putty, where
it can be downloaded from the following link:

https://www.putty.org/

Putty is a standalone program and there is no need to install it. Simply double click to run
it and the Putty startup screen will be displayed. Click SSH and enter the Raspberry Pi IP
address, then click Open (see Figure 2.14). The message shown in Figure 2.15 will be
displayed the first time you access the Raspberry Pi. Click Yes to accept this security alert.

● 25
Learning Python with Raspberry Pi

Figure 2.14 Putty startup screen

Figure 2.15 Click Yes to accept

You will be prompted to enter the username and password. After a successful login, you
should see the command prompt as in Figure 2.16.

Figure 2.16 Successful login

● 26
Chapter 2 • Setting Up the Raspberry Pi 4

2.4.1 Configuring the Putty


By default, the Putty screen background is black with white foreground characters. The
author prefers to have a white background with black foreground characters, with the char-
acter size set to 12 points bold. The steps to configure the Putty with these settings are
given below. Notice that in this example these settings are saved with the name RPI4 so
that they can be recalled whenever the Putty is re-started:

• Restart Putty
• Select SSH and enter the Raspberry Pi IP address
• Click Colours under Window
• Set the Default Foreground and Default Bold Foreground colours to black
(Red:0, Green:0, Blue:0)
• Set the Default Background and Default Bold Background to white (Red:255,
Green:255, Blue:255)
• Set the Cursor Text and Cursor Colour to black (Red:0, Green:0, Blue:0)
• Select Appearance under Window and click Change in Font settings. Set the
font to Bold 12.
• Select Session and give a name to the session (e.g. RPI4) and click Save.
• Click Open to open the Putty session with the saved configuration (see Figure
2.17)
• Next time you re-start the Putty, select the saved session and click Load followed
by Open to start a session with the saved configuration

Figure 2.17 Starting Putty with the saved configuration

2.5 Remote Access of the Desktop


If you are using your Raspberry Pi with local keyboard, mouse, and display you can skip this
section. If on the other hand, you want to access your Desktop remotely over the network,
you will find that SSH services cannot be used. The easiest and simplest way to access your
Desktop remotely from a computer is by installing the VNC (Virtual Network Connection)
client and server. The VNC server runs on your Pi and the VNC client runs on your comput-
er. The steps to install and use the VNC are given below:

• Connect to your Raspberry Pi using the Putty as explained earlier. Then, enter
the following command to install a program called TightVNC server on your Pi
computer. You will see many lines of messages and make sure that there are no
error messages:

● 27
Learning Python with Raspberry Pi

pi@raspberrypi:~ $ sudo apt-get update


pi@raspberrypi:~ $ sudo apt-get install tightvncserver

• Run the VNC server on your Raspberry Pi computer by entering the following
command:

pi@raspberrypi:~ $ vncserver :1

• You will be prompted to enter and verify a password. This will be the password
you will be using to access the Desktop remotely (see Figure 2.18).

Figure 2.18 Enter a password for the VNC server

• The VNC server is now running on your Raspberry Pi. The only command you
need to enter on your Pi computer to start the VNC server is:

pi@raspberrypi:~ $ vncserver :1

• We must now setup a VNC client on our laptop (or desktop). There are many VNC
clients available, but the recommended one which is compatible with TightVNC
is the TightVNC for the PC which can be downloaded from the following link:

https://www.tightvnc.com/download.php

• Download and install the TightVNC software for your PC. You will have to choose
a password during the installation.

• Start the TightVNC Viewer on your PC and enter the Raspberry Pi IP address
(see Figure 2.19) followed by :1. Click Connect to connect to your Raspberry Pi.

● 28
Chapter 2 • Setting Up the Raspberry Pi 4

Figure 2.19 Start the TightVNC and enter the IP address

Enter the password you have chosen earlier. You should now see the Raspberry Pi Desktop
displayed on your PC screen as shown in Figure 2.20.

Figure 2.20 Raspberry Pi Desktop on your PC screen

2.6 Summary
In this chapter we have seen how to install the Raspbian operating system on our Raspber-
ry Pi 4. We have also learned how to access our Raspberry Pi remotely. In the next chapter
we shall be looking at some of the commonly used commands.

● 29
Learning Python with Raspberry Pi

Chapter 3 • Using the Command Line

3.1 Overview
Raspberry Pi operating system is based on a version of the Linux operating system. Linux
is one of the most popular operating systems in use today. Linux is very similar to other
operating systems, such as Windows and Unix. Linux is an open operating system based
on Unix and has been developed collaboratively by many companies and universities since
1991. In general, Linux is harder to manage than some other operating systems like Win-
dows, but offers more flexibility and wider configuration options. There are several popular
versions of the Linux operating system such as Debian, Ubuntu, Red Hat, Fedora and so on.
In this chapter we shall be looking at some of the commonly used Raspberry Pi commands
that we can enter from the command line. The commands entered by the user are shown
in bold for clarity.

3.2 The Raspberry Pi Directory Structure


The Raspberry Pi directory structure consists of a single root directory, with directories and
subdirectories under the root. Different operating system programs, applications, and user
data are stored in different directories and subdirectories.

The root directory is identified by the "/" symbol. Under the root we have directories
named such as bin, boot, dev, etc, home, lib, lost+found, media, mnt, opt, proc,
and many more. The important directory as far as the users are concerned is the home
directory which contains subdirectories for each user of the system. The full path to the
home directory is /home/pi. We can move to our home directory from any other directory
by entering the command cd ~

Some useful directory commands are given below. Command pwd displays the user home
directory:

pi@raspberrypi:~ $ pwd
/home/pi
pi@raspberrypi:~ $

To show the directory structure, enter the command ls / as shown in Figure 3.1.

Figure 3.1 List the directory structure

To show the subdirectories and files in our home directory, enter ls as shown in Figure 3.2.

Figure 3.2 List of files in our home directory

● 30
Chapter 3 • Using the Command Line

The ls command can take a number of arguments. Some examples are given below:
To display the subdirectories and files in a single row:

pi@raspberrypi:~ $ ls -1

To display the file type, enter the following command. Note that directories have a "/" after
their names, executable files have a "*" character after their names:

pi@raspberrypi:~ $ ls -F

To list the results separated by commas:

pi@raspberrypi:~ $ ls –m

We can mix the arguments as in the following example:

pi@raspberrypi:~ $ ls –m –F

subdirectories are created using command mkdir followed by the name of the subdirecto-
ry. In the following example, subdirectory myfiles is created in our working directory (see
Figure 3.3).

Figure 3.3 Creating a subdirectory

Use command rmdir followed by the subdirectory name to remove a subdirectory.

3.3 File Permissions


One of the important arguments used with the ls command is "-l" (lower case letter l)
which displays the file permissions, file sizes, and when they were last modified. In the
example in Figure 3.4, each line relates to one directory or file. Reading from right to left,
the name of the directory or the file is on the right-hand side. The date the directory or
the file was created is on the left-hand side of its name. Next comes the size in bytes. The
characters at the beginning of each line are about the permissions. i.e. who is allowed to
use or modify the file or the subdirectory.

● 31
Learning Python with Raspberry Pi

Figure 3.4 File permissions example

The permissions are divided into 3 categories:

• What the user (or owner, or creator) can do – called USER


• What the group owner (people in the same group) can do – called GROUP
• What everyone else can do – called WORLD

The first pi in the example shows who the user of the file (or subdirectory) is, and the sec-
ond word pi shows the group name that owns the file (or subdirectory). In this example,
both the user and the group names are pi.

The permissions can be analysed by breaking down the characters into four chunks for: File
type, User, Group, World. The first character for a file is "-", and for a directory, it is "d".
Next comes the permissions for the User, Group and World. The permissions are as follows:

• Read permission (r): the permission to open and read a file or to list a directory
• Write permission (w): the permission to modify a file, or to delete or create a file
in a directory
• Execute permission (x): the permission to execute the file (applies to executable
files), or to enter a directory

The three letters rwx are used as a group and if there is no permission assigned then a "-"
character is used.

As an example, considering the Music subdirectory, we have the following permission


codes:

drwxr-xr-x which translates to:

d: it is a directory
rwx: user (owner) can read, write, and execute
r-x: group can read and execute, but cannot write (e.g. create or delete)
r-x: world (everyone else) can read and execute, but cannot write

● 32
Chapter 3 • Using the Command Line

The chmod command is used to change the file permissions. Before going into details of
how to change the permissions, let us look and see what arguments are available in chmod
for changing the file permissions.

The available arguments for changing file permissions are given below. We can use these
arguments to add/remove permissions or to explicitly set permissions. It is important to
realize that if we explicitly set permissions then any unspecified permissions in the com-
mand will be revoked:

u: user (or owner)


g: group
o: other (world)
a: all

+: add
-: remove
=: set

r: read
w: write
x: execute

To change the permissions of a file we type the chmod command, followed by one of the
letters u, g, o, or a to select the people, followed by the + - or = to select the type of
change, and finally followed by the filename. An example is given below. In this example,
subdirectory Music has the user read and write permissions. We will be changing the per-
missions so that the user does not have read permission on this file:

pi@raspberrypi ~$ chmod -u -r Music


pi@raspberrypi ~$ ls –l

The result is shown in Figure 3.5.

Figure 3.5 File permissions of subdirectory Music

● 33
Learning Python with Raspberry Pi

In the following example, rwx user permissions are given to subdirectory Music:

pi@raspberrypi ~$ chmod u+rwx Music

Figure 3.6 shows the new permissions of subdirectory Music.

Figure 3.6 New permissions of subdirectory Music

To change our working directory the command cd is used. In the following example we
change our working directory to Music:

pi@raspberrypi ~$ cd /home/pi/Music
pi@raspberrypi ~/Music $

to go up one directory level, i.e. to our default working directory:

pi@raspberrypi ~/Music $ cd..


pi@raspberrypi ~$

to change our working directory to Music, we can also enter the command:

pi@raspberrypi ~$ cd ~/Music
pi@raspberrypi ~/myfiles $

to go back to the default working directory, we can enter:

pi@raspberrypi ~/Music $ cd ~
pi@raspberrypi ~$

to find out more information about a file we can use the file command. For example:

pi@raspberrypi ~$ file Music


Music: directory
pi@raspberrypi ~$

● 34
Chapter 3 • Using the Command Line

the –R argument of command ls lists all the files in all the subdirectories of the current
working directory. An example is shown in Figure 3.7.

Figure 3.7 Using command –R with ls

3.4 Help

Man
To display information on how to use a command, we can use the man command. As an
example, to get help on using the mkdir command:

pi@raspberrypi ~$ man mkdir


MKDIR(1)

NAME
Mkdir – make directories

SYNOPSIS
Mkir [OPTION]…DIRECTORY…

DESCRIPTION
Create the DIRECTORY(ies), if they do not already exist.

Mandatory arguments to long options are mandatory for short options

-m, --mode=MODE
Set file mode (as in chmod), not a=rwx – umask
-------------------------------------------------------------------------
-------------------------------------------------------------------------

Enter Cntrl+Z to exit from the man display.

Help
The man command usually gives several pages of information on how to use a command.
We can type q to exit the man command and return to the operating system prompt.

The less command can be used to display a long listing one page at a time. Using the up
and down arrow keys, we can move between pages. An example is given below. Type q to
exit:

pi@raspberrypi ~$ man ls | less


<display of help on using the ls command>
pi@raspberrypi ~$

● 35
Learning Python with Raspberry Pi

3.5 Date, Time, and Calendar


To display the current date and time the date command is used. Similarly, the cal com-
mand displays the current calendar. Figure 3.8 shows an example.

Figure 3.8 Commands: date and cal

3.6 File Operations

Copying a File
To make copy of a file, use the command cp. In the following example, a copy of file
mytestfile.txt is made and the new file is given the name test.txt:

pi@raspberrypi ~$ cp mytestfile.txt test.txt

Wildcards
We can use wildcard characters to select multiple files with similar characteristics. e.g. files
having the same file-extension names. The "*" character is used to match any number of
characters. Similarly, the "?" character is used to match any single character. In the exam-
ple below all the files with extensions ".txt" are listed:

pi@raspberrypi ~$ ls *.txt

The wildcard characters [a-z] can be used to match any single character in the specified
character range. An example is given below which matches any files that start with letters
o, p, q, r, s, and t, and with the ".txt" extension:

pi@raspberrypi ~$ ls [o-t]*.txt

Renaming a File
you can rename a file using the mv command. In the example below, the name of file test.
txt is changed to test2.txt:

pi@raspberrypi ~$ mv test.txt test2.txt

● 36
Chapter 3 • Using the Command Line

Deleting a File
The command rm can be used to remove (delete) a file. In the example below file test2.
txt is deleted:

pi@raspberrypi ~$ rm test2.txt

the argument –v can be used to display a message when a file is removed. Also, the –i
argument asks for confirmation before a file is removed. In general, the two arguments are
used together as –vi. An example is given below:

pi@raspberrypi ~$ rm –vi test2.txt


rm: remove regular file 'test2.txt'? y
removed 'test2.txt'
pi@raspberrypi ~$

Removing a Directory
A directory can be removed using the rmdir command:

pi@raspberrypi ~$ rmdir Music

Re-directing the Output


The greater sign > can be used to re-direct the output of a command to a file. For example,
we can re-direct the output of the ls command to a file called lstest.txt:

pi@raspberrypi ~$ ls > lstest.txt

The cat command can be used to display the contents of a file:

pi@raspberrypi ~$ cat mytestfile.txt


This is a file
This is line 2
pi@raspberrypi ~$

Using two greater signs >> adds to the end of a file.

Writing to the Screen or to a File


The echo command can be used to write to the screen. It can be used to perform simple
mathematical operations if the numbers and the operation are enclosed in two brackets,
preceded by a $ character:

pi@raspberrypi ~$ echo $((5*6))


30
pi@raspberrypi ~$

● 37
Learning Python with Raspberry Pi

The echo command can also be used to write a line of text to a file. An example is shown
below:

pi@raspberrypi ~$ echo a line of text > lin.dat


pi@raspberrypi ~$ cat lin.dat
a line of text
pi@raspberrypi ~$

Matching a String
The grep command can be used to match a string in a file. An example is given below
assuming that the file lin.dat contains sting a line of text. Notice that the matched word
is shown in bold:

pi@raspberrypi ~$ grep line lin.dat


a line of text
pi@raspberrypi ~$

Head and Tail Commands


The head command can be used to display the first 10 lines of a file. The format of this
command is as follows:

pi@raspberrypi ~$ head mytestfile.txt


…………………………………..
…………………………………..
pi@raspberrypi ~$

Similarly, the tail command is used to display the last 10 lines of a file. The format of this
command is as follows:

pi@raspberrypi ~$ tail mytestfile.txt


………………………………….
………………………………….
pi@raspberrypi ~$

3.7 System and User Information


These commands are useful as they tell us information about the system. Command cat /
proc/cpuinfo displays information about the processor (command cat displays the con-
tents of a file. In this example, the contents of file /proc/cpuinfo is displayed). Since
there are 4 cores in the Raspberry Pi 4, the display is in 4 sections. Figure 3.9 shows an
example display, where only part of the display is shown here.

● 38
Chapter 3 • Using the Command Line

Figure 3.9 Command: cat /proc/cpuinfo (only part of the output is shown)

Command uname –s displays the operating system Kernel name, which is Linux. Com-
mand uname –a displays complete detailed information about the Kernel and the operat-
ing system.

Command cat /proc/meminfo displays information about the memory on your Pi. Infor-
mation such as the total memory and free memory at the time of issuing the command are
displayed.

Command whoami displays the name of the current user. In this case it displays pi.

A new user can be added to our Raspberry Pi using the command useradd. In the example
in Figure 3.10, user called Johnson is added. A password for the new user can be added
using the passwd command followed by the username. In Figure 3.10, the password for
user Johnson is set to mypassword (not displayed for security reasons). Notice that both
the useradd and passwd are privileged commands and the keyword sudo must be en-
tered before these commands. Notice that the –m option creates a home directory for the
new user.

Figure 3.10 Commands: useradd and passwd

We can login to the new user account by specifying the username and the password.

What Software is Installed on My Raspberry Pi


To find out what software is installed on your Raspberry Pi, enter the following command.
You should get several pages of display:

● 39
Learning Python with Raspberry Pi

pi@raspberrypi ~$ dpkg –l
…………………………….
…………………………….
pi@raspberrypi ~$

We can also find out if a certain software package is already installed on our computer. An
example is given below which checks whether or not software called xpdf (PDF reader) is
installed. In this example, xpdf is installed and the details of this software are displayed:

pi@raspberrypi ~$ dpkg --s xpdf


Package: xpdf
Status: install ok installed
Priority: optional
Section: text
Installed-Size: 395
………………………….
………………………….
pi@raspberrypi ~$

If the software is not installed we get a message similar to the following (assuming we are
checking to see if a software package called bbgd is installed):

pi@raspberrypi ~$ dpkg –s bbgd

dpkg-query: package 'bbgd' is not installed and no information is available

……………………………………………………………………………..
…………………………………………………………………………….
pi@raspberrypi ~$

Super User Commands


Some of the commands are privileged and only the authorized persons can use them.
Inserting the word sudo at the beginning of a command gives us the authority to use the
command without having to log in as an authorized user.

3.8 Resource Monitoring on Raspberry Pi


System monitoring is an important topic for managing usage of your Raspberry Pi. One of
the most useful system monitoring commands is the top, which displays the current usage
of system resources and displays which processes are running and how much memory and
CPU time they are consuming.

Figure 3.11 shows a typical system resource display obtained by entering the following
command (Enter Ctrl+Z to exit):

pi@raspberrypi ~$ top
pi@raspberrypi ~$

● 40
Chapter 3 • Using the Command Line

Figure 3.11 Typical system resource display

Some of the important points in Figure 3.11 are summarized below (for lines 1 to 5 of the
display):

• There are a total of 149 processes in the system


• Currently, only one process is running, 146 processes are sleeping, and
2 processes are in Zombie state
• The percentage CPU utilization is 0.0us for user applications (us)
• The percentage CPU utilization for system applications is 5.2 (sy)
• There are no processes requiring more or less priority (ni)
• 94.8% of the time the CPU is idle (id)
• There are no processes waiting for I/O completion (wa)
• There are no processes waiting for hardware interrupts (hi)
• There are no processes waiting for software interrupts (si)
• There is no time reserved for a hypervisor (st)
• The total usable memory is 1939.5MB, of which 151.3MB bytes are in use,
1353.7MB are free, and 434.5MB are used by buffers/cache
• Line 5 displays the swap space usage

The process table gives the following information for all the processes loaded to the system:

• PID: the process ID number


• USER: owner of the process
• PR: priority of the process
• NI: the nice value of the process
• VIRT: the amount of virtual memory used by the process
• RES: size of the resident memory
• SHR: shared memory the process is using
• S: process status (sleeping, running, zombie)
• %CPU: the percentage of CPU consumed

● 41
Learning Python with Raspberry Pi

• %MEM: percentage of RAM used


• TIME+: total CPU time the task used
• COMMAND: The actual name of the command

The ps command can be used to list all the processes used by the current user. An example
is shown in Figure 3.12.

Figure 3.12 Command: ps

the command ps –ef gives a lot more information about the processes running in the sys-
tem.

Killing a Process
There are many options for killing (or stopping) a process. A process can be killed by spec-
ifying its PID and using the following command:

pi@raspberrypi ~$ kill -9 <PID>

Disk Usage
The disk free command df can be used to display the disk usage statistics. An example is
shown in Figure 3.13. option –h displays in human-readable form.

Figure 3.13 Command: df

3.9 Shutting Down


Although you can disconnect the power supply from your Raspberry Pi when you finish
working with it, it is not recommended since there are many processes running on the sys-
tem and it is possible to corrupt the file system. It is much better to shut down the system
in an orderly manner.

● 42
Chapter 3 • Using the Command Line

The following command will stop all the processes and make the file system safe and then
turn off the system safely:

pi@raspberrypi ~$ sudo halt

the following command stops and then re-starts the system:

pi@raspberrypi ~$ sudo reboot

the system can also be shut down and then re-started after a time by entering the following
command. Optionally, a shutdown message can be displayed if desired:

pi@raspberrypi ~$ shutdown –r <time> <message>

3.10 Summary
This chapter has described the use of some of the important Linux commands. You should
be able to get further information on each command and other Linux commands from the
internet and from other books on Raspberry Pi and Linux.

In the next chapter we shall see how to use a text editor which may be required for devel-
oping our Python programs.

● 43
Learning Python with Raspberry Pi

Chapter 4 • Using a Text Editor in Command Mode

A text editor is used to create or modify the contents of a text file. There are many text ed-
itors available for the Linux operating system. Some popular ones are nano, vim, vi, and
many more. In this chapter, we shall be learning how to use the nano which is the most
commonly used text editor in Linux.

4.1 nano Text Editor


Start the nano text editor by entering the word nano, followed by the filename you wish
to create or modify. An example is given below where a new file called first.txt is created:

pi@raspberrypi ~ $ nano first.txt

You should see the editor screen as in Figure 4.1. The name of the file to be edited is written
at the top middle part of the screen. The message "New File" at the bottom of the screen
shows that this is a newly created file. The shortcuts at the bottom of the screen are there
to perform various editing functions. These shortcuts are accessed by pressing the Ctrl key
together with another key. Some of the useful shortcuts are given below:

Ctrl+W: Search for a word

Ctrl+V: Move to next page

Ctrl+Y: Move to previous page

Ctrl+K: Cut the current row of txt

Ctrl+R: Read file

Ctrl+U: Paste the text you previously cut

Ctrl+J: Justify

Ctrl+\: Search and replace text

Ctrl+C: Display current column and row position

Ctrl+G: Get detailed help on using the nano

Ctrl+-: Go to specified line and column position

Ctrl+O: Save (write out) the file currently open

Ctrl+X: Exit nano

● 44
Chapter 4 • Using a Text Editor in Command Mode

Figure 4.1 nano text editor startup screen

Now, type the following text into the file:

nano is a simple and yet powerful text editor.


This simple text example demonstrates how to use nano.
This is the last line of the example.

The use of nano is now demonstrated with the following steps:

Step 1: Go the beginning of the file by moving the cursor.

Step 2: Look for word simple by pressing Ctrl+W and then typing simple in the window
opened at the bottom left-hand corner of the screen. Press the Enter key. The cursor will
be positioned on the word simple (see Figure 4.2).

Figure 4.2 Searching word simple

● 45
Learning Python with Raspberry Pi

Step 3: Cut the first line by placing the cursor anywhere on the line and then pressing
Ctrl+K. The first line will disappear.

Step 4: Paste the line cut after the first line. Place the cursor on the second line and press
Ctrl+U (see Figure 4.3).

Figure 4.3 Paste the line cut previously

Step 5: Place cursor at the beginning of the word simple in the first row. Enter Ctrl+C.
The row and column positions of this word will be displayed at the bottom of the screen.

Step 6: Press Ctrl+G to display the help page as in Figure 4.4. Notice that the display is
many pages long and you can jump to the next pages by pressing Ctrl+Y or to the previous
pages by pressing Ctrl+V. Press Ctrl+X to exit the help page.

Figure 4.4 Displaying the help page

Step 7: Press Ctrl+- and enter line and column numbers as 2 and 5, followed by the Enter
key, to move cursor to line 2, column 5.

Step 8: Replace word example with word file. Press Ctrl+\ and type the first word as
example (see Figure 4.5). Press Enter and then type the replacement word as file. Press
Enter and accept the change by typing y.

● 46
Chapter 4 • Using a Text Editor in Command Mode

Figure 4.5 Replacing text

Step 9: Save the changes. Press Ctrl+X to exit the file. Type Y to accept the saving, then
enter the filename to be written to, or simply press Enter to write to the existing file (first.
txt in this example). The file will be saved in your current working directory.

Step 10: Display the contents of the file:

pi@raspberrypi ~ $ cat first.txt

This simple text file demonstrates how to use nano.


Nano is a simple and yet powerful text editor
This is the last line of the example.

pi@raspberrypi ~ $

In summary, nano is a simple and yet powerful text editor allowing us to create new text
files or to edit existing files.

4.2 Summary
Text editors are useful in creating new text files, or for modifying the contents of a text file.
Notice that a text editor is not the same as a word processing software. Word processing
software inserts additional control characters inside a text such as bold, underline, and
other formatting characters.

In this chapter, we have seen how to use two of the popular Linux text editor nano. The
remainder of the book is devoted to the Python programming language.

● 47
Learning Python with Raspberry Pi

Chapter 5 • Creating and Running a Python Program

5.1 Overview
In this chapter, we shall be learning how to create and then run a very simple Python pro-
gram. As described in this chapter, basically there are three methods that we can use to
create and run a Python program. The text message Hello From Raspberry Pi 4 will be
displayed on our screen as an example.

Two versions of the Python language are distributed with the Raspberry Pi at the time of
writing this book: Version 2 and 3. The actual version numbers can be displayed by enter-
ing the command python --version as shown in Figure 5.1. The display shows that the
two versions are 2.7.16 and 3.7.3. The advantage of using Python 3 is that most of the new
libraries are being developed for Python 3. Some of the Python 2.7 libraries are not com-
patible with Python 3.7. Python 3.7 has improved integer division, better Unicode support.
Additionally, version 3.7 has better error handling and improved GUI support.

Figure 5.1 Displaying the Python versions

5.2 Method 1 – Interactively from Command Prompt


In this method, we will log in to our Raspberry Pi 4 using the SSH and then create and run
our program interactively. This method is excellent for small programs. The steps are as
follows:

• Login to the Raspberry Pi 4 using SSH

• At the command prompt enter python. You should see the Python command
mode which is identified by three characters >>>

• Type the program:

print ("Hello From Raspberry Pi 4")

• The required text will be displayed interactively on the screen as shown in Figure
5.2

Figure 5.2 Running a program interactively

● 48
Chapter 5 • Creating and Running a Python Program

• Enter Cntrl+X to exit Python

Notice that by default, entering command python invokes version 2.7. If you wish to use
version 3.7 then you should enter the command python3 instead.

5.3 Method 2 – Create a Python File in Command Mode


In this method, we will log in to our Raspberry Pi 4 using the SSH as before and then create
a Python file. A Python file is simply a text file with the extension .py. We can use a text
editor, e.g. the nano text editor to create our file. In this example, a file called hello.py
is created using the nano text editor. Figure 5.3 shows the contents of file hello.py. This
figure also shows how to run the file from the command line. Notice that the program is
run by entering the command:

pi@raspberrypi:~ $ python hello.py

Figure 5.3 Creating and running a Python file

5.4 Method 3 – Create a Python File in GUI mode


In this method, we will log in to our Raspberry Pi 4 using the VNC and create and run our
program in GUI mode on the Desktop. The steps are given below:

• Connect to your Raspberry Pi using the VNC Viewer

• Click to open the Applications menu on Desktop

• Click Programming and then click Thonny Python IDE (see Figure 5.4)

Figure 5.4 Select Python programming environment

• Type in your program as shown in Figure 5.5 and save it e.g. with the name
hello2

● 49
Learning Python with Raspberry Pi

Figure 5.5 Type in your program

• Run the program by clicking Run. You should see the program output displayed
at the bottom part of the screen as shown in Figure 5.6.

Figure 5.6 Run the program

5.5 Which Method?


The choice of a method depends upon the size and complexity of a program. Small pro-
grams or small code to test an idea can be run interactively without creating a program file.
Larger programs can be created as Python files and then they can run either in the com-
mand mode or in the GUI mode. In this book, the interactive method, as well as method 2
are used in the programming examples.

5.6 Summary
In this chapter, we have learned how to create and run a Python program. In the remaining
chapters, of the book we will concentrate on the Python programming language.

● 50
Chapter 6 • Python Programming

Chapter 6 • Python Programming

6.1 Overview
Python is an interpreted, interactive and object-oriented programming language. It was
developed by Guido van Rossum in the 1980s at the National Institute for Mathematics and
Computer Science in the Netherlands. It is derived from many other languages including
C, C++, Modula-3, SmallTalk, and Unix shell. The language is now maintained by a team
of people at the Institute.

Python is interactive which means that you can issue a command and see the result im-
mediately without having to compile the command. It is interpreted, thus requiring no
pre-compilation before it is run.

Python supports object oriented techniques of programming. It is a beginners' language


which is easy to learn and easy to maintain. Beginners can easily learn to programme in
a relatively short period of time. Python supports a large library of functions which makes
it very powerful. The language is portable, meaning that it can run on several different
popular platforms.

In this and next chapters, we will be looking at the details of the Python programming
language on the Raspberry Pi computer, and see how we can write programs using this
language. Many example programs are given to show how electronic engineers can use the
Python language to help them in their calculations.

6.2 Variable Names


Python variable names are case sensitive and can start with a letter A to Z or a to z or
an underscore character "_", followed by more letters or numbers 0 to 9. Some valid and
invalid example variable names are given below:

SUM - valid
Sum - valid
SUm - valid
_total - valid
Cnt5 - valid
8tot - invalid
%int - invalid
&xyz - invalid
My_Number - valid
@loop - invalid
_Account - valid

Note that variables total, Total, TOTAL, ToTaL, or toTAL are all different.

● 51
Learning Python with Raspberry Pi

6.3 Reserved Words


There are some names which are reserved for use by the Python interpreter and thus can-
not be used as variable names by programmers. A list of these reserved names is given
below. Notice that all the reserved names contain lower case letters:

and for raise


assert from return
break global try
class if while
continue i mport with
def in yield
del is
elif lambda
else not
except or
exec pass
finally print

6.4 Comments
Comment lines in Python start with a hash sign "#". All characters after the # sign are
ignored by the Python interpreter. An example comment line is shown below:

# This is a comment line

Comments can also be inserted after a statement:

Sum = 0 # Another comment

6.5 Line Continuation


The line continuation character "\" can be used to continue a statement on the following
lines. An example is shown below:

Sum = a +\
b +\
c

Which is equivalent to:

Sum = a + b + c

6.6 Blank Lines


A line containing no statements is ignored by the Python interpreter.

● 52
Chapter 6 • Python Programming

6.7 More Than One Statement on a Line


It is permissible to have more than one statement on a single line by separating the state-
ments with a semicolon character. An example is given below:

cnt = 5; sum = 0; tot = 20;

6.8 Indentation
In most programming languages blocks of code are identified by using braces at the begin-
ning and end of the block, or by identifying the end of the block using a suitable statement.
e.g. END, WEND, or ENDIF. In Python language, there are no braces or statements to indi-
cate the start and end of a block. Instead, blocks of code are identified by line indentation.
All statements within a block must be indented the same amount. The actual number of
spaces used to indent a block is not important as long as all the statements in the block use
the same number of spaces.

A valid block of code is given below (don't worry at this stage what the code does):

if j == 5:
a = a + 1
b = a + 2
else:
a = 0
b = 0

The following block of code is not valid since the indentation is not correct:

if j == 5:
a = a + 1
b = a + 2
else:
a = 0
b = 0

6.9 Python Data Types


Python supports the following data types:

• Numbers
• Strings
• Lists
• Dictionaries
• Tuples
• Sets
• Files

● 53
Learning Python with Raspberry Pi

6.10 Numbers
Python supports the following numeric variable types:

• int - signed integer


• long - long integer
• float - floating-point real number
• Complex number

Numbers can be represented in decimal, octal, binary, or hexadecimal. Long integers are
shown with an upper case letter L.

Some example numbers are shown below:

Integer

100 - decimal
-67 - decimal
500 - decimal
0x20 - hexadecimal
0b10000001 - binary
0o2377 - octal
202334567L - long decimal
0x3AEEFAE - hexadecimal

Floating point

2.355
23.780
-45.6
1.298
24.45E4

Complex

24.4+2,6j
0.78-4.2j
23.7j

We can assign numeric values to variables. These variable objects are created when values
are assigned to them:

sum = 28
a = 0

● 54
Chapter 6 • Python Programming

We can delete a variable object by using the del statement:

del sum, a

We can assign a value to several variables at the same time:

w = x = y = z = 0

Similarly, we can have statements of the form:

w, x, y = 3, 5, 8

Which is equivalent to:

w = 3
x = 5
y = 8

we can perform the following mathematical operations on numbers:

Expression Operators

+ addition
- Subtraction
* multiplication
/ division
>> shift right
<< shift left
** power (exponentiation)
% remainder

Bitwise Operators

| bitwise OR
& bitwise AND
^ bitwise exclusive-or
~ bitwise complement

Some Mathematical Functions

pow(x,y) same as x**y


abs(x) absolute value of x
round(x,n) round x to n digits from the decimal point
floor(x) largest integer not greater than x
int(x) convert x to integer
hex(x) hexadecimal equivalent of integer x

● 55
Learning Python with Raspberry Pi

bin(x) binary equivalent of integer x


exp(x) exponential of x
factorial(n) factorial of number n
ceil(x) smallest integer not less than x
log(x) natural logarithm of x (base 2)
log10(x) logarithm of x (base 10)

Some Mathematical Utility Libraries

random number library


math mathematics library

Figure 6.1 to Figure 6.3 show examples of using numbers in Python. Statement import
is used to import a library to a Python program. math library contains a large number of
mathematical functions, such as logarithmic functions, trigonometric function, square root,
hyperbolic functions, angular conversion, and so on. Further details on these functions can
be obtained from the following link:

https://docs.python.org/3/library/math.html

random library is useful to generate random numbers. Function randint(a, b) in this li-
brary generates an integer random number between integers a and b inclusive. Details of
functions available in the random library can be obtained from the following link:

https://docs.python.org/2/library/random.html

Figure 6.1 Using numbers in Python

● 56
Chapter 6 • Python Programming

Figure 6.2 Using numbers in Python

Figure 6.3 Using numbers in Python

6.11 Strings
In Python, strings are declared by enclosing characters between a pair of single or double
quotation marks. An example is given below:

myname = "James Booth"

We can manipulate strings by extracting characters, joining two strings, assigning a string
to another string, and so on. Some commonly used string manipulation operations are
shown in Figure 6.4 and Figure 6.5.

● 57
Learning Python with Raspberry Pi

Figure 6.4 String manipulation operations

Figure 6.5 String manipulation operations

Notice that a third index as the step can be used in string slicing operation. The step is add-
ed to the first offset until the second offset and the character at this position is extracted.
In the following example, the characters at positions 0, 2, 4, 6 are extracted:

>>> a = "computer"
>>> b = a[0:7:2]
>>> print(b)
cmue

6.11.1 String Functions


Python supports a large number of string functions. Some commonly used string functions
are given below:

● 58
Chapter 6 • Python Programming

• capitalize() change first letter of a string to upper case and all other
characters to lower case
• count(str,beg,end) find how many times str occurs in a string. String start-
ing and ending positions should be specified
• find(str,beg,end) determine if str occurs in a string. String starting and
ending positions should be specified. The index is re-
turned if the str is found, otherwise -1 is returned
• len(string) return the length of a string
• isalpha() return true if string contains all alphabetical characters
• isalnum()  return true if string contains alphabetical and numeric
characters
• isdigit() return true if string contains all digits
• islower() return true if string contains all lower case letters
• isupper() return true if string contains all upper case letters
• lower() convert all upper case characters to lower case
• upper() convert all lower case characters to upper case
• lstrip() remove all leading white spaces
• rstrip() remove all trailing spaces
• swapcase() change case of all letters

Figure 6.6 shows examples of using some of the string functions.

Figure 6.6 Using the string functions

6.11.2 Escape Sequences


Escape sequences are special non-printable characters used to generate functions such as
newline, tab, formfeed, carriage return and so on. Escape sequences start with character
"\". A list of the commonly used escape sequences is given below:

• \n newline
• \a bell
• \b backspace

● 59
Learning Python with Raspberry Pi

• \f formfeed
• \r carriage return
• \t horizontal tab
• \v vertical tab
• \xhh character with 2 hexadecimal value hh

As an example, the following statement will display letter a followed by two newlines:

print("a\n\n")

6.12 Print Statement


The print statement is one of the most commonly used statements. It displays text or num-
bers on the screen. Text is displayed by enclosing it in quotes. Numeric data is displayed by
simply entering the variable name. The data to be displayed is enclosed in round brackets.
Text and numeric data can be mixed in display outputs and the type of the variable to be
displayed can be declared using formatting characters. A list of the commonly used format-
ting characters is given below:

• %c character
• %s string
• %d signed integer
• %u unsigned integer
• %x lower case hexadecimal number
• %X upper case hexadecimal number
• %f floating-point number
• %E exponential notation

Figure 6.7 shows some examples of using the print statement.

Figure 6.7 Using the print statement

● 60
Chapter 6 • Python Programming

6.13 List Variables


List variables are variables separated by commas and enclosed in square brackets. The
variables in a list can be of different types. The contents of a list can be accessed using
square brackets to index the required item inside the list. Indexing starts from 0. As with
the strings, the "*" character can be used for repetition and the "+" character can be used
for concatenation. Some examples are given below:

mylist = ['John', 'Adam', 230, 12.25, 'Peter', 89]


second = [30, 23]

s = mylist[0] # s = 'John'
s = mylist[2] # s = 230
s = mylist[2:4] # s = 230, 12.25
s = mylist[3:] # s = 12.25, 'Peter', 89
s = mylist * 2 # s = 
'John', 'Adam', 230, 12.25, 'Peter', 89, 'John',
'Adam', 230, 12.25, 'Peter', 89
s = mylist + second # s = 'John', 'Adam', 230, 12.25, 'Peter', 89, 30, 23

The contents of a list can be modified by assigning a new value to the required index po-
sition. For example, we can change the 2nd element of the list mylist from 230 to 100 as:

mylist[2] = 100

Python does not allow to reference items that are not present in a list. For example, the
following statement gives an error message:

mylist[200]

Lists can be nested to form two dimensional matrices. An example is given below:

M = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]

The nested list is indexed starting from [0][0]. For example, the elements of row 1 can be
accessed as follows:

>>> M[1] # Elements of row 1


[4, 5, 6]

>>> M[1][1] # Element at row 1, column 1


5

The statement L = [ ] creates an empty list called L.

● 61
Learning Python with Raspberry Pi

6.13.1 List Functions


Python language supports large number of list functions. Some commonly used list func-
tions are given below:

• del([i:j]) delete elements from i to j-1


• list.append(x) append an item to the end of a list
• list.extend([x,y,z]) add several items to the list
• cmp(L1,L2) compare elements of lists L1 and L2
• len(L) length of list L
• max(L) item with the maximum value
• min(L) item with the minimum value
• list.count(x) returns how many times x occurs in a list
• list.index(x) returns the position of the first occurrence of x
• list.insert(i,x) inserts x at position i in the list
• list.remove(x) removes the indexed item from the list
• list.reverse() reverses a list
• list.sort() sorts a list
• list.pop() delete and return the last item

Figure 6.8 shows some examples of using the print statement.

Figure 6.8 Using the list functions

6.14 Tuple Variables


Tuples are similar to lists but their contents cannot be changed. i.e. they are read-only.
Also, tuple variables are enclosed in round brackets (parenthesis). Some examples are
given below:

● 62
Chapter 6 • Python Programming

mytuple = ['John', 'Adam', 230, 12.25, 'Peter', 89]

second = [30, 23]

s = mytuple[0] # s = 'John'
s = mytuple[2] # s = 230
s = mytuple[2:4] # s = 230, 12.25
s = mytuple[3:] # s = 12.25, 'Peter', 89
s = mytuple * 2 # s = 'John', 'Adam', 230, 12.25, 'Peter', 89, 'John',
'Adam', 230, 12.25, 'Peter', 89
s = mytuple + second # s = 'John', 'Adam', 230, 12.25, 'Peter', 89, 30,
23

The following statement is not valid since we cannot change the contents of a tuple:

mytuple[2] = 200

6.15 Dictionary Variables


Dictionaries are similar to hash tables with keys and values. Each key is separated from
its value by a colon sign, the items are separated by command, and the whole thing is en-
closed in curly brackets. The keys in a dictionary must have data types of numbers, strings,
or tuples. The values can be of any data type. An example is given below:

mydict = {'Name': 'John', 'Surname': 'Adams', 'Age': 25}


s = mydict['Name'] # s = 'John'
s = mydict['Age'] # s = 25
s = mydict.keys() # s = ['Age', 'Surname', 'Name']
s = mydict.values() # s = [125, 'Adams', 'John']

6.15.1 Dictionary Functions


Python language supports large number of dictionary functions. Some commonly used dic-
tionary functions are given below:

• cmp(d1, d2) compare two dictionaries d1 and d2


• len() the number of items in a dictionary
• del(d[key]) delete an item from the dictionary
• d.clear remove all items from the dictionary
• d.keys() return a list of dictionary keys
• d.values() return a list of dictionary values

Figure 6.9 shows some examples of using the print statement.

● 63
Learning Python with Raspberry Pi

Figure 6.9 Using the dictionary functions

6.16 Keyboard Input


Python provides the following function for reading data from the keyboard:

• raw_input provides a prompted read. The data from the keyboard is re-
turned as a string

figure 6.10 shows examples of using the keyboard input function. Notice that the function
returns a string. Therefore, if numeric data is entered then it should be converted into a
numeric data type before being used in mathematical operations.

Figure 6.10 Keyboard input examples

Notice that Python version 3 provides the statement called input for reading prompted
data from the keyboard. This statement evaluates the data read i.e. it identifies whether
the user entered a string or a number or a list.

6.17 Comparison Operators


Valid Python comparison operators are:

• == checks if two operands are equal


• != checks if two operands are not equal
• > checks if the left operand is greater than the right one

● 64
Chapter 6 • Python Programming

• < checks if the left operand is less than the right one
• >= checks if the left operand is greater than or equal to the right one
• <= checks if the left operand is less than or equal to the right one

6.18 Logical Operators


Valid Python logical operators are:

• and logical AND of the two operands


• or logical OR of the two operands
• not logical inverse of the operand

6.19 Assignment Operators

• = assignment operator
• += compound add operator
• -= compound subtract operator
• *= compound multiply operator
• /= compound divide operator

6.20 Control of Flow


In normal program flow, statements are executed sequentially one after another one. The
flow control statements are used to make decisions and change the order of execution de-
pending on the results of these decisions.

Python programming language supports the following flow control statements:

• if
• if-else
• elif
• for
• while
• break
• continue
• pass

6.20.1 if, if-else, and elif


The general format of the if statement is:

if expression: statement
or
if expression:
Statement 1
Statement 2
else:
Statement 1
Statement 2

● 65
Learning Python with Raspberry Pi

Notice the use of indentation inside the if blocks and the colon character at the end of the
if and else statements.

An example use of the if statement is:

if a == 5: print('a is 5')

if there is only one statement after the if, then it can be typed on the same line. If there is
more than one statement then all the statements must be written on the next lines with
the same amount of indentation. An example is given below:

if a == 100:
x = 0
y = 0
else:
x = 1
y = 10

The elif statement is used to check for different conditions in an if block. An example is
given below:

if a > 10:
b = 0
c = 0
elif a == 10:
b = 2
c = 4

Notice that the if statements can be nested as shown in the following example:

if a == 100:
c = 0
k = 1
if b == 10:
c = 20
m = 1
else:
c = 23

6.20.2 for Statement


The for statement is used to create loops (iteration) in programs. The general format of
this statement is:

for variable in sequence:


statements

● 66
Chapter 6 • Python Programming

Here, the sequence is evaluated first and the first item in the sequence is assigned to the
variable and the statements are executed. Then the second item is assigned to the varia-
ble and the statements are executed. This continues until there are no more items in the
sequence. An example use of the for statement is shown below:

for letter in "COMPUTER":


print(letter)

The following will be displayed on the screen:

C
O
M
P
U
T
E
R

The for statement is commonly used to create loops in programs. The range statement
denotes the range of the variable as in the following example:

for cnt in range(0, 5):


print(cnt)

The following will be displayed on the screen:

0
1
2
3
4

Notice that the upper value of the range is one less than the specified value i.e. in the above
example, the range is from 0 to 4 and not to 5.

We can specify a step size in the last parameter when using the range statement, in the
following example, the step size is 5 and the list takes values 0, 5, 10, 15, 20, 25:

List(range(0, 30, 5))

The for statement can be nested if desired.

● 67
Learning Python with Raspberry Pi

6.20.3 while Statement


The while statement can also be used to create loops (iteration) in programs. The general
format of this statement is:

while expression:
statements

The statements are executed while the expression evaluates to True. An example is given
below:

cnt = 0
while cnt < 5:
print(cnt)
cnt = cnt + 1

The output of the program is as follows:

0
1
2
3
4

Notice that the statements that belong to the while statement must be indented. It is im-
portant to make sure that the expression is modified inside the loop, otherwise, an infinite
loop will be formed as shown in the following example:

cnt = 0
while cnt < 5:
print(cnt)

6.20.4 continue Statement


The continue statement is used in for and while loops and this statement skips all the re-
maining statements in a loop and returns to the beginning of the loop. An example is given
below. In this example, number 3 is not displayed by the print statement:

cnt = 0
while cnt < 5:
cnt = cnt + 1
if cnt == 3:
continue
print(cnt)

● 68
Chapter 6 • Python Programming

The output of this example is as follows:

1
2
4
5

6.20.5 break Statement


The break statement is used in for and while loops and this statement terminates the loop
and execution continues with the next statement. An example is given below:

cnt = 0
while cnt < 5:
cnt = cnt + 1
if cnt == 3:
break
print(cnt)

The output of this program is as follows:

1
2

6.20.6 pass Statement


The pass statement is used when a statement is required syntactically but you do not want
any command or code to execute. The pass statement is a null operation and nothing hap-
pens when it executes. An example is given below:

for letter in 'COMPUTER':


if letter == 'P':
pass
print('Passed')
print(letter)

The output of this program is:

C
O
M
Passed
P
U
T
E
R

● 69
Learning Python with Raspberry Pi

We have covered the basic statements of the Python programming language. We will now
develop several projects using the knowledge we have gained so far.

6.21 Case Study 1 – 4 Band Resistor Colour Code Identifier


Description: In this project the user enters the three colours of a 4 band resistor and the
program calculates and displays the value of the resistor in Ohms. The tolerance of the
resistor is not displayed.

Aim: The aim of this case study is to show how the keyboard input, lists and control state-
ments can be used in a program.

Background Information: Resistor values are identified by the following colour codes:

Black: 0
Brown: 1
Red: 2
Orange: 3
Yellow: 4
Green: 5
Blue: 6
Violet: 7
Grey: 8
White: 9

First two colour determine the first two digits of the value while the last colour determines
the multiplier. For example, red red red corresponds to 22 x 102 = 2200 Ohms.

Program Listing: Figure 6.11 shows the program listing (program: resistor.py). At the
beginning of the program, a list called colour is created which stores the valid resistor
colours. Then a heading is displayed and a while loop is created which runs as long as
string variable yn is equal to y. Inside the loop the program reads the three colours from
the keyboard using functions raw_input and stores as strings in variables FirstColour,
SecondColour and ThirdColour. These strings are then converted into lower case so that
they are compatible with the values listed in the list box. The index values of these colours
in the list are then found using function calls of the form colours.index. Remember that
the index values start from 0. As an example, if the user entered red then the correspond-
ing index value will be 2. The resistor value is then calculated by multiplying the first colour
number by 10 and adding to the second colour number. The result is then multiplied by
the power of 10 of the third colour index. The final result is displayed on the screen. The
program then asks whether or not the user wants to continue. If the answer is y then the
program returns to the beginning, otherwise the program is terminated.

#===================================================
# RESISTOR COLOUR CODES
# ---------------------
#

● 70
Chapter 6 • Python Programming

# The user enters the three colours of a resistor


# and the program calculates and displays the value
# of the resistor in Ohms
#
# Program: resistor.py
# Date : July, 2019
# Author : Dogan Ibrahim
#===================================================
colours = ['black','brown','red','orange','yellow','green',\
'blue','violet','grey','white']

print("RESISTOR VALUE CALCULATOR")


print("=========================")
yn = "y"

while yn == 'y':
FirstColour = raw_input("Enter First Colour: ")
SecondColour = raw_input("Enter Second Colour: ")
ThirdColour = raw_input("Enter Third Colour: ")
#
# Convert to lower case
#
FirstColour = FirstColour.lower()
SecondColour = SecondColour.lower()
ThirdColour = ThirdColour.lower()
#
# Find the values of colours
#
FirstValue = colours.index(FirstColour)
SecondValue = colours.index(SecondColour)
ThirdValue = colours.index(ThirdColour)
#
# Now calculate the value of the resistor
#
Resistor = 10 * FirstValue + SecondValue
Resistor = Resistor * (10 ** ThirdValue)
print("Resistance = %d Ohms" % (Resistor))
#
# Ask for more
#
yn = raw_input("\nDo you want to continue?: ")
yn = yn.lower()

Figure 6.11 Program listing

● 71
Learning Python with Raspberry Pi

The program was created using the nano text editor and then run from the command line
by entering the following command:

pi@raspberrypi:~ $ python resistor.py

Figure 6.12 shows a typical run of the program.

Figure 6.12 Typical run of the program

6.22 Case Study 2 – 4  Band Resistor Colour Code Identifier Including


Small Resistors
Description: The program given in Figure 6.11 can calculate the values of resistors if they
are greater than or equal to 10 Ohms. For smaller resistors, gold and silver colours are used
as the third colour. Gold divides the result by 10 and silver divides by 100. For example,
red red silver corresponds to 0.22 Ohms. This program calculates the values of all types of
resistors identified by 4 colour bands.

Program Listing: Figure 6.13 shows the program listing (program: resistor2.py). Col-
ours gold and silver are added to the list. The indexes of gold and silver in the list are 10
and 11 respectively. Most of the program is same as in Figure 6.11, except that if the third
colour is gold then the result is divided by 10. Similarly, if the third colour is silver then
the result is divided by 100. Notice that if the resistor value is less than 10 Ohms then it
is displayed in floating-point format with 2 digits after the decimal point by using the print
formatting parameter %3.2f.

#=================================================
# RESISTOR COLOUR CODES
# ---------------------
#
# The user enters the three colours of a resistor
# and the program calculates and displays the value
# of the resistor in Ohms. The program identifies all
# types of resistors with 4 colour bands
#
# Program: resistor2.py

● 72
Chapter 6 • Python Programming

# Date : July, 2019


# Author : Dogan Ibrahim
#===================================================
colours = ['black','brown','red','orange','yellow','green',\
'blue','violet','grey','white', 'gold', 'silver']

print("RESISTOR VALUE CALCULATOR")


print("=========================")
yn = "y"

while yn == 'y':
FirstColour = raw_input("Enter First Colour: ")
SecondColour = raw_input("Enter Second Colour: ")
ThirdColour = raw_input("Enter Third Colour: ")
#
# Convert to lower case
#
FirstColour = FirstColour.lower()
SecondColour = SecondColour.lower()
ThirdColour = ThirdColour.lower()
#
# Find the values of colours
#
FirstValue = colours.index(FirstColour)
SecondValue = colours.index(SecondColour)
ThirdValue = colours.index(ThirdColour)
#
# Now calculate the value of the resistor
#
Resistor = 10 * FirstValue + SecondValue
if ThirdValue == 10:
Resistor = Resistor / 10.0
print("Resistance = %3.2f Ohms" % (Resistor))
elif ThirdValue == 11:
Resistor = Resistor/100.0
print("Resistance = %3.2f Ohms" % (Resistor))
else:
Resistor = Resistor * (10 ** ThirdValue)
print("Resistance = %d Ohms" % (Resistor))
#
# Ask for more
#
yn = raw_input("\nDo you want to continue?: ")
yn = yn.lower()

Figure 6.13 Program listing

● 73
Learning Python with Raspberry Pi

Figure 6.14 shows a typical run of the program.

Figure 6.14 Typical run of the program

6.23 Case Study 3 – Series or Parallel Resistors


Description: This program calculates the total resistance of a number of series or parallel
connected resistors. The user specifies whether the connection is in series or in parallel.
Additionally, the number of resistors used is also specified at the beginning of the program.

Aim: The aim of this case study is to show how the keyboard input and flow control state-
ments can be used in a program.

Background Information: When a number of resistors are in series then the resultant
resistance is the sum of the resistance of each resistor. When the resistors are in parallel
then the reciprocal of the resultant resistance is equal to the sum of the reciprocal resist-
ances of each resistor.

Program Listing: Figure 6.15 shows the program listing (program: serpal.py). At the
beginning of the program a heading is displayed and the program enters into a while loop.
Inside his loop the user is prompted to enter the number of resistors in the circuit and
whether they are connected in series or in parallel. Function str converts a number into
its equivalent string. e.g. number 5 is converted into string "5". If the connection is serial
(mode equals to 's') then the value of each resistor is accepted from the keyboard and the
resultant is calculated and displayed on the screen. If on the other hand the connection is
parallel (mode is equal to 'p') then again the value of each resistor is accepted from the
keyboard and the reciprocal of the number is added to the total. When all the resistor val-
ues are entered, the resultant resistance is displayed on the screen.

● 74
Chapter 6 • Python Programming

#===================================================
# RESISTORS IN SERIES OR PARALLEL
# -------------------------------
#
# This program calculates the total resistance of
# serial or parallel connected resistors
#
# Program: serpal.py
# Date : July, 2019
# Author : Dogan Ibrahim
#===================================================
print("RESISTORS IN SERIES OR PARALLEL")
print("===============================")
yn = "y"

while yn == 'y':
N = int(raw_input("\nHow many resistors are there?: "))
mode = raw_input("Are the resistors series (s) or parallel (p)?: ")
mode = mode.lower()
#
# Read the resistor values and calculate the total
#
resistor = 0.0

if mode == 's':
for n in range(0,N):
s = "Enter resistor " + str(n+1) + " value in Ohms: "
r = int(raw_input(s))
resistor = resistor + r
print("Total resistance = %d Ohms" %(resistor))

elif mode == 'p':


for n in range(0,N):
s = "Enter resistor " + str(n+1) + " value in Ohms: "
r = float(raw_input(s))
resistor = resistor + 1 / r
print("Total resistance = %.2f Ohms" %(1 / resistor))
#
# Check if the user wants to exit
#
yn = raw_input("\nDo you want to continue?: ")
yn = yn.lower()

Figure 6.15 Program listing

● 75
Learning Python with Raspberry Pi

Figure 6.16 shows a typical run of the program.

Figure 6.16 Typical run of the program

6.24 Case Study 4 – Resistive Potential Divider


Description: This case study calculates the resistances in a resistive potential divider cir-
cuit.

Aim: The aim of this case study is to show how to use the keyboard input and flow control
statements in a program.

Background Information: Resistive potential divider circuits consists of two resistors.


These circuits are used to lower a voltage the desired value. Figure 6.17 shows a typical
resistive potential divider circuit. Here, Vin and Vo are the input and output voltages re-
spectively. R1 and R2 is the resistor pair used to lower the voltage from Vin to Vo. A large
number of resistor pair can be used to get the desired output voltage. Choosing large re-
sistors draw little current from the circuit, and choosing small resistors draw larger current.
In this design, the user specifies Vin, Vo, and R2. The program calculates the required R1
value to lower the voltage to the desired level. Additionally, the program displays the out-
put voltage with the chosen physical resistors.

Figure 6.17 Resistive potential divider circuit

● 76
Chapter 6 • Python Programming

The output voltage is given by:

Vo = Vin R2 / (R1 + R2)

R1 is then given by:

R1 = (Vin – Vo) R2/ Vo

The above formula is used to calculate the required value of R1, given Vin, Vo, and R2

Program Listing: Figure 6.18 shows the program listing (program: divider.py). At the
beginning of the program, a heading is displayed. The program then reads Vin, Vo, and R2
from the keyboard. The program calculates R1 and displays R1 and R2. The user is then
asked to enter a chosen physical value for R1. With the chosen value of R1, the program
displays Vin, Vo, R1, and R2 and asks the user whether or not the result is acceptable. If the
answer to this question is y then the program terminates. If on the other hand, the answer
is n then the user is given the option of trying again.

#======================================================
# RESISTIVE POTENTIAL DIVIDER
# ---------------------------
#
# This is a resistive potential divider circuit program.
# The program calculates the resistance values that will
# lower the input voltage to the desired value
#
# Program: divider.py
# Date : July, 2019
# Author : Dogan Ibrahim
#=======================================================
print("RESISTIVE POTENTIAL DIVIDER")
print("===========================")
R1flag = 1
R2flag = 0

while R1flag == 1:
Vin = float(raw_input("\nInput voltage (Volts): "))
Vo = float(raw_input("Desired output voltage (Volts): "))
R2 = float(raw_input("Enter R2 (in Ohms): "))
#
# Calculate R1
#
R1 = R2 * (Vin - Vo) / Vo
print("\nR1 = %3.2f Ohms R2 = %3.2f Ohms" %(R1, R2))
#
# Read chosen physical R1 and display actual Vo

● 77
Learning Python with Raspberry Pi

#
NewR1 = float(raw_input("\nEnter chosen R1 (Ohms): "))

#
# Display and print the output voltage with chosen R1
#
print("\nWith the chosen R1,the results are:")
Vo = R2 * Vin / (NewR1 + R2)
print("R1 = %3.2F R2 = %3.2f Vin = %3.2f Vo = %3.3f" %(NewR1,R2,Vin,Vo))
#
# Check if happy with the values ?
#
happy = raw_input("\nAre you happy with the values? ")
happy = happy.lower()
if happy == 'y':
break
else:
mode = raw_input("Do you want to try again? ")
mode = mode.lower()
if mode == 'y':
R1flag = 1
else:
R1flag = 0
break

Figure 6.18 Program listing

Figure 6.19 shows a typical run of the program.

Figure 6.19 Typical run of the program

6.25 Trigonometric Functions


Python supports a large number of trigonometric functions. The arguments to trigono-
metric functions must be in radians. The math library must be imported into the program
before these functions can be used:

● 78
Chapter 6 • Python Programming

• sin(x) trigonometric sine


• cos(x) trigonometric cosine
• tan(x) trigonometric tangent
• asin(x) trigonometric arc sin
• atan(x) trigonometric arc tangent
• atan2(y, x) trigonometric atan(y/x)
• degrees(x) convert degrees into radians
• radians(x) convert radians into degrees

Some examples of using the trigonometric functions are given in Figure 6.20.

Figure 6.20 Trigonometric function examples

6.26 User-defined Functions


Functions are like small programs within a program. We can use functions to break-up a
complex program into several manageable sections where each section can be implement-
ed as a function. Functions enable us to reuse parts of our programs. For example, we can
create a function to calculate the cube-root of a number and then call this function from
different parts of our program. Another advantage of using functions is that they make it
easier to maintain and update our programs.

A function that we create can be called from anywhere in a program. Functions have their
own variables and their own commands. As we have seen in earlier parts of this chapter,
Python has a large number of built-in functions for various operations such as arithmetic,
trigonometric, string manipulation and so on. User-defined functions are created by pro-
grammers. In this section, we shall be looking at how functions can be created and used
in our programs.

A user-defined function consists of the following:

• functions begin with the keyword def, followed by function name, and round
brackets, followed by a colon sign.
• Input arguments to the function must be placed inside the brackets at the begin-
ning of the function definition.
• The body of a function must be indented with the same number of spaces on the
left hand side
• An optional text message can be displayed at the first line of a function to de-
scribe what the function does.
• A function must be terminated with the return statement

● 79
Learning Python with Raspberry Pi

An example function, named Mult is given below. This function takes two numbers first and
second as its arguments, multiplies them, and returns the result:

def Mult(first, second):


"This is a simple multiplication function"
result = first * second
return result

A function is called from the main program by specifying the name of the function and
enclosing any arguments in a pair of brackets. For example, to call the above function to
multiply numbers 5 and 3 and sore the result in variable called a, we include the following
statement in our program:

a = Mult(5, 3)

we can also call a function by specifying the keyword arguments. i.e.:

a = Mult(first = 5, second = 3)

Figure 6.21 shows the above example in a Python program.

Figure 6.21 Creating and calling a function

Another example is shown in Figure 6.22. In this example, the function displays a string
passed as an argument. Notice that there is no data returned from this function.

Figure 6.22 A function displaying a string

The variables used in a function are local to that function. Thus, for example, if there are
two variables with the same name, one inside the function and the other one outside,
changing the one inside the function does not change the one outside. Variables outside
a function are called global variables, whereas the ones inside a function are called lo-
cal variables. See Figure 6.23 for an example where the contents of variable res are not
changes outside the function.

● 80
Chapter 6 • Python Programming

Figure 6.23 Variables in a function are local

The rules for global variables are as follows:

• Global variables are variables assigned at the top of the program outside the
function definitions
• Global names must be declared only if they are assigned within a function
• Global names may be referenced within a function without being declared

Therefore, by declaring a variable outside the functions and also inside a function but with
the global keyword allows us to change its contents inside the function. An example is given
below which identifies the use of global variables:

cnt = 10 # variable cnt is global


def tstfunc(): # function declaration
global cnt # variable cnt defined as global
cnt = 200 # value of global cnt is changed

tstfunc() # function is called


print(cnt) # value of cnt is 200

as explained above, it the value of a global variable is not changed inside a function then
there is no need to define it as global. In the following code there is no need to define x as
global inside the function:

x = 10
y = 4

def tst():
global y
y = x + 2

It is important to note that the variables in a function call are passed by value. This means
that the value of a parameter cannot be changed inside a function. An example is shown
in Figure 6.24. In this example, notice that the value of variable cnt is not changed inside
the function call.

● 81
Learning Python with Raspberry Pi

Figure 6.24 Variables are passed by value

A function normally returns only one item back to the calling program. In some applications,
we may want to return more than one item to the calling program. This is easily done by
returning a tuple and then unpacking it in the main program. An example is shown in Figure
6.25. In this example, function MyFunc is declared with two arguments. The arguments
are added and stored in a local variable called sum. Similarly, the difference of the argu-
ments is stored in variable diff. The function returns both sum and diff as a tuple. The
calling main program unpacks the returned data and stores in variables x and y.

Figure 6.25 Returning more than one variable from a function

6.27 Example Programs


Now that we have looked at some features of the Python programming language we should
be ready to develop programs. In this section, many example programs are given to make
the reader familiar with using various featured of Python in programs.

Example 1
Write a program to read an angle from the keyboard in degrees and display the trigonomet-
ric sine of this angle. Repeat until the user stops the program.

Solution 1
The required program listing is shown in Figure 6.26 (program: trig.py). The angle entered
by the user is converted into floating point and is stored in variable angle. Then the trigo-
nometric sine of this angle is displayed. The program continues until the user enters n in
response to prompt Any more?

#----------------------------------------------
# TRIGONOMETRIC SINE PROGRAM
# ==========================
#
# This program reads an angle from the keyboard
# and displays its trigonometric sine

● 82
Chapter 6 • Python Programming

#
# Author: Dogan Ibrahim
# File : trig.py
# Date : July, 2019
#----------------------------------------------
import math

yn = 'y'
print("Trigonometric sine")
print("==================\n")

while yn == 'y':
angle = float(raw_input("Enter angle in degrees: "))
r = math.radians(angle)
s = math.sin(r)
print("sine of %3.2f degrees is: %f\n" %(angle, s))
yn = raw_input("Any more? ")

Figure 6.26 Program listing

An example run of the program is shown in Figure 6.27.

Figure 6.27 Example run of the program

Example 2
Modify the program in Example 1 so that the user can choose between sine, cosine, and
tangent.

Solution 2
The modified program listing is shown in Figure 6.28 (program: trigall.py). The user is
given a menu with four choices: sine, cosine, tangent, exit. The angle is read from the key-
board and is converted into radians. The program then calculates the trigonometric value
and displays on the screen. This process is repeated until the user selects the exit option.

● 83
Learning Python with Raspberry Pi

#-----------------------------------------------------
# TRIGONOMETRIC SINE,COSINE,TANGENT PROGRAM
# =========================================
#
# This program reads an angle from the keyboard
# and displays its trigonometric sine, cosine, or
# tangent depending on user choice. The angle is
# read in degrees,converted into radians and then
# the required trigonometric function is calculated
#
# Author: Dogan Ibrahim
# File : trigall.py
# Date : July, 2019
#-----------------------------------------------------
import math

choice = '1'
while choice != '0':
print("Trigonometric Sine, Cosine, or Tangent")
print("======================================\n")
print("1. Sine")
print("2. Cosine")
print("3. Tangent")
print("0. Exit")
choice = raw_input("Enter choice: ")

if choice != '0':
angle = float(raw_input("Enter angle in degrees: "))
r = math.radians(angle)
if choice == '1':
s = math.sin(r)
strng = "sine"
elif choice == '2':
s = math.cos(r)
strng = "cosine"
elif choice == '3':
s = math.tan(r)
strng = "tangent"
print(strng + " of %3.2f degrees is: %f\n" %(angle, s))
print("End of program")

Figure 6.28 Modified program listing

An example run of the program is shown in Figure 6.29.

● 84
Chapter 6 • Python Programming

Figure 6.29 Example run of the program

Example 3
Write a program to tabulate the trigonometric sines of angles from 0º to 90º in steps of 5º.

Solution 3
The required program listing is shown in Figure 6.30 (program: sinetable.py). After dis-
playing a heading, the for statement is used to create a loop. Variable angle takes values
from 0 to 90 (inclusive) in steps of 5. The trigonometric sine is calculated and displayed.

#--------------------------------------------------
# TRIGONOMETRIC SINE TABLE
# ========================
#
# This program tabulates the trigonometric sine of
# angles from 0 to 90 degrees in steps of 5 degress
#
# Author: Dogan Ibrahim
# File : sinetable.py
# Date : July, 2019
#--------------------------------------------------
import math

print("TABLE OF TRIGONOMETRIC SINE")


print("=========================\n")
print(" ANGLE SINE")

for angle in range(0, 95, 5):


r = math.radians(angle)
s = math.sin(r)
print(" %d %f" %(angle, s))

● 85
Learning Python with Raspberry Pi

print("End of program")

Figure 6.30 Program listing

An example run of the program is shown in Figure 6.31.

Figure 6.31 Example run of the program

Example 4
Repeat Example 3, but tabulate the trigonometric sine, cosine and tangent of angles from
0º to 30º in steps of 2º.

Solution 4
The required program listing is shown in Figure 6.32 (program: alltrig.py). After displaying
a heading, the program calculates and displays the trigonometric functions sine, cosine and
tangent.

#--------------------------------------------------
# TABLE OF TRIGONOMETRIC FUNCTIONS
# ================================
#
# This program tabulates the trigonometric sine,
# cosine and tangent from 0 to 30 degrees in steps
# of 2 degrees
#
# Author: Dogan Ibrahim
# File : alltrig.py
# Date : July, 2019
#--------------------------------------------------

● 86
Chapter 6 • Python Programming

import math

print("TABLE OF TRIGONOMETRIC FUNCTIONS")


print("================================\n")
print(" ANGLE SINE COSINE TANGENT")

for angle in range(0, 32, 2):


r = math.radians(angle)
s = math.sin(r)
c = math.cos(r)
t = math.tan(r)
print(" %d %f %f %f" %(angle, s, c, t))

print("End of program")

Figure 6.32 Program listing

An example run of the program is shown in Figure 6.33.

Figure 6.33 Example run of the program

Example 5
Write a program to read metres from the keyboard. Convert into yards and inches and
display the result.

Solution 5
The required program listing is shown in Figure 6.34 program: conv.py). After displaying
a heading, metres is read from the keyboard using the raw_input statement. The value is
then converted into yards and inches by multiplying with 1.0936 and 39.370 respectively.
The results are displayed on the screen.

● 87
Learning Python with Raspberry Pi

#--------------------------------------------------
# CONVERSION PROGRAM
# ==================
#
# This program reads metres from the keyboard and
# converts and displays in yards and inches
#
# Author: Dogan Ibrahim
# File : conv.py
# Date : July, 2019
#--------------------------------------------------
print("Convert metres into yards and inches")
print("====================================")
metres = float(raw_input("Enter metres: "))
yards = 1.0936 * metres
inches = 39.370 * metres
print("%f metres = %f yards, %f inches" %(metres, yards, inches))
print("End of program")

Figure 6.34 Program listing

An example run of the program is shown in Figure 6.35.

Figure 6.35 Example run of the program

Example 6
Repeat Example 5 but do the conversion in a function called Conv. Show how this function
can be called from the main program.

Solution 6
The required program listing is shown in Figure 6.36 (program: convfunc.py). Function
Conv is declared at the beginning of the program. Metres to be converted into yards and
inches is passed as an argument to the function. The function returns the yards and inches
in a tuple. The main program reads the metres from the keyboard and calls function Conv.
The result is displayed on the screen.

● 88
Chapter 6 • Python Programming

#--------------------------------------------------
# CONVERSION PROGRAM
# ==================
#
# This program reads metres from the keyboard and
# converts and displays in yards and inches
#
# Author: Dogan Ibrahim
# File : convfunc.py
# Date : July, 2019
#--------------------------------------------------
def Conv(m):
"Convert metres into yards and inches"
y = 1.0936 * m
i = 39.370 * m
return y, i

print("Convert metres into yards and inches")


print("====================================")
metres = float(raw_input("Enter metres: "))
yards, inches = Conv(metres)
print("%f metres = %f yards, %f inches" %(metres, yards, inches))
print("End of program")

Figure 6.36 Program listing

An example run of the program is shown in Figure 6.37.

Figure 6.37 Example run of the program

Example 7
Write a function called Tconv to convert ºC to ºF. Show how this function can be used in a
main program.

Solution 7
The formula to convert ºC to ºF is given by:

F = 1.8C + 32

The required program listing is shown in Figure 6.38 (program: ctof.py). Main program
reads the temperature in degrees Centigrade from the keyboard and calls function Tconv
to convert into Fahrenheit. The result is displayed on the screen.

● 89
Learning Python with Raspberry Pi

#-----------------------------------------------------
# CONVERSION PROGRAM
# ==================
#
# This program reads temperature in degrees Celsius
# from the keyboard and converts into degrees Fahrenheit
#
# Author: Dogan Ibrahim
# File : ctof.py
# Date : July, 2019
#-----------------------------------------------------
def Tconv(C):
"Convert Centigrade to Fahrenheit"
F = 1.8 * C + 32
return F

print("Temperature Conversion (C to F)")


print("==============================")
Centigrade = float(raw_input("Enter temperature in Centigrade: "))
Fahrenheit = Tconv(Centigrade)
print("%f Centigrade = %f Fahrenheit" %(Centigrade, Fahrenheit))
print("End of program")

Figure 6.38 Program listing

An example run of the program is shown in Figure 6.39.

Figure 6.39 Example run of the program

Example 8
Write a function called Cyl to calculate the area and volume of a cylinder, given its radius
and height. Use this function in a main program.

Solution 8
The area and volume of a cylinder are given by the formula:

Area = 2πrh
Volume = πr2h

The required program listing is shown in Figure 6.40 (program: cylinder.py). the radius

● 90
Chapter 6 • Python Programming

and height of the cylinder are passed as arguments to a function which calculates the area
and volume of the cylinder and returns the results to the main program which are displayed
on the screen.

#-----------------------------------------------------
# CONVERSION PROGRAM
# ==================
#
# This program reads the radius and height of a cylinder
# and calculates and displays its area and volume
#
# Author: Dogan Ibrahim
# File : cylinder.py
# Date : July, 2019
#-----------------------------------------------------
import math

def Cyl(r, h):


"Area and volume of a cylinder"
area = 2 * math.pi * r * h
volume = math.pi * r * r * h
return area, volume

print("Area and Volume of a Cylinder")


print("=============================")
radius = float(raw_input("Enter the radius: "))
height = float(raw_input("Enter the height: "))
A, V = Cyl(radius, height)
print("Area = %f Volume = %f" %(A, V))
print("End of program")

Figure 6.40 Program listing

An example run of the program as shown in Figure 6.41.

Figure 6.41 Example run of the program

● 91
Learning Python with Raspberry Pi

Example 9
Write a program to store the names of the days of a week and then display these names.

Solution 9
The required program listing is shown in Figure 6.42 (program: wdays.py). List days
stores the names of the days in a week. A for loop is used to display these names.

#----------------------------------------------
# DAYS OF A WEEK
# ==============
#
# This program displays teh days of a week
#
# Author: Dogan Ibrahim
# File : wdays.py
# Date : July, 2019
#----------------------------------------------
days = ["Monday","Tuesday","Wednesday","Thursday",\
"Friday","Saturday","Sunday"]

for day in days:


print(day)

Figure 6.42 Program listing

An example run of the program is shown in Figure 6.43.

Figure 6.43 Example run of the program

Example 10
Write a program to read a word from the keyboard and then display the letters of this word
in reverse order on the screen.

Solution 10
The required program listing is shown in Figure 6.44 (program: letters.py). A word is read
from the keyboard and stored in string variable word. Then the letters of this word are
displayed in reverse order.

● 92
Chapter 6 • Python Programming

#----------------------------------------------
# LETTERS OF A WORD
# =================
#
# This program reads a word and displays its letter
# in reverse order
#
# Author: Dogan Ibrahim
# File : letters.py
# Date : July, 2019
#----------------------------------------------
word = raw_input("Enter a word: ")
l = len(word)
k = 0

while l != 0:
k = k -1
print(word[k])
l = l -1

Figure 6.44 Program listing

An example run of the program is shown in Figure 6.45.

Figure 6.45 Example run of the program

Example 11
Write a calculator program to carry out the four simple mathematical operations of addi-
tion, subtraction, multiplication, and division on two numbers received from the keyboard.

Solution 11
The required program listing is shown in Figure 6.46 (program: calc.py). Two numbers are
received from the keyboard and stored in variables n1 and n2. Then, the required math-
ematical operation is received and it is performed. The result, stored in variable result, is
displayed on the screen. The user is given the option of terminating the program.

● 93
Learning Python with Raspberry Pi

#----------------------------------------------
# CALCULATOR PROGRAM
# ==================
#
# This is a simple calculator program that can
# carry out 4 basic arithmetic opertions
#
# Author: Dogan Ibrahim
# File : calc.py
# Date : July, 2019
#----------------------------------------------
any = 'y'
while any == 'y':
print("\nCalculator Program")
print("==================")

n1 = float(raw_input("Enter first number: "))


n2 = float(raw_input("Enter second number: "))
op = raw_input("Enter operation (+-*/): ")

if op =="+":
result = n1 + n2
elif op == "-":
result = n1 - n2
elif op == "*":
result = n1 * n2
elif op == "/":
result = n1 / n2
print("Result = %f" %(result))
any = raw_input("\nAny more (yn): ")

Figure 6.46 Program listing

An example run of the program is shown in Figure 6.47.

● 94
Chapter 6 • Python Programming

Figure 6.47 Example run of the program

Example 12
Write a program to simulate double dice. i.e. to display two random numbers between 1
and 6 every time it is run.

Solution 12
The required program listing is shown in Figure 6.48 (program: dice.py). Here, the random
number generator randint is used to generate random numbers between 1 and 6 when the
Enter key is pressed. The program is terminated when letter X is entered.

#----------------------------------------------
# DOUBLE DICE
# ===========
#
# This program displays two random dice numbers
# between 1 and 6 when the Enter key is pressed
#
# Author: Dogan Ibrahim
# File : dice.py
# Date : July, 2019
#----------------------------------------------
import random
strt = 'a'

while strt.upper() != 'X':


strt = raw_input("Pres ENTER to start, X to exit ")
first = random.randint(1, 6)
second = random.randint(1, 6)
print("%d %d" %(first, second))

Figure 6.48 Program listing

● 95
Learning Python with Raspberry Pi

An example run of the program is shown in Figure 6.49.

Figure 6.49 Example run of the program

Example 13
Write a program to display the squares of integer numbers between 1 and 10.

Solution 13
The required program listing is shown in Figure 6.50 (program: sqrs.py).

#----------------------------------------------
# SQUARES OF NUMBERS
# ==================
#
# This program displays the squares of numbers
# between 1 and 10
#
# Author: Dogan Ibrahim
# File : sqrs.py
# Date : July, 2019
#----------------------------------------------
print("NUMBER SQUARE")
print("====== ======")

for k in range(1, 11):


print("%d %d" %(k, k * k))

Figure 6.50 Program listing

● 96
Chapter 6 • Python Programming

An example run of the program is shown in Figure 6.51.

Figure 6.51 Example run of the program

Example 14
Write a program to calculate and display the sum of integer numbers in a list.

Solution 14
The required program listing is shown in Figure 6.52 (program: nsums.py). The program
calculates the sum of numbers between 1 and 10 and displays the result.

#----------------------------------------------
# SUM OF NUMBERS
# ==============
#
# This program calculates and displays the sum
# of numbers in a list
#
# Author: Dogan Ibrahim
# File : nsums.py
# Date : July, 2019
#----------------------------------------------
numbers = [1, 3, 5, 2, 9, 7]

L = len(numbers)
sum = 0

for k in range(L):
sum = sum + numbers[k]

print("Sum = %d" %(sum))

Figure 6.52 Program listing

The program displays 27 as the sum of the numbers in the list in Figure 6.52.

● 97
Learning Python with Raspberry Pi

Example 15
Write a program to use functions to calculate and display the areas of shapes: square,
rectangle, triangle, circle, and cylinder. The sizes of the required sides should be received
from the keyboard.

Solution 15
The areas of the shapes to be used in the program are as follows:

Square: side = a area = a2


Rectangle: sides a, b area = ab
Circle: radius r area = πr2
Triangle: base b, height h area = bh/2
Cylinder: radius r, height h area = 2πrh

The required program listing is shown in Figure 6.53 (program: areas.py). a different func-
tion is used for each shape and the sizes of the sides are received inside the functions. The
main program displays the calculated area for the chosen shape.

#------------------------------------------------------------
# AREAS OF SHAPES
# ===============
#
# This program calculates and displays the areas of various
# geometrical shapes
#
# Author: Dogan Ibrahim
# File : areas.py
# Date : July, 2019
#------------------------------------------------------------
import math

def Square(a): # square


return a * a

def Rectangle(a, b): # rectangle


return(a * b)

def Triangle(b, h): # triangle


return(b * h / 2)

def Circle(r): # circle


return(math.pi * r * r)

def Cylinder(r, h): # cylinder


return(2 * math.pi * r * h)

● 98
Chapter 6 • Python Programming

print("AREAS OF SHAPES")
print("===============\n")
print("What is the shape?: ")

shape = raw_input("Square (s)\nRectangle(r)\nCircle(c)\n\


Triangle(t)\nCylinder(y): ")

shape = shape.lower()
if shape == 's':
a = float(raw_input("Enter a side of the square: "))
area = Square(a)
s = "Square"
elif shape == 'r':
a = float(raw_input("Enter one side of the rectangle: "))
b = float(raw_input("Enter other side of the rectangle: "))
area = Rectangle(a, b)
s = "Rectangle"
elif shape == 'c':
radius = float(raw_input("Enter radius of the circle: "))
area = Circle(radius)
s = "Circle"
elif shape == 't':
base = float(raw_input("Enter base of the triangle: "))
height = float(raw_input("Enter height of the triangle: "))
area = Triangle(base, height)
s = "Triangle"
elif shape == 'y':
radius = float(raw_input("Enter radius of cylinder: "))
height = float(raw_input("Enter height of cylinder: "))
area = Cylinder(radius, height)
s = "Cylinder"

print("Area of %s is %f" %(s, area))

Figure 6.53 Program listing

An example run of the program is shown in Figure 6.54.

● 99
Learning Python with Raspberry Pi

Figure 6.54 Example run of the program

6.28 Case Study 5 - R  esistive Attenuator Design – Equal Source &


Load Resistances
Description: This case study calculates the resistances in a resistive attenuator circuit
where the source and the load resistances are equal to each other.

Aim: The aim of this case study is to show how to use the keyboard input, flow control
statements, and logarithms in a program.

Background Information: A resistive attenuator is a two-port resistive circuit designed


to attenuate the power applied to its input terminals. Attenuators are generally used in
radio, audio, and communication circuits to weaken a stronger signal. Attenuators are also
used to provide impedance matching between a source and a load. The performance of
an attenuator is expressed by the number of decibels (dB) the input signal has decreased.
Expressed mathematically, the logarithm to base 10 of the ratio of the output signal to the
input signal, multiplied by 20 is known as the decibel:

dB = 20 Log10 Vo/Vin (6.1)

For example, if the ratio of output/input voltage is 0.707, this corresponds to -3dB. Similar-
ly, a ratio of 0.5 corresponds to -6dB. To find the actual voltage ratio with a given dB, we
have to take the anti-logarithm as given by the following formula:

Vo/Vin = Antilog10 (dB / 20) (6.2)

As an example, -10dB corresponds to the voltage ratio of Vo/Vin = Antilog10 (-0.5) = 0.316
There are many types of resistive attenuator circuits in use, but the commonly used ones
are the T and Pi type circuits, having 3 resistors each. Figure 6.55 shows the T type atten-
uator with two identical resistors R1 and a single resistor R2.

Figure 6.55 Resistive T type attenuator

● 100
Chapter 6 • Python Programming

The design equations of this circuit are as follows (see web site: https://www.electronics-
tutorials.ws/attenuators/pi-pad-attenuator.html for more details). The source and the load
resistances are assumed to be equal in this design:

(6.3)

(6.4)

Where, Z is the source resistance, which is also equal to the load resistance, and K is known
as the attenuation factor, where:

K = Antilog10(dB/20) = 10dB/20

For example, for a 6dB attenuation, K will be 106/20 = 1.9953. Alternatively, if we want to
attenuate the input signal by a factor of 12, then the value of K will be 12.

Figure 6.56 shows the Pi type resistive attenuator again with two identical resistors R1 and
a single resistor R2.

Figure 6.56 Resistive Pi type attenuator

The design equations of this circuit are as follows (see web site: https://www.electronics-
tutorials.ws/attenuators/pi-pad-attenuator.html for more details). The source and the load
resistances are assumed to be equal in this design:

(6.5)

(6.6)

Where, Z is the source resistance, which is also equal to the load resistance, and K is the
impedance factor as before.

● 101
Learning Python with Raspberry Pi

Program Listing: Figure 6.57 shows the program listing (program: attenuator.py). After
displaying a heading, the user is prompted to enter the source (which is also the load) re-
sistance Z, attenuation factor K in decibels, and the type of circuit to be used as T or P (for
Pi). The program calculates and displays the values of the resistors.

#----------------------------------------------------
# RESISTIVE ATTENUATOR DESIGN
# ===========================
#
# This program designs a T or Pi type resistive
# attenuator. The user enters the source (also load)
# resistance, atenuation factor and type of design
#
# Author: Dogan Ibrahim
# File : attenuator.py
# Date : July, 2019
#----------------------------------------------------
print("Resistive Attenuator Design")
print("===========================")
Z = float(raw_input("Enter source resistance in Ohms: "))
Kdb = float(raw_input("Enter attenuation Factor in dB: "))
T = raw_input("Enter attenuator type (T or P): ")
T = T.lower()
K = pow(10.0, Kdb/20.0)

if T == 't':
R1 = Z * (K - 1) / (K + 1)
R2 = R1
R3 = 2 * Z * K / (K * K - 1)
elif T == 'p':
R1 = Z * (K + 1) / (K - 1)
R3 = R1
R2 = Z * (K * K - 1) / (2 * K)

print("\nResults:")
print("-------")
print("Z = %f Ohms\nK = %f dB\nK (Vi/Vo) = %f\nR1=%f Ohms\nR2=%f Ohms\
\nR3=%f Ohms"
%(Z, Kdb, K, R1, R2, R3))

Figure 6.57 Program listing

An example run of the program is shown in Figure 6.58. The design parameters are as
follows:

● 102
Chapter 6 • Python Programming

Source (load) resistance, Z = 50 Ohms


Attenuation factor = 12 decibels
Attenuation type= T

The designed circuit is shown in Figure 6.59.

Figure 6.58 Example run of the program

Figure 6.59 Designed attenuator circuit

6.29 Case Study 6 - R  esistive Attenuator Design – Unequal Source &


Load Resistances
Description: This case study calculates the resistances in a resistive attenuator circuit
where the source and the load resistances may not be equal to each other.

Aim: The aim of this case study is to show how to use the keyboard input, flow control
statements, and logarithms in a program.

Background Information: In an attenuator where the source and the load resistances
are not equal to each other different formula are used to calculate the resistance values. In
this section, we will only consider a Pi type network shown in Figure 6.60.

Figure 6.60 Pi type attenuator with different source and load resistances

● 103
Learning Python with Raspberry Pi

The design equations are as shown in Figure 6.61.

Figure 6.61 Pi attenuator design equations

Program Listing: Figure 6.62 shows the program listing (program: attenuator2.py). After
displaying a heading, the user is prompted to enter the source and the load resistances ZS
and ZL, and the attenuation factor K in decibels. The program calculates and displays the
values of the resistors.

#----------------------------------------------------
# RESISTIVE Pi ATTENUATOR DESIGN
# ==============================
#
# This program designs a Pi type resistive attenuator
# where the source and the load resistances may be
# different to each other
#
# Author: Dogan Ibrahim
# File : attenuator2.py
# Date : July, 2019
#----------------------------------------------------
import math

print("Resistive Attenuator Design With Different Source & Load")


print("========================================================")
ZS = float(raw_input("Enter source resistance in Ohms: "))
ZL = float(raw_input("Enter load resistance in Ohms: "))
Kdb = float(raw_input("Enter attenuation Factor in dB: "))
K = pow(10.0, Kdb/20.0)

● 104
Chapter 6 • Python Programming

R1 = ZS * ((K * K - 1) / (K * K - 2 * K * math.sqrt(ZS / ZL) + 1))


R2 = 0.5 * (math.sqrt(ZS * ZL)) * (K * K - 1) / K
R3 = ZL * ((K * K - 1) / ( 1 + K * K - (2 * K / math.sqrt(ZS/ZL))))

print("\nResults:")
print("-------")
print("ZS = %f Ohms\nZL = %f Ohms\nK = %f dB\nK (Vi/Vo) = %f\nR1=%f Ohms\
nR2=%f Ohms\nR3=%f Ohms"%(ZS, ZL, Kdb, K, R1, R2, R3))

Figure 6.62 Program listing

An example run of the program is shown in Figure 6.63. The design parameters are as
follows:

Source resistance, ZS = 75 Ohms


Load resistance, ZL = 50 Ohms
Attenuation factor = 6 decibels

Figure 6.63 Example run of the program

The designed circuit is shown in Figure 6.64.

Figure 6.64 Designed attenuator circuit

6.30 Recursive Functions


Recursive functions are functions that call themselves either directly or indirectly and such
functions are supported by Python. Although the topic of recursive functions is an advanced
topic, an example is given in Figure 6.65 to illustrate the principles of such functions. This
recursive function implements the factorial operation. Detailed analysis of recursive func-
tions is beyond the scope of this book.

● 105
Learning Python with Raspberry Pi

Figure 6.65 Recursive factorial function

6.31 Exceptions
It is possible that there are major errors in our programs, such as dividing by zero, file
privilege error, and so on. Normally, when Python encounters such errors it cannot handle
them and the program crashes.

One way to handle such errors orderly and avoid crashes is to use exception handling in our
programs. The basic method is that whenever an error occurs the program detects this er-
ror and takes appropriate measures to handle the error and continue to execute normally.
Exception handling is also useful if we wish to terminate a running program in an orderly
manner, for example, to shut down any input-output operations when the program is ter-
minated asynchronously by the user (e.g. by pressing the Cntrl+C key).

The statements try and except are used to handle unexpected error or terminations in our
programs. The general format of exception handling is as follows:

try:
Normal program statements
Normal program statements
except condition 1:
If condition 1 type error occurs then execute this block of code
……………..
……………..
except condition 2:
If condition 2 type error occurs then execute this block of code
……………….
……………….
else:
If there are no errors detected then execute this block of code
…………………
…………………

We can use the except statement with no condition in order to handle any type of excep-
tion. Some of the commonly used exceptions are:

exception EOFError: end-of-file condition is reached while reading data

exception ImportError: import statement could not load a module

● 106
Chapter 6 • Python Programming

exception IndexError: sequence subscript is out of range

exception KeyError: a dictionary key is not found in the set of existing keys

exception KeyboardInterrupt: u
 ser hit the interrupt key (normally the Cntrl+C
or Delete key)
exception MemoryError: operation ran out of memory

exception OverFlowError: arithmetic operation resulted in overflow

exception RuntimeError: a
 n error is detected that does not fall in any other
categories

exception ValueError: a
 n operation or function receives an argument that has
the right type but an appropriate value

exception ZeroDivisionError: a division by zero occurred

Some examples of using exceptions in programs are given below.

Example 1
Write a program to wait for an input from the keyboard. Terminate the program orderly
when the Cntrl+C keys are pressed on the keyboard.

Solution 1
Figure 6.66 shows the program listing (program: except1.py). Exception KeyboardIn-
terrupt is used in this program. Message End of Program is displayed when Cntrl+C key
combination is pressed on the keyboard.

#=====================================================
# KeyboardInteerupt EXCEPTION
#
# This program detects the keyboard entry Cntrl+C and
# the program is teminated orderly after the message
# End of Program is displayed
#
# Author : Dogan Ibrahim
# File : except1.py
# Date : July, 2019
#======================================================
try:
mode = raw_input("Enter Cntrl+C to terminate the program: ")
except KeyboardInterrupt:
print("\nEnd of Program")

Figure 6.66 Program listing

● 107
Learning Python with Raspberry Pi

An example run of the program is shown in Figure 6.67.

Figure 6.67 Example run of the program

Example 2
Write a program to detect division by zero and to display the message Divide by Zero
when this exception is detected.

Solution 2
Figure 6.68 shows the program listing (program: except2.py). Here, the program is forced
to divide a number by zero and this is detected as an exception and the program displays
a message when this occurs.

#=====================================================
# ZeroDivisionError EXCEPTION
#
# This program detects when a number is divided by zero
# and generates an exception to display a message
##
# Author : Dogan Ibrahim
# File : except2.py
# Date : July, 2019
#======================================================
print("Divide by zero exception")

try:
s = 10 / 0
except ZeroDivisionError:
print("Divide by Zero")

Figure 6.68 Program listing

When the program is run it displays the following message:

Divide by zero exception


Divide by Zero

6.31.1 try/finally Exceptions


Statement finally can be used in exception handling. Try/finally combination specifies ex-
ception where the block beginning with finally is always executed on the way out, regard-
less of whether an exception occurs in the try block. An example is given below:

● 108
Chapter 6 • Python Programming

Example 3
Write a program to look for KeyboardInterrupt exception and display the message Ex-
ception not occurred if an exception has not occurred.

Solution 3
Figure 6.69 shows the program listing (program: except3.py). The block inside finally is
executed regardless of whether an exception occurs.

#=====================================================
# try/finally In EXCEPTION
#
# This program detects the keyboard entry Cntrl+C and
# displays the message Keyboard Interrupt if interrupt
# occurs. Message Continue is displayed regardless of
# whether an exception occurrede
#
# Author : Dogan Ibrahim
# File : except3.py
# Date : July, 2019
#======================================================
try:
mode = raw_input("Enter Cntrl+C to terminate the program: ")
except KeyboardInterrupt:
print("\nKeyboard Interrupt")
finally:
print("\nContinue")

Figure 6.69 Program listing

Example run of the program is shown in Figure 6.70.

Figure 6.70 Example run of the program

6.32 Case Study 7 – Zener Diode Based Voltage Regulator


Description: This case study is about designing a zener diode based voltage regulator
circuit.

Aim: The aim of this case study is to show how to use the keyboard input, and flow control
statements.

● 109
Learning Python with Raspberry Pi

Background Information: Zener diodes are used in voltage regulator circuits. A zener
diode is like a general-purpose diode. When the diode is biased in the forward direction it
behaves just like a normal signal diode, but when biased in the reverse direction, the volt-
age remains constant for a wide range of currents. As a result of this characteristic, zener
diodes are used as fixed voltage sources in power supply applications. The typical forward
voltage of the diode at 1mA current is around 0.6 volts. As shown in Figure 6.71, in the
reverse direction a small leakage current flows. As the breakdown voltage is approached
the current begins to avalanche and the voltage across the zener diode becomes nearly
constant. There is a minimum current that puts the device into the breakdown region, and
a maximum current at which point the device can be damaged if the current is increased.

Figure 6.71 Typical zener diode characteristics

Zener diodes are available from about 2.4V to 200V and some popular ones have the fixed
voltages of 2.7V, 3.3V, 4.7V, 5.1V, 10V, 12V, 15V, etc.

Figure 6.72 shows a zener diode used as a voltage regulator. Input voltage is applied to
the cathode terminal of the diode through a resistor and the output voltage is taken across
the diode. Design of a zener diode regulator circuit depends on the correct choice of the
resistor.

Figure 6.72 Zener diode based voltage regulator

The calculation of resistor Rs depends on the load current requirements and its minimum
value is given by:

● 110
Chapter 6 • Python Programming

Rs = (Vin - Vz) / (Izmin+ ILmax) (6.7)

Where Vin is the input voltage, Vz is the zener voltage, Izmin is the minimum zener current
(or zener test current in data sheets), and ILmax is the maximum load current. Before
choosing a zener diode for an application we have to make sure that the maximum power
capacity of the diode is not exceeded when there is no load. This is given by:

Pz = Vz x Is (6.8)

Where,

Is = (Vin – Vz) / Rs (6.9)

The power rating of the resistor is calculated as:

Prs = (Vin – Vz) x Is (6.10)

Program Listing: Figure 6.73 shows the program listing (program: zener.py). At the
beginning of the program a heading is displayed and the user is prompted to enter Vin,
Vz, Izmin, and ILmax. The required resistor value and the minimum power ratings of the
resistor and the zener diode are calculated and displayed.

#----------------------------------------------------
# ZENER DIODE VOLTAGE REGULATOR
# =============================
#
# This is a zener diode based voltage regulator design
# program which calculates the required resistance value
#
# Author: Dogan Ibrahim
# File : zener.py
# Date : July, 2019
#----------------------------------------------------
print("Zener Diode Voltage Regulator")
print("=============================")
Vin = float(raw_input("Enter Vin (Volts): "))
Vz = float(raw_input("Enter zener (load) voltage (Volts): "))
Izmin = float(raw_input("Enter minimum zener current (mA): "))
IzminA = Izmin / 1000.0
ILmax = float(raw_input("Enter maximum load current (mA): "))
ILmaxA = ILmax / 1000.0
#
# Now do the calculations
#
Rs = (Vin - Vz) / (IzminA + ILmaxA)
Is = (Vin - Vz) / Rs

● 111
Learning Python with Raspberry Pi

Pz = Vz * Is
Pz = Pz * 1000.0
Prs = (Vin - Vz) * Is
Prs = Prs * 1000.0
#
# Display the results
#
print("\nResults")
print("=======")
print("Vin=%3.2fV\nVz=%3.2fV\nIzmin=%3.2fmA\nILmax=%3.2fmA\nRs=%3.2f Ohms\
\nPrs=%3.2fmW\nPz=%3.2fmW" %(Vin, Vz, Izmin, ILmax, Rs, Prs, Pz))

Figure 6.73 Program listing

Example run of the program is shown in Figure 6.74, which has the following specifications:

• Vin = 10V
• Vz = 5.1V
• Izmin = 5mA
• ILmax = 100mA

Figure 6.74 Example run of the program

Figure 6.75 shows the designed zener diode circuit where the output voltage is 5.1V. The
required resistor value is calculated to be 46.67 Ohms. We should choose 47 ohms 1W as
the nearest physical resistor. The 5.1V zener diode should have around 1W power rating.

Figure 6.75 Designed zener diode circuit

● 112
Chapter 6 • Python Programming

6.33 Date and Time


In some applications it may be necessary to get the current date and time. Python supports
a number of functions to get the current date and time. Module time must be imported
before these functions can be used. Some of the commonly used date and time functions
are as follows:

• time.localtime() returns the current date and time in the following format:
time.struct_time(tm_year=2013,tm_mon=12,tm_mday=18,
tm_hour=12,tm_min=45,tm_sec=3,tw_wday=2,tm_
yday=352,
• tm_isdst=0)
• time.asctime() returns the date and time in standard readable format
• time.clock() returns the current CPU time in seconds
• time.ctime() returns the current date and time
• time.time() returns the current time in seconds since the epoch
• time.sleep(x) suspends the calling program for x seconds

Some examples are given in Figure 6.76.

Figure 6.76 Example date and time functions

The datetime module can also be used for date and time functions. This module must be
imported in order to use these functions. Some examples of date functions are shown in
Figure 6.77.

Figure 6.77 Examples of using the datetime date functions

Function strftime(format) is very useful as it can be used to format a date and time
string. Some examples of using this function are given in Figure 6.78.

● 113
Learning Python with Raspberry Pi

Figure 6.78 Examples of using strftime

6.34 Creating Our Own Modules


In some applications, we may want to create our own Python modules and import them into
our programs. Python modules are simply .py program files. Writing a module is just like
writing any other Python program. Modules can contain functions, classes, and variables.
A simple module called msg.py is shown below:

def hello():
print("Hello there!")

we can now import this module in our Python programs. An example program called
myprog.py is shown below:

import msg
msg.hello()

Running the program: python myprog.py will display the following output:

Hello there!

We can also modify our program myprog.py and import and then call the module as fol-
lows:

from msg import hello


hello()
We can use variables in our module as shown below:

msg.py
def hello():
print("Hello there!")

name = "Jones"

myprog.py
import msg
msg.hello()
print(msg.name)

● 114
Chapter 6 • Python Programming

The program will display:

Hello there!
Jones

Aliases can be created for modules. This is shown in the following code:

myprog.py
import msg as tst
tst.hello()

Will display the output:

Hello there!

An example module is given below that calculates the cube of a number

Example 4
Write a module that calculates the cube of the integer number passed to it. Show how this
module can be imported and used in a program.

Solution 4
Figure 6.79 shows the module listing (program: cubeno.py). Function cube inside cubeno.
py has the number as its argument. The cube of this number is calculated and returned.
Figure 6.80 shows the program (program: myprog.py). As an example, when the number
is 3, the output from the program is:

Cube of 3 is: 27

def cube(N):
r = N * N * N
return r

Figure 6.79 Program cubeno.py listing

import cubeno
n= 3
res = cubeno.cube(n)
print("Cube of %d is: %d" %(n,res))

Figure 6.80 Program myprog.py

Module Search Path: When a module is to be imported, Python looks at the following
folders in the order given:

● 115
Learning Python with Raspberry Pi

• The folder from which the module is called (where the calling main program is)
• The list of directories contained in the PYTHONPATH environment variable.
• Installation dependent list of directories configured when Python was installed

Python search path can be displayed by entering the following command interactively:

>>> import sys


>>> sys.path

The display on the authors computer is shown in Figure 6.81.

Figure 6.81 Python path display

To make sure that your module is found by Python, you can do one of the following:

• Put the module program file in the folder where your main program is
• Modify PYTHONPATH environment variable to contain the folder where the
mo-dule program is
• Put the module program in one of the folders already contained in the
PYTHONPATH

6.35 Summary
In this chapter, we have learned how to use the basic functions of the Python programming
language. Many examples and case studies are given to help the user understand the var-
ious topics.

In the next chapter, we shall be looking at plotting graphs using Python. Examples of using
Python to design electronic circuits will be given in the form of case studies.

● 116
Chapter 7 • Plotting Graphs With Python

Chapter 7 • Plotting Graphs With Python

7.1 Overview
In the last chapter, we have learned the basic features of the Python programming lan-
guage and many examples and case studies are given.

In this chapter, we shall be looking at how to draw graphs using the Python programming
language. In addition, examples and case studies will be given on drawing graphs for elec-
tronic circuits.

7.2 The Matplotlib Graph Plotting Library


Matplotlib is a Python plotting library that is used to create two-dimensional graphs. Before
using this package, it has to be installed on your Raspberry Pi 4 using the following com-
mand:

pi@raspberrypi:~ $ sudo apt-get install python-matplotlib

We must import module matplotlib at the beginning of our programs before we can use
Matplotlib using the statement:

import matplotlib.pyplot as plt

Perhaps the easiest way to learn how to use Matplotlib is to look at an example.

Notice that Matplotlib is supported by Python v3 and therefore if you are using the com-
mand line, the command to start your program should be:

pi@raspberrypi:~ $ python3 <programname.py>

Additionally, graphs can only be plotted in Desktop mode. If you are not using a directly
connected monitor then you should start the VNC server on your Raspberry Pi and then
start the VNCViewer on your PC to get into the Desktop mode.

Example 1
Write a program to draw a line graph passing from the following (x, y) points:

x: 2 4 6 8
y: 4 8 12 16

Solution 1
The required program listing is shown in Figure 7.1 (program: graph1.py). This program
is very simple. Function call plt.plot plots the graph with the specified x and y values. The
graph is shown on Desktop when statement plt.show() is executed. Start the program by
entering the following command in the Accessories-> Terminal windows at the Desktop:

pi@raspberrypi:~ $ python3 graph1.py

● 117
Learning Python with Raspberry Pi

#----------------------------------------------
# SIMPLE LINE GRAPH
# =================
#
# This program draws a lien graph passing from
# the following points:
# x = 2 4 6 8
# y = 4 8 12 16
#
# Author: Dogan Ibrahim
# File : graph1.py
# Date : July, 2019
#----------------------------------------------
import matplotlib.pyplot as plt

x = [2, 4, 6, 8]
y = [4, 8, 12, 16]

plt.plot(x, y)
plt.show()

Figure 7.1 Program listing

Figure 7.2 shows the graph plotted by the program. Notice that at the bottom of the graph
we have several buttons to control the graph, such as zoom, save, etc.

Figure 7.2 Line graph drawn by the program

● 118
Chapter 7 • Plotting Graphs With Python

We can add titles, axis labels, and grid to our graph using the following functions:

plt.xlabel("X values")
plt.ylabel("Y values")
plt.title("Simple X-Y Graph")
plt.grid(True)

The new graph is shown in Figure 7.3.

Figure 7.3 Graph with labels, title, and grid

Matplotlib supports a large number of functions (see web link: https://matplotlib.org/2.0.2/


api/pyplot_summary.html for a full description of all the functions). Some commonly used
functions are:

• bar: make a bar plot


• box: turn the axis box on or off
• boxplot: make a box plot
• figtext: add text to the figure
• hist: plot a histogram
• legend: place a legend on the axes
• loglog: make a logarithmic plot
• pie: plot a pie chart
• polar: make a polar plot
• plotfile: plot data in a file
• semilogx: logarithmic plot with log on x-axis
• semilogy: logarithmic plot with log on y-axis
• suptitle: add a centered title to the plot
• tick_params: change the appearance of ticks and tick labels

Example 2
Write a program to draw a sine curve from 0 to 2π.

● 119
Learning Python with Raspberry Pi

Solution 2
We have to use numpy arrays to store our data points before plotting. Figure 7.4 shows
the program listing (program: graph2.py).

#----------------------------------------------
# SINE GRAPH
# ==========
#
# This program draws a sine graph from 0 to 2pi
#
# Author: Dogan Ibrahim
# File : graph2.py
# Date : July, 2019
#----------------------------------------------
import matplotlib.pyplot as plt
import numpy as np

#
# Calculate the data points in np
#
x = np.arange(0, 2 * np.pi, 0.1)
y = np.sin(x)

#
# Now plot the graph
#
plt.plot(x, y)
plt.xlabel("X values")
plt.ylabel("Sin(X)")
plt.title("Sine Wave")
plt.grid(True)
plt.show()

Figure 7.4 Program listing

The graph drawn by the program is shown in Figure 7.5.

● 120
Chapter 7 • Plotting Graphs With Python

Figure 7.5 Graph drawn by the program

Example 3
Draw the graph of the following function as x is varied from 0 to 4:

y = 2x2 + 3x + 2

Solution 3
Figure 7.6 shows the program listing (program: graph3.py). After calculating the x and y
values the graph is drawn as shown in Figure 7.7.

#----------------------------------------------
# Function Graph
# ==============
#
# This program draws a graph of the function:
# y = 2x2 + 3x + 2 from x=0 to x = 4
#
# Author: Dogan Ibrahim
# File : graph3.py
# Date : July, 2019
#----------------------------------------------
import matplotlib.pyplot as plt
import numpy as np

#
# Calculate the data points in np
#
x = np.arange(0, 4, 0.1)
y = [(2 * i * i + 3 * i + 2) for i in x]

● 121
Learning Python with Raspberry Pi

# Now plot the graph


#
plt.plot(x, y)
plt.xlabel("X values")
plt.ylabel("Y values")
plt.title("y=2x2 + 3x + 2")
plt.grid(True)
plt.show()

Figure 7.6 Program listing

Figure 7.7 Graph drawn by the program

Example 4
This is an example of drawing two graphs on the same axes. Write a program to draw the
graphs of the following two functions as x is varied from 0 to 3:

y = x2 + 2
y = x2 + 4

Solution 4
Figure 7.8 shows the program listing (program: graph4.py). After calculating the x and y
values the graphs are drawn as shown in Figure 7.9.

#----------------------------------------------
# Function Graph
# ==============
#
# This program draws a graph of the functions:
# y = x2 + 2
# y = x2 + 4 from x=0 to x = 3
#

● 122
Chapter 7 • Plotting Graphs With Python

# Author: Dogan Ibrahim


# File : graph4.py
# Date : July, 2019
#----------------------------------------------
import matplotlib.pyplot as plt
import numpy as np

#
# Calculate the data points in np
#
x = np.arange(0, 3, 0.1)
y1 = [(i * i + 2) for i in x]
y2 = [(i * i + 4) for i in x]

#
# Now plot the graph
#
plt.plot(x, y1, linestyle='solid')
plt.plot(x, y2, linestyle='dashed')
plt.xlabel(“X values")
plt.ylabel(“Y values")
plt.title(“y=x2+2 and y=x2+4")
plt.grid(True)
plt.show()

Figure 7.8 Program listing

Figure 7.9 Graph drawn by the program

In order to identify the individual graphs in a multi-graph drawing, we can plot each graph
with a different colour, or with different types of lines. Some examples are shown below:

● 123
Learning Python with Raspberry Pi

plt.plot(x, y1, color='blue')


plt.plot(x, y2, color='green')

or

plt.plot(x, y1, linestyle='solid')


plt.plot(x, y2, linestyle='dashed')

Figure 7.10 shows the graph in Figure 7.9 drawn with different line styles.

Figure 7.10 Using different line styles

Example 5
In this example, we use legends to identify multiple graphs in a multi-graph drawing. The
functions to be drawn are same as the ones given in the previous example.

Solution 5
Figure 7.11 shows the program listing (program: graph5.py). Matplotlib functions label
is used to identify the two graphs. Also, statement plt.legend() must be specified to draw
the legend.

#----------------------------------------------
# Function Graph
# ==============
#
# This program draws a graph of the functions:
# y = x2 + 2
# y = x2 + 4 from x=0 to x = 3
#
# In this program the graphs are identified
#
# Author: Dogan Ibrahim

● 124
Chapter 7 • Plotting Graphs With Python

# File : graph5.py
# Date : July, 2019
#----------------------------------------------
import matplotlib.pyplot as plt
import numpy as np

#
# Calculate the data points in np
#
x = np.arange(0, 3, 0.1)
y1 = [(i * i + 2) for i in x]
y2 = [(i * i + 4) for i in x]

#
# Now plot the graph
#
plt.plot(x, y1, linestyle='solid', label='x2+2')
plt.plot(x, y2, linestyle='dashed', label='x2+4')
plt.xlabel("X values")
plt.ylabel("Y values")
plt.title("y=x2+2 and y=x2+4")
plt.grid(True)
plt.legend()
plt.show()

Figure 7.11 Program listing

Figure 7.12 shows the graph drawn by the program.

Figure 7.12 Graph drawn by the program

● 125
Learning Python with Raspberry Pi

Example 6
Write a program to draw a pie chart for the following data;

France = 15%, Germany = 20%, Italy = 20%, UK = 45%

Solution 6
Figure 7.13 shows the program listing (program: graph6.py). The Pie chart is drawn with
equal aspect ratio so that is a circle.

#----------------------------------------------
# Pie Chart
# =========
#
# This program draws a pie chart for the data:
#
# France=15%, Germany=20%,Italy=20%,UK=45%
#
# Author: Dogan Ibrahim
# File : graph6.py
# Date : July, 2019
#----------------------------------------------
import matplotlib.pyplot as plt
import numpy as np

labels = “France", “Germany", “Italy", “UK"


sizes = [15, 20, 20, 45]

x, chrt = plt.subplots()
chrt.pie(sizes, labels=labels)
chrt.axis('equal')
plt.show()

Figure 7.13 Program listing

The Pie chart drawn by the program is shown in Figure 7.14.

● 126
Chapter 7 • Plotting Graphs With Python

Figure 7.14 Pie chart drawn by the program

We can explode parts of the Pie chart by specifying the parts to be exploded. For example,
to explode the fourth item in our example, we can issue the statement:

Explode = (0, 0, 0, 0.1) # specify amount to be exploded

The amount of explosion is determined by the value we specify. Also, the percentages of
each part can be written inside the Pie chart elements by using the statement:

autopct='%1.1f%%' # Specify 1 digit after decimal point

Parts of the Pie chart can be shadowed if desired to give it a 3D effect. This can be done
using the statement:

shadow=True

The program shown in Figure 7.15 (program: graph7.py) makes use of the above features
and the resulting Pie chart is shown in Figure 7.16.

#----------------------------------------------
# Pie Chart
# =========
#
# This program draws a pie chart for the data:
#
# France=15%, Germany=20%,Italy=20%,UK=45%
#
# Part UK is exploded in this graph.Also, the
# percentage of each part is written inside the
# corresponding parts and pats are shadowed
#
# Author: Dogan Ibrahim

● 127
Learning Python with Raspberry Pi

# File : graph7.py
# Date : July, 2019
#----------------------------------------------
import matplotlib.pyplot as plt
import numpy as np

labels = "France", "Germany", "Italy", "UK"


sizes = [15, 20, 20, 45]
explode = (0, 0, 0, 0.1)

x, chrt = plt.subplots()
chrt.pie(sizes, labels=labels, explode=explode,\
autopct='%1.1f%%',shadow=True)
chrt.axis('equal')
plt.show()

Figure 7.15 Program listing

Figure 7.16 Pie chart drawn by the program

Example 7
Write a program to draw a bar chart for the following data:

France = 10, Italy = 8, Germany = 6, UK = 2

Solution 7
Figure 7.17 shows the program listing (program: graph8.py). After specifying the values
for each bar, the bar chart is drawn.

● 128
Chapter 7 • Plotting Graphs With Python

#----------------------------------------------
# Bar Chart
# =========
#
# This program draws a bar chart for the data:
# France=10, Italy=8,Germany=6,UK=2
#
# Author: Dogan Ibrahim
# File : graph8.py
# Date : July, 2019
#----------------------------------------------
import matplotlib.pyplot as plt
import numpy as np

labels = ("France", "Germany", "Italy", "UK")


pos = np.arange(len(labels))
values = [10, 8, 6, 2]

plt.bar(pos, values, align='center',alpha=0.5)


plt.xticks(pos, labels)
plt.ylabel('MB/s')
plt.title('Internet Speed')
plt.show()

Figure 7.17 Program listing

Figure 7.18 shows the graph drawn by the program.

Figure 7.18 Graph drawn by the program

● 129
Learning Python with Raspberry Pi

We can plot a horizontal bar chart by replacing the statement plt.bar with plt.barh.

7.3 Case Study 8 – RC Transient Circuit Analysis - Charging


Description: This case study is about analysing a charging RC transient circuit by plotting
its time response.

Aim: The aim of this case study is to show how to use the keyboard input, flow control
statements, and also how to draw graphs using the Python programming language.

Background Information: RC circuits are used in many radio and communications cir-
cuits. A typical RC transient circuit consists of a resistor in series with a capacitor as shown
in Figure 7.19. When the switch is closed, the voltage across the capacitor rises exponen-
tially with a time constant, T = RC.

Figure 7.19 Charging RC circuit

Expressed mathematically, assuming that initially the capacitor is discharged, when the
switch is closed the voltage across the capacitor rises a given by the following formula:

(7.1)

Initially, the voltage across the capacitor is 0V, and in steady-state the voltage across the
capacitor becomes equal to Vin. The time constant is the time where the output voltage
rises to around 63.2% of its final value.

Program Listing: Figure 7.20 shows the program listing (program: RCrise.py). After
displaying heading, the values of the input voltage Vin, and resistor and capacitor values
are read from the keyboard. Notice that Python V3 does not support function raw_input,
instead in Python V3 we have to use just input for reading from the keyboard. The program
then calculates the time constant as T=RC and displays the time constant and also draws
the time response of the circuit. The graph is drawn as the time value (x-axis) changes
from 0 to 6T and 50 points are taken to draw the graph. The time constant is also written
on the graph at the point (Time constant, Vin / 2). The horizontal axis is in seconds, while
the vertical axis is in volts.

#----------------------------------------------
# RC TRANSIENT RESPONSE
# =====================
#
# This program reads the R and C values and then
# calculates and displays the time conctant. Also,

● 130
Chapter 7 • Plotting Graphs With Python

# the time response of teh circuit is drawn


#
# Author: Dogan Ibrahim
# File : RCrise.py
# Date : July, 2019
#----------------------------------------------
import matplotlib.pyplot as plt
import numpy as np
import math

print("RC Transient Response")


print("=====================")

#
# Read Vin, R and C
#
Vin = float(input("Enter Vin in Volts: "))
R = float(input("Enter R in Ohms: "))
C = float(input("Enter C in microfarads: "))
C = C / 1000000.0

#
# Calculate and display time constant
#
T = R * C
F = 6.0 * T
N = F / 50.0
print("Time constant = %f seconds" %(T))

#
# Now plot the time response
#
x = np.arange(0, F, N)
y = [(Vin * (1.0 - math.exp(-i/T))) for i in x]

plt.plot(x, y)
plt.xlabel("Time (s)")
plt.ylabel("Capacitor Volts")
plt.title("RC Response")
plt.grid(True)
TC = "T="+str(T)+"s"
plt.text(T, Vin/2, TC)
plt.show()

Figure 7.20 Program listing

● 131
Learning Python with Raspberry Pi

Figure 7.21 shows an example graph displayed by the program. In this program the follow-
ing input values were used (see Figure 7.22):

• Vin = 10 Volts
• R = 1000 Ohm
• C = 100 microfarad

The time constant was calculated to be 0.1 seconds.

Figure 7.21 Graph plotted by the program

Figure 7.22 Input values to the example program

7.4 Case Study 9 – RC Transient Circuit Analysis - Discharging


Description: This case study is about analysing a discharging RC transient circuit by plot-
ting its time response.

Aim: The aim of this case study is to show how to use the keyboard input, flow control
statements, and also how to draw graphs using the Python programming language.

Background Information: In this case study an RC circuit is used as in Figure 7.23. We


assume that the capacitor is fully charged after switch s1 is closed. We then close switch s2
so that the capacitor discharges through resistor R. The time response of the voltage across
the capacitor is then given by:

(7.2)

● 132
Chapter 7 • Plotting Graphs With Python

Where Vo is the initial voltage across the capacitor (normally the same as Vin) before s2 is
closed. Again, T=RC is known as the time constant of the circuit.

Figure 7.23 Discharging RC circuit

Program Listing: Figure 7.24 shows the program listing (program: RCfall.py). After dis-
playing heading, the values of the initial voltage across the capacitor (Vo), and the resistor
and capacitor are read from the keyboard. Notice that Python V3 does not support function
raw_input, instead in Python V3 we have to use just input for reading from the keyboard
The program then calculates the time constant as T=RC and displays the time constant and
also draws the time response of the circuit. The graph is drawn as the time value (x-axis)
changes from 0 to 6T and 50 points are taken to draw the graph. The time constant is also
written on the graph at the point (Time constant, Vo / 2). The horizontal axis is in seconds,
while the vertical axis is in volts.

#----------------------------------------------
# RC TRANSIENT RESPONSE
# =====================
#
# This program reads the R and C values and then
# calculates and displays the time constant. Also,
# the time response of the circuit is drawn as the
# capacitor is discharged
#
# Author: Dogan Ibrahim
# File : RCfall.py
# Date : July, 2019
#----------------------------------------------
import matplotlib.pyplot as plt
import numpy as np
import math

print("RC Transient Response")


print("=====================")

#
# Read Vo, R and C
#
Vo = float(input("Enter Initial Capacitor Voltage in Volts: "))
R = float(input("Enter R in Ohms: "))
C = float(input("Enter C in microfarads: "))

● 133
Learning Python with Raspberry Pi

C = C / 1000000.0

#
# Calculate and display time constant
#
T = R * C
F = 6.0 * T
N = F / 50.0
print("Time constant = %f seconds" %(T))

#
# Now plot the time response
#
x = np.arange(0, F, N)
y = [(Vo * (math.exp(-i/T))) for i in x]

plt.plot(x, y)
plt.xlabel("Time (s)")
plt.ylabel("Capacitor Volts")
plt.title("RC Response")
plt.grid(True)
TC = "T="+str(T)+"s"
plt.text(T, Vo/2, TC)
plt.show()

Figure 7.24 Program listing

Figure 7.25 shows an example graph displayed by the program. In this program the follow-
ing input values were used (see Figure 7.26):

• Vin = 10 Volts
• R = 1000 Ohm
• C = 100 microfarad

The time constant was calculated to be 0.1 seconds.

● 134
Chapter 7 • Plotting Graphs With Python

Figure 7.25 Graph plotted by the program

Figure 7.26 Input values to the example program

7.5 Transient RL Circuits


The time response of a transient resistor-inductor circuits is similar to the RC circuit. When
the circuit is connected to a DC supply of value Vin, the current in the circuit rises exponen-
tially and is given by the following formula:

(7.3)

Where Vin is in volts, R in Ohms, L in Henries, and t in seconds. The time constant of this
circuit is given by T = L/R.

After the current reaches its steady-state value, disconnecting the DC supply and shorting
the leads causes the current in the circuit to fall exponentially, given by the following for-
mula:

(7.4)

Where Vo is the initial voltage across the inductor.

The transient response of RL circuits is similar to those of the RC circuits and therefore are
not covered further in this book.

● 135
Learning Python with Raspberry Pi

7.6 Case Study 10 – RCL Transient Circuit Analysis


Description: This case study is about analysing the transient response of a second-order
series-connected RLC circuit by plotting its time response.

Aim: The aim of this case study is to show how to use the keyboard input, flow control
statements, and also how to draw graphs using the Python programming language.
Background Information: An RLC circuit (Figure 7.27) is a second-order system that can
have 3 modes of operation depending on the values of the components when a DC voltage
is applied across its terminals.

Figure 7.27 RLC circuit

Underdamped mode: This mode is identified when the following condition holds true:

(7.5)

When DC voltage is applied to the circuit, the current in the circuit is given by the following
formula:

(7.6)

Where,

and, (7.7)

Critically damped mode: In this mode of operation, the following is satisfied:

(7.8)

When DC voltage is applied to the circuit, the current in the circuit is given by the following
formula:

(7.9)

Where,

and, (7.10)

● 136
Chapter 7 • Plotting Graphs With Python

Overdamped mode: In this mode of operation, the following is satisfied:

(7.11)

When DC voltage is applied to the circuit, the current in the circuit is given by the following
formula:

(7.12)

Where,

and, (7.13)

Program Listing: Figure 7.28 shows the program listing (program: RLC.py). At the be-
ginning of the program a heading is displayed and then the values of the input voltage,
resistor, capacitor and the inductor are read and stored in variables Vin, R, C, and L re-
spectively. The program then finds out in which mode the circuit will be operating based
on the value of ξ. Then, three functions are used, one for each mode, to calculate and plot
the transient response of the circuit. The mode of the circuit is displayed on the graph at
the coordinate (3T, 0), where T = 2π/W. In all the graphs, 80 points are used to draw the
points from 0 to 6T.

#------------------------------------------------
# RLC TRANSIENT RESPONSE
# ======================
#
# This program reads the R,L,C values and then
# calculates and displays the transient response
#
# Author: Dogan Ibrahim
# File : RLC.py
# Date : July, 2019
#------------------------------------------------
import matplotlib.pyplot as plt
import numpy as np
import math
global x, y, z

def critically_damped():
global x,y
x = np.arange(0, F, N)
y = [Vin*((1/L) * i * math.exp(-i*w)) for i in x]

def underdamped():
global x,y,z

● 137
Learning Python with Raspberry Pi

x = np.arange(0, F, N)
zeta = math.sqrt(1 - z*z)
y = [Vin*(1/(w*L*zeta)*(math.exp(-z*w*i))*math.sin(w*i*zeta)) for i in x]

def overdamped():
global x,y,z
x = np.arange(0, F, N)
y = [Vin*(1/(w*L*(math.sqrt(z*z-1))))*(math.exp(-z*w*i))*\
math.sinh(w*i*math.sqrt(z*z-1)) for i in x]

print("RLC Transient Response")


print("=====================")

#
# Read Vin, R,C and L
#
Vin = float(input("Enter Vin in Volts: "))
R = float(input("Enter R in Ohms: "))
C = float(input("Enter C in microfarads: "))
C = C / 1000000.0
L = float(input("Enter L in millihenries: "))
L = L / 1000.0
w = math.sqrt(1/(L * C))
z = (R/2) * math.sqrt(C / L)
T = (2.0 * math.pi) / w
F = 6 * T
N = F / 80.0

#
# Find the mode of operation
#
mode = R - 2.0 * math.sqrt(L / C)
if abs(mode) < 0.01:
case = 2
md = "Critically Damped"
critically_damped()
elif mode < 0:
case = 1
md = "Underdamped"
underdamped()
elif mode > 0:
case = 3
md = "Overdamped"
overdamped()

● 138
Chapter 7 • Plotting Graphs With Python

#
# Now plot the time response
#
plt.plot(x, y)
plt.xlabel("Time (s)")
plt.ylabel("Current")
plt.title("RLC Response")
plt.grid(True)
plt.text(3*T,0, md)
plt.show()

Figure 7.28 Program listing

Figure 7.29 shows a typical run of the program with the following values:

• Vin = 10 Volts
• R = 10 Ohms
• C = 100 microfarads
• L = 200 microhenries

Figure 7.29 Response of the circuit

7.7 Summary
In this chapter, we have learned how to draw line graphs, pie charts, and bar graphs using
the Python programming language. We have also learned how to plot the time response of
RC and RLC transient circuits. In the next chapter, we shall be looking at how data can be
saved in files on the Raspberry Pi micro SD card using the Python programming language.

● 139
Learning Python with Raspberry Pi

Chapter 8 • Files in Python With the Raspberry Pi

8.1 Overview
In the last chapter, we have learned how to draw graphs in Python, and also have learned
how to plot the transient responses of RC and RLC circuits. In this chapter, we will look
at the file operations in Python programming, especially using the Raspberry Pi. We will
learn how to create new files, read existing files, and carry out other file operations on the
Raspberry Pi micro SD.

8.2 Python File Operations


Files in Raspberry Pi are stored on the micro SD card which also keeps the operating system
data and files.

A file in Python is opened using the keyword open. The general format of the open state-
ment is:

file object = open(filename, access mode)

The filename is the name of the file that should be created (if new) or opened (if already
existing).

Access mode defines the type of operation to be performed on the file. Some commonly
used access modes are:

• r open file for reading (file pointer positioned at the beginning)


• r+ open for both reading and writing (file pointer at the beginning)
• w open for writing. If the file already exists, overwrite it. If the file does not
exist then create a new file
• w+ open for both writing and reading. If the file already exists then overwrite
it, otherwise create a new file
• a open the file for appending. If the file already exists, the pointer is posi-
tioned at the end for appending. If the file does not exist then a new file
is created
• a+ open for both appending and reading. If the file already exists, the pointer
is positioned at the end for appending. If the file does not exist then a new
file is created for reading and writing
• b open the file in binary mode
• rb open a file for reading in binary format
• t open the file in text mode (default)

An opened file should be closed properly using the close() statement so that its contents
are not destroyed.

An example of opening an existing file called myfile.txt for reading is:

f = open("myfile.txt", "r")

● 140
Chapter 8 • Files in Python With the Raspberry Pi

The file is opened in the default working directory of the user, which is /home/pi on the
Raspberry Pi. The file should be closed using the statement:

f.close()

Data can be read and written to an opened file using the following statements:

• f.read() read contents of entire file. The number of bytes to read can be
specified with the statement f.read(n). For example, f.read(5)
will read 5 bytes from the file.
• f.readline() read a file line by line.
• F.readlines() read content of a file until end of file is reached

The following functions can be used to get information about a file:

• f.closed returns true if the file is closed, false otherwise


• f.mode returns the access mode that the file was opened
• f.name returns the name of the file
• f.tell() returns the current position within the file

an example is shown below (characters enters by the user are in bold for clarity):

>>> f = open("myfile.txt", "r")


>>> print(f.name)
myfile.txt
>>> print(f.closed)
False
>>> print(f.mode)
r
>>>

Some operating system based file operations are given below. Before using these opera-
tions, we must import the os module to our program:

• os.rename(oldfile, newfile) rename a file


• os.remove(filename) remove (delete) a file
• os.mkdir(newdirectory) create a new directory
• os.chdir(directory) change working directory
• os.rmdir(directory) remove (delete) a directory
• os.getcwd() returns name of current directory

Figure 8.1 shows a program code that creates a file called myfile.txt in the default di-
rectory and the following line of text written to the file. Command ls can be issued to see
that the file has actually been created. Entering command cat myfile.txt will display the
contents of the file:

● 141
Learning Python with Raspberry Pi

This is a sample text file

Figure 8.1 Creating and displaying the contents of a file

Some examples are given below to show how the various file operations can be used in
Python programs.

Example 1
Write a program to calculate the squares of numbers from 1 to 10 and store your results as
a table in a file called squares.txt.

Solution 1

The required program listing is shown in Figure 8.2 (program: flsqr.py). A for loop is used
to create the table. The file is opened in write mode and the table data is stored in the file.

#===================================================
# SQUARES OF NUMBERS
# ==================
#
# This program calculates the squares of numbers
# from 1 to 10 and saves them as a table in a file
# called squares.txt.
#
# Author: Dogan Ibrahim
# File: flsqr.py
# Date: July, 2019
#===================================================
f = open("squares.txt", "w")
f.write("Number Square\n")

for i in range(1, 11):


f.write("%d %d\n" %(i, i*i))

f.close()

Figure 8.2 Program listing

Figure 8.3 shows the file contents by issuing the cat command.

● 142
Chapter 8 • Files in Python With the Raspberry Pi

Figure 8.3 Contents of the file

Example 2
Write a program to read the contents of the file created in Example 1 using the read()
statement and display the data on the screen.

Solution 2
The required program listing is shown in Figure 8.4 (program flrd1.py). File squares.txt is
opened in read mode. This program uses function read to read the entire contents of the
file which is then displayed on the screen.

#===================================================
# Read and Display Contents of a File
# ===================================
#
# This program reads teh contents of file squares.txt
# and displays its contents on teh screen
#
# Author: Dogan Ibrahim
# File: flrd1.py
# Date: July, 2019
#===================================================
f = open("squares.txt", "r")
contents = f.read()
print(contents)
f.close()

Figure 8.4 Program listing

Example 3
Write a program to read contents of the file created in Example 1 line by line using the
readline() statement and display the data on the screen.

Solution 3
The required program listing is shown in Figure 8.5 (program: flrd2.py). File squares.txt
is opened in read mode. This program uses function readline() to read the file line by line.
Notice that a newline character is displayed at the end of each line so that there is a blank

● 143
Learning Python with Raspberry Pi

line between each line as shown in part in Figure 8.6. By adding statement strip() to the
print statement we can disable this extra new line .i.e. use print(line.strip()) instead of
print(line)

#===================================================
# Read and Display Contents of a File
# ===================================
#
# This program reads the contents of file squares.txt
# and displays its contents on the screen
#
# Author: Dogan Ibrahim
# File: flrd2.py
# Date: July, 2019
#===================================================
f = open("squares.txt", "r")

while True:
line = f.readline()
if not line:
break;
print(line.strip())

f.close()

Figure 8.5 Program listing

Figure 8.6 Lines displayed with new line at the end

Example 4
Write a program to read contents of the file created in Example 1 and store the data in a
list.

Solution 4
Figure 8.7 shows the program listing (program: flrd3.py). At the beginning of the program,
an empty list called MyList is created. File squares.txt is then opened in read mode. The
lines are read from the file and stored in MyList. Figure 8.8 shows the contents of MyList
after the program is run.

● 144
Chapter 8 • Files in Python With the Raspberry Pi

#===================================================
# Read Contents of a File and Store in a List
# ===========================================
#
# This program reads the contents of file squares.txt
# and stores the data in a list
#
# Author: Dogan Ibrahim
# File: flrd3.py
# Date: July, 2019
#===================================================
MyList = list()
with open("squares.txt", "r") as f:
for line in f:
MyList.append(line.strip())

print(MyList)
f.close()

Figure 8.7 Program listing

Figure 8.8 Contents of MyList after the program is run

Example 5
Write a program to read and display the contents of the file created in Example 1 using
function readlines().

Solution 5
Figure 8.9 shows the program listing (program: flrd4.py). Function readlines() is similar
to function read(), but it reads all the lines of a file into a list. The output from the program
is shown in Figure 8.10.

#===================================================
# Read Contents of a File and Store in a List
# ===========================================
#
# This program reads the contents of file squares.txt
# and stores the data in a list
#
# Author: Dogan Ibrahim
# File: flrd4.py
# Date: July, 2019
#==================================================

● 145
Learning Python with Raspberry Pi

with open("squares.txt", "r") as f:


MyList = f.readlines()
for line in MyList:
print(line.strip())

print(MyList)
f.close()

Figure 8.9 Program listing

Figure 8.10 Output from the program

8.3 Case Study 11 – RC Circuit Frequency Response


Description: In this case study we calculate the frequency response (magnitude and
phase) of an RC circuit and store the data in a file called rcfreq.txt in the form of a table
Aim: The aim of this case study is to show how to use the keyboard input, flow control
statements, and also how to calculate the frequency response of a circuit and save the
results in a file.

Background Information: The frequency response of a circuit consists of the change


of its magnitude and the phase angle as the frequency is changed. In this case study, we
will consider a simple RC circuit shown in Figure 8.11 with the component values, R = 470
Ohms and C = 20 microfarads, where the capacitor is the output. The magnitude (transfer
function) and phase of the frequency response of this circuit are given by the following
formula:

(8.1)

The magnitude is usually denoted in decibels:

(8.2)

And the phase is:

(8.3)

Where, w = 2πf, and f is the frequency

● 146
Chapter 8 • Files in Python With the Raspberry Pi

In this case study, we will calculate the magnitude in decibels and the phase in degrees as
the frequency is changed from 0 to 150Hz in steps of 10Hz.

Figure 8.11 RC Circuit used in the case study

Program Listing: Figure 8.12 shows the program listing (program: freqrc.py). At the
beginning of the program, the values of R and C are read from the keyboard. The program
then calculates the magnitude in decibels and the phase angle in degrees as the frequency
is changed and saves the results in the file.

#===================================================
# Frequency Response of RC circuit
# ================================
#
# This program calculates teh frequency reponse of
# an RC circuit and saves teh frequecny-magnitude in
# a file called rcfreq.txt
#
# Author: Dogan Ibrahim
# File: freqrc.py
# Date: July, 2019
#===================================================
import math

print("RC Frequency Response")


print("=====================")
#
# Read in the component values
#
R = float(raw_input("Enter R in Ohms: "))
C = float(raw_input("Enter C in microfarads: "))
C = C / 1000000.0

#
# Now calculate and store the freq-magnitude in a file
#
f = open("rcfreq.txt", "w")
f.write("Frequency (Hz) Magnitude (dB) Phase (degrees)\n")

for freq in range(0, 160, 10):


w = 2.0 * freq * math.pi

● 147
Learning Python with Raspberry Pi

d = w * C * R
denom = d * d + 1
M = math.sqrt(1 / denom)
M = 20 * math.log10(M)
phase = -math.degrees(math.atan(d))
f.write("%3d %10.4f %10.4f\n" %(freq, M, phase))

f.close()

Figure 8.12 Program listing

Figure 8.13 shows the contents of file rcfreq.txt.

Figure 8.13 Output of the program

8.4 Case Study 12 – Save Raspberry Pi 4 CPU Temperature in a File


Description: It is well known that the CPU temperature of Raspberry Pi can rise to very
high values and this may affect the performance of the system. In this case study, we save
the Raspberry Pi CPU temperature in a file called cputemp.txt every 10 seconds with time
stamping.

Aim: The aim of this case study is to show how to measure the Raspberry Pi CPU temper-
ature and then save it in a file with time stamping.

Background Information: The CPU temperature of the Raspberry Pi 4 can be measured


using the following command while in command mode:

pi@raspberrypi:~ $ vcgencmd measure_temp


temp=40.0'C

To measure the temperature from Python we have to issue the following commands in a
Python V3 session (see also Appendix A.3):

>>> fl = open("/sys/class/thermal/thermal_zone0/temp")

● 148
Chapter 8 • Files in Python With the Raspberry Pi

>>> rd = float(fl.read())
>>> Temp = rd / 1000
>>> Print(temp)
40.894
>>> close(fl)
>>>

Program Listing: Figure 8.14 shows the Python V3 program listing (program: cputemp.
py). At the beginning of the program, the time module is imported to the program. The
program then opens a file called cputemp.txt in write mode. A loop is formed where the
CPU temperature is measured every 10 seconds and is saved in the file with current time
stamping. The number of records saved is displayed every 10 seconds. The program is
terminated orderly and the file is closed when the user enters Cntrl+C at the keyboard.

#-------------------------------------------------------
# SAVE THE RASPBERRY PI 4 CPU TEMPERATURE IN A FILE
# =================================================
#
# This program measures and saves the CPU temperature
# of teh Raspberry Pi 4 every 10 seconds and the saves
# in a file called cputemp.txt
#
# Author: Dogan Ibrahim
# File : cputemp.py.py
# Date : July, 2019
#-------------------------------------------------------
import time

print("Save the Raspberry Pi 4 CPU temperature\n")


MyFile = open("cputemp.txt", "w")
count = 0

#
#Read the CPU temperature
#
try:
while True:
fl = open("/sys/class/thermal/thermal_zone0/temp")
rd = fl.read()
temp = (float)(rd) / 1000
tim = time.ctime()
MyFile.write("%s %5.2f C\n" %(tim, temp))
count = count + 1
print("Saved %d records" %(count))
fl.close()
time.sleep(10)

● 149
Learning Python with Raspberry Pi

except KeyboardInterrupt:
print("End of saving the temperature\n")
MyFile.close()

Figure 8.14 Program listing

Figure 8.15 shows a typical run and the output from the program.

Figure 8.15 Typical run and output from the program

8.5 Saving Data on an External USB Memory Stick


Raspberry Pi is equipped with 2 x USB2.0 and 2 x USB 3 ports. There are applications where
we may want to save data on an external USB memory stick. This section shows how we
can identify a USB port and also how data can be saved on a USB memory stick. The steps
are given below:

Plug-in your USB memory stick to one of the Raspberry Pi USB ports

Enter the following command to check if your memory stick is visible:

pi@raspberrypi:~ $ ls –l /dev/disk/by-label

You should see a display similar to the one shown in Figure 8.16. Notice that in this display
sda1 with the label name DOGANS is our memory stick

● 150
Chapter 8 • Files in Python With the Raspberry Pi

Figure 8.16 Checking the memory stick

We now have to create a Mount Point, which is a directory that will point to our memory
stick. Enter the following command:

pi@raspberrypi:~ $ sudo mkdir /media/usb

Now we have to mount the drive. Enter the following command to mount the drive:

pi@raspberrypi:~ $ sudo mount /dev/sda1 /media/usb –o uid=pi,gid=pi

To display the contents of the memory stick, enter the following command:

pi@raspberrypi:~ $ ls –l /media/usb

To unmount the drive, enter the following command:

pi@raspberrypi:~ $ sudo umount /media/usb

when you restart your Raspberry Pi your drive mount will be lost and you will have to mount
again using the above instructions. You can make your memory stick to be mounted auto-
matically after system re-start. The steps or this are as follows:

Enter the following command and note the uuid number of your memory stick (see Figure
8.17). In this example, the uuid number was: 4083-7126

pi@raspberrypi:~ $ ls –l /dev/disk/by-uuid

Figure 8.17 Note your uuid number

Use the nano text editor and edit file /etc/fstab

pi@raspberrypi:~ $ sudo nano /etc/fstab

● 151
Learning Python with Raspberry Pi

Add the following line to the end of this file:

UUID=4083-7126 /media/usb vfat auto,nofail,noatime,users,rw,uid=pi,gid=pi

Enter Cntrl+X followed by Y to save and exit the file

Re-start your Raspberry Pi:

pi@raspberrypi:~ $ sudo reboot

After restarting your Raspberry Pi, the memory stick will be mounted automatically. Enter
the following command to make sure that the files on your memory stick will be displayed:

pi@raspberrypi:~ $ ls –l /media/usb

The options in the UUID command are:

nofail: continue to boot if the memory stick is not plugged in


noatime: do not update the file access time (improves the performance)
vfat: assume that the drive was formatted with FAT32

Note: You can unmount the drive after re-start, or remove the drive from file /etc/fstab
if it is not required anymore.

8.6 Case Study 13 – Save Raspberry Pi 4 CPU Temperature on Memory Stick


Description: This case study is similar to case study 12, but here the CPU temperature is
stored on an USB memory stick in a file called cputemp.txt every 10 seconds with time
stamping.

Aim: The aim of this case study is to show how to save data on an USB memory stick with
time stamping.

Program Listing: Before writing the program it is assumed that the memory stick is al-
ready mounted either manually or automatically after system re-start on your Raspberry
Pi. Figure 8.18 shows the program listing (program: usbwrite.py). You should run this
program with Python V3:

pi@raspberrypi:~ $ python3 usbwrite.py

#-------------------------------------------------------
# SAVE THE RASPBERRY PI 4 CPU TEMPERATURE IN A FILE
# =================================================
#
# This program measures and saves the CPU temperature
# of the Raspberry Pi 4 every 10 seconds and the saves
# in a file called usbcputemp.txt on an USB memory stickt

● 152
Chapter 8 • Files in Python With the Raspberry Pi

#
# Author: Dogan Ibrahim
# File : usbwrite.py
# Date : July, 2019
#-------------------------------------------------------
import time

print("Save the Raspberry Pi 4 CPU temperature on a USB stick\n")


MyFile = open("/media/usb/cputemp.txt", "w")
count = 0

#
#Read the CPU temperature
#
try:
while True:
fl = open("/sys/class/thermal/thermal_zone0/temp")
rd = fl.read()
temp = (float)(rd) / 1000
tim = time.ctime()
MyFile.write("%s %5.2f C\n" %(tim, temp))
count = count + 1
print("Saved %d records" %(count))
fl.close()
time.sleep(10)

except KeyboardInterrupt:
print("End of saving the temperature on the memory stick\n")
MyFile.close()

Figure 8.18 Program listing

Notice that the memory stick is identified by folder name: /media/usb/. Figure 8.19
shows running and displaying the contents of file cputemp.txt on the memory stick.

Figure 8.19 Running and displaying the file on the USB memory stick

● 153
Learning Python with Raspberry Pi

8.7 Summary
In this chapter, we have learned how to create files either on the micro SD card or on an
external USB memory stick, and how to write and read from the files on these media.
In the next chapter, we shall be looking at matrices and see how matrices can be created,
inverted etc. Additionally, we shall be learning how to use matrices to carry out mesh and
nodal analysis of electrical circuits.

● 154
Chapter 9 • Array and Matrix Operations With Python

Chapter 9 • Array and Matrix Operations With Python

9.1 Overview
In the last chapter, we have learned how to store data in files, both on the micro SD card
and on an external USB memory stick. In this chapter, we shall be looking at the arrays and
matrices and learn how we can use matrices in solving mesh and nodal electrical circuits in
order to calculate the current and voltage in the circuit.

9.2 Arrays
Arrays can be created using the numpy module. The following example shows how a 2 x
2 array can be created:

>>> from numpy import array


>>> x = array([[2.0, 4.0], [-3.0, 5.2]])
>>> print(x)
[[2. 4. ]
[-3 5.2]]
>>>

Array elements can be accessed by specifying the row and column numbers. The element
at the top left-hand side is (0 , 0). Some examples are given below:

>>> print(x[0,1])
4.0
>>>

To change a row:

>>> x[0] = [ 12.2, 4.5]


>>> print(x)
[[12.2 4.5]
[-3 5.2]]
>>>

To change an element:

>>> x[0, 1] = 5
>>> print(x)
[[12.2 5. ]
[-3 5.2]]
>>>

We can specify all the elements of an array as floating point by specifying dtype=float as
shown below:

>>> x = array([[1, 3], [4, 0]], dtype=float)

● 155
Learning Python with Raspberry Pi

9.2.1 Array Operations and Functions


Python supports many array operations and array functions. Some example array opera-
tions are shown in Figure 9.1. Figure 9.2 shows some array functions.

Figure 9.1 Some array operations

Figure 9.2 Some array functions

A unit matrix can be created using function identity and specifying the order of the matrix.
In the following example a 3 x 3 unit matrix called A is created:

>>> A = identity(3)
>>> print(A)
[[ 1. 0. 0.]
[ 0. 1. 0.]
[ 0. 0. 1.]]
>>>

9.2.2 Array Multiplication


Arrays can be multiplied by a constant or two arrays can be multiplied as a Dot Product
as shown in Figure 9.3.

● 156
Chapter 9 • Array and Matrix Operations With Python

Figure 9.3 Array multiplication

9.2.3 Copying Arrays


Sometimes we may need to make copy of an array. Function copy() is used for this pur-
pose as shown in the following example:

>>> from numpy import array


>>> a = array([[1, 2], [3, 4]])
>>> b = a.copy()
>>> print(b)
[[ 1 2 ]
[ 3 4 ]]
>>>

9.3 Systems of Linear Algebraic Equations


Systems of linear algebraic equations, also known as simultaneous algebraic equations are
very important in electrical circuit analysis. Circuits can be analysed using the mesh or the
nodal analysis methods which consists of linear algebraic equations.

Before analysing electrical circuits, we shall be looking at the solution of systems of linear
algebraic equations using the Python programming language.

The general form of a system of linear equations is:

a11x1 + a12x2 + ……+ a1nxn = b1


a21x1 + a22x2+……..+ a2nxn = b2
………………………………..
…………………………………
an1x1 + an2x2 + ……+ annxn = bn

We can express the above general system of equations as a matrix operation as follows:

(9.1)

● 157
Learning Python with Raspberry Pi

or as,

Ax = b 9.2)

where,

A = (9.3)

x = (9.4)

b = (9.5)

Multiplying both sides of equation (9.2) by A-1 we get:

A-1Ax = A-1b

or,

x = A-1b (9.6)

Therefore, we can find the solution by taking the inverse of A and multiplying with b. Func-
tion inv returns the inverse of a matrix. Some examples are given below.
Example 1

Solve the following system of linear equations:

2x + 3y = 11
4x + y = 7

Solution 1

Here, A =

x =

b =

● 158
Chapter 9 • Array and Matrix Operations With Python

The solution is shown in Figure 9.4 where the result is given as x = 1, y = 3. Notice that
module inv must be imported from numpy.linalg.

Figure 9.4 Solution of the equations

Python also supports the function solve for solving a system of linear equations without
having to use equation (9.6). An example is given below.

Example 2
Solve the following system of linear equations:

2x + y + 2z = 10
x + y + z = 6
x + 2y + 3z = 14

Solution 2

Here, A =

x =

b =

The solution is shown in Figure 9.5 where function solve is used. Notice that module solve
must be imported from numpy.linalg. In this example, the solution is found to be x =1,
y = 2, z = 3

Figure 9.5 Solution of the equations

Example 3
Solve the following system of linear equations:

2x + y + 2z = 18.3
2.5x + y + z = 11.35
x + 2y + 2z = 12.7

● 159
Learning Python with Raspberry Pi

Solution 3

Here, A =

x =

b =

The solution is shown in Figure 9.6 where function solve is used. In this example, the solu-
tion is found to be x =2.5, y = -3.1, z = 8.2

Figure 9.6 Solution of the equations

9.4 Case Study 14 – DC Circuits Mesh Analysis 1


Description: Mesh analysis is a method of representing an electrical circuit as a matrix and
then analysing and calculating the current and voltages in the circuit. In this case study we
will analyse a simple DC circuit consisting of 3 resistors and 2 batteries. It is assumed that
the readers are familiar with the basic circuit theory and have analysed circuits using the
mesh analysis before.

Aim: The aim of this case study is to show how to read data from the keyboard in the form
of a matrix, and how to calculate the current and voltages in a DC circuit consisting of re-
sistors and batteries.

Background Information: In the mesh analysis, we assume currents in each loop of


the circuit and then enter the circuit elements (resistors and batteries in this case). Then
the matrix equation Ax = b is formed where A represents the circuit elements in terms of
resistances, x represents the currents in the circuit, and b represents the voltage sources
(e.g. batteries). The matrix equation is then solved as shown in the examples earlier in
this chapter. After calculating the currents in the circuit, we can easily calculate the voltage
across every resistor.

In this case study, the circuit shown in Figure 9.7 is used as an example. This circuit con-
sists of 3 resistors: 10 Ohms, 20 Ohms, and 40 Ohms, and two voltage sources (batteries):
10 Volts and 20 Volts.

● 160
Chapter 9 • Array and Matrix Operations With Python

Figure 9.7 Circuit to be analysed

From an inspection of the circuit, we can write the elements of matrices A, b and x for this
circuit are as follows:

Here, A =

x =

b =

Just as a reminder, assuming that the currents in each loop are taken in the same direction
(e.g. clockwise):

A11 = Sum of all the resistances in loop1


A12 = Sum of all the resistances common to loop 1 and loop 2 (negative)
A21 = Sum of all the resistances common to loop 2 and loop 1 (negative)
A22 = Sum of all the resistances in loop 2

Program Listing: Figure 9.8 shows the program listing (program: mesh.py). At the be-
ginning of the program a heading is displayed. Arrays A and b are cleared (filled with ze-
roes). The program then reads the number of rows of the A matrix, which is also equal to
the number of columns. Then the elements of A and b matrices are read and the currents
are calculated and displayed. As shown in Figure 9.9, the currents in the two loops are:
I1 = -0.143A and I2 = -0.429A. We can then calculate the voltage across each resistor as
follows:

Voltage across 10 Ohm resistor = 10 x I1 = -1.43 Volts


Voltage across 40 Ohm resistor = 40 x (I1 – I2) = 11.44 Volts
Voltage across 20 Ohm resistor = 20 x I2 = -8.58 Volts

#====================================================
# CIRCUIT MESH ANALYSIS
# =====================
#
# This program carries out mesh analysis of a circuit.
# The user enters the circuit elements in the form of
# A and b matrices and the program calculates and

● 161
Learning Python with Raspberry Pi

# displays the values of the currents in the circuit


#
# Author: Dogan Ibrahim
# File : mesh.py
# Date : July 2019
#======================================================
from numpy import array
from numpy import *
from numpy.linalg import solve

print("Circuit Mesh Analysis")


print("=====================")
rows = int(raw_input("Enter number of rows of A: "))
cols = rows
A = zeros((rows, cols))
b = zeros(rows)

#
# Read the matrix A elements
#
for i in range(0, rows):
for j in range(0, cols):
A[i, j] = float(raw_input("Enter A%d%d:" %(i+1, j+1)))

#
# Read the matrix b elements
#
print("")
for i in range(0, rows):
b[i] = float(raw_input("Enter b%d:" %(i+1)))

#
# Calculate and display the currents in the circuit
#
x = solve(A, b)

print("\nResults:")
for i in range(0, rows):
print("I%d = %7.3fA" %(i+1, x[i]))

Figure 9.8 Program listing

● 162
Chapter 9 • Array and Matrix Operations With Python

Figure 9.9 Calculating the currents in the circuit

9.5 Case Study 15 – DC Circuits Mesh Analysis 2


Description: In this case study we look at a more complex circuit and calculate the cur-
rents in the circuit using our program mesh.py.

Aim: The aim of this case study is to show how a more complex circuit can be analysed
using the program developed in the previous case study.

The circuit used in this case study is shown in Figure 9.10, which consists of 8 resistors and
4 voltage sources (batteries) in 3 loops.

Figure 9.10 Circuit for the example

Figure 9.11 shows the currents in each loop calculated using program mesh.py developed
in the previous case study. In this example, the loop currents are: I1 = 4.569A, I2 =
13.708A, I3 = 1.054A

● 163
Learning Python with Raspberry Pi

Figure 9.11 Calculating currents in the circuit

9.6 Case Study 16 – DC Circuits Mesh Analysis 3


Description: In this case study we look at a more complex circuit with a current source
in addition to voltage sources and calculate the currents in the circuit using our program
mesh.py.

Aim: The aim of this case study is to show how a more complex circuit can be analysed
using the program developed in the previous case study.

The circuit used in this case study is shown in Figure 9.12, which consists of 4 resistors a
voltage source and a current source.

Figure 9.12 Circuit for the example

The circuit shown in Figure 9.12 can be converted into its equivalent circuit by replacing the
current source with a voltage source as shown in Figure 9.13.

Figure 9.13 Equivalent circuit of Figure 9.12

The circuit now consists of 2 loops with 333 resistors. Using the mesh analysis program
as shown in Figure 9.14, the current in the circuit are calculated to be: I1 = 0.182A, I2 =
-0.182A.

● 164
Chapter 9 • Array and Matrix Operations With Python

Figure 9.14 Calculating currents in the circuit

9.7 Case Study 17 – DC Circuits Node Analysis 1


Description: In this case study we analyse a simple circuit using the node analysis meth-
od. Node analysis gives the voltages at the node points of the circuit.

Aim: The aim of this case study is to show how to do node analysis of a circuit using Py-
thon.

Background Information: Node analysis is similar to mesh analysis but here we have
to enter the circuit elements at the nodes of the circuit. If there are n nodes in a circuit
then there will be n-1 independent equations where one node is taken to be the reference
node. Then the matrix equation Ax = b is formed where A represents the circuit elements
in terms of conductances (inverse or resistance), x represents the voltages at each node
in the circuit, and b represents the current sources. The matrix equation is then solved as
shown in the examples earlier in this chapter. After calculating the voltages in the circuit,
we can easily calculate the current through every resistor.

In this case study, the circuit shown in Figure 9.15 is used as an example. This circuit con-
sists of 4 resistors and 2 current sources, and has 3 nodes.

Figure 9.15 Circuit to be analysed

From an inspection of the circuit, we can write the elements of matrices A, b and x for this
circuit are as follows:

● 165
Learning Python with Raspberry Pi

Here, A =

x =

b =

To make the calculation simpler, we will be entering the resistances to the program and the
program will convert them into conductances for its internal calculations.

Program Listing: Figure 9.16 shows the program listing (program: node.py). At the be-
ginning of the program a heading is displayed and the user is asked to enter the number
of nodes there are in the circuit (excluding the reference node). The elements at each node
are then entered for the A matrix in terms of the resistances at each node. A 0 must be
entered to terminate the entry for a node. The program internally converts the en-
tered values into conductances by taking their inverses. This makes it easier to enter the
element values. The currents at each node are then entered for the b matrix. The program
calculates and displays the voltages at the nodes. After calculating the voltages, we can
easily calculate the current through each resistor by dividing the voltage across it by its
resistance.

#====================================================
# CIRCUIT NODE ANALYSIS
# =====================
#
# This program carries out node analysis of a circuit.
# The user enters the circuit elements in the form of
# A and b matrices and the program calculates and
# displays the values of the voltages in the circuit
#
# Author: Dogan Ibrahim
# File : node.py
# Date : July 2019
#======================================================
from numpy import array
from numpy import *
from numpy.linalg import solve

print("Circuit Node Analysis")


print("=====================")
rows = int(raw_input("Enter number of nodes: "))
cols = rows

● 166
Chapter 9 • Array and Matrix Operations With Python

A = zeros((rows, cols))
b = zeros(rows)

#
# Read the matrix A elements
#
total = 0
elements = 1
for i in range(0, rows):
for j in range(0, cols):
while True:
elements = float(raw_input("Enter A%d%d:" %(i+1, j+1)))
if elements == 0:
break
total = total + (1 / elements)
A[i, j] = total
total = 0
print("")

#
# Read the matrix b elements
#
print("")
for i in range(0, rows):
b[i] = float(raw_input("Enter b%d:" %(i+1)))

#
# Calculate and display the currents in the circuit
#
x = solve(A, b)

print("\nResults:")
for i in range(0, rows):
print("V%d = %7.3fV" %(i+1, x[i]))

Figure 9.16 Program listing

Figure 9.17 shows the output when the program is run for this example. The voltages at
each node are calculated to be: V1 = 404.286V, V2 = 350.000V, V3 = 412.875V.

● 167
Learning Python with Raspberry Pi

Figure 9.17 Calculating voltages in the circuit

9.8 Summary
In this chapter, we have learned how to create arrays and matrices and how to use them in
mesh and node circuit analysis. Several examples and case studies are given to show how
circuits can be analysed using the arrays and matrices in Python programming language. In
the next chapter, we shall be learning how to use GUI (Graphical User Interface) in Python
programs and then learn how to develop GUI based programs for analysing RLC resonant
circuits and also how to calculate the inductance of single-layer air-core coils.

● 168
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

Chapter 10 • Using the Tkinter Graphical User Interface (GUI)


in Python

10.1 Overview
In the last chapter, we have learned how to use arrays and matrices to carry out mesh and
node analysis for electrical circuits.

In this chapter, we shall be learning how to use the Tkinter graphical user interface soft-
ware in Python programs. After making an introduction to Tkinter and learning how to use
its basic features, we shall be analysing and designing a transistor circuit with the help of
GUI interfaces.

10.2 GUI with the Tkinter


Tkinter is an inbuilt Python module that is used to create GUI applications. Tkinter is al-
ready part of Python and therefore there is no need to install it. In this chapter, Python V3
is used and therefore you should run your programs by giving commands of the following
format:

pi@raspberrypi:~ $ python3 filename.py

Tkinter consists of a number of widgets used to build GUI applications. Some of the com-
monly used widgets are further information on widgets can be obtained from the link:

https://docs.python.org/3/):

• Label used to create single line widgets like texts or images


• Button used to place buttons in GUI applications
• Checkbox used to make several choices
• Radio Button used to make a single choice
• Canvas used to draw shapes in GUI applications
• Frame these are used like containers in GUI applications
• Menu used to create menus in GUI applications
• Entry used to create input fields in GUI applications
• Message used to display messages
• Scales used as sliders
• Dialogs used to create dialogs

The positions of the widgets are controlled by the following commands:

• pack() organize the widgets such that they occupy the entire available
width
• grid() organize the widgets in table-like structure
• place() place the widgets at desired positions

● 169
Learning Python with Raspberry Pi

Some examples of creating and using widgets are given below.

10.2.1 Label

Example 1
Create a Label and display the message Hello From Tkinter… with this label.

Solution1
Figure 10.1 shows the required program listing (program: gui1.py). At the beginning of
the program, module tkinter is imported into the program. A window is created with the
title MY FIRST TKINTER EXAMPLE. Then the font size is changed and a Label is created
to display message Hello From Tkinter…

#====================================================
# DISPLAY TEXT USING A LABEL
# ==========================
#
# This rogram displays text "Hello From Tkinter..."
# using a Label.
#
# Author: Dogan Ibrahim
# File : gui1.py
# Date : July 2019
#====================================================
from tkinter import *

window = Tk()

window.title("MY FIRST TKINTER EXAMPLE")


labelfont = ('times', 20, 'bold')
LabelWidget = Label(window, text = "Hello From Tkinter...")
LabelWidget.config(font=labelfont)
LabelWidget.pack()

window.mainloop()

Figure 10.1 Program listing

You should run your program from the Desktop if a monitor is connected directly to your
Raspberry Pi. Alternatively, start the VNC server on your Raspberry Pi and create a Desktop
using the VNC Viewer:

pi@raspberrypi:~ $ vncserver :1

● 170
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

Once in the Desktop mode, open a terminal session (Accessories -> Terminal) and enter
the following command to run your program:

pi@raspberrypi:~ $ python3 gui1.py

Figure 10.2 shows the message displayed on the Desktop. Clicking the up expand button
expands the window to its full size as shown in Figure 10.3.

Figure 10.2 Message displayed on the Desktop

Figure 10.3 Expanding the window to its full size

We can insert the following statement after the window title in order to increase the initial
size of the window. The corresponding display is shown in Figure 10.4:

window.geometry("400x400")

● 171
Learning Python with Raspberry Pi

Figure 10.4 Expanding the initial window size

When widgets are packed, we can specify whether it should expand to take up all the avail-
able space. By default, widgets are not expanded. We can specify the following keywords
with the pack() function:

• side="position" to specify the position, where it can take the values: top, bot-
tom, left, right
• expand="yes" expands to the allocated space
• fill="stretch" can be used to stretch the widget, where it can take the values: x
(horizontal stretching), y (vertical stretching) or both (stretch in both directions)
• Setting expand="yes" and fill="both" will place the widget in the center of the
window.

For example, displaying 3 labels with different sizes with the default pack() will see that
each label is given the size of the text it displays:

BxxxxxxxE
BxxxxxxxxxxxE
BxxxxE

Where B and E are the beginnings and endings of the labels respectively. If now we use the
pack(fill="x") option, the labels will be horizontally stretched so that all three labels have
the same width (the texts are not the same width):

B xxxxxxx E
BxxxxxxxxxxxE
B xxxx E

We can use internal or external Paddings to adjust the placement of widgets. padx and
pady add external horizontal padding to a widget respectively, and ipadx and ipady add
horizontal and vertical internal padding (padding added to the inside of the widget borders)
to a widget respectively. By default, no padding is added to a widget.

● 172
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

10.2.2 Button

Example 2
Create a Label and a Button such that the Button has the title Click Me. When the button
is clicked the message You Clicked Me should be displayed by the Label.

Solution 2
Figure 10.5 shows the program listing (program: gui2.py). Inside the main program, the
window title and size are specified. Then a Button widget is declared with the title Click
Me. When the button is clicked, function disp is called which displays the message You
Clicked Me.

#====================================================
# LABEL AND BUTTON EXAMPLE
# ========================
#
# This rogram displays text “You Clicked Me" when the
# button is clicked
#
# Author: Dogan Ibrahim
# File : gui2.py
# Date : July 2019
#====================================================
from tkinter import *

window = Tk()

def disp():
LabelWidget = Label(window, text = “You Clicked Me")
LabelWidget.config(font=labelfont)
LabelWidget.pack(side="top")

window.title(“LABEL AND BUTTON EXAMPLE")


window.geometry(“400x200")
labelfont = ('times', 20, 'bold')
ButtonWidget = Button(window, text = “Click Me", command=disp)
ButtonWidget.pack(side="top",expand="yes",fill="both")

window.mainloop()

Figure 10.5 Program Listing

● 173
Learning Python with Raspberry Pi

Figure 10.6 and Figure 10.7 show the display before and after clicking the button.

Figure 10.6 Before clicking the button

Figure 10.7 After clicking the button

Example 3
Show the differences between using different parameters of function pack().

Solution
Figure 10.8 to Figure 10.10 show various displays with different parameters of function
pack().

Figure 10.8 pack(side="left")

● 174
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

Figure 10.9 pack(side="top")

Figure 10.10 pack(side="top", expand="yes")

Example 4
Write a program that uses a Label and two Buttons. Pressing one of the buttons should
display message Button 1 Pressed, and pressing the other button should terminate the
program.

Solution 4
Figure 10.11 shows the program listing (program: gui3.py). The output of this program is
shown in Figure 10.12.

#==========================================================
# LABEL AND TWO BUTTONS
# =====================
#
# This rogram displays text “Button1 Pressed" when one
# button is clicked,and terminates when other one is pressed
#

● 175
Learning Python with Raspberry Pi

# Author: Dogan Ibrahim


# File : gui3.py
# Date : July 2019
#===========================================================
from tkinter import *

window = Tk()

def disp():
LabelWidget = Label(window, text = “Button 1 Pressed")
LabelWidget.config(font=labelfont)
LabelWidget.pack()

window.title(“LABEL AND BUTTON EXAMPLE")


window.geometry(“400x200")
labelfont = ('times', 20, 'bold')
Button1 = Button(window, text = “Click Me", command=disp)
Button1.pack(side="left")
Button2 = Button(window, text="Quit", command=window.quit)
Button2.pack(side="right")

window.mainloop()

Figure 10.11 Program listing

Figure 10.12 Output of the program

Figure 10.13 shows another example (program: gui4.py) with a label and two buttons. The
output of this program is shown in Figure 10.14.

#====================================================
# LABEL AND TWO BUTTONS
# =====================
#
# Label and 2 Buttons.
#
# Author: Dogan Ibrahim

● 176
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

# File : gui4.py
# Date : July 2019
#====================================================
from tkinter import *

window = Tk()

window.title("EXAMPLE")
window.geometry("300x300")
Button1 = Button(window, text = "Hello").pack(side="left",fill="y")

Label1=Label(window,text="This is Top").pack(side="top")

Button2=Button(window,text="Here").pack(side="right",expand="yes",fill="x")

window.mainloop()

Figure 10.13 Another program with a label and two buttons

Figure 10.14 Output of the program

The anchor option of function pack() can be used to position a widget. Eight points of a
compass (E, W, N, S, NE, NW, SE, SW) and CENTER are supported.

The foreground colour, background colour, the height and width of a widget can be con-
trolled as shown in Figure 10.15 (program: gui5.py). The output of this program is shown
in Figure 10.16.

#============================================
# USING COLOURS
# =============
#
# Using foreground and background colours and

● 177
Learning Python with Raspberry Pi

# height and width


#
# Author: Dogan Ibrahim
# File : gui5.py
# Date : July 2019
#=============================================
from tkinter import *

window = Tk()

window.title("EXAMPLE")
labelfont=('times', 18, 'bold')
L1=Label(window,text="Hello Tkinter")
L1.config(bg='black', fg='white')
L1.config(font=labelfont)
L1.config(height=4, width=20)
L1.pack(expand="yes", fill="both")

window.mainloop()

Figure 10.15 Program listing

Figure 10.16 Output of the program

10.2.3 Message

Example 5
Write a program to use the message widget to display the message This is a message
from Tkinter.

Solution 5
Figure 10.17 shows the program listing (program: gui6.py). The output of the program is
shown in Figure 10.18.

#=================================================
# MESSAGE WIDGET
# ==============
#
# This program displays the message: This is a message

● 178
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

# from Tkinter
#
# Author: Dogan Ibrahim
# File : gui6.py
# Date : July 2019
#=================================================
from tkinter import *

window = Tk()

window.title(“EXAMPLE")
msg = Message(window,text="This is a message from Tkinter")
msg.config(fg='blue',bg='white',font=('times',18,'italic'))
msg.pack(fill="x", expand="yes")

window.mainloop()

Figure 10.17 Program listing

Figure 10.18 Output of the program

10.2.4 Entry

Example 6
This example shows how to use the Entry widget. This widget is a single-line text input
field used to get text from the user. In this example, the user enters a text and this text is
displayed on the screen.

Solution 6
Figure 10.19 shows the program listing (program: gui7.py). The insert method of Entry
has two parameters. The first parameter is the position where the text should be inserted
and 0 is the first position at the left. The next parameter is a string that is optional where
this string is displayed when function insert is called. In the program in Figure 10.19. A
Button entitled Get is created and when this button is pressed the user entered text is dis-
played on the screen. Figure 10.20 shows an output from the program.

● 179
Learning Python with Raspberry Pi

#=================================================
# Entry WIDGET
# ============
#
# This program reads user's text and displays it
#
# Author: Dogan Ibrahim
# File : gui7.py
# Date : July 2019
#=================================================
from tkinter import *

window = Tk()

def get():
value=ent.get()
print("%s" %value)

ent = Entry(window)
ent.insert(0, '')
ent.pack(side="top", fill="x")

ent.focus()
butn = Button(window, text="Get", command=get)
butn.pack(side="left")

window.mainloop()

Figure 10.19 Program listing

Figure 10.20 Output from the program

10.2.5 Grid
So far we have aligned our widgets using the options of function pack(). Grids are very
useful when we want to line up widgets horizontally. Grids allow tabular displays where we
can arrange the row and column positions of widgets in a grid fashion. In general, input
forms (e.g. Entry) are best arranged using grids. Grid row and column co-ordinates start
from 0. An example uses of grids are shown below.

Example 7
Write a program to display the names of 6 countries on 6 buttons using grids.

● 180
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

Solution 7
Figure 10.21 shows the program listing (program: gui8.py). Notice how the row and
column numbers are used to position the buttons on the screen. Figure 10.22 shows the
output of the program.

#=================================================
# Using Grids
# ===========
#
# In this example the names of 6 counries are displayed
#
# Author: Dogan Ibrahim
# File : gui8.py
# Date : July 2019
#=================================================
from tkinter import *

window = Tk()

countries = ['UK','Germany','France','Italy','Belgium','Ireland']

r = 0
for country in countries:
Button(window, text = country, width = 50).grid(row = r, column = 0)
r = r + 1

window.mainloop()

Figure 10.21 Program listing

Figure 10.22 Output from the program

10.2.6 Radio Button


Radio Buttons are also called Option Buttons allow the user to choose one of a set of
pre-defined options. Groups of Radio button widgets have to be associated with the same
variable such that clicking a button changes the value of this variable. Radio buttons are
shown as small round shaped buttons on the screen. Two examples for the use of Radio
buttons are given below.

● 181
Learning Python with Raspberry Pi

Example 8
Write a program to display a country and 6 possible options where only one of the options is
the capital city of the country. Choose the country as France and the possible capital cities
as: London, Rome, Paris, Ankara, Istanbul, and Madrid.

Solution 8
Figure 10.23 shows the program listing (program: gui9.py). 6 Radio buttons are used to
display the 6 cities. Clicking on a city enables its Radio button as shown in Figure 10.24.

#====================================================
# Using Radio Buttons
# ===================
#
# In this example a country and 6 cities are displayed
# and the user is asked to click the capital city of
# the displayed country.
#
# Author: Dogan Ibrahim
# File : gui9.py
# Date : July 2019
#====================================================
from tkinter import *

window = Tk()

capcity = 0
window.geometry("400x150")

Label(window, text = "Capital city of France?").pack()


Radiobutton(window,text="London", variable = capcity, value =
1).pack(anchor="w")
Radiobutton(window,text="Rome", variable = capcity, value =
2).pack(anchor="w")
Radiobutton(window,text="Paris", variable = capcity, value =
3).pack(anchor="w")
Radiobutton(window,text="Ankara", variable = capcity, value =
4).pack(anchor="w")
Radiobutton(window,text="Istanbul", variable = capcity, value =
5).pack(anchor="w")
Radiobutton(window,text="Madrid", variable = capcity, value =
6).pack(anchor="w")

window.mainloop()

Figure 10.23 Program listing

● 182
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

Figure 10.24 Clicking on Paris

Example 9
Modify the program in Figure 10.23 so that the user is given a message based on the
selected country. For example, you may display Correct when the correct capital city is
selected, or Not Correct when a wrong selection is made.

Solution 9
Figure 10.25 shows the modified program (program: gui10.py). Every capital city is given
a value from 1 to 6. A Button is created with the title Select one. Also, grids are used to
display all the widgets in the program. When the button is clicked, function choice is acti-
vated. Inside this function the program checks the value of user's choice. Variable capcity.
get() returns an integer variable between 1 and 6 corresponding to the values of the 6
cities displayed by the Radio buttons. If the user selects the correct answer (Paris in this
example, which has the value 3) then a Label displays the message Correct, otherwise
message Not Correct is displayed at the specified row and column co-ordinates. Figure
10.26 shows a typical run of the program where the incorrect and then the correct answer
is chosen.

#====================================================
# Using Radio Buttons
# ===================
#
# In this example a country and 6 cities are displayed
# and the user is asked to click the capital city of
# the displayed country. Messages are displayed to let
# the user know if the chosen city is correct or not
#
# Author: Dogan Ibrahim
# File : gui10.py
# Date : July 2019
#====================================================
from tkinter import *

window = Tk()
window.title("Capital Cities")

def choice():
if capcity.get() == 3:

● 183
Learning Python with Raspberry Pi

Label(window, text=" Correct").grid(row=1, column=5)


else:
Label(window, text="Not Correct").grid(row=1, column=5)

capcity = IntVar()
value = 0

Button(window, text="Select one", command=choice).grid(row=8,column=1)

Label(window, text = "Capital city of France?").grid(row=0,column=1)


Radiobutton(window,text="London ", variable = capcity, value =
1).grid(row=1,column=0)
Radiobutton(window,text="Rome ", variable = capcity, value =
2).grid(row=2,column=0)
Radiobutton(window,text="Paris ", variable = capcity, value =
3).grid(row=3,column=0)
Radiobutton(window,text="Ankara ", variable = capcity, value =
4).grid(row=4,column=0)
Radiobutton(window,text="Istanbul", variable = capcity, value =
5).grid(row=5,column=0)
Radiobutton(window,text="Madrid ", variable = capcity, value =
6).grid(row=6,column=0)

window.mainloop()

Figure 10.25 Program listing

Figure 10.26 Typical run of the program

The program given in Figure 10.25 can be made more efficient and more user-friendly by
storing the cities in a list and using a for loop to display the Radio buttons as shown in
Figure 10.27 (program: gui11.py).

#====================================================
# Using Radio Buttons
# ===================
#
# In this example a country and 6 cities are displayed

● 184
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

# and the user is asked to click the capital city of


# the displayed country. Messages are displayed to let
# the user know if the chosen city is correct or not
#
# Author: Dogan Ibrahim
# File : gui11.py
# Date : July 2019
#====================================================
from tkinter import *

window = Tk()
window.title("Capital Cities")
cities = ["London","Rome ","Paris ","Ankara ","Istanbul","Madrid "]

def choice():
if capcity.get() == 2:
Label(window, text=" Correct").grid(row=1, column=5)
else:
Label(window, text="Not Correct").grid(row=1, column=5)

capcity = IntVar()
value = 0

Button(window, text="Select one", command=choice).grid(row=8,column=1)

Label(window, text = "Capital city of France?").grid(row=0,column=1)

for i in range (6):


Radiobutton(window,text=cities[i],variable = capcity, value =
i).grid(row=i+1,column=0)

window.mainloop()

Figure 10.27 More efficient program

10.2.7 Checkbox
Checkboxes are also known as tickboxes and they allow users to make multiple selections
from a number of different options. Checkboxes are shown as small square boxes on the
screen. A checkbox can either be in the state of off or on. An example is given below to
illustrate how a checkbox can be used in a Python program.

● 185
Learning Python with Raspberry Pi

Example 10
Write a program to use checkboxes. A button should be used with the title: Select the
programming languages you know. The user will be given the following choices: Pascal,
Basic, C. The program displays the selected options. Use a button with the title Quit to
terminate the program.

Solution 10
Figure 10.28 shows the program listing (program: gui12.py). The user makes a selection
by clicking all the boxes that are relevant. When the selection button is clicked, function
choice is called. This function displays the choices made by the user as shown in the exam-
ple display in Figure 10.29.

#====================================================
# Using Checkbuttons
# ===================
#
# In this example the user selects the programming
# languages that he/she knows
#
# Author: Dogan Ibrahim
# File : gui12.py
# Date : July 2019
#====================================================
from tkinter import *

window = Tk()
window.title("Programming Languages")
languages = ["Pascal","Basic","C"]

def choice():
if Var1.get() == 1:
Label(window, text="Pascal").grid(row=1, column=5)
if Var2.get() == 1:
Label(window, text="Basic").grid(row=2,column=5)
if Var3.get() == 1:
Label(window, text="C").grid(row=3,column=5)

Button(window, text="Select all that apply", command=choice).


grid(row=8,column=1)
Button(window, text="Quit", command=window.quit).grid(row=8,column=2)

Label(window, text = "Select the programming languages you know").


grid(row=0,column=1)

Var1 = IntVar()

● 186
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

Var2 = IntVar()
Var3 = IntVar()

Checkbutton(window,text=languages[0],variable = Var1).grid(row=1,sticky="w")
Checkbutton(window,text=languages[1],variable = Var2).grid(row=2,sticky="w")
Checkbutton(window,text=languages[2],variable = Var3).grid(row=3,sticky="w")

window.mainloop()

Figure 10.28 Program listing

Figure 10.29 Example display


10.2.8 Dialogs
A number of dialogs are provided that can be used to display warnings, errors, or to select
files or colours. In order to use the dialogs, we have to import module messagebox. The
following options are available:

• askquestion
• askokcancel
• askretrycancel
• askyesno
• askyesnocancel
• showerror
• showinfo
• showwarning

An example is given below which uses some of the dialogs.

Example 11
Write a program to show the output when some of the above dialogs are used.

Solution 11
Figure 10.30 shows the program listing (program: gui13.py). Four buttons are used in
this program. Pressing the buttons displays 4 different types of dialogs as shown in Figure
10.31.

● 187
Learning Python with Raspberry Pi

#====================================================
# Using Dialogs
# =============
#
# In this example two dialog type displays are shown
#
# Author: Dogan Ibrahim
# File : gui13.py
# Date : July 2019
#====================================================
from tkinter import *
from tkinter import messagebox

window = Tk()
window.title("Dialogs")

def error():
messagebox.showerror("","You clicked error")

def okcancel():
messagebox.askokcancel("","You clicked OK or CANCEL")

def yesno():
messagebox.askyesno("","You clicked YES-NO")

def warning():
messagebox.showwarning("","You clicked WARNING")

Button(window, text="Error", command=error).pack(fill="x")


Button(window, text="OK or CANCEL", command=okcancel).pack(fill="x")
Button(window, text="YES-NO", command=yesno).pack(fill="x")
Button(window, text="WARNING", command=warning).pack(fill="x")

window.mainloop()

Figure 10.30 Program listing

Figure 10.31 Program output

● 188
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

Dialog widget also used to select files. An example is given below.

Example 12
Write a program using a tkinter dialog to display the files in the default directory /home/pi

Solution 12
Figure 10.32 shows the program listing (program: gui14.py). The output of the program
is shown in Figure 10.33.

#====================================================
# Using Dialogs
# =============
#
# In this example the default folder is listed with all
# the files and the user is asked to select a file
#
# Author: Dogan Ibrahim
# File : gui14.py
# Date : July 2019
#====================================================
from tkinter import *
from tkinter import filedialog

window = Tk()

filedialog.askopenfilename(initialdir="/home/pi",title="Select a file")

window.mainloop()

Figure 10.32 Program listing

Figure 10.33 Output of the program

● 189
Learning Python with Raspberry Pi

The file option of the dialog widget supports the following additional file operations:

• asksavefilename to save file


• askdirectory to open directory

10.2.9 Scale (Slider)


Scales (or slides) are used to select numeric values by moving the position the scale with
the mouse. Scales can be horizontal or vertical. Two examples of using of the scale widget
are given below.

Example 13
In this example, a vertical scale is drawn and its current numeric value is displayed on the
screen.

Solution 13
Figure 10.34 shows the program listing (program: gui15.py). The range of the scale is set
using the from_= and to= statements. The numeric value of the scale is obtained using
the statement S1.get(). Figure 10.35 shows the output of the program when the scale
was set to 15.

#====================================================
# Using Scales (Slides)
# =====================
#
# This example displays the scale's numeric value on
# the screen
#
# Author: Dogan Ibrahim
# File : gui15.py
# Date : July 2019
#====================================================
from tkinter import *

window = Tk()

def get():
print(S1.get())

S1 = Scale(window, from_=0, to=50)


S1.pack()
Button(window, text="Show", command=get).pack()

window.mainloop()

Figure 10.34 Program listing

● 190
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

Figure 10.35 Output of the program

The scale is drawn vertical by default. By including the statement orient=HORIZONTAL


we can draw a horizontal scale.

Example 14
By default, scales start from 0 when they start. We can, however use the statement set(n)
to set the initial value of the scale to n. In this example, we will be drawing a horizontal
scale that goes from 0 to 50 and starting at 25.

Solution 14
Figure 10.36 shows the program listing (program: gui16.py). The output of the program
is shown in Figure 10.37.

#====================================================
# Using Scales (Slides)
# =====================
#
# This example displays a horizontal scale that goes
# from 0 to 50 with 25 as the starting value
#
# Author: Dogan Ibrahim
# File : gui16.py
# Date : July 2019
#====================================================
from tkinter import *

window = Tk()

def get():
print(S1.get())

S1 = Scale(window, from_=0, to=50, orient=HORIZONTAL)


S1.set(25)
S1.pack()

Button(window, text="Show", command=get).pack()

window.mainloop()
Figure 10.36 Program listing

● 191
Learning Python with Raspberry Pi

Figure 10.37 Output of the program

10.2.10 Menu
Menus are useful tools for users to make a choice from a number of options. We can see
menus in almost all applications. For example, Windows Word has a number of menu op-
tions at the top of the screen, such as under File we have the menu options of New Open
Save Save As Print Share, etc. An example is given below which shows how the menu
widget can be used in a program.

Example 15
Write a menu based program using the menu widget. The menu should have the top-level
options: File and Home. File menu should further have the submenus: New Open Save
Save As and Exit.

Solution 15
Figure 10.38 shows the program listing (program: gui17.py). Two menus are created:
filemenu and homemenu. Under filemenu the following submenus are created using
the add_command statement: New Open Save Save As Exit. Command add_separa-
tor adds a separator between the menu items. When a menu item is clicked the program
jumps to the function specified in the command field of the submenu and a message is dis-
played on the screen about the selected submenu item. For example, clicking on submenu
OpenFile sends the program control to function OpenFile where message Open File is
displayed by the function. Figure 10.39 shows the output of the program.

#========================================================
# Using Menu
# ==========
#
# This example shows how a menu and submenus can be created
#
# Author: Dogan Ibrahim
# File : gui17.py
# Date : July 2019
#========================================================
from tkinter import *

window = Tk()
window.title("MENU")

def NewFile():

● 192
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

print("New File")

def OpenFile():
print("Open File")

def SaveFile():
print("Save File")

def SaveAs():
print("Save As")

menu = Menu(window)
window.config(menu=menu)

filemenu = Menu(menu)
menu.add_cascade(label="File", menu=filemenu)
filemenu.add_command(label="New", command=NewFile)
filemenu.add_command(label="Open", command=OpenFile)
filemenu.add_command(label="Save", command=SaveFile)
filemenu.add_command(label="Save As", command=SaveAs)
filemenu.add_separator()
filemenu.add_command(label="Exit", command=window.quit)

homemenu = Menu(menu)
menu.add_cascade(label="Home", menu=homemenu)

window.mainloop()

Figure 10.38 Program listing

Figure 10.39 Output of the program

● 193
Learning Python with Raspberry Pi

10.2.11 Binding to Events


Tkinter applications run inside event loops entered via the mainloop. A mechanism is pro-
vided by tkinter so that the programmer can bind Python function and methods to tkinter
events. Therefore, if an event occurs in a widget then a handler function is called in Python
to process this event. Some examples are given below.

Example 16
Write a tkinter based program to display the following messages when the mouse is clicked
when its pointer is over a button widget:

Action Display
Clicking left mouse Left mouse button clicked
Clicking right mouse button Right mouse button clicked
Double-clicking left mouse button Double left mouse button clicked

Solution 16
Figure 10.40 shows the program listing (program: gui18.py). Figure 10.41 shows the out-
put of the program when the left mouse and right mouse were clicked over the widget, and
then the left mouse was clicked twice. Notice that the left mouse button is identified with
<Button-1>, right mouse button with <Button-2> and double clicking the left mouse
with <Double-1>.

#===========================================================
# Events and Binds
# ================
#
# In this example when the mouse is clicked when the mouse
# pointer is over a widget, message Mouse Over is displayed
#
# Author: Dogan Ibrahim
# File : gui18.py
# Date : July 2019
#===========================================================
from tkinter import *

window = Tk()
window.geometry(“150x100")

def leftbutton(event):
print(“Left mouse button clicked")

def rightbutton(event):
print(“Right mouse button clicked")

def doubleleftbutton(event):
print(“Double left mouse button clicked")

● 194
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

btn = Button(window, text="Mouse Click Tester")


btn.pack()
btn.bind_all('1', leftbutton)

window.mainloop()

Figure 10.40 Program listing

Figure 10.41 Output of the program

The following events are identified in tkinter based applications:

Event Description

<Button-n> Mouse button is pressed when the mouse pointer is over


the widget. For left Mouse button n=1, for middle mouse
button n=1, and for right mouse button n=3. The mouse
scroll-up event (with wheel type mouse) is identified
with n=4, and scroll down with n=5.

<ButtonRelease> Event occurs when the mouse button is released over a


widget. Button numbers are as above.

<Double-n> Mouse button is clicked twice. Button numbers are as


above

<Motion> The mouse pointer is moved over a widget while it is


being held down. For left mouse use <B1-Motion>,
for middle mouse <B2-Motion>, and For right mouse
<B3-Motion>

<FocusIn> Keyboard focus moved to this widget

<FocusOut> Keyboard focus moved away from this widget

<Enter> The mouse pointer entered the widget (mouse button is


not pressed)

<Leave> The mouse pointer left the widget

● 195
Learning Python with Raspberry Pi

<Return> User pressed the Enter key. Other keys can also be used,
e.g. Shift_L. For any shift key, Control_L for any control
key, Alt_L for any Alt key, etc.

<Key> Any key is pressed

<Shift-Up> Up arrow key is pressed

x User typed an "x" key. All printable keys can be used.

10.3 Case Study 18 – Resonance in Series RLC Circuits


Description: In this case study we use tkinter GUI to read the resistance, inductance and
capacitance in a series-connected RLC circuit and then calculate and display the resonance
frequency, current in the circuit at resonance, voltage across the inductor and capacitor at
resonance, the Q-factor, the Bandwidth of the circuit, and upper and lower -3dB points at
resonance.

Aim: The aim of this case study is to show how to use tkinter to read user input from the
keyboard and also how to calculate the resonance frequency of an RLC circuit.

Background Information: In a series resonance RLC circuit there is a frequency point


where the capacitive reactance of the capacitor becomes equal to the inductive reactance
of the inductor. The point at which this occurs is called the Resonant Frequency of the cir-
cuit. Series Resonance circuits are used as tuned circuits in communication systems, mains
filters, noise filters, etc. The resonant frequency fr of an RLC circuit is given by the following
formula:

(10.1)

The circuit current at resonance is given by:

(10.2)

The inductive reactance at resonance is given by:

(10.3)

The voltage across the inductor and capacitor at resonance are given by:

(10.4)

The Q-factor of a resonant circuit is given by:

(10.5)

● 196
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

The Bandwidth is given by:

(10.6)

The upper and lower -3dB frequency points are given by:

(10.7)

And

(10.8)

Figure 10.42 shows the definition of Bandwidth in a resonant circuit.

Figure 10.42 Bandwidth in a resonant circuit

Program Listing: Figure 10.43 shows the program listing (program: resonance.py). The
program is based on using the Entry widgets of tkinter to read the values of the resistance,
inductance, capacitance, and the applied voltage. 4 Labels and 4 Entry widgets are used to
read the values of R, L, C and V. Two Buttons are used in the program, entitled Quit and
Calculate. Clicking Quit terminates the program. Clicking Calculate calls function calcu-
late where formula (10.1) to (10.8) are used to calculate the various resonance values.
The calculated values are displayed using Labels inside function calculate.

#==============================================================
# Series RLC Circuit Resonance Calculations
# =========================================
#
# This program reads the values RLC and calculates and
# displays all the resonace related values
#
# Author: Dogan Ibrahim
# File : resonance.py
# Date : July 2019

● 197
Learning Python with Raspberry Pi

#==============================================================
from tkinter import *
import math

window = Tk()
window.title("SERIES RLC RESONANCE")

#
# Calculate and display the various resonance values
#
def calculate():
R = Re.get()
Rr = float(R) # R as floating point
L = Le.get()
Lr = float(L) /1000.0 # convert to Henries
C = Ce.get()
Cr = float(C) / 1000000.0 # convert to Farads
V = Ve.get()
Vr = float(V) # V as floating point
#
# Now carry out the calculations
#
LC = math.sqrt(Lr * Cr)
fr = 1.0 / (2*math.pi*LC) # resonant frequency
Ir = Vr / Rr # current in circuit
Xl = 2 * math.pi * fr * Lr # inductive reactance
Vl = Ir * Xl # Voltage across L and C
Q = 2 * math.pi * fr * Lr / Rr # Q factor
BW = fr / Q # Bandwidth
fl = fr - BW / 2 # lower -3dB freq
fh = fr + BW / 2 # higher -3dB freq
#
# Now display the calculated values
#
Label(window, text=" fr (Hz)= %10.2f" %(fr)).grid(row=8, column=0)
Label(window, text=" I(A)= %10.2f" %(Ir)).grid(row=9, column=0)
Label(window, text=" Xl (Ohms)= %10.2f" %(Xl)).grid(row=10, column=0)
Label(window, text=" Vl (Volts)= %10.2f" %(Vl)).grid(row=11, column=0)
Label(window, text=" Q= %10.2f" %(Q)).grid(row=12, column=0)
Label(window, text=" BW= %10.2f" %(BW)).grid(row=13, column=0)
Label(window, text=" fl (Hz)= %10.2f" %(fl)).grid(row=14, column=0)
Label(window, text=" fh (Hz)= %10.2f" %(fh)).grid(row=15, column=0)

#
# Display the circuit components to be read
#

● 198
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

R = Label(window, text="R (Ohms): ").grid(row=1, column=0)


L = Label(window, text="L (mH) : ").grid(row=2, column=0)
C = Label(window, text="C (uF : ").grid(row=3, column=0)
V = Label(window, text="V (Volt): ").grid(row=4, column=0)

#
# Read the circuit component values usieng Entry
#
Re = Entry(window)
Re.grid(row=1, column=1)
Le = Entry(window)
Le.grid(row=2, column=1)
Ce = Entry(window)
Ce.grid(row=3, column=1)
Ve = Entry(window)
Ve.grid(row=4, column=1)

#
# Button to Quit the program
#
butnquit = Button(window, text="Quit", command=window.quit)
butnquit.grid(row=18, column=0)

#
# Button to calculate the values
#
butncalc = Button(window, text="Calculate", command=calculate)
butncalc.grid(row=18, column=1)

window.mainloop()

Figure 10.43 Program listing

Figure 10.44 shows a typical run of the program. Notice that the resistance is entered in
Ohms, capacitance in microfarads, inductance in millihenries, and voltage in Volts. The
frequency is displayed in Hertz.

● 199
Learning Python with Raspberry Pi

Figure 10.44 Typical run of the program

10.4 Case Study 19 – Inductance of a Single Layer Coil


Description: In this case study we use tkinter GUI to calculate the inductance of an air-
core, single-layer coil, given its diameter, length, and the number of turns.

Aim: The aim of this case study is to show how to use tkinter to read user input from the
keyboard and also how to calculate the inductance of a single layer air core coil.

Background Information: The inductance of a single layer air core coil can be calculated
using the well-known Wheeler's formula. The formula, given below is accurate to within 1%
for L/D > 0.4 i.e, the coil is not too short. For short coils this formula is not very suitable:

(10.9)

Where L is the inductance in microhenries, N is the number of turns, D is the diameter of


the coil in cm, and L is the length of the coil in cm.

Program Listing: Figure 10.45 shows the program listing (program: coil.py). The pro-
gram uses tkinter Entry widgets to read D, N, and L from the keyboard. The inductance is
then calculated and displayed. The user is warned that the results may not be accurate if
the coil is not short. Figure 10.46 shows a typical run of the program.

#=====================================================================
# Inductance of a Single Layer Coil
# =================================
#
# This program calculates teh inductance of a single layer air
# core coil. Number of turns,diameter,and length are read from keyboard
#
# Author: Dogan Ibrahim
# File : coil.py
# Date : July 2019
#=====================================================================

● 200
Chapter 10 • Using the Tkinter Graphical User Interface (GUI) in Python

from tkinter import *

window = Tk()
window.title(“INDUCTANCE")

#
# Calculate and display the various resonance values
#
def calculate():
N = Ne.get()
Nf = float(N) # N as floating point
D = De.get()
Df = float(D) # D as floating point
L = Le.get()
Lf = float(L) # L as floating point

#
# Now carry out the calculation and display the inductance
#
Ind = (Df * Df * Nf * Nf) / (45 * Df + 100* Lf)
Label(window, text="Inductance (microhenries)= %10.4f" %(Ind)).grid(row=5,
column=0)
if Lf / Df <= 0.4:
Label(window, text="Coil is too short,may not be accurate").grid(row=7,
column=0)
else:
Label(window, text=" “).grid(row=7,
column=0)

#
# Display the coil parameters to be read
#
N = Label(window, text="Number of turns (N): “).grid(row=1, column=0)
D = Label(window, text="Coil diameter (cm) : “).grid(row=2, column=0)
L = Label(window, text="Coil length(cm) : “).grid(row=3, column=0)

#
# Read the coil parameter values usieng Entry
#
Ne = Entry(window)
Ne.grid(row=1, column=1)
De = Entry(window)
De.grid(row=2, column=1)
Le = Entry(window)
Le.grid(row=3, column=1)

● 201
Learning Python with Raspberry Pi

#
# Button to Quit the program
#
butnquit = Button(window, text="Quit", command=window.quit)
butnquit.grid(row=8, column=0)

#
# Button to calculate the values
#
butncalc = Button(window, text="Calculate", command=calculate)
butncalc.grid(row=8, column=1)

window.mainloop()

Figure 10.45 Program listing

Figure 10.46 Typical run of the program


10.5 Summary
In this chapter, we have learned how to develop GUI based programs using the tkinter
package of the Python programming language. In the next chapter, we will be looking at
how to analyze and design transistor circuits using the Python.

● 202
Chapter 11 • BJT Transistor Circuit Analysis and Design

Chapter 11 • BJT Transistor Circuit Analysis and Design

11.1 Overview
In the last chapter, we have learned how to develop GUI based programs using the tkinter.
In this chapter, we shall be concentrating on analysing and designing transistor circuits
using the Python programming language.

11.2 BJT Transistor DC Analysis


In this section, we shall be looking at the BJT transistor DC analysis. Because this book is
not about the analysis or design of transistor amplifiers in detail, only the NPN type transis-
tors are considered in common-emitter configuration. We will start the analysis by looking
at two of the popular transistor biasing techniques: collector feedback biasing, and voltage
divider biasing.

11.2.1 Collector Feedback Biasing


This type of biasing requires two resistors. As shown in Figure 11.1, the base resistor RB
is connected to the transistor collector instead of the supply voltage rail VC. This method
of biasing employs feedback to stabilize the bias point. If the collector current increases,
the collector voltage will drop, thus reducing the base voltage and therefore automatically
reducing the collector current so that the transistor operating point is stabilized.

Figure 11.1 Collector feedback biasing

11.3 Case Study 20 – Analyzing Collector Feedback Biasing


Description: In this case study we will analyze the DC voltages and currents in the tran-
sistor circuit shown in Figure 11.1. The user enters the values of the two resistors, supply
voltage, and the value of the transistor current gain β.

Aim: The aim of this case study is to show how DC analysis can be carried out on a BJT
transistor configured as in Figure 11.1.

Background Information: The voltages and currents relating to Figure 11.1 can be cal-
culated as follows:

● 203
Learning Python with Raspberry Pi

and (11.1)

(11.2)

(11.3)

(11.4)

There are 3 equations: (11.2), (11.3), and (11.4) with 3 unknowns: IB. VC. and IC. Solving
these equations we find the value of VC as:

(11.5)

Then, from (11.2) we find IB, from (11.4) we find IC.

Program Listing: Figure 11.2 shows the program listing (program: bias1.py). The pro-
gram displays a heading and then reads the values of the two resistors, supply voltage, and
the current gain β (or B) of the transistor. It then calculates and displays the base current,
collector current, emitter current, and the collector-emitter voltage using the above equa-
tions. Figure 11.3 shows a typical run of the program with the following component values:

RB = 3300 Ohm
RC = 1000 Ohm
VCC = 10 Volt
β = 100

This program was run with Python V2.

#=================================================
# Collector Feedback Biasing
# ==========================
#
# This program analyzes a collector feedbak bias
#
# Author: Dogan Ibrahim
# File : bias1.py
# Date : July 2019
#=================================================
print("Collector Feedback Biassed Transistor Analysis")
print("==============================================")
#
# Read the component values
#

● 204
Chapter 11 • BJT Transistor Circuit Analysis and Design

Vcc = float(raw_input("Enter supply voltage (Volts): "))


RB = float(raw_input("Enter RB (Ohms): "))
RC = float(raw_input("Enter RC (Ohms): "))
B = float(raw_input("Enter current gain(B): "))

#
# Calculations
#
Vb = 0.7
Vcnum = RB*Vcc + Vb * RC * (1 + B)
Vcdenom = RC * (1 + B) + RB
Vc = Vcnum / Vcdenom
Vce = Vc
IB = 1000.0 * ((Vc - Vb) / RB)
IC = B * IB

#
# Display the results
#
print("\nVb=%7.3f V\nVc=%7.3f V\nVce=%7.3f V\nIB=%7.3f mA\nIC=%7.3f mA"
%(Vb,Vc,Vce,IB,IC))

Figure 11.2 Program listing

Figure 11.3 Typical run of the program

11.4 Voltage Divider Biasing


In this biasing technique, the common emitter transistor is biased using a voltage divider
network to increase the stability of the operating point. As shown in Figure 11.4, this is the
most commonly used type of biasing. Resistors RB1 and RB2 form a voltage divider circuit
which provides the base voltage. Voltage divider biasing makes the transistor independent
changes in the current gain and dependent on external component values. Generally, the
potential divider network is chosen such that the voltage drop across RB2 is much less than
for RB1. As a rule of thumb, the current through the potential divider resistors is chosen to
be at least 10 times the transistor base current so that it is high enough to have no effect
on the changes in the current gain.

● 205
Learning Python with Raspberry Pi

Figure 11.4 Voltage divider biasing

11.5 Case Study 21 – Analyzing Voltage Divider Biasing


Description: In this case study we will analyze the DC voltages and currents in the tran-
sistor circuit shown in Figure 11.4. The user enters the values of all the resistors, supply
voltage, and the value of the transistor current gain β.

Aim: The aim of this case study is to show how DC analysis can be carried out on a BJT
transistor configured as in Figure 11.4.

Background Information: The voltages and currents relating to Figure 11.4 can be cal-
culated as follows:

(11.6)

(11.7)

(11.8)

(11.9)

(11.10)

(11.11)

(11.12)

(11.13)

● 206
Chapter 11 • BJT Transistor Circuit Analysis and Design

(11.14)

Notice that the base current is usually very small compared to the collector current and
in most calculations equations (11.10), (11.11), and (11.12) are approximately replaced
with:


Program Listing: Figure 11.5 shows the program listing (program: bias2.py). The pro-
gram displays a heading and then reads the values of all the two resistors, supply voltage,
and the current gain β (or B) of the transistor. It then calculates and displays all the voltag-
es and current shown in equations (11.6) to (11.14). A typical run of the program is shown
in Figure 11.6 with the following component values:

Vcc = 12 Volt
RB1 = 30,000 Ohm
RB2 = 10,000 Ohm
RC = 1000 Ohm
RE = 1000 Ohm
β = 100

#=================================================
# Voltage Divider Biasing
# =======================
#
# This program analyzes a voltage divider bias
#
# Author: Dogan Ibrahim
# File : bias2.py
# Date : July 2019
#=================================================
print("Voltage Divider Biassed Transistor Analysis")
print("===========================================")
#
# Read the component values
#
Vcc = float(raw_input("Enter supply voltage (Volts): "))
RB1 = float(raw_input("Enter RB1 (Ohms): "))
RB2 = float(raw_input("Enter RB2 (ohms): "))
RC = float(raw_input("Enter RC (Ohms): "))
RE = float(raw_input("Enter RE (Ohms): "))
B = float(raw_input("Enter current gain(B): "))

● 207
Learning Python with Raspberry Pi

#
# Calculations
#
Vb = 0.7
VB = Vcc * (RB2 / (RB1 + RB2))
IB1 = (Vcc - VB) / RB1
IE = (VB - Vb) / RE
RB = RB1 * RB2 / (RB1 + RB2)
IB = (VB - Vb) / (RB + RE * (B + 1))
IB2 = IB1 - IB
IC = IE - IB
VCE = Vcc - (IC * RC + IE * RE)
VE = IE * RE
VC = Vcc - RC * IC
IB1 = 1000.0 * IB1
IB2 = 1000.0 * IB2
IE = 1000.0 * IE
IC = 1000.0 * IC
IB = 1000.0 * IB

#
# Display the results
#
print("\nVB=%7.3f V\nVCE=%7.3f V\nVE=%7.3f V\nVC=%7.3f V" %(VB,VCE,VE,VC))
print("\nIB1=%7.3f mA\nIB2=%7.3f mA\nIB=%7.3f mA\nIC=%7.3f mA\nIE=%7.3f mA"
%(IB1,IB2,IB,IC,IE))

Figure 11.5 Program listing

Figure 11.6 Typical run of the program

11.6 Case Study 22 – Designing Transistor Amplifier Circuit


Description: In this case study we will design a single common emitter transistor amplifier
circuit with the given supply voltage and voltage gain.

● 208
Chapter 11 • BJT Transistor Circuit Analysis and Design

Aim: The aim of this case study is to show how a single-stage common emitter amplifier
can be designed using the Python programming language.

Background Information: The circuit diagram of a single stage common emitter am-
plifier circuit is shown in Figure 11.7. The AC parameters of this amplifier circuit can be
calculated using the following formula (see Hybrid Pi model):

where at the required -3db frequency

where at the required -3db frequency

where at the required -3db frequency

The design starts from the specification of the required voltage gain, or the input voltage
and the required output voltage. The power supply voltage is usually supplied. We first have
to find the resistor values for biasing the transistor and also providing the required gain.
Briefly, the steps are as follows:

● 209
Learning Python with Raspberry Pi

• Given the input and required output voltages, calculate the required voltage gain.
• Choose a collector current of around 2mA.
• Assume the VCE to be Vcc/2
• Choose a value for RL. Thinking that the gain without the source and load resis-
tors is given by RL x IE /25 at room temperature, choose RL to give 30% higher
gain than the required value
• Choose a value for RE (assuming that IE = Ic) from equation Vcc = IcRL + VCE
+IcRE
• Calculate base current from IB / β
• Calculate the base voltage from VB = 0.7 + IcRE
• Assume that the current in R1 and R2 will be 10 times the base current and cal-
culate suitable values for R1 and R2
• Calculate the input and output impedances
• Check that the overall gain is as required, if not go back and adjust Ic, RL, or RE
• Calculate suitable values for C1, C2 and CE

Figure 11.7 Common emitter amplifier circuit

Program Listing: Figure 11.8 shows the program listing (program: amplifier.py). At the
beginning of the program, a heading is displayed.

#=====================================================
# Single Stage Common Emitter Amplifier Design
# ============================================
#
# This program designs a common emitter amplifier
#
# Author: Dogan Ibrahim
# File : amplifier.py
# Date : July 2019
#======================================================
import math

print("Single Stage Common Emitter Amplifier Design")


print("============================================")
#
# Read the component values

● 210
Chapter 11 • BJT Transistor Circuit Analysis and Design

#
Vcc = float(raw_input("Enter supply voltage (Volts): "))
Vin = float(raw_input("Enter Vin (Volts): "))
Vout = float(raw_input("Enter Vout (Volts): "))
RS = float(raw_input("Enter Rs (ohms): "))
RL = float(raw_input("Enter RL (Ohms): "))
f = float(raw_input("Enter lowest frequency to amplify (Hz): "))
B = float(raw_input("Enter current ratio (B): "))

#
# Calculations
#
Gr = Vout / Vin # Gain
IC = 2 # IC=2mA
Ge = Gr * (1.3) # Estimate gain 30% higher
RC = Ge * 25 / IC # Collector resistance
RCRL = (RC * RL) / (RC + RL)
re = 25.0 / IC
Rinbase = B * re # Base resistance
G1 = RCRL / re # G1
VCE = Vcc / 2 # VCE
IC = IC / 1000.0
RE = (Vcc - RC * IC - VCE) / IC # RE
VB = 0.7 + IC * RE
IB = IC / B
IR1R2 = 10.0 * IB # 10 times base current
R2 = VB / IR1R2
R1 = (Vcc - VB) / IR1R2
RB = (R1 * R2) / (R1 + R2)
Zi = (RB * Rinbase) / (RB + Rinbase)
G2 = Zi / (RS + Zi)
G = G1 * G2
XC = Zi / 10.0
C1 = 1000000.0 / (2 * math.pi * f * XC)
Zo = RCRL
XC = Zo / 10.0
C2 = 1000000.0 / (2 * math.pi * f * XC)
XC = RE / 10.0
CE = 1000000.0 / (2 * math.pi * f * XC)

#
# Display the results
#
print("\nRESULTS:")
print("=======")
print("Gain=%7.3f\nIC=%7.3f mA\nIB=%7.3f mA" %(G,IC*1000.0,IB*1000.0))

● 211
Learning Python with Raspberry Pi

print("\nVcc=%7.3f V\nVB=%7.3f V\nVCE=%7.3f V" %(Vcc,VB,VCE))


print("\nR1=%7.3f Ohm\nR2=%7.3f Ohm\nRC=%7.3f Ohm\nRE=%7.3f Ohm"
%(R1,R2,RC,RE))
print("\nC1=%7.3f uF\nC2=%7.3f uF\nCE=%7.3f uF" %(C1,C2,CE))
print("\nZi=%7.3f Ohm\nZo=%7.3f Ohm" %(Zi,Zo))

Figure 11.8 Program listing

An example run of the program is shown in Figure 11.9. In this example the following spec-
ifications were assumed:

Vin = 0.010V
Vout = 0.4V
Rs = 100 Ohm
RL = 15K
fl = 40Hz
Vcc = 12V
β = 100

It is clear that the required voltage gain of the transistor (without the source and load re-
sistances) is 0.4V/0.010V = 40.

Figure 11.9 Example run of the program

● 212
Chapter 11 • BJT Transistor Circuit Analysis and Design

11.7 Summary
In this chapter, we have learned how to use Python to analyze the DC bias characteristic of
BJT transistors. We have also developed a program to design single stage common emitter
transistor amplifier with the given specifications. In the next chapter, we shall be looking at
how to design active filters with the help of Python.

● 213
Learning Python with Raspberry Pi

Chapter 12 • Active Filters

12.1 Overview
In the last chapter, we have learned how to develop programs to analyze and design tran-
sistor bias circuits and common emitter based single stage amplifiers. In this chapter, we
shall be learning how to use Python to design active low-pass filters. Low-pass and Band-
pass filters are used commonly in electrical circuits, especially in communications circuits.
In this chapter, we shall only be looking at the design of second-order active low-pass
filters. Filters of higher-order can easily be designed by cascading the basic second-order
sections. When cascading filter sections, the overall gain is the product of the gain of each
section.

12.2 Case Study 23 – Designing Low-Pass Active Filters


Description: In this case study we will design second-order low-pass active filters. Users
enter the cut-off frequency of the filter and the program will calculate and display the com-
ponent values.

Aim: The aim of this case study is to show how a second-order active filter can be designed
using the Python programming language.

Background Information: There are several forms of second-order active low-pass fil-
ters. The one used in this case study is the well-known Sallen-Key type filter whose circuit
diagram is shown in Figure 12.1. The filter consists of two capacitors and two resistors. This
type of filter has unity gain in the pass-band.

Figure 12.1 Second order low-pass filter

It is possible to design Sallen-Key type filters with higher gains, but care should be taken
since the high gain filters can easily become unstable and oscillate, giving high overshoot
in their time responses and high gains at their cut-off frequencies. The Q factor of a filter
defines its quality, i.e. the damping of the response. For low-pass filters, Q should have a
value of 0.707. Higher values of Q may cause instability and overshoots in the time and fre-
quency responses. Another parameter used in filter design is the damping factor, denoted
with ξ. This is related to the Q factor with the following equation:

The ideal value for ξ is also 0.707. Lower values of ξ give rise to oscillations and instability
in the designed circuit. To maintain stability the gain of an active filter must not be greater

● 214
Chapter 12 • Active Filters

than 3. The relationship between the gain and Q factor is:

Figure 12.2 shows the filter frequency response for various values of ξ. It is clear from this
figure that ξ = 0.707 gives a flat response.

Figure 12.2 Filter frequency response for different values of ξ

The cut-off frequency of the filter in Figure 12.1 is given by:

In order to make sure that Q = 0.707, the following must be satisfied:

Let R1 = R2 = R, and C1 / C2 = n, then we have to make sure that C1 / C2 >= 4Q2,


i.e. C1 / C2 >= 2,

or C2 / C1 <= 0.5

The filter design equation then becomes:

or,

● 215
Learning Python with Raspberry Pi

The design steps are then as follows:

• Read the filter cut-off frequency


• Select a value for C2
• Select a value for C1, making sure that C1 / C2 >= 2. For Q=0.707, select C1 /
C2 = 2
• Calculate the required R

Program Listing: Figure 12.3 shows the program listing (program: lowpass.py). At the
beginning of the program a heading is displayed and the user is required to enter the filter
cut-off frequency, C1 and C2 in microfarads. The program calculates and displays the re-
quired resistors, making sure that the above inequality is satisfied. The user is then asked
to enter the actual physical resistors to be used and displays the actual cut-off frequency
when these resistors are used. If the user is not happy with the calculated cut-off frequency
then the program is restarted so that the user can select new values for the capacitors.

#=====================================================
# Second Order Low-Pass Active Filter Design
# ==========================================
#
# This program designs a second order low-pass filter
#
# Author: Dogan Ibrahim
# File : lowpass.py
# Date : July 2019
#======================================================
import math

yn = 'n'
while yn == 'n':
print("Second Order Low-Pass Active Filter Design")
print("==========================================")
#
# Read the cut-off frequency and C1, C2
#
C1 = 1
C2 = 1
f = float(raw_input("Enter the cut-off frequency (Hz): "))

while C1/C2 < 2:


C2 = float(raw_input("Enter C2 (microfards): "))
C = 2 * C2
C1 = float(raw_input("Enter C1 (microfarads) C1 >= %d : " %(C)))

C1F = C1 / 1000000.0
C2F = C2 / 1000000.0

● 216
Chapter 12 • Active Filters

#
# Calculations
#
n = C1F / C2F
r = 2 * math.pi * f * C2F * math.sqrt(n)
R = 1 / r

#
# Display the results
#
print("\nRESULTS:")
print("=======")
print("C1=%7.3f uF\nC2=%7.3f uF\nR1=%7.3f Ohm\nR2=%7.3f Ohm" %(C1,C2,R,R))

print("\nEnter the actual physical resistors to be used:")


Rnew = float(raw_input("Enter R1, R2 (Ohms): "))
fn = 2 * math.pi * Rnew * C2F * math.sqrt(n)
fnew = 1 / fn
print("Actual cut-off requency = %7.3f Hz" %(fnew))
yn = raw_input("Are you happy with the actual cut-off frequecy (yn)? ")
yn = yn.lower()

Figure 12.3 Program listing

An example run of the program is shown in Figure 12.4. In this example, the following
specifications were used:

Cut-off frequency = 1000Hz


C2 = 12μF
C1 = 6μF

Figure 12.4 Example run of the program

● 217
Learning Python with Raspberry Pi

The resistor values are calculated to be R1 = R2 = 18.759 Ohm. Selecting the nearest phys-
ical value as 18 Ohm gives the cut-off frequency as 1042.033Hz. We accept this value and
respond with y to terminate the program. The application given in the following link can be
used to display the frequency response, Q factor, etc of a low-pass Sallen-Key type filter:

http://sim.okawa-denshi.jp/en/OPstool.php

Using this application, the transfer function, Q factor, damping factor, the frequency and
phase responses of the designed filter with the new resistors are shown in Figure 12.5 and
Figure 12.6.

Figure 12.5 Designed filter specifications

Figure 12.6 Frequency and phase responses of the designed filter

● 218
Chapter 12 • Active Filters

The above application also shows the step response of the designed filter. This is shown in
Figure 12.7.

Figure 12.7 Step time response of the designed filter

12.3 High-Pass Filters


For completeness, the circuit diagram of a second-order active high-pass filter is shown in
Figure 12.8 The design equations are:

Figure 12.8 Second-order active high-pass filter

12.4 Band-Pass Filters


For completeness, the circuit diagram of a second-order active high-pass filter is shown in
Figure 12.9 The center frequency of this filter is given by:

● 219
Learning Python with Raspberry Pi

Figure 12.9 Second order active band-pass filter

12.5 Summary
In this chapter, we have learned how to design active low-pass filters of type Sallen-Key
using the Python programming language. Interested readers can expand their knowledge
and learn how to design other types of filters, such as high-pass and band-pass. In the next
chapter, we shall be looking at how to access the Raspberry Pi 4 hardware and peripheral
devices from Python.

● 220
Chapter 13 • Accessing Raspberry Pi 4 Hardware and Peripheral Devices From Python

Chapter 13 • Accessing Raspberry Pi 4 Hardware and Peripheral


Devices From Python

13.1 Overview
All versions of Raspberry Pi include a socket for connecting external devices, such as sen-
sors, LEDs, actuators, etc. For the sake of completeness, in this chapter, we will look at how
external devices connected to Raspberry Pi can be accessed from Python. In this chapter,
the following types of peripheral access from Python will be covered with one example from
each type of access.

• Parallel access (GPIO)


• Pulse Width Modulation (PWM)
• I2C access
• SPI access
• Serial access

There are many project-based books on using Python to access peripheral devices connect-
ed to Raspberry Pi. Interested readers can search Google or Amazon for articles and books
in this field. The author has the following publications on this topic:

• Raspberry Pi 3 Basic to Advanced Projects (Elektor publication)


• Motor Control Projects with Arduino and Raspberry Pi (Elektor publication)
• Camera Projects Book: 39 Experiments with Raspberry Pi and Arduino (Elektor
publication)
• Hardware Projects for Raspberry Pi (Elektor publication)
• Raspberry Pi Advanced Programming (Elektor publication)

Before going into the details of the hardware interface, it is worthwhile to look at the Rasp-
berry Pi 4 GPIO connector. This is a 40-pin dual-in-line 2.54mm wide connector as shown
in Figure 13.1.

Figure 13.1 Raspberry Pi GPIO connector

● 221
Learning Python with Raspberry Pi

13.2 GPIO – Parallel Interface


When the GPIO connector is at the far side of the board, the pins at the bottom, starting
from the left of the connector are numbered as 1, 3, 5, 7, and so on, while the ones at the
top are numbered as 2, 4, 6, 8 and so on.

The GPIO provides 26 general purpose bi-directional I/O pins. Some of the pins have mul-
tiple functions. For example, pins 3 and 5 are the GPIO2 and GPIO3 input-output pins
respectively. These pins can also be used as the I2C bus I2C SDA and I2C SCL pins respec-
tively. Similarly, pins 9,10,11,19 can either be used as general purpose input-output, or as
the SPI bus pins. Pins 8 and 10 are reserved for UART serial communication.

Two power outputs are provided: +3.3V and +5.0V. The GPIO pins operate at +3.3V logic
levels (not like many other computer circuits that operate with +5V). A pin can either be
an input or an output. When configured as an output, the pin voltage is either 0V (logic
0) or +3.3V (logic 1). Raspberry Pi 3 is normally operated using an external power supply
(e.g. a mains adapter) with +5V output and minimum 2A current capacity. A 3.3V output
pin can supply up to 16mA of current. The total current drawn from all output pins should
not exceed the 51mA limit. Care should be taken when connecting external devices to the
GPIO pins as drawing excessive currents or short-circuiting a pin can easily damage your Pi.
The amount of current that can be supplied by the 5V pin depends on many factors such as
the current required by the Pi itself, current taken by the USB peripherals, camera current,
HDMI port current, and so on.

When configured as an input, a voltage above +1.7V will be taken as logic 1, and a voltage
below +1.7V will be taken as logic 0. Care should be taken not to supply voltages greater
than +3.3V to any I/O pin as large voltages can easily damage your Pi.

13.2.1 The GPIO Library


The GPIO library is called RPi.GPIO and it should already be installed on your Raspberry
Pi 4. This library must be included at the beginning of your Python programs if you will be
using the GPIO functions. The statement to include this library is:

import RPi.GPIO as GPIO

If you get an error while trying to import the GPIO library then it is possible that the library
is not installed. Enter the following commands while in the command mode (identified by
the prompt pi@raspberrypi:~ $) to install the GPIO library (characters that should be
entered by you are in bold):

pi@raspberrypi: ~ $ sudo apt-get update


pi@raspberrypi: ~$ sudo apt-get install python-dev
pi@raspberrypi: ~$ sudo apt-get install python-rpi.gpio

The GPIO provides a number of useful functions. Some of the available functions are given
in the next sections

● 222
Chapter 13 • Accessing Raspberry Pi 4 Hardware and PeripheralDevices From Python

13.2.2 Pin Numbering


There are two ways that we can refer to the GPIO pins. The first is using the BOARD num-
bering, where the pin numbers on the GPIO connector of the Raspberry Pi 4 are used. Enter
the following statement to use the BOARD method:

GPIO.setmode(GPIO.BOARD)

The second numbering system, also known as the BCM method is the preferred method
and it uses the channel numbers allocated to the pins. This method requires that you know
which channel number refers to which pin on the board. In this book, we shall be using this
second method. Enter the following statement to use the BCM method:

GPIO.setmode(GPIO.BCM)

The GPIO is a 40 pin header, mounted at one side of the board. Appendix A shows the
Raspberry Pi 4 GPIO pin configuration.

13.2.3 Channel (I/O port pin) Configuration

Input Configuration
You need to configure the channels (or port pins) you are using whether they are input or
output channels. The following statement is used to configure a channel as an input. Here,
channel refers to the channel number based on the setmode statement above:

GPIO.setup(channel, GPIO.IN)

When there is nothing connected to an input pin, the data at this input is not defined. We
can specify additional parameters with the input configuration statement to connect pull-up
or pull-down resistors by software to an input pin. The required statements are:
For pull-down:

GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

For pull-up:

GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)

We can detect an edge change of an input signal at an input pin. Edge change is when
the signal changes from LOW to HIGH (rising edge), or from HIGH to LOW (falling edge).
For example, pressing a push-button switch can cause an edge change at the input of a
pin. The following statements can be used to wait for an edge of the input signal. These
are blocking functions. i.e. the program will wait until the specified edge is detected at the
input signal. For example, if this is a push-button, the program will wait until the button is
pressed:

● 223
Learning Python with Raspberry Pi

To wait for a rising edge:

GPIO.wait_for_edge(channel, GPIO.RISING)

To wait for a falling edge:

GPIO.wait_for_edge(channel, GPIO.FALLING)

We can also wait until either a rising or a falling edge is detected by using the following
statement:

GPIO.wait_for_edge(channel, GPIO.BOTH)

We can use event detection function with an input pin. This way, we can execute the event
detection code whenever an event is detected. Events can be rising edge, falling edge, or
change in either edge of the signal. Event detection is usually used in loops where we can
check for the event while executing other code.

For example, to add rising event detection to an input pin:

GPIO.add_event_detect(channel, GPIO.RISING)

We can check whether or not the event occurred by the following statement:

If GPIO.event_detected(channel):
……………………………
……………………………

Event detection can be removed by the following statement:

GPIO.remove_event_detect(channel)

We can also use interrupt facilities (or callbacks) to detect events. Here, the event is han-
dled inside a user function. The main program carries on its usual duties and as soon as
the event occurs the program stops whatever it is doing and jumps to the event handling
function. For example, the following statement can be used to add interrupt based event
handling to our programs on rising edge of an input signal. In this example, the event han-
dling code is the function named MyHandler:

GPIO.add_event_detect(channel, GPIO.RISING, callback=MyHandler)


……………………………………………………………………………
……………………………………………………………………………

def MyHandler(channel):
………………….
………………….

● 224
Chapter 13 • Accessing Raspberry Pi 4 Hardware and PeripheralDevices From Python

We can add more than one interrupt by using the add_event_callback function. Here the
callback functions are executed sequentially:

GPIO.add_event_detect(channel, GPIO.RISING)
GPIO.add_event_callback(channel, MyHandler1)
GPIO.add_event_callback(channel, MyHandler2)
……………………………………………………….
……………………………………………………….

def MyHandler1(channel):
……………………
……………………

def MyHandler2(channel):
……………………
……………………

When we use mechanical switches in our projects we get what is known as the switch
bouncing problem. This occurs as the contacts of the switch bounce many times until they
settle to their final state. Switch bouncing could generate several pulses before it settles
down. We can avoid switch bouncing problems in hardware or software. GPIO library pro-
vides a parameter called bounce-time that can be used to eliminate the switch bouncing
problem. An example use of this parameter is shown below where the switch bounce time
is assumed to be 10ms:

GPIO.add_event_detect(channel,GPIO=RISING,callback=MyHandler, bouncetime=10)

We can also use the callback statement to specify the switch bouncing time as@

GPIO.add_event_callback(channel, MyHandler, bouncetime=10)

To read the state of an input pin we can use the following statement:

GPIO.input(channel)

Output Configuration
The following statement is used to configure a channel as an output. Here, channel refers
to the port number based on the setmode statement described earlier:

GPIO.setup(channel, GPIO.OUT)

We can specify a value for an output pin during its setup. For example, we can configure a
channel as output and at the same time set its value to logic HIGH (+3.3V):

GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)

● 225
Learning Python with Raspberry Pi

To send data to an output port pin we can use the following statement:

GPIO.output(channel, value)

Where value can be 0 (or GPIO.LOW, or False), or 1 (or GPIO.HIGH, or True)

At the end of the program, we should return all the used resources to the operating system.
This is done by including the following statement at the end of our program:

GPIO.cleanup()

13.2.4 Case Study 24 – Flashing an LED


Description: In this case study we will connect an LED to one of the Raspberry Pi GPIO
pins and then flash the LED by turning it ON and OFF every second.

Aim: The aim of this case study is to show how an LED can be connected to a GPIO pin and
how the GPIO library can be used to flash the LED.

Background Information: The forward voltage of an LED is around 1.8V. The current
through the LED depends on the required light intensity and the type of LED used. In gen-
eral 3mA should give enough visible light for small LEDs. Because the output voltage of
a GPIO pin is +3.3V we have to use a current limiting resistor in series with the LED. The
value of the current limiting resistor is calculated as:

R = (3.3V – 1.8V / 3mA = 500 Ohm. We can choose a 470 Ohm resistor

Figure 13.2 shows the LED connected to pin GPIO 2 of the Raspberry Pi.

Figure 13.2 LED connected to pin GPIO 2

Program Listing: The program is very simple and is shown in Figure 13.3 (program: LED.
py). At the beginning of the program the RPi.GPIO and the time modules are imported to
the program. Then the pin numbering is configured to use BCM notation and GPIO is con-
figured as an output pin. The remainder of the program is run indefinitely in a while loop
where the LED is turned ON and OFF with one second delay between each output. Run the
program with the command: python LED.py from the command line. You can enter Cn-
trl+C to terminate the program.

● 226
Chapter 13 • Accessing Raspberry Pi 4 Hardware and PeripheralDevices From Python

#-------------------------------------------------------
#
# FLASHING LED
# ============
#
# In this project a small LED is connected to GPIO 2 of
# the Raspberry Pi 4. The program flashes the LED every
# second.
#
# Program: LED.py
# Date : August 2019
# Author : Dogan Ibrahim
#--------------------------------------------------------
import RPi.GPIO as GPIO # import GPIO library
import time # import time library
GPIO.setwarnings(False) # disable warning messages

GPIO.setmode(GPIO.BCM) # set BCM pin numbering


GPIO.setup(2, GPIO.OUT) # configure GPIO 2 as output

try:
while True:
GPIO.output(2, 1) # turn ON LED
time.sleep(1) # wait 1 second
GPIO.output(2, 0) # turn OFF LED
time.sleep(1) # wait 1 second

except KeyboardInterrupt:
GPIO.cleanup()

Figure 13.3 Program listing

13.3 PWM
PWM waves are frequently used in power control applications. The waveform is basically a
positive square wave with variable ON and OFF times. As shown in Figure 13.4, the total of
the ON and OFF times is known as the period of the waveform. The ratio of the ON time to
the period is known as the Duty Cycle and it is represented as a percentage. i.e.

Duty Cycle = (T / P) x 100%

where, T is the ON time, and P is the period (ON time + OFF time).

● 227
Learning Python with Raspberry Pi

Figure 13.4 PWM waveform

By varying the duty cycle from 0% to 100% we can easily control a load, e.g. a motor. For
example, at 50% duty cycle the load receives half of the total power. Similarly, at 100%
duty cycle the load receives full power.

Python PWM library supports the following commands:

P = GPIO.PWM(channel, frequency) - Configure channel for PWM with speci-


fied frequency

p.start(DC) - Start PWM with specified Duty Cycle

p.stop() - Stop PWM

p.ChangeFrequency(frequency) - Change PWM frequency

p.ChangeDutyCycle(DC) - Change Duty Cycle

13.3.1 Case Study 25 – Changing the Brightness of an LED


Description: In this case study we will connect an LED to one of the Raspberry Pi GPIO
pins as in the previous case study and then change the brightness of the LED by supplying
it a PWM voltage where the duty cycle is varied every 100ms.

Aim: The aim of this case study is to show how a PWM waveform can be generated using
the PWM library.

Background Information: By varying the duty cycle of a PWM waveform we effectively


vary the average voltage supplied to a load.

Program Listing: Figure 13.5 shows the program listing (program: PWM.py). GPIO is
configured as a PWM channel with the frequency of the waveform set to 1kHz. The PWM is
initially started with 50% Duty Cycle and then the Duty Cycle is varied every 0.1 seconds
(100 ms).

● 228
Chapter 13 • Accessing Raspberry Pi 4 Hardware and PeripheralDevices From Python

#====================================================
# VARYING THE LED BRIGHTNESS
# ==========================
#
# In this program a PWM waveform is supplied to the
# LED with varying Duty Cycle. The net effect is that
# the LED brightness changes
#
# Author: Dogan Ibrahim
# File : PWM.py
# Date : August 2019
#======================================================
import RPi.GPIO as GPIO # import GPIO
import time # import time
GPIO.setwarnings(False)

GPIO.setmode(GPIO.BCM) # set mode BCM


GPIO.setup(2, GPIO.OUT) # GPIO output

p = GPIO.PWM(2, 1000) # PWM frequency=1kHz


DC = 50 # Duty Cycle=50%
p.start(DC) # start PWM

try:
while True:
p.ChangeDutyCycle(DC) # change Duty Cycle
DC = DC + 1 # increment Duty Cycle
if DC > 100: # if > 100
DC = 0 # set to 0
time.sleep(0.1) # 0.1 second delay

except KeyboardInterrupt: # CntrlC interrupt


GPIO.cleanup()

Figure 13.5 Program listing

13.4 I2C
I2C (or I2C) is a bus standard developed by Philips back in the '80s to enable communica-
tion between processors and sensors. This bus standard uses two wires for communication:
SDA (data) and SCL (clock). The bus operates as master-slave where the Raspberry Pi is
the master and the sensors or actuators are the slaves. The SDA and SCL lines are pulled
up to +3.3V through internal pull-up resistors inside Raspberry Pi. Each slave has its own
unique address, and the address of a slave can normally be changed to avoid a clash on
the bus. Communication on the I2C bus is always started by the master where it sends the
address of the slave it wants to communicate with. Only one slave on the bus can respond
to this request.

● 229
Learning Python with Raspberry Pi

Before using the I2C bus we have to import module smbus into our program. The following
commands are provided by the Python I2C module:

bus = smbus.SMBus(1) create n I2C object called bus


data = bus.read_byte(address)  read data from a register (not speci-
fied)
data = bus.read_byte_data(address, reg) read data from a register
bus.write_byte(address, data) write data to a register (not specified)
bus.write_byte_data(address, ref, data) write data to a register
data = bus.read_word_data(address, reg) read word data from a register
write_word_data(address, reg, data) write word data to a register
data = read_block_data(address, reg) read block data
write_block_data(address, reg, data) write block data

13.4.1 Case Study 26 – Using I2C LCD


Description: In this case study we will connect an I2C type LCD to our Raspberry Pi and
then display text TESTING I2C on the LCD.

Aim: The aim of this case study is to show how an I2C type LCD can be connected to Rasp-
berry Pi and how data can be displayed on the LCD.

PWM waveform can be generated using the PWM library.

Background Information: The circuit diagram of the project is shown in Figure 13.6. Al-
though Raspberry Pi 3 is shown in the Figure, the same circuit can be used with Raspberry
Pi 4 as well. The I2C LCD has 4 pins: GND, +V, SDA, and SCL. SDA is connected to pin
GPIO 2 and SCL is connected to pin GPIO 3. +V pin of the display should be connected to
the +5V (pin 2) of the Raspberry Pi 3 (some versions of Raspberry Pi, such as the Rasp-
berry Pi Zero and Raspberry Pi Zero W cannot supply enough power to drive the LCD. It is
recommended to use an external +5V supply to power for the LCD if you are using one of
these models). Note that there is no problem mixing the +3.3V GPIO pins of the Raspberry
Pi with the +5V of the I2C LCD. This is because the Raspberry Pi is the I2C master device
and the SDA and SCL lines are pulled up to +3.3V through resistors. SCL line is the clock
which is always output from the master device. The slave device (I2C LCD here) only pulls
down the SDA line when it acknowledges the receipt of data and it does not send any data
to the master device. Therefore, there are no voltage level problems as long as the Rasp-
berry Pi I2C output pins can drive the I2C LCD inputs, which is the case here.

● 230
Chapter 13 • Accessing Raspberry Pi 4 Hardware and PeripheralDevices From Python

Figure 13.6 Circuit diagram of the project

Program Listing: Before using the I2C pins of the Raspberry Pi we have to enable the I2C
peripheral interface on the device. The steps for this are as follows:

Start the configuration menu from the command prompt:

pi@raspberrypi:~ $ sudo raspi-config


Go down the menu to Interface Options
Go down and select I2C
Enable the I2C interface
Select Finish to complete

Now we have to install the I2C library on our Raspberry Pi 4. The steps are as follows:
Enter the following commands from the command menu:

pi@raspberrypi:~ $ sudo apt-get update


pi@raspberrypi:~ $ sudo apt-get install –y python-smbus i2c-tools
pi@raspberrypi:~ $ sudo reboot

Enter the following command to test the installation. You should see i2c_bcm2837 listed:

pi@raspberrypi:~ $ lsmod | grep i2c_

Modify the config file as follows:

pi@raspberrypi:~ $ sudo nano /etc/modules

Add the following lines (if they are not already there):

i2c-bcm2837
i2c-dev

Exit from nano by typing Ctrl X and Y to save the file. You can check the
contents of this file by entering the command:

pi@raspberrypi:~ $ cat /etc/modules

● 231
Learning Python with Raspberry Pi

Reboot the Raspberry Pi 4 by entering:

pi@raspberrypi:~ $ sudo reboot

Connect your LCD to the Raspberry Pi 4 device and enter the following command to check
whether or not the LCD is recognized by the Raspberry Pi 4:

pi@raspberrypi:~ $ sudo i2cdetect –y 1

You should see a table similar to the one shown below. A number in the table means that
the LCD has been recognizes correctly and the I2C slave address of the LCD is shown in the
table. In this example the LCD address is 27:

1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

We should now install an I2C LCD library so that we can send commands and data to our
LCD. There are many Python libraries available for the I2C type LCDs. The one chosen here
is called the RPi_I2C_driver. This library is installed as follows:

• Go to the following web link:

https://gist.github.com/DenisFromHR/cc863375a6e19dce359d

• Scroll down to section RPi_I2C_driver.py. Click Raw at the top right-hand side
of the screen and save the file in a folder (e.g. Desktop) with the name RPi_
I2C_driver.py (the easiest option might be to copy the file into the Notebook
and then save it as RPi_I2C_driver.py).

• Start your Raspberry Pi 4 in command mode.

• Start the WinSCP file copy utility (you should install it if you already do not have
it) on your PC and copy file RPi_I2C_driver.py to folder usr/lib/python2.7
on your Raspberry Pi 4.

• Check to make sure that the file is copied successfully. You should see the file
listed with the command:

pi@raspberrypi: ~ $ ls /usr/lib/python2.7

● 232
Chapter 13 • Accessing Raspberry Pi 4 Hardware and PeripheralDevices From Python

We are now ready to write our program. Figure 13.7 shows the program listing (lcd.py). At
the beginning of the program libraries RPi.GPIO, timer, and the LCD driver library RPi_I2C_
driver are imported to the program. Then text TESTING I2C is displayed.

#---------------------------------------------------------
#
# I2C LCD SECONDS COUNTER
# =======================
#
# In this program an I2C LCD is connected to the Raspberry Pi
# and text TESTING I2C is displayed on the LCD
#
# Program: lcd.py
# Date : August 2019
# Author : Dogan Ibrahim
#----------------------------------------------------------
import RPi_I2C_driver

LCD = RPi_I2C_driver.lcd()
LCD.lcd_clear() # clear LCD
LCD.lcd_display_string("TESTING I2C", 1) # display string

while True:
pass

Figure 13.7 Program listing

The I2C LCD library supports the following functions (see the I2C LCD library documenta-
tion for more details):

lcd_clear() clear LCD and set to home position


lcd_display_string(text, row) display text at LCD row
lcd_write_char(c) display character
lcd_write(cmd) write command cmd to LCD
lcd.backlight(1/0) enable/disable LCD backlight
lcd_display_string_pos(text,row,col) display text at given row,column

13.5 SPI
Serial Peripheral Interface (SPI) bus consists of two data wires and one clock wire. Addi-
tionally, a chip enable (CE) connection is used to select a slave in a multi-slave system. The
wires used are:

MOSI: M
 aster Out Slave In. This signal is output from the master and is input to
a slave

MISO: Master In Slave Out. This signal is output from a slave and input to a master

● 233
Learning Python with Raspberry Pi

SCLK: The clock, controlled by the master

CE: Chip Enable (slave select)

There are 4 SPI operational modes known as mode 0 to mode3. The mode determines the
relationship between the clock pulses and the data pulses. Data can be read at the leading
edge or at the trailing edge of the clock. CPOL (clock polarity) and CPHA (clock phase) de-
termine the mode of operation. CPOL determines the polarity of the clock. In mode 0, both
CPOL and CPHA are 0 and data is sampled at the leading rising edge of the clock. In mode
2, CPOL=1 and CPHA=0, data is sampled at the leading falling edge of the clock. In mode
1, CPOL=0 and CPHA=1 and the data is sampled on the trailing falling edge of the clock. Fi-
nally, in mode 3, CPOL=1 and CPHA=1 where the data is sampled on the trailing rising edge
of the clock. Mode 0,0 is used by the Raspberry Pi which is the most commonly used mode.
The SPI bus on the Raspberry Pi supports the following functions:

Function Description

open (0,0) Open SPI bus 0 using CE0


open (0,1) Open SPI bus 0 using CE1
close() disconnect the device from the SPI bus
writebytes([array of bytes]) Write an array of bytes to SPI bus device
readbytes(len) Read len bytes from SPI bus device
xfer2([array of bytes]) Send an array of bytes to the device with CEx
asserted at all times
xfer([array of bytes]) Send an array of bytes de-asserting and assert-
ing CEx with every byte transmitted

13.5.1 Case Study 27 – Using SPI – Analog Temperature Sensor


Description: In this case study an analog temperature sensor chip is used to measure and
then display the ambient temperature every second on the monitor. Because the Raspberry
Pi does not have any analog-to-digital converters (ADC) on-board, an external ADC chip is
used here.

Aim: The aim of this project is to show how an SPI bus compatible external ADC chip can
be connected and controlled from Python.

Background Information: The dual MCP3002 ADC chip is used in this project to provide
analog input capability to the Raspberry Pi. This chip has the following features:

• 10-bit resolution (0 to 1023 quantization levels)


• On-chip sample and hold
• SPI bus compatible
• Wide operating voltage (+2.7V to +5.5V)
• 75 Ksps sampling rate
• 5nA standby current, 50µA active current

● 234
Chapter 13 • Accessing Raspberry Pi 4 Hardware and PeripheralDevices From Python

The MCP3002 is a successive approximation 10-bit ADC with on-chip sample and hold
amplifier. The device is programmable to operate as either differential input pair or as dual
single-ended inputs. The device is offered in an 8-pin package. Figure 13.8 shows the pin
configuration of the MCP3002.

Figure 13.8 Pin configuration of the MCP3002

The pin definitions are as follows:

Vdd/Vref: Power supply and reference voltage input


CH0: Channel 0 analog input
CH1: Channel 1 analog input
CLK: SPI clock input
DIN: SPI serial data in
DOUT: SPI serial data out
CS/SHDN: Chip select/shutdown input

In this case study the supply voltage and the reference voltage are set to +3.3V. Thus, the
digital output code is given by:

Digital output code = 1024 x Vin / 3.3

or, Digital output code = 310.30 x Vin

Each quantization level corresponds to 3300mV/1024 = 3.22mV. The MCP3002 ADC has
two configuration bits: SGL/DIFF and ODD/SIGN. These bits follow the sign bit and are
used to select the input channel configuration. The SGL/DIFF is used to select single-ended
or pseudo-differential mode. The ODD/SIGN bit selects which channel is used in single-
ended mode and is used to determine polarity in pseudo-differential mode. In this project
we are using channel 0 (CH0) in single ended mode. According to the MCP3002 datasheet,
SGL/DIFF and ODD/SIGN must be set to 1 and 0 respectively.

Figure 13.9 shows the circuit diagram of the project (although Raspberry Pi 3 is shown in
the figure, the circuit is applicable to all versions of Raspberry Pi). A TMP36DZ type analog
temperature sensor chip is connected to CH0 of the ADC. TMP36DZ is a 3 terminal small
sensor chip with pins: Vs, GND, and Vo. Vs is connected to +3.3V, GND is connected to sys-
tem ground, and Vo is the analog output voltage. The temperature in degrees Centigrade
is given by:

Temperature = (Vo – 500) / 10

● 235
Learning Python with Raspberry Pi

Where, Vo is the sensor output voltage in millivolts.

CS, Dout, CLK, and Din pins of the ADC are connected to the SPI pins CE0, MISO, SCLK,
and MOSI pins of the Raspberry Pi 3 respectively.

Figure 13.9 Circuit diagram of the project

Program Listing: Figure 13.10 shows the program listing (program: tmp36.py). Function
get_adc_data is used to read the analog data, where the channel number (channel_no)
is specified in the function argument as 0 or 1. Notice that we have to send the start bit,
followed by the SGL/DIFF and ODD/SIGN bits and the MSBF bit to the chip.

It is recommended to send leading zeroes on the input line before the start bit. This is often
done when using microcontroller-based systems that must send 8 bits at a time. The fol-
lowing data can be sent to the ADC (SGL/DIFF = 1 and ODD/SIGN = channel_no) as bytes
with leading zeroes for a more stable clock cycle. The general data format is:

0000 000S DCM0 0000 0000 0000

Where, S = start bit, D = SGL/DIFF bit, C = ODD/SIGN bit, M = MSBF bit

For channel 0: 0000 0001 1000 0000 0000 0000 (0x01, 0x80, 0x00)

For channel 1: 0000 0001 1100 0000 0000 0000 (0x01, 0xC0, 0x00)

Notice that the second byte can be sent by adding 2 to the channel number (to make it 2
or 3) and then shifting 6 bits to the left as shown above to give 0x80 or 0xC0.

The chip returns 24 bit data (3 bytes) and we must extract the correct 10 bit ADC data from
this 24 bit data. The 24 bit data is in the following format ("X" is don't care bit):

XXXX XXXX XXXX DDDD DDDD DDXX

● 236
Chapter 13 • Accessing Raspberry Pi 4 Hardware and PeripheralDevices From Python

Assuming that the returned data is stored in 24 bit variable ADC, we have:

ADC[0] = "XXXX XXXX"


ADC[1] = "XXXX DDDD"
ADC[2] = "DDDD DDXX"

Thus, we can extract the 10 bit ADC data with the following operations:

(ADC[2] >> 2) so, low byte = "00DD DDDD"


and
(ADC[1] & 15) << 6) so, high byte = "DD DD00 0000"

Adding the low byte and the high byte we get the 10 bit converted ADC data as:

DD DDDD DDDD

The module spidev must be imported at the beginning of the program before any of the
above functions are called. Also, you must enable the SPI interface on your Raspberry Pi 4
in the configuration menu. The steps are:

• Get into command mode (e.g. from Putty)

• Enter the following command:

pi@raspberrypi:~ $ sudo raspi-config

• Select the Interface Options

• Enable SPI interface

• Finish and exit the configuration menu

At the beginning of the program, modules RPi.GPIO and spidev are imported to the pro-
gram and an instance of the SPI is created. Function get_adc_data reads the temperature
from sensor chip MCP3002 and returns a digital value between 0 and 1023. This value is
then converted into millivolts, 500 is subtracted from it, and the result is divided by 10 to
find the temperature in degrees Centigrade. The temperature is displayed on the monitor
every second.

#---------------------------------------------------------------
#
# ANALOG TEMPERATURE SENSOR
# =========================
#
# In this project a TMP36 type analog temperature chip is used
# to measure the ambient temperature. The temperature is read

● 237
Learning Python with Raspberry Pi

# using a SPI bus compatible MCP3002 ADC chip.The result is


# converted to degrees Centigrade and is displayed on the monitor
#
# Program: tmp36.py
# Date : August 2019
# Author : Dogan Ibrahim
#----------------------------------------------------------------
import RPi.GPIO as GPIO
import spidev
import time
GPIO.setwarnings(False)
#
# Create SPI instance and open the SPI bus
#
spi = spidev.SpiDev()
spi.open(0,0) # we are using CE0 for CS

GPIO.setmode(GPIO.BCM)

#
# This function returns the ADC data read from the MCP3002
#
def get_adc_data(channel_no):
ADC = spi.xfer2([1, (2 + channel_no) << 6, 0])
rcv = ((ADC[1] & 15) << 6) + (ADC[2] >> 2)
return rcv

#
# Start of main program. Read the analog temperature, convert
# into degrees Centigrade and display on the monitor every second
#
while True:
adc = get_adc_data(0)
mV = adc * 3300.0 / 1023.0 # convert to mV
Temp = (mV - 500.0) / 10.0 # temperature in C
print("Temperature = %f " %Temp) # display temperature
time.sleep(1) # wait one second

Figure 13.10 Python program listing

A typical display on the monitor is shown in Figure 13.11.

● 238
Chapter 13 • Accessing Raspberry Pi 4 Hardware and PeripheralDevices From Python

Figure 13.11 Typical display

13.6 The serial


Serial interface has traditionally been based on the RS232 protocol. According to this pro-
tocol, serial data is sent with the least significant bit first in a timely manner. The bit time
is set by the Baud rate which is the number of bits sent (or received) every second. Typical
Baud rates are 9600, 19200, 38400, etc. In most applications, data transfer starts with
a start bit, followed by 8 data bits, and a stop bit. Therefore, 10 bits represent each byte
i.e. each character. As an example, at 9600 Baud, we can transfer 960 characters every
second. In some applications, 7 bits of data is used. Also, some applications use a parity
bit to check whether or not the data has been sent correctly. The voltage levels in a typical
RS232 serial communication are ±12V. Since these voltage levels are not compatible with
the modern microcontrollers, 0 and +5V (or +3.3V) are used instead where 0 represents
logic 0 and +5V (or +3.3V) represents logic 1. As shown in Figure 13.12, only 3 pins are
required for serial communication: TX, RX, and GND. It is important to realize that in a
serial communication both sides must be set to the same Baud rate.

Figure 13.12 Simplest serial communication

13.6.1 Case Study 28 – Using Serial Communication – Serial Loopback


Description: In this case study a serial loopback is setup by connecting the serial output
of the Raspberry Pi back to its serial input. Any data sent to the serial output is therefore
received back and is displayed on the monitor for test purposes.

Aim: The aim of this project is to show how the serial ports of the Raspberry Pi can be
accessed from Python.

Background Information: By default, pin 8 and pin 10 of the Raspberry Pi are the serial
TXD and RXD ports respectively. In this case study, pin 8 is connected to pin 10 through a
2K current limiting resistor (this is necessary to protect the RXD pin from short circuit as
both pins may have been set as outputs with one at 0 and the other one at 1). Figure 13.13
shows the serial loopback used in this case study.

● 239
Learning Python with Raspberry Pi

Figure 13.13 Serial loopback

The best way to test the serial port on Raspberry Pi is to use the minicom program. This
can be installed as follows:

pi@raspbeerypi:~ $ sudo apt-get install minicom

By default, the Raspberry Pi's serial port is configured to be used for console input/output.
To be able to use the serial port to connect and talk to other serial devices, the serial port
console login needs to be disabled. After disabling the console logins, the only way to log in
to our Raspberry Pi will be via SSH using the Putty terminal emulator.

Disable Serial Port Login on Raspberry Pi 4


The serial port logins can be disabled by the following steps:

• Start the configuration menu:

pi@raspberrypi:~ $ sudo raspi-config

• Select Interfacing Options

• Select P6 Serial

• Select No to Would you like a login shell to be accessible over serial?

• Select Yes to Would you like the serial port hardware to be enabled?

• Exit and reboot your Raspberry Pi:

pi@raspberrypi:~ $ sudo reboot

Don't forget to go back and enable serial logins after you finish working with the serial port.
To test the serial port, enter the following command to start minicom on your Raspberry
Pi 4:

pi@raspberrypi:~ $ minicom –b 9600 –o –D /dev/ttyS0

here, -b means that the next item is the Baud rate, -o means that the mode should not
be initialized (there is no modem), and –D means that the device name is the next item.

● 240
Chapter 13 • Accessing Raspberry Pi 4 Hardware and PeripheralDevices From Python

You should now see the Mincom screen. Whatever you type through the keyboard will be
echoed back on the keyboard as shown in Figure 13.14.

Figure 13.14 minicom screen

To exit from minicom, enter Cntrl+A followed by X. To clear the screen enter Cntrl+A
followed by C. To display the minicom help screen enter Cntrl+A followed by Z.
Note: you will have to replace /dev/ttyS0 with /dev/ttyAMA0 if you are using earlier
than Raspberry Pi 3.

Program Listing: Python on Raspberry Pi supports the following serial port commands:

write(a) send data a (character or string)


a = read() read one byte from serial port
a = read(n) read n bytes from serial port
a = ser.readline() read a whole line from the serial port. The line must be
terminated with a new line character '\n'.
open(x, b) open serial port x (/dev/ttyS0) with baud rate b
close() close serial port

You may have to install the serial module for the above commands to work:

pi@raspberrypi@~ $ sudo apt-get install python-serial

The program listing is shown in Figure 13.15 (program: serialport.py). This program
opens the serial port at 9600 Baud. Text Testing serial port is sent to serial port. This text
is then read and displayed on the screen.

Figure 13.15 Program listing

13.7 Summary
In this chapter, we have learned how to program using Python to access the peripheral
devices connected to our Raspberry Pi. In the next chapter, we shall be looking at how to
use Python to develop programs using Wi-Fi so that we can communicate with the external
world.

● 241
Learning Python with Raspberry Pi

Chapter 14 • Python and the Internet on Raspberry Pi 4

14.1 Overview
In the last chapter, we learned how to access peripheral devices connected to Raspberry
Pi. In this chapter, we shall be learning how to communicate with the external world over
a Wi-Fi link.

14.2 Internet Communication Protocols


There are basically two types of internet communication protocols: TCP/IP (Transmission
Control Protocol) and UDP (User Datagram Protocol). Both protocols operate on the prin-
ciple of server-client type communication. TCP/IP provides reliable communication with
acknowledgment of received data packets. It is a connection based protocol where the
server and client must connect to each other before data transfer can take place. TCP/IP
has higher overhead than UDP as it has a larger packet overhead. UDP, on the other hand
is connectionless protocol where the server and client do not connect to each other before
they can exchange data. Data transfer is not guaranteed with UDP since there is no ac-
knowledgment of received packets. As a result of this UDP has less overhead and is faster
than TCP/IP.

14.3 TCP/IP Based Communication


As has been discussed earlier in this chapter, TCP/IP is a reliable data exchange protocol.
The server and the client communicate through sockets as described by the following PDL
(Program Description Language):

Server
• Create a socket
• Bind the socket to a port with your IP address
• Listen for connections from clients
• Accept connection to a client
• Exchange data (send and receive data) with the client
• Close the connection

Client
• Create a socket
• Connect to the server by specifying its IP address and port number
• Exchange data (send and receive data) with the server
• Close the connection

In the examples in this chapter, the server is the Raspberry Pi, while the client is a PC or a
mobile phone.

Before starting to write network-based programs, we have to know the IP address of our
Raspberry Pi Wi-Fi link. This can be obtained by entering the command ifconfig as show in
Figure 14.1. In this figure, the IP address is: 192.168.1.202

● 242
Chapter 14 • Python and the Internet on Raspberry Pi 4

Figure 14.1 Displaying the IP address of the Raspberry Pi

14.3.1 Case Study 29 – Sending a Text Message to a Mobile Phone Using TCP/IP
Description: In this case study a TCP/IP based communication is established with an An-
droid mobile phone. The program reads text messages from the keyboard and sends to the
mobile phone.

Aim: The aim of this project is to show how TCP/IP communication can be established with
an Android mobile phone.

Background Information: Port numbers range from 0 to 65535. Numbers from 0 to


1023 are reserved and are called as well-known ports. For example, port 23 is the Telnet
port, port 25 is the SMTP port, etc. In this chapter, we shall be using port number 5000 in
our programs. Figure 14.2 shows the case study set up where the Raspberry Pi and mobile
phone communicate over a Wi-Fi router.

Figure 14.2 Case study setup

Raspberry Pi Program Listing: In this case study Raspberry Pi is the server. Figure 14.7
shows the Raspberry Pi program listing (program: tcpserver.py). At the beginning of the
program, a TCP/IP socket is created (sock.SOCK_STREAM) and is then bind to port 5000.
The program listens for a connection. Notice that it is possible for the server to listen to
multiple clients, but of course, it can communicate with only one at any time. When the
client makes a connection this is accepted by the server. The server then reads a message
from the keyboard and sends to the client over the Wi-Fi link.

In this case study the TCP/UDP TEST TOOL apps (V4.2) from animod is used which is
available free of charge in the Play Store (see Figure 14.3).

● 243
Learning Python with Raspberry Pi

Figure 14.3 Apps used in the case study

The program is run as follows:

• Run the server program:

pi@raspberrypi:~ $ python tcpserver.py

• Run the Android apps and select TCP CLIENT, set the Target IP to 192.168.1.202
and the port to 5000 and click CONNECT to connect to the server (see Figure
14.4)

Figure 14.4 Connect to the server

• You should see a connection message on your Raspberry Pi screen and also the
IP address of the remote Android mobile phone (Figure 14.5). Now enter a mes-
sage and press Enter key. In this example, the message HELLO FROM RASP-
BERRY PI is sent to the client. Enter n to terminate the Raspberry Pi program.
Figure 14.6 shows the message displayed on the mobile phone.

Figure 14.5 Client IP address displayed

● 244
Chapter 14 • Python and the Internet on Raspberry Pi 4

Figure 14.6 Message displayed on the mobile phone

#==============================================
# SEND TEXT MESSAGES USING TCP/IP
# ===============================
#
# This is the TCP/IP server program. It receives
# text messages from the keyboard and sends to an
# Android mobile phone over a Wi-Fi link
#
# Author: Dogan Ibrahim
# File : tcpserver.py
# Date : August 2019
#================================================
import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


sock.bind(("192.168.1.202", 5000))
sock.listen(1)

client, addr = sock.accept() # accept connection


print("Connected to client: ", addr)

yn = 'y'

while yn == 'y':
msg = raw_input("Enter your message: ")
client.send(msg)

yn = raw_input("Send more messages?: ")


yn = yn.lower()

print("\nClosing connection to client")


sock.close()
Figure 14.7 Raspberry Pi program listing

● 245
Learning Python with Raspberry Pi

14.3.2 Case Study 30 – Communicating with a PC Using TCP/IP


Description: In this case study a TCP/IP based communication is established between the
Raspberry Pi and a PC running Python. Messages are exchanged between the Raspberry Pi
and the PC.

Aim: The aim of this project is to show how TCP/IP communication can be established with
a PC.

Background Information: In this case study the Raspberry Pi is the server and the PC
is the client. The programs on both sides are developed using the Python programming
language. Python 2.7 is used on the PC. If you do not have Python on your PC, you should
install it from the following web site:

https://www.python.org/downloads/release/python-2715/

Figure 14.8 shows the case study setup where the Raspberry Pi and the PC communicate
over a Wi-Fi router.

Figure 14.8 Case study setup

Raspberry Pi Program Listing: The Raspberry Pi program is similar to the one given in
Figure 14.7. It is modified slightly by adding a few lines to send and receive messages from
the client. The Raspberry Pi program listing (program: tcpserver2.py) is shown in Figure
14.9.

#==============================================
# TCP/IP SERVER
# =============
#
# This is the TCP/IP server program on Raspberry Pi.
# The program exchanges text messages with the Python
# program running on the PC.
#
# Author: Dogan Ibrahim

● 246
Chapter 14 • Python and the Internet on Raspberry Pi 4

# File : tcpserver2.py
# Date : August 2019
#================================================
import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


sock.bind((“192.168.1.202", 5000))
sock.listen(1)

client, addr = sock.accept() # accept connection


print(“Connected to client")

try:
while True:
msg = raw_input(“Message to send: “)
client.send(msg)
data = client.recv(1024)
print(“Received msg:", data)

except KeyboardInterrupt:
print(“\nClosing connection to client")
sock.close()

Figure 14.9 Raspberry Pi program listing

PC Program Listing: The PC program listing is shown in Figure 14.10 (program: client.
py). The program creates a socket and connects to the server. Then, messages are ex-
changed between the client and the server.

#=============================================================
# TCP/IP CLIENT
# =============
#
# This is the client program on the PC.The program exchanges
# messages with the server on the Raspberry Pi
#
# Author: Dogan Ibrahim
# File : client.py
# Date : August 2019
#=============================================================
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((“192.168.1.202", 5000))

try:
while True:

● 247
Learning Python with Raspberry Pi

msg = sock.recv(1024)
print(“Received message: “, msg)
data = raw_input(“Enter message to send: “)
sock.send(data)

except KeyboardInterrupt:
print(“Closing connection to server")
sock.close()

Figure 14.10 PC program listing

The steps to run the program is as follows:

• Run the server program on the Raspberry Pi


• Run the client program on the PC
• Write messages as desired

Figure 14.11 shows a typical run of the two programs.

Figure 14.11 Example run of the program

Note: You may find that after exiting the program you may not be able to run it again. This
is because the socket stays open for about 30 seconds and the error message saying that
the Address is already in use may be displayed. You can check the state of the port with
the following command:

pi@raspberrypi:~ $ netstat –n | grep 5000

If the display includes the text ESTABLISHED then it means that the socket has not been
closed properly and you will have to restart your Raspberry Pi to run the program again. If
on the other hand, you see the message with TIME_WAIT then you should wait about 30
seconds before re-starting the program.

● 248
Chapter 14 • Python and the Internet on Raspberry Pi 4

14.3.3 Case Study 31 – C  ontrolling an LED Connected to Raspberry Pi


From Mobile Phone Using TCP/IP
Description: In this case study an LED is connected to the Raspberry Pi as in Figure 13.2.
The LED is turned ON and OFF by sending commands ON and OFF respectively from an
Android mobile phone.

Aim: The aim of this project is to show how an LED on the Raspberry Pi can be controlled
from an Android mobile phone by sending commands using the TCP/IP protocol over an
Wi-Fi link.

Background Information: In this case study the Raspberry Pi is the server and the mo-
bile phone is a client. Figure 14.12 shows the case study setup.

Figure 14.12 Case study setup

Raspberry Pi Program Listing: Figure 14.13 shows the program listing (program:
serverled.py). As in the previous program, a socket is created and port 5000 is used. The
server waits for a connection from the client and then accepts the connection. It then waits
to receive a command from the client. If the command is ON then the LED is turned ON. If
on the other hand the command is OFF then the LED is turned OFF. Sending command X
terminates the server connection.

#=============================================================
# CONTROL LED FROM MOBILE PHONE
# =============================
#
# In this program TCP/IP is used where Raspberry Pi is the
# server and mobile phone is the client. An LED connected to
# Raspberry Pi is controlled from mobile phone
#
# Author: Dogan Ibrahim
# File : serverled.py
# Date : August 2019
#===============================================================

● 249
Learning Python with Raspberry Pi

import socket
import RPi.GPIO as GPIO
import time

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(2, GPIO.OUT)

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


sock.bind(("192.168.1.202", 5000))
sock.listen(1)
client, addr = sock.accept()

data = [' '] * 10


while data[0] != 'X':
data = client.recv(1024)
if data[0] == 'O' and data[1] == 'N':
GPIO.output(2, 1)
elif data[0] == 'O' and data[1] == 'F' and data[2] == 'F':
GPIO.output(2, 0)

print("Closing connection")
GPIO.cleanup()
sock.close()

Figure 14.13 Program listing

The program is tested using the Android apps TCP/UDP TEST TOOL used in the previous
project. The server program started, then the client is started. Figure 14.14 shows sending
the ON command to turn ON the LED.

● 250
Chapter 14 • Python and the Internet on Raspberry Pi 4

Figure 14.14 Command sent to turn ON the LED

14.4 UDP Based Communication


As it has been discussed earlier in this chapter, UDP is not a reliable data exchange protocol
and there is no mechanism to check whether or not data has been transferred correctly.
The server and the client communicate through sockets as described by the following PDL
(Program Description Language):

Server
• Create a socket
• Bind the socket to a port with your IP address
• Wait to receive data from a client
• Exchange data (send and receive data) with the client (if required)
• Close the socket

Client
• Create a socket
• Send data to the server
• Exchange data (send and receive data) with the server (if required)
• Close the socket

Note that since there is no connection, the client does not know whether the server is there
or not. The client may send data but the server may not be there to receive this data in
which case the data will be lost. If the client waits to receive data and the server is not
available to send data then the client may have to wait forever. For this reason, we usually
specify a timeout in the client software.

● 251
Learning Python with Raspberry Pi

In the examples in this chapter, the server is the Raspberry Pi, while the client is a PC or a
mobile phone.

14.4.1 Case Study 32 – Sending a Text Message to a Mobile Phone Using UDP
Description: In this case study a UDP based communication is established with an Android
mobile phone. The program reads text messages from the keyboard and sends to the mo-
bile phone.

Aim: The aim of this project is to show how UDP communication can be established with
an Android mobile phone.

Background Information: Figure 14.2 shows the case study setup where the Raspberry
Pi and mobile phone communicate over a Wi-Fi router.

Raspberry Pi Program Listing: In this case study Raspberry Pi is the server and the
mobile phone is the client. Figure 14.15 shows the Raspberry Pi program listing (program:
udpserver.py). At the beginning of the program a UDP socket is created (sock.SOCK_
DGRAM) and is then bind to port 2000. The server program then reads text messages sent
from the mobile phone and displays on the screen. Messages sent by Raspberry Pi are
displayed on the mobile phone.

#==============================================
# SEND TEXT MESSAGES USING UDP
# ============================
#
# This is the UDP server program on Raspberry Pi.
# The program exchanges text messages with an Android
# mobile phone
#
# Author: Dogan Ibrahim
# File : udpserver.py
# Date : August 2019
#================================================
import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)


sock.bind((“192.168.1.202", 2000))

try:
while True:
data, addr = sock.recvfrom(1024)
print(“Received msg:", data)
msg = raw_input(“Message to send: “)
sock.sendto(msg, addr)

except KeyboardInterrupt:

● 252
Chapter 14 • Python and the Internet on Raspberry Pi 4

print(“\nClosing connection to client")


sock.close()

Figure 14.15 Raspberry Pi program listing

The program is tested using the Android apps TCP/UDP TEST TOOL and selecting UDP.
The steps to test the program are as follows:

• Start the server program on Raspberry Pi:

pi@raspberrypi:~ $ python udpserver.py

• Start the mobile phone apps and set the target IP to 192.168.1.202, target port
to 2000, and local port to 5000.

• Write a message on mobile phone apps and click SEND. The message will be
displayed on the Raspberry Pi screen.

• Write a message on Raspberry Pi and this message will be displayed on the mo-
bile phone

• Enter Cntrl+C on Raspberry Pi to close the socket

Figure 14.16 and Figure 14.17 show example displays on the mobile phone and Raspberry
Pi respectively.

Figure 14.16 Example display on mobile phone

● 253
Learning Python with Raspberry Pi

Figure 14.17 Example display on Raspberry Pi

14.4.2 Case Study 33 – C  ontrolling an LED Connected to Raspberry Pi


From Mobile Phone Using UDP
Description: In this case study an LED is connected to the Raspberry Pi as in Figure 13.2.
The LED is turned ON and OFF by sending commands ON and OFF respectively from an
Android mobile phone.

Aim: The aim of this project is to show how an LED on the Raspberry Pi can be controlled
from an Android mobile phone by sending commands using the UDP protocol over a Wi-Fi
link.

Background Information: In this case study the Raspberry Pi is the server and the mo-
bile phone is a client. Figure 14.12 shows the case study setup.

Raspberry Pi Program Listing: Figure 14.18 shows the program listing (program: ud-
pled.py). As in the previous program, a socket is created the server waits to receive com-
mands from a client to control the LED. If the command is ON then the LED is turned ON.
If on the other hand, the command is OFF, the LED is turned OFF. Command X terminates
the server program.

#=============================================================
# CONTROL LED FROM MOBILE PHONE
# =============================
#
# In this program UDP is used where Raspberry Pi is the
# server and mobile phone is the client. An LED connected to
# Raspberry Pi is controlled from mobile phone
#
# Author: DOgan Ibrahim
# File : udpled.py
# Date : August 2019
#===============================================================
import socket
import RPi.GPIO as GPIO
import time

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(2, GPIO.OUT)

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

● 254
Chapter 14 • Python and the Internet on Raspberry Pi 4

sock.bind(("192.168.1.202", 2000))

data = [' '] * 10


while data[0] != 'X':
data, addr = sock.recvfrom(1024)
if data[0] == 'O' and data[1] == 'N':
GPIO.output(2, 1)
elif data[0] == 'O' and data[1] == 'F' and data[2] == 'F':
GPIO.output(2, 0)

print("Closing connection")
GPIO.cleanup()
sock.close()

Figure 14.18 Raspberry Pi program listing

The program can be tested using the TCP/UDP TEST TOOL apps on the mobile phone as
in the previous case study.

14.5 Using Flask to Create a Web Server to Control Raspberry Pi GPIO Ports
From the Internet
Flask is a simple micro-framework written in Python for Python. It is free of charge and can
be used to create a web server on Raspberry Pi to control its GPIO ports over the internet.
The nice advantage of Flask is that it does not require special tools or libraries, has no da-
tabase or any other third party libraries.

Flask should already be available in Python on your Raspberry Pi, but if not, it can be in-
stalled on Raspberry Pi with the following command:

pi@raspberrypi:~ $ sudo apt-get install python-flask

It will be a good idea to create a new folder on your Raspberry Pi and store all of your flask
related documents there. Let's create a folder called MyFlask under our default directory
/home/pi:

pi@raspberrypi:~ $ mkdir MyFlask

Make MyFlask your default directory:

pi@raspberrypi:~ $ cd MyFlask

We are now ready to create our first web server application using Flask. Use the nano editor
and create a file called test.py with the following lines in it:

from flask import Flask # import module flask


app = Flask(__name__) # create a flask object called app

● 255
Learning Python with Raspberry Pi

@app.route('/')
def index(): # run index when called
return 'Hello from Flask' # msg to display when run

if __name__ == '__main__':
app.run(debug=True, port=80, host='0.0.0.0') # listen on port 80

Now, run the above program:

pi@raspberrypi:~ $ sudo python test.py

You should see messages similar to the ones shown in Figure 14.19.

Figure 14.19 Flask messages

Now, open a web browser from a computer connected to the same Wi-Fi router and enter
the IP address of your Raspberry Pi, in this example 192.168.1.202. You should see the
Hello from Flask message appear on a web page as shown in Figure 14.20.

Figure 14.20 Message on the web page

We can now create an HTML page and pass variables from a Python program. create a
folder called templates under MyFlask, move to directory templates and create a file
called index.html with the following lines (notice that the variables inside the double curly
brackets will have data passed to them from the Python program):

<head>
<title>{{ title }}</title>
</head>
<body>
<h1>Hello from Flask</h1>
<h2>The time on the server is: {{ time }}</h2>
</body>

● 256
Chapter 14 • Python and the Internet on Raspberry Pi 4

We will now modify our test.py program as follows:

from flask import Flask, render_template


import time

app = Flask(__name__)

@app.route('/')

def index():
now = time.ctime()
DataToPass = {
'title' : "TESTING FLASK",
'time': now
}
return render_template('index.html', **DataToPass)

if __name__ == '__main__':
app.run(debug=True, port=80, host='0.0.0.0') # listen on port 80

Current date and time are obtained using function call time.ctime() and is stored in vari-
able now. Then, a dictionary called DataToPass is created and values of title and time are
stored in this dictionary. These values will be passed to the items in double curly brackets in
web page defined by index.html. When the function returns, variables inside the dictionary
are returned to the web browser through the dictionary.

Now, run program test.py, go to a web browser and enter the IP address of your Raspberry
Pi. You should see a display similar to the one shown in Figure 14.21.

Figure 14.21 Web page displaying the date and time

Now that we have learned how to pass variables from a Python program to a web page we
can monitor the status of a GPIO pin, or control a GPIO pin from a web page.

14.5.1 Case Study 34 – W  eb Server - Controlling an LED Connected to


Raspberry Pi Using Flask
Description: In this case study an LED is connected to the Raspberry Pi as in Figure 13.2.
The LED is turned ON or OFF via remote web pages.

Aim: The aim of this project is to show how an LED on the Raspberry Pi can be controlled
from web pages using Flask.

● 257
Learning Python with Raspberry Pi

HTML Template Program Listing: The HTML template index.html in folder /home/
pi/MyFlask/templates is simple and it consists of a title and two buttons: ON and OFF.
The title is in double curly brackets and therefore it expects data to be passed to it from
Python. Two buttons are defined called LED ON and LED OFF with green and red colours
respectively, the LED ON button having reference /LED/on and LED OFF having refer-
ence /LED/off. Figure 14.22 shows the program listing.

<head>
<title>{{ title }}</title>
</head>

<body>
<h3>
<a href="/LED/on"><button type="button"><font color="green">LED ON</
button></a>
<a href="/LED/off"><button type="button"><font color="red">LED OFF</
button></a>
</h3>
</body>

Figure 14.22 HTML template program listing

Raspberry Pi Program Listing: Figure 14.23 shows the Python program listing on Rasp-
berry Pi in folder /home/pi/MyFlask (program: test.py). The program has the basic
Flask type template as shown earlier with some additional code. Port pin GPIO 2 is config-
ured as an output and the LED is turned OFF at the beginning of the program. The title to
be passed to index.html is named LED CONTROL and function index is used to pass this
string. Notice that another app.route is created with parameters device and action. In
this example, the device is LED and its actions are on and off. Function action checks the
device and if it is LED then the actuator is set to LED. For every actuator, we must have
an action. If the action is on, the LED is turned ON by the statement GPIO.output(actu-
ator, GPIO.HIGH), otherwise, if the action is off, the LED is turned OFF.

#========================================================
# CONTROLLING LED FROM WEB PAGE
# =============================
#
# This program turns the LED ON or OFF from a web browser
# activated from any computer on the same Wi-Fi router as
# the Raspberry Pi. The LED is controlled by clicking
# buttons when the web page is started
#
# Author: Dogan Ibrahim
# File : test.py
# Date : August 2019
#=========================================================

● 258
Chapter 14 • Python and the Internet on Raspberry Pi 4

from flask import Flask,render_template


import RPi.GPIO as GPIO

app=Flask(__name__)

#
# Define GPIO2 as output and turn OFF LED at beginning
#
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
LED = 2
GPIO.setup(LED, GPIO.OUT)
GPIO.output(LED, 0)

@app.route('/')
def index():
DataToPass = {
'title': "LED CONTROL"
}
return render_template('index.html', **DataToPass)

@app.route("/<device>/<action>")
def action(device, action):
if device == "LED":
actuator = LED

if action == "on":
GPIO.output(actuator, GPIO.HIGH)
if action == "off":
GPIO.output(actuator, GPIO.LOW)
return render_template('index.html')

if __name__ == '__main__':
app.run(debug=True, port=80,host='0.0.0.0')

Figure 14.23 Raspberry Pi program listing

To run the program you should follow the steps given below:

• Connect an LED to GPIO 2 through a current limiting resistor

• Run program test.py

pi@raspberrypi:~/MyFlask $ sudo python test.py

• You should see a screen similar to the one shown in Figure 14.19

● 259
Learning Python with Raspberry Pi

• Activate a web browser from a computer connected to the same Wi-Fi router and
enter the IP address of your Raspberry Pi. As shown in Figure 14.24, you should
see two buttons to control the LED. Clicking the buttons turns the LED ON or OFF.

Figure 14.24 Controlling the LED from a web page

• Terminate your program by entering Cntrl+C.

Modified Program
You could remove file index.html from the case study and use only test.py to control the
LED. The modified program (test2.py) is shown in Figure 14.25. To control the LED, you
should enter the following web commands after starting test2.py:

• To turn the LED ON: 192.168.1.202/LED/on


• To turn the LED OFF: 192.168.1.202/LED/off

#========================================================
# CONTROLLING LED FROM WEB PAGE
# =============================
#
# This program turns the LED ON or OFF from a web browser
# activated from any computer on the same Wi-Fi router as
# the Raspberry Pi. The commands are (assuming that the IP
# address of Raspberry Pi is: 192.168.1.202):
#
# 192.168.1.202/LED/on turn LED ON
# 192.168.1.202/LED/off turn LED OFF
#
# Author: Dogan Ibrahim
# File : test2.py
# Date : August 2019
#=========================================================
from flask import Flask,render_template
import RPi.GPIO as GPIO

app=Flask(__name__)

#
# Define GPIO2 as output and turn OFF LED at beginning

● 260
Chapter 14 • Python and the Internet on Raspberry Pi 4

#
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
LED = 2
GPIO.setup(LED, GPIO.OUT)
GPIO.output(LED, 0)

@app.route("/<device>/<action>")
def action(device, action):
if device == "LED":
actuator = LED

if action == "on":
GPIO.output(actuator, GPIO.HIGH)
return "LED turned ON"
if action == "off":
GPIO.output(actuator, GPIO.LOW)
return "LED turned OFF"

if __name__ == '__main__':
app.run(debug=True, port=80,host='0.0.0.0')

Figure 14.25 Modified program

The modified program displays messages LED turned ON and LED turned OFF. Figure 14.26
shows the web command to turn ON the LED.

Figure 14.26 Turning ON the LED

14.6 Summary
In this chapter, we have learned how to develop programs to communicate with the exter-
nal world over Wi-Fi. We have also learned how to control the GPIO from a web page. In the
next chapter, we shall be looking at the Bluetooth and see how we can develop programs
to communicate using Bluetooth.

● 261
Learning Python with Raspberry Pi

Chapter 15 • B
 luetooth Communication on Raspberry Pi 4
Using Python

15.1 Overview
In the last chapter, we have seen how to communicate with the external world using Wi-
Fi. In this chapter, we will learn how to develop Python programs to communicate using
Bluetooth on our Raspberry Pi 4.

Bluetooth is commonly used to communicate with other devices. All smartphones nowa-
days support communication through Bluetooth. Bluetooth operates at 2.4GHz with data
rates lower than that of Wi-Fi. Bluetooth is not as secure as Wi-Fi but it is easier to use. The
power consumption of Bluetooth is lower compared to Wi-Fi and also it also has a shorter
range.

15.2 Case Study 35 – Bluetooth Control of LED From a Mobile Phone


Description: In this case study, an LED is connected to the Raspberry Pi 4 port GPIO 2
as before and it is controlled by sending commands from an Android mobile phone using
Bluetooth for communication.

The following commands can be sent from the Android mobile phone to control the LED:

L1 Turn the LED ON


L0 Turn the LED OFF

Aim: The aim of this project is to show how the Bluetooth of the Raspberry Pi 4 can be
used in a Python program.

Background Information: Figure 15.1 shows the project setup. An LED is connected to
GPIO 2 through a current limiting resistor.

Figure 15.1 Case study setup

In this case study, we shall be sending commands from an Android mobile phone to our
Raspberry Pi 4. We must, therefore, first of all, enable Bluetooth from the Settings menu
on our Android device.

● 262
Chapter 15 • Bluetooth Communication on Raspberry Pi 4 Using Python

There are two ways you can enable Bluetooth on the Raspberry Pi 4: using graphical desk-
top (GUI mode), or using the command mode.

Using the Graphical Desktop


The steps for enabling Bluetooth on the Raspberry Pi 4 using the graphical desktop are
given below:

• Start the VNC server on your Raspberry Pi 4 and login using the VNC Viewer.

• Click on the blue Bluetooth icon on your Raspberry Pi 4 screen at the top right-
hand side, and turn Bluetooth ON, if it is not already ON. Then, select Make
Discoverable. You should see the Bluetooth icon flashing.

• Select raspberrypi in the Bluetooth menu (raspberrypi is the default Bluetooth


name of your Raspberry Pi 4) on your mobile device (you may have to scan on
your mobile device). You should see the Connecting message on your mobile
device.

• Accept the pairing request on your Raspberry Pi 4 as shown in Figure 15.2

Figure 15.2 Bluetooth pairing request on Raspberry Pi

• You should now see the message Connected Successfully on your Raspberry
Pi 4

Using Command Mode


You can enable Bluetooth on your Raspberry Pi 4 using the command mode. Additionally,
you can make Bluetooth discoverable, scan for nearby Bluetooth devices and then connect
to a Bluetooth device. The steps are given below (characters types by the user are in bold
for clarity):

• Make your Bluetooth discoverable with the following command:

pi@raspberrypi: ~ $ sudo hciconfig hci0 piscan

• Start the Bluetooth tool on your Raspberry Pi 3 from the command mode:

pi@raspberrypi:~ $ bluetoothctl

● 263
Learning Python with Raspberry Pi

• Turn Bluetooth ON:

[bluetooth]# power on

• Configure Bluetooth to run:

[bluetooth]# agent on
[bluetooth]# default-agent

• Make device discoverable:

[bluetooth]# discoverable on

• Scan for nearby Bluetooth devices, you may have to wait several minutes:

[bluetooth]# scan on

• Enter command devices to see nearby Bluetooth devices (see Figure 15.3).
Make a note of the MAC address of the device you wish to connect to (Android
mobile phone in this case study) as we will be using this address to connect to
the device. An example is shown in Figure 15.3:

[Bluetooth]# devices

Figure 15.3 Nearby Bluetooth devices

In this example our mobile phone is MyAndoid and the Bluetooth MAC address
is: B4:CD:27:15:68:7B

• Pair the device:

[bluetooth]# pair B4:CD:27:15:68:7B

• Connect to our mobile phone:

[bluetooth]# connect B4:CD:27:15:68:7B

• Exit from the Bluetooth tool by entering Cntrl+Z

● 264
Chapter 15 • Bluetooth Communication on Raspberry Pi 4 Using Python

You can find the Bluetooth MAC address of your Raspberry Pi 4 by entering the
following command:

pi@raspberrypi:~ $ hciconfig | grep "BD Address"

You can change the Bluetooth broadcast name by the following command:

pi@raspberrypi:~ $ sudo hciconfig hci0 name "new name"

To see your Bluetooth broadcast name, enter:

pi@raspberrypi:~ $ sudo hciconfig hci0 name

Some other useful Raspberry Pi 4 Bluetooth commands are:

• To reset Bluetooth adapter: sudo hciconfig hci0 reset


• To restart Bluetooth: sudo invoke-rc.d bluetooth restart
• To list Bluetooth adapters: hciconfig

You can find the Bluetooth MAC address of your Android phone as follows:

• Go to the Settings menu


• Tap About Phone
• Tap Status
• Scroll down to see your Bluetooth address

Python Bluetooth Library


You will need to install the Python Bluetooth library before developing your program. This
is done by entering the following command in the command mode:

pi@raspberrypi:~ $ sudo apt-get install bluez python-bluez

Accessing From the Mobile Phone


In order to be able to access the Raspberry Pi 4 from a mobile phone apps make the fol-
lowing changes to your Raspberry Pi 4 from the command line:

• Start nano to edit the following file:

pi@raspberrypi:~ $ sudo nano /etc/systemd/system/dbus-org.bluez.


service

• Add –C at the end of the ExecStart= line. Also add another line after the Exec-
Start line. The final two lines should look like:

ExecStart=/usr/lib/bluetooth/bluetoothd -C
ExecStartPost=/usr/bin/sdptool add SP

● 265
Learning Python with Raspberry Pi

• Exit and save the file by entering Ctrl+X followed by Y

• Reboot Raspberry Pi 4:

pi@raspberrypi:~ $ sudo reboot

Android Bluetooth Apps


In this project, we will be sending commands to the Raspberry Pi 4 from an Android-based
mobile phone. We, therefore, need an application on our mobile phone where we can
send data through Bluetooth. There are many such applications free of charge in the An-
droid Play Store. The one chosen by the author is called Bluetooth Terminal HC-05 by
mightyIT (see Figure 15.4). You should install this application (or a similar one) on your
Android phone so that you can send commands to your Raspberry Pi 4.

Figure 15.4 Android Bluetooth apps

Program Listing: Figure 15.5 shows the program listing of the project (program: blue.
py, do not call your program Bluetooth.py!). The Bluetooth code is similar to TCP/IP code.
At the beginning of the program modules socket, RPi.GPIO, and Bluetooth are imported to
the program. The LED port is defined and configured as output. The program then creates
a Bluetooth socket, binds and listens on this socket, and then waits to accept a connection.
The remainder of the program is executed in a loop where the program issues statement
ClientSock.recv and waits to read data from the mobile phone. The received data is de-
coded and the LED is turned ON or OFF as requested.

#=======================================================
# LED CONTROL BY BLUETOOTH
# ========================
#
# In this Case Study an LED is connected to GPIO 2.The
# LED is controlled by sending commands from an Android

● 266
Chapter 15 • Bluetooth Communication on Raspberry Pi 4 Using Python

# mobile phone using a Bluetooth apps.


#
# Valid comamdns are:
# L1 Turn ON the LED
# L0 Turn OFF the LED
#
# Author: Dogan Ibrahim
# File : blue.py
# Date : August 2019
#========================================================
import socket
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
import bluetooth

#
# LED is on GPIO 2, configure as output and turn OFF
#
LED = 2
GPIO.setup(LED, GPIO.OUT)
GPIO.output(LED, 0)

#
# Start of main program loop.Configure Bluetooth, create a
# port, listen for client connections, and accept connection
#
port = 1
ServerSock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
ServerSock.bind(("", port))
ServerSock.listen(1)
ClientSock, addr = ServerSock.accept()

#
# Now receive comamnds and decode
#
while True:
data = ClientSock.recv(1024) # receive command
if data[0] == 'L': # first char L?
if data[1] == '1': # second char 1?
GPIO.output(LED, 1) # turn ON LED
elif data[1] == '0': # second char 0?
GPIO.output(LED, 0) # turn OFF LED

Figure 15.5 Program listing

● 267
Learning Python with Raspberry Pi

To send command L1, enter L1 and click Send ASCII as shown in Figure 15.6. Notice that
you must start the Raspberry Pi 4 program before starting the mobile application.

Figure 15.6 Mobile application

You could enter the program name in the following format inside file /etc/rc.local so that
the program starts automatically every time the Raspberry Pi 4 re-starts:

python /home/pi/bluet.py &

When you finish your project don't forget to remove the above line from file /etc/rc.local,
otherwise the program will run every time your Raspberry Pi 4 is re-started. You should
also shut down your Raspberry Pi 4 orderly instead of just removing the power cable. The
command to shut down orderly is:

pi@raspberrypi:~ $ sudo shutdown now

15.3 Summary
In this chapter, the use of the Raspberry Pi 4 Bluetooth module from a Python program
has been described with a simple case study. Readers should find it easy to expand this
program for their own needs

● 268
Appendix A • Using wxPython Graphical User Interface

Appendix A • Using wxPython Graphical User Interface

There are several graphics packages that can be used with the Python programming lan-
guage. The most important ones are Tkinter, wxPython, and PyQt. We have seen in an
earlier chapter how to use the Tkinter in graphics-based applications. In this Appendix we
shall be looking briefly at the details of wxPython with some simple examples. Interested
readers can get further information on wxPython from the following web site. There are also
many example codes and tutorials on wxPython on the internet.:

www.wxpython.org

wxPython is an easy to use Graphical User Interface package that supports buttons, win-
dows, slides, spinboxes, paintboxes, and many other widgets. wxPython is basically a Py-
thon wrapper that was released in 1998, so it is well established and has been around for
very long time. wxPython includes large number of widgets. Interested readers can find out
about the various widgets in the following link:

https://wxpython.org/Phoenix/docs/html/gallery.html

In this Appendix, we will be using wxPython version 4, also known as the Phoenix release.
Earlier versions of wxPython were built for Python version 2, but version 4 is compatible
both with Python 2 and Python 3. To install wxPython on your Raspberry Pi, enter the
following command (Depending on your processor power, it may take a long time for this
command to complete):

pi@raspberrypi:~ $ pip install -U –f \ https://extras.wxpython.org/


wxPython4/extras/linux/gtk3/ubuntu-16.04 wxPython

A.1 wxPython Template


The easiest way to use wxPython is by using a template and then adding our own code to
this template. Figure A.1 shows the simplest wxPython template (program: temp.py). The
place where we should insert our own code is shown in the program. All the graphics based
programs must run from the Desktop. You can either connect a monitor to your Raspberry
Pi, or use the vncserver and vncViewer to access the Desktop and run the program from
the Terminal application in Desktop.

import wx

class Interface(wx.Frame):

def __init__(self, parent):


super(Interface, self).__init__(parent)
self.setup()
self.Show()

def setup(self):

● 269
Learning Python with Raspberry Pi

self.SetTitle("wxPython Application")
self.SetBackgroundColour('white')
self.Centre()
self.SetSize(300,400)

#
# Put your own Code here
#

if __name__ == '__main__':
app = wx.App()
Interface(None)
app.MainLoop()

Figure A.1 wxPython Program template

Figure A.2 Display generated when the template program is run

Now that we have a template, we can create some example GUI based programs with
wxPython.

A.2 Some Example Widgets


Some example widgets are given in this section.

Example 1 – Static Text Widgets


Write a program to create the static text widget to display the message Hello from wx-
Python

Solution 1
The program listing is shown in Figure A3 (program stext.py). The template is used and
our code is placed after the comment Put your own code here.

StaticText widget has the following parameters:

wx.StaticText(parent, id, label, position, size, style)

● 270
Appendix A • Using wxPython Graphical User Interface

where the style can take the values:

wx.ALIGHN_LEFT
wx.ALIGHT_RIGHT
wx.ALIGN_CENTER
wx.ST_NO_AUTORESIZE

Here, the message is displayed at position (50, 50), in 10 point, Roman characters, Normal
style, and BOLD. Font has the following parameters:

wx.Font(pointSize, family, style, weight, underline=False, faceName="",


encoding=wx.FONTENCODING_DEFAULT)

family can be:


wx.DECORATIVE, wx.DEFAULT,wx.MODERN, wx.ROMAN, wx.SCRIPT or wx.SWISS.

style can be:


wx.NORMAL, wx.SLANT or wx.ITALIC.

weight can be:


wx.NORMAL, wx.LIGHT, or wx.BOLD

import wx

class Interface(wx.Frame):

def __init__(self, parent):


super(Interface, self).__init__(parent)
self.setup()
self.Show()

def setup(self):
self.panel=wx.Panel(self)
self.SetTitle("wxPython Application")
self.SetBackgroundColour('white')
self.Centre()
self.SetSize(300,300)

#
# Put your own Code here
#
text = wx.StaticText(self, label="Hello from wxPython",pos=(50,50))
font = wx.Font(10, wx.ROMAN, wx.NORMAL, wx.BOLD)
text.SetFont(font)

if __name__ == '__main__':

● 271
Learning Python with Raspberry Pi

app = wx.App()
Interface(None)
app.MainLoop()

Figure A.3 Program listing

Figure A.3 shows the static text display.

Figure A.4 The static text displayed

Example 2 – Button Widget


Create a button widget such that when it is clicked the message I am clicked is displayed.

Solution 2
Figure A.5 shows the program listing (program: button.py). In this program, the same
template as before is used but the background colour is set to yellow. When the button is
clicked, function OnClicked is called. This function implements a Static Text which dis-
plays the message I am clicked as shown in Figure A.6.

Button widget has the following parameters:

wx.Button(parent, id, label, pos, size, style)

import wx

class Interface(wx.Frame):

def __init__(self, parent):


super(Interface, self).__init__(parent)
self.setup()
self.Show()

def setup(self):

● 272
Appendix A • Using wxPython Graphical User Interface

self.panel=wx.Panel(self)
self.SetTitle("wxPython Application")
self.SetBackgroundColour('yellow')
self.Centre()
self.SetSize(400,400)
#
# Put your own Code here
#
butn = wx.Button(self, label = "Click Me", pos=(80,80))
butn.Bind(wx.EVT_BUTTON, self.OnClicked)

def OnClicked(self, event):


text = wx.StaticText(self, label="I am clicked", pos=(50,50))
font = wx.Font(10, wx.ROMAN, wx.NORMAL, wx.BOLD)
text.SetFont(font)

if __name__ == '__main__':
app = wx.App()
Interface(None)
app.MainLoop()

Figure A.5 Program listing

Figure A.6 Button with Static Text

Example 3 – Slider
Write a program to display a slider between 1 and 100.

Solution 3
Figure A.7 shows the program listing (program: slider.py). A slider can be Horizontal or
Vertical. For example, a Horizontal slider has the following parameters:

wx.Slider(parent, id, value, minValue, maxValue, pos=wxDefaultPosition,


size=wx.DefaultSize, style=wx.SL_HORIZONTAL, validator=wx.DefaultValidator,
name="slider")

● 273
Learning Python with Raspberry Pi

The style parameter can have the values shown in Table A.1.

If set, the slider will display tick marks across it. The spacing is governed
wx.SL_AUTOTICKS
by the setter method SetTickFreq.

wx.SL_HORIZONTAL The slider will be horizontal. This is the default.

If set, the slider will display labels for the minimum and maximum value,
wx.SL_LABELS and a read-only display of the current value. The current value might not
display on all platforms.

wx.SL_LEFT For a vertical slider, the ticks will be on the left of the slider.

wx.SL_RIGHT For a vertical slider, the ticks will be on the right of the slider.

wx.SL_TOP For a horizontal slider, the ticks will be on top of the slider.

wx.SL_VERTICAL The slider will be vertical.

Table A.1 Style parameter values

import wx

class Interface(wx.Frame):

def __init__(self, parent):


super(Interface, self).__init__(parent)
self.setup()
self.Show()

def setup(self):
self.panel=wx.Panel(self)
self.SetTitle("wxPython Application")
self.SetBackgroundColour('white')
self.Centre()
self.SetSize(300,300)
#
# Put your own Code here
#
slider = wx.Slider(self, 100, 25, 1, 100,
pos=(20,20),size=(250,-1),style=\
wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS)

if __name__ == '__main__':
app = wx.App()
Interface(None)
app.MainLoop()

Figure A.7 Program listing

● 274
Appendix A • Using wxPython Graphical User Interface

Figure A.8 Slider

We can bind an event to a slider and get the value of the slider in this event. This is shown
in the next example.

Example 4 – Slider Value


Write a program to bind an event to a slider widget and display the value of the slider on
the screen.

Solution 4
Figure A.9 shows the program listing (program: sliderevent.py). Function GetValue re-
turns the slider values (it actually returns the current slider value) as shown in the pro-
gram. An example display is shown in Figure A.10 where the slider positions are displayed
as the slider arm is moved.

import wx

class Interface(wx.Frame):

def __init__(self, parent):


super(Interface, self).__init__(parent)
self.setup()
self.Show()

def setup(self):
self.panel=wx.Panel(self)
self.SetTitle("wxPython Application")
self.SetBackgroundColour('white')
self.Centre()
self.SetSize(300,300)
#
# Put your own Code here
#
slider = wx.Slider(self, 100, 25, 1, 100,
pos=(20,20),size=(250,-1),style=\
wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS)
slider.Bind(wx.EVT_SLIDER, self.OnSliderScroll)

def OnSliderScroll(self, event):


obj = event.GetEventObject()

● 275
Learning Python with Raspberry Pi

val = obj.GetValue()
print(val)

if __name__ == '__main__':
app = wx.App()
Interface(None)
app.MainLoop()

Figure A.9 Program listing

Figure A.10 Displaying slider positions

A.3 Case Study 36 – Display the Raspberry Pi 4 CPU Temperature


Using wxPython

Description: In this case study, the CPU temperature of Raspberry Pi 4 is read every 5
seconds and is displayed on a graphical screen using wxPython.

Aim: The aim of this project is to show how an item (temperature in this case) can be dis-
played and updated at frequent intervals on a wxPython widget.

Background Information: There are several ways that the Raspberry Pi 4 CPU tempera-
ture can be obtained (e.g. see case study 12, chapter 8.4). In this case study, we will obtain
the CPU temperature using the following simple statements:

>>> from gpiozero import CPUTemperature


>>> cpu = CPUTemperature()
>>> cpu.temperature
42.5

● 276
Appendix A • Using wxPython Graphical User Interface

Program Listing: In this program, we will create a timer that invokes a function called
GetTemperature every 5 seconds. The temperature is read, converted into string, letter
C added, and displayed by a Static Text widget. In addition, the heading CPU TEMPERA-
TURE: is displayed using another Static Text widget. Figure A.11 shows the program listing
(program: tempwidget.py). The output of the program is shown in Figure A.12.

import wx
from gpiozero import CPUTemperature

class Interface(wx.Frame):

def __init__(self, parent):


super(Interface, self).__init__(parent)
self.setup()
self.Show()

def setup(self):
self.panel=wx.Panel(self)
self.SetTitle("RPI 4 CPU TEMPERATURE")
self.SetBackgroundColour('white')
self.Centre()
self.SetSize(400,450)
#
# Put your own Code here
#
# Create a timer, bind it to function OnTimer, and start the timer
# at every 10 seconds
#
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
self.timer.Start(5000)
#
# Create a Static Text to display a heading
#
t = wx.StaticText(self, label="CPU TEMPERATURE:", pos=(110,120))
fnt = wx.Font(10,wx.DECORATIVE, wx.NORMAL, wx.BOLD)
t.SetFont(fnt)
#
# Create a Static Text to display temperature
#
self.text = wx.StaticText(self, label='', pos=(100,150))
font = wx.Font(24, wx.ROMAN, wx.NORMAL, wx.BOLD)
self.text.SetFont(font)

def OnTimer(self, event):


cpu = CPUTemperature()

● 277
Learning Python with Raspberry Pi

cpu = cpu.temperature
temp = str(cpu) + " C"
self.text.SetLabel(temp)

if __name__ == '__main__':
app = wx.App()
Interface(None)
app.MainLoop()

Figure A.11 Program listing

Figure A.12 Output of the program

● 278
Appendix B • Object-oriented Programming

Appendix B • Object-oriented Programming

Traditional programming is procedural where programs are developed using block of state-
ments to manipulate the data. The new generation of programming is called object ori-
ented programming where data and functionality are combined and wrapped inside called
objects. Although procedural programming is still widely used, writing large programs is
easier and better suited to the object-oriented programming (OOP) techniques.

In OOP, classes and objects are the main concepts. Classes create new types, where ob-
jects are the instances of the classes. Classes can have functions called methods of the
class. Variables belonging to a class are called fields. The fields and methods of a class are
referred to as the attributes of that class.

Python supports both procedural and object-oriented programming. In this book, we have
programmed using only procedural techniques. In this appendix, we will be learning the
basic principles of OOP with Python. Interested readers can find many tutorials, books, and
articles on the internet.

B.1 Classes and Methods


Creating a class is simple. All we have to do is use the keyword class, followed by a name.
The methods and fields of the class are then indented:

class Car:

Methods are just like functions, except we have the additional variable called self. An ex-
ample is shown below:

class Car:
def msg(self):
print("Hello from class")

c = Car()
c.msg()

The output of this code will be:

Hello from class


We could have also used the command:
Car().msg()

Initialization
We may want to initialize some variables when a class is created. This is done using double
underscores at the beginning and end of the name init and specifying the variable to be
initialized. An example is given below where model takes the value Mercedes. Notice in
this code that we do not call function init, this is done automatically:

● 279
Learning Python with Raspberry Pi

class Car:
def __init__(self, model):
self.model = model

def msg(self):
print("My car is: ", self.model)

c = Car("Mercedes")
c.msg()

The output of this code will be:

('My car is: ', 'Mercedes')

We could have also used the command:

Car("Mercedes").msg()

B.2 Variables
Variables in OOP can be class variables or object variables. Class variables are shared by all
instances of the class. Object variables, on the other hand, are local to each method in the
class. An example is given below:

class Car:
count = 0

def __init__(self, model):


self.model = model
Car.count += 1
print(Car.count)

def dec(self):
print("My car is: ", self.model)
Car.count -= 1
print(CAR.count)

def zero(self):
Car.count = 0
print(Car.count)

c = Car("Mercedes")
c.dec()
c.dec()
c.zero()

● 280
Appendix B • Object-oriented Programming

In this example, count is a class variable and is accessible from all methods of the class.
Running the program given the following display:

1
0
-1
0

B.3 Inheritance
OOP has the advantage that code can be re-used through what is called inheritance. Sup-
pose you want to write a program to keep track of professional employees and secretaries
in a firm. These people may have some common characteristics such as name, age, and
address. There are also some specific characteristics such as their salaries, training courses
they attended, etc. One way will be to write two independent classes and adding common
characteristics. Instead of this, we could create a common class and then have the profes-
sional employee class and secretaries class inherit from this common class. The advantage
of using this method through inheritance is that any changes to the common class will be
automatically reflected in both classes.

An example is given below to illustrate how inheritance works.

Example 1
Write an OOP to have two classes called Shape and Rectangle. Class Shape will accept
the sides of a polygon type shape from the keyboard as floating-point numbers. Class
Rectangle will inherit the sides from class Shape and calculate and display the area of a
rectangle.

Solution 1
Figure B1 shows the program listing (program: inheritoop.py). Class Shape has 2 meth-
ods: GetSides and DisplaySides. Method GetSides reads the sides of the shape, while
DisplaySides displays the sides of the shape. Class Rectangle inherits the sides as a and
b and calculates the area by multiplying a with b. The area is then displayed on the screen
as shown in Figure B.2.

class Shape:
def __init__(self, number_of_sides):
self.no = number_of_sides
self.sides = [0 for i in range(self.no)]
print("Number of sides=%d" %(self.no))

def GetSides(self):
for i in range(self.no):
x = float(raw_input("Enter side %d: " %(i+1)))
self.sides[i] = x

def DisplaySides(self):

● 281
Learning Python with Raspberry Pi

for i in range(self.no):
print("Side %f: " %(self.sides[i]))

class Rectangle(Shape):
def __init__(self):
Shape.__init__(self, 2)

def Area(self):
a, b = self.sides
area = a * b
print("Area of rectangle=%f" %area)

r=Rectangle()
r.GetSides()
r.DisplaySides()
r.Area()

Figure B.1 Program listing

Figure B.2 Output of the program

● 282
INDEX

INDEX

A Expression operators 55
Active filter 214
Array operations 155 F
Array multiplication 156 Files 140
Attenuator design 100, 103 Flask 255
float 54
B for statement 66
Bar chart 129 frequency response 146
Bitwise operators 55
Blank lines 52 G
Bluetooth 262 GPIO 222
BJT transistor 203 Grid 180
break statement 69
Button 173 H
head 38
C HDMI 14
cal 36 High-pass filter 219
Check box 185
chmod 33 I
Collector feedback biasing 203 I2C 229
comments 52 Ifconfig 23
continue statement 68 Indentation 53
Copying arrays 157 Inductance 200
cp 36 int 54
CPU fan 16
CPU temperature 148 K
Critically damped mode 136 Keyboard input 64
CSI 14 Keyboard interrupt 109

D L
Data types 53 Label 170
date 36, 113 LCD 230
df 42 Linear algebraic equations 157
Dialogs 187 List variables 61
Dictionary variables 63 Logical operators 65
dpkg 40 long 54
DSI 14 low-pass active filter 214
ls 30
E
echo 37 M
Entry 179 man 35
Escape sequences 59 matplotlib 117
Ethernet 14 Matrix operations 155
Exceptions 106 Mathematical functions 55

● 283
Learning Python with Raspberry Pi

MCP3002 235 Strings 57


Menu 192 String functions 58
Message 178
Mesh analysis 160 T
mkdir 31 tail 38
modules 115 TCP/IP 242
TCP client 244
N TCP server 244
nano 44 Temperature sensor 234
Node analysis 165 Thonny 49
NOOBS 19 time 36, 113
Tkinter 169
O Transient RL circuit 135
Object oriented programming 279 Transistor amplifier 208
Overdamped mode 138 Trigonometric functions 78
try/finally 108
P Tuple variables 62
pass statement 69
Pie chart 127 U
Pin numbering 223 UDP 251
print statement 60 Underdamped mode 136
ps 42 USB keyboard 15
Putty 25 USB memory stick 150
pwd 30 USB port 14
PWM 227 User defined function 79

R V
Radio button 181 Variable names 51
RC transient circuit charging 130 vncserver 28
RC transient circuit discharging 132 Voltage divider biasing 205
Recursive functions 105
Resonance 196 W
Remote access 24 Web server 257
Reserved words 52 while statement 68
Resistive potential divider 76 whoami 39
Resistor colour code 70, 72 wxPython 269
RLC transient circuit 136
rm. 37 Z
rmdir 37 Zener diode 108

S
Series and parallel resistors 74
Serial port 238
SPI 233
Slider 190
SSH 24

● 284
For Electronics Engineers
Learning Python with
Raspberry Pi

This book is about teaching the Python programming language


using the Raspberry Pi 4 computer. The book makes an
introduction to Raspberry Pi 4 and then teaches Python with
the topics: variables, strings, arrays, matrices, tuples, lists,
dictionaries, user functions, flow of control, printing, keyboard
input, graphics, GUI, object oriented programming and many
more topics. The book is aimed for beginners, students,
Prof. Dr. Dogan practising engineers, hobbyists, and for anyone else who may
Ibrahim has a BSc. in want to learn to program in Python. The book includes many
Electronic Engineering, example programs and case studies. All the example programs
an MSc. in Automatic and case studies have been tested fully by the author and are
Control Engineering, all working. The example programs aim to teach the various
and a Ph.D. in Digital programming concepts of Python. The case studies cover the
Signal Processing. use of Python in the analysis and design of electronic circuits.
He worked in many Some of the case study topics are:
industrial organisations
before returning to • Resistor colour code identification
academia. Prof. Ibrahim • Resistive potential divider circuits
is the author of over 60 • Resistive attenuator design
technical books and over • Zener diode voltage regulator design
200 technical articles • RC and RLC transient circuits
on microcontrollers, • Circuit frequency response
microprocessors, and • Saving data on external memory stick
related fields. He is a
• Mesh and node circuit analysis using matrices
Chartered Electrical
• Resonance in RLC circuits
Engineer and a Fellow
• Transistor Biasing analysis
of the Institution of
• Transistor amplifier design
Engineering Technology.
• Design of active filters
• Interfacing hardware with GPIO, I2C and SPI
ISBN 978-1-907920-80-6 • Using Wi-Fi with Python and TCP/IP and UDP programs
• Using Bluetooth from Python

Full program listings of all the programs used in the book are
available at the Elektor website of the book. Readers should be
able just to copy and use these programs in their Raspberry Pi
Elektor International Media BV
projects without any modifications.
www.elektor.com

LEARN DESIGN SHARE

● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEA
IGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● D
HARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN
N ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEA
SIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● D

You might also like