Escolar Documentos
Profissional Documentos
Cultura Documentos
4 FLAPS: 0
PYTHON 3 - PROGRAMMING
FOR ELECTRONICS ENGINEERS
PYTHON 3
PROGRAMMING AND GUIS
PYTHON 3
Andrew Pratt PROGRAMMING AND GUIS
AND
Andrew Pratt served for
that is required to produce Python programs.
25 years in the Royal
Air Force as an Aircraft Hardware interfacing is achieved using an Arduino Uno as
LEARN
LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIG
SHARE
N • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHA
SIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LE
• LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN
RN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SH
Table of Contents
Table of Contents
Chapter 1 Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.6 Redirection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.4 IDLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.6.1 Integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.6.2 Floats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.6.4 Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.6.5 Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.6.6 Tuples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
2.7 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
2.8 Imports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
2.9 Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
●5
Python 3: Programming and GUIs for Electronic Engineers
2.12 Hexadecimal Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
3.2 Tkinter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
3.4 Callbacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.6.2 Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
4.2 Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
4.3 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
●6
Table of Contents
5.2.2 Uploading the Arduino Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
6.2.1 Passing Arguments to a Function without Specifying How Many (*args) . . . 102
●7
Python 3: Programming and GUIs for Electronic Engineers
7.2 The Bit Map File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
●8
Table of Contents
10.2.1 The Wrapper Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
●9
Preface to the Second Edition
● 11
Chapter 1 • Linux
Chapter 1 • Linux
1.1 • Introduction
Linux has been chosen as the OS (operating system) because as you will see as you read
the book you have so much freedom to change things and experiment. If you are already
an experienced Linux user and are used to using the command line you will be familiar
with the contents of this chapter. You might use Linux but never venture away from the
graphic interfaces provided or perhaps you are completely new to Linux. The examples
shown in this book were developed using Debian 8 Jessie, the current stable release.
There are several Debian based distributions available. Two popular examples are Mint
and Ubuntu and if you want to use a Raspberry Pi there is Raspbian.
Here I am assuming that you either have or want to install a Debian based OS. If this is
not the case you could try using a virtual machine such as VirtualBox that will allow you
to keep your existing OS, however this might run slower than is desired. At the time of
writing, Debian can be obtained by download from "https://www.debian.org/distrib/netinst".
It is not difficult to install.
If you are new to Linux things are going to seem strange at first, particularly the file
directories. Throughout the book we are going to be using the command line to access
files and start applications etc. This might seem like a backward step, but the Linux
command line is full of quick short cuts and time saving tricks. Also while writing
programs the same command line statements will sometimes need to be put into the
code.
Find on your Desktop or Applications Menu for your OS the icon for a "Terminal Emulator"
● 13
Chapter 2 • Getting Started with Python
2.1 • Introduction
;prog_02_01.asm //prog_02_01.c
mov eax, 1
int 0x80;
Prog 2-1a (prog_0201.asm) Prog 2-1b (prog_02_01.c)
user@debian:~/programs/chap02_progs$ ./assembler_demo
It’s a lot easier in python!
user@debian:~/programs/chap02_progs$
● 21
Python 3: Programming and GUIs for Electronic Engineers
operating system.
So if that's what a C compiler does, why are we going to need Python? Basically Python
is a whole lot easier to use than C. Python is an interpreted language. The Python
interpreter has to be installed on the computer for the operating system you are using.
Python is a cross platform language. Python takes your script and compiles it into
something called byte code that runs on a virtual machine on your operating system;
this compilation occurs when you start a program. This is slower than a compiled C
program but what is too slow depends on what you’re doing. Python is fast enough for
the applications in this book.
In Python the above programs would be:
To any readers who are new to Python 3 but have some experience of Python2 you will
notice some things have changed, for example the "print 'Hello World'" statement is now
a function and is written as "print('Hello World')". There are other differences.
This book deals with Python 3. Although Python 2 is still widely used, if you are new to
Python you should start with Python 3. First check to see if Python 3 is installed by typing
"python3" at the command line.
user@debian:~$ python3
Python 3.4.2 (default, Oct 8 2014, 13:14:40)
[GCC 4.9.1] on linux
Type “help”, “copyright”, “credits” or “license” for more information.
>>>
This puts you into an interactive session with Python which we will deal with later, so to
escape from this use "Ctrl d", that is to press the Control key and d simultaneously.
Make sure you have Python 3. If not it can be easily installed. While connected to the
Internet, type this at the command line:
One of the really good features of a Debian based Linux OS is the package management
that makes installation and removal of software very easy. Not all Linux distributions are
this easy, notably Slackware. Although my favourite, it can be a lot more work as you
have to manually find and install any other software that the software you are installing is
dependent on. These dependencies can go to several layers.
Open Mousepad by pressing Alt + F2 and entering "mousepad". Alternatively use any
text editor you prefer. Type in the following program (Note how lines two and three are
indented - this is part of the code logic. Although the code is provided typing some of the
programs will help to familiarise you with the language):
● 22
Chapter 3 • Graphic User Interfaces
3.1 • Introduction
As far as functionality is concerned, adequate programs can be written with just the
command line as an interface. However a graphical interface is much more attractive,
offering the usual widgets that most computer users are used to using: buttons, check
buttons, text entry boxes, etc. Python offers a simple way of creating these interfaces for
your programs. Two of the projects later in the book will plot graphs of values derived
from analog quantities being measured. The last chapter will show you another way of
producing GUIs for platforms that have lower resources and do not need the X-server. As
mentioned before, there is no intention of trying to treat any of the topics in the utmost
depth but rather to give the reader a set of useful introductory tools to build projects that
work and give pointers to further learning. Presented here are some simple examples.
The best way to understand them is to run and experiment with them.
3.2 • Tkinter
Tkinter is the standard library that provides python bindings to Tk which is a graphical
programming library. Tkinter offers a great deal of variety. I have presented a few
example programs that do not by any means cover all of what is available. I would
recommend running the example programs and altering them to suit you. The widgets
that make up the interface have attributes with particular names, only some are in the
example programs.
Firstly you should test to see if you have tkinter installed. Start a Python 3 interactive
session and try "import tkinter". If it is not installed you will get the result below:
user@debian:~$ python3
Python 3.4.2 (default, Oct 8 2014, 13:14:40)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tkinter
Traceback (most recent call last):
File "/usr/lib/python3.4/tkinter/__init__.py", line 39, in <module>
import _tkinter
ImportError: No module named ‘_tkinter’
To install tkinter, do the following at the command line while connected to the Internet.
● 59
Python 3: Programming and GUIs for Electronic Engineers
We will start by creating the simplest graphical program that creates an empty window
and then does nothing other than resize, minimize, maximize and close. These three
lines of code actually do a lot of work.
Program 3-1 Empty window
#prog_03_01
import tkinter
Although there are only three lines in this program, there are three new things to point
out. First we import "tkinter", the package we need to create the GUIs.
Second the line "root = tkinter.Tk()" is an example of creating an instance of a class,
something we will go into in more detail in the chapter on Object Oriented Programming
(OOP). Here root is the name that is given, in this case to an instance of the class Tk,
the name is your choice. As a real world analogy you are an instance of the class of
humans and have a name. Third the line "root.mainloop()" means that having created the
instance root, we call the "mainloop()" function or method that runs the event driven loop
that controls our interface. Pressing a button would be an event and cause something to
be done by calling some function in your program.
We will now build some very short example GUIs to see how to add widgets, call functions
to react to events, and control the layout and appearance. Different widgets will be
introduced as we progress.
Up until now our programs have been started using the command line instruction
"python3 prog_xxx.py". We can make the script executable by using the command line
instruction "chmod 755 prog_xxx.py". This will change the file permissions (see Chapter
1.8 on page 18). In order for the script to run, the first line is added "#!/usr/bin/
env python3". Although this looks like a comment, it starts with "!" then the path to
the Python interpreter. When put on the first line, Linux knows to call "python3" to run
the script. We can start the program either from the command line with "./prog_03_02.
py" the "./" (means look for the file in the current directory) or you can double click on
the file in the File manager. Another way is to copy the executable script to the Desktop
from where it can run from by double clicking on it. I would recommend starting from the
command line when debugging programs.
● 60
Python 3: Programming and GUIs for Electronic Engineers
The scale widget can be used as in input and output interface. It is particularly useful for
control applications because it mimics a traditional analogue control device. This next
program, Program 3-7 also introduces the Label widget, which presents read only text
to the user. In the program, a Scale called ‘scale_in’ is created with options to set it as
horizontal, 500 pixels long, a resolution of 0.1 and to call the ‘drive_output()’ function
when it is moved. Not apparent by inspecting the code, the scale passes a value of
its position to the function being called, so we have the argument ‘scale_value’ in the
function. It can be any legal name. This variable is a string holding the floating value of
the position. The value of the scale position is converted to a floating point assigned to
the local variable r. The text for the label has been formatted to give five decimal places
in the circumference output and a minimum width including the decimal point of nine
characters. The radius output has one decimal place and a width of five characters. Both
have been padded with leading zeros. This gives a smoother digital display without the
position jumping. The "\t" inserts a tab space in the string. To get the value of pi, the
math library has been imported.
Program 3-7 Label widget
#!/usr/bin/env python3
#prog_03_07.py
import tkinter
import math
def drive_output(scale_value):
r = float(scale_value)
c = 2 * math.pi * r
lbl_out.configure(text = ‘Radius {0:05.1f} \t-\t Circumference {1:09.5f}’.format(r, c))
root = tkinter.Tk()
root.title(‘Scale Input’)
scale_in = tkinter.Scale(orient = ‘horizontal’, length = 500, resolution = 0.1, command = drive_output)
lbl_out = tkinter.Label()
lbl_out.grid(row = 0, column = 0, pady = 10)
scale_in.grid(row = 1,column = 0, pady = 10, padx = 10)
root.mainloop()
Program 3-8 on page 67 uses another Scale to display the output value. Here the
scale’s set() method is used to determine the position of the slider. Also added are
"tickinterval" markers and an option called label that is part of the Scale object.
A "commented out" line is the alternative method of obtaining the scale position directly
as a float. To try this move the comment prefix # to the other line. The definition of the
‘scale_out’ does not include a call back as it is being used as an output widget not an
input.
The lines that create the instances of Scale, scale_in and scale_out are long lines of code
and it is recommended to limit printed lines in the editor to 80 characters. You can fold
back code over more lines if that part is enclosed in parenthesis which this part is.
● 66
Chapter 3 • Graphic User Interfaces
##!/usr/bin/env python3
#prog_03_08.py
import tkinter
import math
def drive_output(scale_value):
r = float(scale_value)
#r = scale_in.get() # Can also be used
c = 2 * math.pi * r
scale_out.set(c)
root = tkinter.Tk()
root.title(‘Scale Input’)
root.mainloop()
3.6.2 • Entry
If you want to type in data directly, the Entry widget can be used to accept a single line of
text.
Program 3-9 below takes a text input of a numerical value. When the button is clicked,
the function Calculate() converts the string in the Entry to a float and squares it putting
the answer in the label. There is no protection here for non numerical data being entered.
You can have your code put a string in the entry box by using the method insert(index,
s) where s is the string to insert in the entry box and it gets inserted before the position
index.
Program 3-9 Text input
#!/usr/bin/env python3
#prog_03_09
import tkinter
def calculate():
x_string = ent_input.get()
x = float(x_string)
y = x*x
y_string = str(y)
lab_output.configure(text = y_string)
root = tkinter.Tk()
root.title(‘Entry’)
ent_input = tkinter.Entry(root)
ent_input.insert(0,’0.0’)
● 67
Chapter 4 • Object Oriented Programming
4.1 • Introduction
So far our programs have been what are called procedural programs. Object orientation
is a different way of writing programs. It is about creating software models of real world
items as separate objects; these objects contain the data and the functions that are
associated with objects. Please be aware that the treatment of this topic is just enough
to achieve the aim of producing working interfaces. We will introduce new concepts, the
class, and inheritance. The objects we are talking about here are individual instances
of a class. You are an instance of the class human. You have a name which can be used
to distinguish you from other instances of the class human. The class of human has the
attribute height if your name is jsmith. Your height might be “jsmith.height = 1.6”.
4.2 • Class
The block of code that is the class is like a factory that produces instances of that class.
These instances encapsulate data and methods, methods being the term used for
functions in classes. This is a convenient way of programming as programs get more
complicated.
Let us consider for an initial example the electronic circuit of the voltage comparator.
If the input voltage is above a certain level, we will call the setpoint, then the output is
on, otherwise it is off.
In python we could create a class to represent voltage comparators like these, as in
Program 4-1. This program has a class named “Comparator”. The class is used to create
two instances of voltage comparators that have different setpoints.
To create a class, we start with the word “class” then give it a name, in this case
Comparator. It is the convention to start class names with a capital letter.
Indented below this first line is the rest of the class. Our class here has two methods.
Moving down to the line “comp1=....”, after the end of the class code, this line creates an
instance of a voltage comparator I have called comp1.
When creating an instance of a class, the method __init__ () of that class is called
automatically, if it exists. The word init has two underscores on both sides. Now look
at this method: there are two arguments, the first is “self” meaning that the function
belongs to this instance.
Program 4-1 Voltage comparators
#!/usr/bin/env python3
# prog_04_01a.py
class Comparator:
def __init__(self, setpoint): # Method runs whenever a new instance is created
self.switch_level = setpoint
self.output = False
def switching(self, voltage):
if voltage > self.switch_level:
self.output = True
else:
self.output = False # End of class code
● 73
Python 3: Programming and GUIs for Electronic Engineers
The second argument which I have named setpoint is the argument passed to the __
init__() method whenever a new instance is created. Here the value is 5. The next line
sets the variable switch_level to 5 which will be the setpoint for the comparator comp1.
Again the self means that this variable belongs to the instance being created. The last line
of __init__() sets the variable output to off or False.
Moving on to the line “comp2=.......”, this line creates another instance of Comparator
but this time when __init__() runs, the setpoint is set to the value 6.
Figure 4-1 is a pictorial overview of this instance creation.
Looking at the last two line of the program, these lines print out the states of the outputs.
The function switching(self, voltage) has not been called yet.
Now let’s apply an input voltage of 5.5 to our two instances of the Comparator class.
This is the purpose of the switching(self, voltage) method.
To call the switching() method of comp1 with an input value of 5.5 you use “comp1.
switching(5.5)” and for comp2, “comp2.switching(5.5).
Program 4-2 on page 75 shows these program lines added and two lines to print out
the new output states.
● 74
Chapter 5 • The Arduino Uno as a Slave
5.1 • Introduction
The first edition of this book used the Future Technologies Development International
(FTDI) UM245 USB interface to read and write single bytes from and to the project
hardware. The approach of this book is to use the Arduino Uno as a slave. No code writing
is required for the Uno as an Arduino Uno universal sketch is provided. This makes the
Arduino respond to programs written in Python on the PC which is the master. The sketch
is provided as a hex file that AVRDUDE can load into your Arduinos. A Python tool is
provided in the programs.
This chapter shows how to program and configure Arduinos and will give an overview of
how to use the communication functions in Python to command the slaves. At the end
of the chapter, more details on the protocol will be given, although useful information on
fault finding can be read later.
The programs written in Python have GUIs that the user can use to monitor and control
real electronic hardware. The Arduino Uno provides a hardware interface of digital and
analogue inputs and outputs (IO) that can be connected to electronic circuits. The
Arduino is the slave and the PC running the Python program is the master. For reliable
communications between the Python program and the IO, a serial communications
protocol is provided that has a number of functions that transmit data in frames back and
forth. Each frame has an error detecting check sum.
Before your Python programs can talk to the slave, you will need to install the Python
serial library. This is very easy from the command line, just type the following:
This is needed to use the USB serial interface. However you will need to add yourself
to the "dialout" group otherwise you will not have permission to open the ports "/dev/
ttyACM*".
To add yourself to the "dialout" group, type the following at the command line:
The Arduino program (sketch) has already been written using the Arduino C/C++
functions and has been compiled to a ".hex" file that you can upload to your Arduino Uno.
This is done using AVRDUDE, an open source project written by Brian S Dean. AVRDUDE
is a command line utility that requires several command line arguments. A Python GUI
tool is presented here to make it easy. Figure 5-1 on page 82 shows the user interface.
Installing AVRDUDE is easily done by typing this at the command line:
● 81
Python 3: Programming and GUIs for Electronic Engineers
When this has completed you can then use the Python GUI tool.
You might have more than one project in existence, so to prevent accidentally running the
wrong software with a hardware project the Arduino is given a project identity number.
The master program on the PC will only command Arduinos with their project ID. Also
you might have more than one Arduino in your project so the slaves are given an address
within this project.
These two numbers are written to the Electrically Erasable Programmable Read-Only
Memory (EEPROM) in the Arduino with another tool provided in the zip file. The address
and the project numbers are retained in the EEPROM when the Arduino is powered off so
they only have to be entered once for each project.
● 82
Chapter 5 • The Arduino Uno as a Slave
#!/usr/bin/env python3
#prog_05_01.py
import tkinter
import uno_slave
class GuiDigOuts():
def __init__(self, master):
self.uno1 = uno_slave.Uno(address = 1,project = 1, config_digital = [2,3,4,5,6,7,8,9])
master.title(‘Write Digital Outputs’)
self.chkvar_2= tkinter.IntVar() # Control variables
self.chkvar_3= tkinter.IntVar()
self.chkvar_4= tkinter.IntVar()
self.chkvar_5= tkinter.IntVar()
self.chkvar_6= tkinter.IntVar()
self.chkvar_7= tkinter.IntVar()
self.chkvar_8= tkinter.IntVar()
self.chkvar_9= tkinter.IntVar()
self.chkbtn_2 = tkinter.Checkbutton(master,text = ‘Pin 2’, variable = self.chkvar_2)
self.chkbtn_3 = tkinter.Checkbutton(master,text = ‘Pin 3’, variable = self.chkvar_3)
self.chkbtn_4 = tkinter.Checkbutton(master,text = ‘Pin 4’, variable = self.chkvar_4)
self.chkbtn_5 = tkinter.Checkbutton(master,text = ‘Pin 5’, variable = self.chkvar_5)
self.chkbtn_6 = tkinter.Checkbutton(master,text = ‘Pin 6’, variable = self.chkvar_6)
self.chkbtn_7 = tkinter.Checkbutton(master,text = ‘Pin 7’, variable = self.chkvar_7)
self.chkbtn_8 = tkinter.Checkbutton(master,text = ‘Pin 8’, variable = self.chkvar_8)
self.chkbtn_9 = tkinter.Checkbutton(master,text = ‘Pin 9’, variable = self.chkvar_9)
self.btn_write = tkinter.Button(master,text = ‘Write’, command = self.dig_write)
● 89
Python 3: Programming and GUIs for Electronic Engineers
def dig_write(self):
self.uno1.write_digital_dict[2] = self.chkvar_2.get()
self.uno1.write_digital_dict[3] = self.chkvar_3.get()
self.uno1.write_digital_dict[4] = self.chkvar_4.get()
self.uno1.write_digital_dict[5] = self.chkvar_5.get()
self.uno1.write_digital_dict[6] = self.chkvar_6.get()
self.uno1.write_digital_dict[7] = self.chkvar_7.get()
self.uno1.write_digital_dict[8] = self.chkvar_8.get()
self.uno1.write_digital_dict[9] = self.chkvar_9.get()
self.uno1.write_digital()
tk = tkinter.Tk()
front_end = GuiDigOuts(tk)
tk.mainloop()
Program 5-2 is for the same circuit. It drives one LED on at a time so that the position
of the lit LED moves backwards and forwards. The speed of the change of position is
controlled by a scale. This program introduces a useful technique for calling a method at
intervals. Top level windows, in this case our master has a function called self.master.
after() that calls a function after a time interval. Here we are using it at the end of the
method drive() to call drive() again. The time interval is determined by the position
of the scale. Unlike using time.sleep(), the method after() does not block or in other
words stall the flow of the program. A point to remember is that sleep() has the time
interval expressed in seconds using a float, and the after() method has the time interval
expressed in milliseconds using an integer.
Program 5-2 Call a method at intervals
#!/usr/bin/env python3
#prog_05_02.py
import tkinter
import uno_slave
import time
class GuiDigOuts():
def __init__(self, master):
self.master = master
self.uno1 = uno_slave.Uno(address = 1, project = 1, config_digital = [2,3,4,5,6,7,8,9])
self.master.title(‘Write Digital Outputs - Timed Sequence’)
self.rate_scale = tkinter.Scale(master, orient = ‘horizontal’, length = 500, from_ = 1,
to = 100, tickinterval = 10,label = ‘Step Interval (ms)’)
def drive(self):
self.uno1.write_digital_dict[self.step] = 0
if self.step == 9:
self.direction = -1
if self.step == 2:
self.direction = 1
● 90
Chapter 6 • Further Examples of GUIs
6.1 • Introduction
This chapter moves on to more advanced GUIs and introduces further aspect of Python
and Tkinter. The GUIs will be all about interfacing with the Arduino slave. You must read
Chapter 5 on page 81 before trying the projects in this chapter in order to understand
how the Arduino is used here. The programs presented will be object oriented. The
programs will be getting longer and more complicated. This is where object oriented
programming starts to make things more manageable. If you have trouble understanding
parts of the code, try experimenting by changing one part at a time; this can be great
help towards understanding. Also some more Python features will be introduced.
As shown in Chapter 3 on page 61, there are a lot of standard widgets available but
you have to write code to make them do what you want. Often something similar crops
up in more than one program that would result in duplicating code and wasting time.
One such example is to plot a graph of the analogue inputs against time. The following
program is a class that can be used to create instances of an object that will do this and
require very little code to include it in other projects. The class that is called Graph and it
will be in a module or separate file.
Figure 6-1 shows a GUI that will be Program 6-2 on page 110, the custom widget with
the canvas and two buttons Reset and Flyback can be seen with its raised border, is an
instance of the class Graph. This widget can be placed in any GUI you write, simply by
importing the module plotter and creating an instance of Graph and calling its methods.
Program 6-1 below is plotter.py. The class plots up to six analogue inputs simultaneously
against time. Measurements on the graph can be taken by using the mouse to point to
a position on the graph and left clicking. The Flyback button causes the graph to restart
plotting from the left end without deleting anything. The Reset button also restarts from
the left end but also clears the canvas. As well as the time saving, this approach gives the
benefit of dependability that the code can be relied upon and only needs to be imported
and used.
● 101
Python 3: Programming and GUIs for Electronic Engineers
Up until now we have been specifying the arguments that are being passed to a function,
see paragraph 2.7 on page 42. Suppose that we want to pass different numbers of
arguments depending on the application. In Program 6-1 on page 103, notice the
function definition "def plot (self, *args)". Here we can pass up to 6 analogue input values
to be plotted. In the function, args is a tuple that contains all the arguments passed from
the calling function. The word args is not mandatory, it is just the convention. What is
important is that it is prefixed with the single *.
Here is an example you can try in an interactive session.
The function fun() is called with four arguments: the first a string, the second a float,
the third an integer and finally another string. In the function definition *args is used.
The function prints args; you can see that this is a tuple. If we use the built in method
enumerate() we can obtain index numbers and values for the arguments that have been
passed regardless of how many there are. The function enumerate() yields two values:
one being an enumeration of the position of the argument and the other being its value.
In the method plot() (Program 6-1), the arguments for the analogue inputs are
enumerated to be the variable channel and y the value. The variable palette is a list of
different colours for each analogue input.
If you look at the __init__() method for the class two of the arguments are keyword
arguments scale_x and scale_y. They are after the two positional arguments height and
width. Keyword arguments have default values that they take if they are not passed by
the calling method these are the values after the equal signs. If values are passed by the
● 102
Chapter 7 • Bit Map Graphics
7.1 • Introduction
This chapter is mainly about the anatomy of bit map images and how to operate on
them. In the last chapter the canvas widget was used to draw on when producing GUIs
in Tkinter. What if you want to plot a graph and save it as an image file? Python does
provide a method for saving canvases as postscript files, but what we will do in this
chapter is create and modify bitmap images that can be saved and read by any image
viewer. Bit map images are very easy to manipulate as they are an array of pixels like
points on a piece of graph paper.
The bit map images we will be dealing with will have each pixel colour defined by three
bytes, one for each primary colour. As an illustration Figure 7-1 represents an image 8
by 6 pixels. There is a square for each pixel and a byte for each of the three colours. The
image is white except for a red line across the top and the three pixels starting from the
bottom left hand corner are red, green and blue.
● 119
Python 3: Programming and GUIs for Electronic Engineers
The image depicted by Figure 7-1 on page 119 is in the zip file, its name is fig1image.
bmp. To view it you will need maximum zoom. Figure 7-2 shows how the bytes that
define the image are sequenced in the file. The first four pixels and the last two from
Figure 7-1. Note that the order of the bytes for each pixel is blue, green and then red.
image_content_dictionary = {(7, 3): [255, 255, 255], (1, 3): [255, 255, 255], (3, 0):
[255, 255, 255],................}
● 120
Chapter 8 • A Project to Monitor Your Electricity Consumption
8.1 • Introduction
This chapter is about a larger project that will monitor the current in a mains electricity
supply. The first thing to point out that there is no direct connection to the mains wiring
required. A non-invasive technique is used involving a coil of wire placed near to the
supply cables. The probe will measure the current flowing and transmit the value to the
receiver that will be connected to the Arduino slave. A graph of current against time will
be plotted. The next chapter gives details of how to use a web browser as a GUI that can
be viewed on a mobile phone or other computer. This will allow you to view the output
when away from home. The reason for the radio link is that very often the mains incomer
to a building is not at a convenient place for a computer.
The remote sensing head driven by the coil comprises a filter, amplifier, and precision
half wave rectifier, a PIC microcontroller and a low power radio transmitter. The
PIC microcontroller is a 12F1822 and it can be programmed using a tool written in
Python that uses the Arduino slave. The code for the PIC is provided. The transmitter
and receiver are readily available from Farnell Components who have international
distribution.
The probe that was used in the prototype was a coil of insulated wire, air cored with 5
turns and a diameter of approximately 60mm, as shown in Figure 8-2 on page 132. The
pickup coil is connected to the sensing head by a length of coaxial cable. A twisted pair
could be used. This is not the usual way of measuring current in a supply cable. Normally
a current transformer with a magnetic core that one of the supply cables runs through
is used. The core has a winding on it connected to a low impedance circuit. This has the
disadvantage that either the current transformer must be fitted to the cable before it is
connected or a split core transformer must be used. Either option is not suitable for a
home construction project as even if you use a split core you probably won't have room
to fit it on a domestic installation. The method described here is completely non-invasive.
The way that this sensing coil works is that some of the magnetic field from the two
supply cables links with the coil. As one of the cables is closer to the coil than the other,
there will be a resultant field that induces a voltage in the coil. Now this is where this
method is flawed. The instantaneous magnetic flux from the supply current is proportional
to the instantaneous current in the supply cable but the voltage induced in the coil is
proportional to the rate of change of the magnetic flux. If we are only considering one
● 131
Python 3: Programming and GUIs for Electronic Engineers
frequency (50Hz in the UK), the maximum rate of change of flux is proportional to the
maximum instantaneous current, only phase shifted by 90 degrees. However there are
harmonics present in the supply current, if you compare the maximum rate of change
of a 150Hz sine wave with the maximum rate of change of a 50Hz sine wave of equal
amplitude it is three times greater, five times greater for the fifth harmonic. To overcome
this problem a low pass filter is included in the sensing head to reduce the effect of any
harmonic content in the supply. It must be pointed out that this will not give results
accurate enough for metering purposes. Please note, on the photograph the supply cables
are the two running above the coil. In the UK these are referred to as the meter tails.
● 132
Python 3: Programming and GUIs for Electronic Engineers
self.num_samples = self.X
self.graph1 = plotter.Graph(master,self.X, self.Y,
scale_x = self.num_samples, scale_y = self.calibration_dict[‘fullscale_current’])
self.graph1.frm.grid(row = 0, column = 0, padx = 10, pady =10,columnspan = 3)
self.reading()
def reading(self):
self.uno1.read_analog(1)
raw = self.uno1.read_analog_dict[0]
i = (raw-self.calibration_dict[‘raw_offset’]) * self.calibration_dict[‘raw_to_current’]
y = int(i*self.Y/self.calibration_dict[‘fullscale_current’])
self.circ_buffer.append([raw,i,y])
if self.x%self.X == 0:
self.graph1.flyback()
self.graph1.plot(y)
self.x = self.x + 1
self.master.after(10000, self.reading)
def calibration(self):
self.cal_window = tk.Toplevel()
self.cal_window.title(‘Calibration’)
self.cal_output = tk.Text(self.cal_window, width = 30, height = 20, relief = ‘ridge’)
self.btn_save_cal = tk.Button(self.cal_window, text = ‘Save Calibration’, command = self.save_calibration)
self.lbl_raw = tk.Label(self.cal_window, text = ‘Raw/Current/Screen Position’)
self.lbl_offset = tk.Label(self.cal_window, text = ‘raw_offset’)
self.strvar_offset = tk.StringVar()
self.strvar_offset.set(self.calibration_dict[‘raw_offset’])
self.ent_offset = tk.Entry(self.cal_window, textvariable = self.strvar_offset, width = 10)
self.lbl_raw_to_current = tk.Label(self.cal_window, text = ‘raw_to_current’)
self.strvar_raw_to_current = tk.StringVar()
self.strvar_raw_to_current.set(self.calibration_dict[‘raw_to_current’])
self.ent_raw_to_current = tk.Entry(self.cal_window, textvariable = self.strvar_raw_to_current, width = 10)
self.lbl_fullscale_current = tk.Label(self.cal_window, text = ‘fullscale_current’)
self.strvar_fullscale_current = tk.StringVar()
self.strvar_fullscale_current.set(self.calibration_dict[‘fullscale_current’])
self.ent_fullscale_current = tk.Entry(self.cal_window, textvariable = self.strvar_fullscale_current,
width = 10)
self.cal_window.grid()
self.lbl_raw.grid(row = 0, column = 0)
self.cal_output.grid(row = 1, column = 0, rowspan = 7)
self.lbl_offset.grid(row = 1, column = 1, sticky = ‘S’)
self.ent_offset.grid(row = 2, column = 1, sticky = ‘N’)
self.lbl_raw_to_current.grid(row = 3, column = 1, sticky = tk.S)
self.ent_raw_to_current.grid(row = 4, column = 1, sticky = tk.N)
self.lbl_fullscale_current.grid(row = 5, column = 1, sticky = tk.S)
● 138
Chapter 8 • A Project to Monitor Your Electricity Consumption
def calibration_update(self):
try:
self.cal_output.delete(1.0, tk.END)
for data in self.circ_buffer:
self.cal_output.insert(tk.END,’raw = {0:d} i = {1:0.2f}A y = {2:d}\n’.format(data[0], data[1],
data[2]))
self.cal_output.see(tk.END)
except:
self.master.after_cancel(self.after_handle)
def save_calibration(self):
self.calibration_dict[‘raw_offset’] = float(self.strvar_offset.get())
self.calibration_dict[‘raw_to_current’] = float(self.strvar_raw_to_current.get())
self.calibration_dict[‘fullscale_current’]= float(self.strvar_fullscale_current.get())
try:
calibration_file = open(‘current_monitor_cal.dat’,’bw’)
pickle.dump(self.calibration_dict, calibration_file)
calibration_file.close()
except:
self.cal_output.insert(END,’\vFailed to open file to save calibration\n’)
self.cal_output.see(END)
def capture(self):
file_name = tk.filedialog.asksaveasfilename(filetypes = [(‘Bit Map’,’*.bmp’)],title = ‘Choose or Enter
File Name’)
if file_name:
segments = []
tags = self.graph1.can.find_all() # find all objects on the canvas
for tag in tags: # loop through objects
if self.graph1.can.type(tag) == ‘line’: # filter out the lines
segments.append(self.graph1.can.coords(tag)) # make a list of coordinate lists
draw1 = bmp_draw.BmpDraw(‘current_monitor_screen_cap_template.bmpt’)
if draw1.flag == True:
for x in range (0,self.X, 90):
draw1.line(x, 0, x, self.Y, [0,255,0])
draw1.write_file(file_name)
tk.messagebox.showinfo(‘Capture’, ‘Capture Saved’)
else:
tk.messagebox.showinfo(“Capture”, ‘Capture Cancelled’)
tkin = tk.Tk()
front_end = CurrentLogger(tkin)
tkin.mainloop()
● 139
Chapter 9 • Web Browser Interfaces
9.1 • Introduction
Desktop GUI applications are satisfactory if you only want to interface with some local
hardware. It is however often more convenient to use a mobile device such as a tablet
computer or mobile phone. This allows you to remotely access your hardware devices
even when away from home. Security and safety have to be considered when remotely
controlling real electrical and electromechanical devices. This chapter will only cover
enough to give you a practical GUI for you own projects; it is certainly not a reference for
web design. This chapter is being presented as following on from the current monitoring
project started in the last chapter. You can easily apply the information in this chapter
to other projects of your own invention that might want to monitor similar analogue or
digital inputs to the Arduino slave.
9.2 • HTML 5
To generate the graphic interface, we are going to use HTML5 to display the graph from
the current monitoring project from the last chapter. HTML stands for Hypertext Markup
Language. It defines a web page in elements and these are represented by tags. Only the
most basic coverage of this topic will be given here. We only need to generate and display
an image similar to the Python canvas widget in the desktop program. Although HTML
5 has a canvas object, we will not be using it Instead we will be using Scaleable Vector
Graphics (SVG). The code that we need to write here is remarkably simple.
Program 9-1 Index.html
The above HTML script can be viewed in a web browser by typing /home/ in the URL bar
and then navigating to the file that is under the programs for Chapter 9. The file name
is index.html. The first line is a comment and does nothing to the web page. Comments
are enclosed by the tags “<!--” and “-->”. The next declares to the browser what type
of document it is. The first tag is “<html>” and it has a closing tag on the last line of
“</html>”. The next pair of tags enclose the header, and then there is the SVG code
enclosed in the svg tags. The opening tag defines the size of the graphic.
The lines that are drawn are defined between the “<line” and “/>”. The lines are defined
in a way similar to that used on the Python canvas, with x and y coordinates for each
end of the line, colour defined by the red, green and blue values, and stroke-width value.
Figure 9-1 shows the resulting graphic being viewed locally by using the path to the file.
To view a web page on a different device to the one that the file is on you need a web
server. The Apache Web Server was used in the first edition of this book and common
gateway interface (CGI) scripts were used to generate interactive web pages. In this
● 145
Python 3: Programming and GUIs for Electronic Engineers
edition I am using the CherryPy Web Framework which offers a much more straight
forward way of creating our dynamic web pages.
Figure 9-1
CherryPy is a web framework for Python that gives us a web server and a framework to
serve dynamic content allowing the user to interact with Python programs running on the
server. To install, you need to type this at the command line:
We will start with the content of the “index.html” shown above and serve it using
CherryPy.
Program 9-2 CherryPy
#!/usr/bin/env python3
#prog_09_02.py
import cherrypy
class SvgDemo:
@cherrypy.expose
def index(self):
return ‘’’
<!DOCTYPE html>
<html>
<body>
<h3>Lines Using Scaleable Vector Graphics</h3>
<svg height=”500” width=”720”>
<line x1=”360” y1=”0” x2=”360” y2=”500” style=”stroke:rgb(0,255,0);stroke-width:2” /><!-- vertical line -->
● 146
Chapter 10 • Curses Interfaces
10.1 • Introduction
The curses interface runs on a terminal. Curses is a Python package for the ncurses
library that allows you to write text based user interfaces that are independent of the
terminal being used. Although the interface is character based, many of the features
of a GUI can be produced. One example of this type is the Midnight Commander File
manager. Unlike a basic command line program, curses allows you to print anywhere
on the screen and have multiple windows in the display for entering and reading data.
Some limited graphics such as bars that change their length can be used for meter
indications and windows that change colour can be used as indicators. The reason that
you might want to use them is that they can run without the X-windows and therefore
are useful on low resource computers. Curses is already part of Python and is simpler to
use than the ncurses library that you would use if programming in C. The curses package
is not available for Python on Microsoft Windows. Figure 10-1 shows an example of a
representation of a gauge. There are no readymade widgets but it is easy to produce your
own widgets as classes that you can re-use.
As an example to start with, Prog 10 - 1 prints a message to the screen in two different
positions. Normally with a terminal, printing takes place at the cursor position and you
can't choose an arbitrary position on the screen, but with Curses you can.
Program 10-1 Print message to screen
#!/usr/bin/env python3
#prog_10_01.py
import curses
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
stdscr.addstr(5, 20, 'Curses can write anywhere on the screen')
stdscr.addstr(7, 10, 'Curses can write anywhere on the screen')
stdscr.getch()
curses.echo()
curses.nocbreak()
curses.endwin()
Figure 10-2 on page 164 shows the output of this program. Firstly you have to import
curses and then call the function curses.initscr(). This function initialises the library and
returns window object that it is customary to call stdscr, which represents the whole
screen. On stdscr, text can be written and separate windows can be placed. Here there
are no windows, just the stdscr. The curses.noecho() function prevents characters
appearing as you type: there are special functions to do that. The curses.cbreak()
function stops the line buffering of input as happens with a normal terminal that would
require you to press the return key. To get text to print to the screen, the addstr()
● 163
Python 3: Programming and GUIs for Electronic Engineers
function is called. This is a method of the screen or window and can take the arguments
to position the text, the string to print, and also attributes for the text, but here there
are none. An important note is the order of the positional arguments. The first one is
the number of lines down the screen or window, and the second one is the number
of columns or character places along the screen from the left. Curses does not draw
individual pixels, only characters.
The wrapper function handles this problem and does away with having to manually call
these functions. You have to put your code in a function, in this case it is called main()
and it must have one argument called stdscr. The program starts by calling curses.
wrapper() and this function must be given the name of your function because it calls it.
When the wrapper function calls your function, it passes it to the stdscr object. When
your function finishes, the program returns to the wrapper function and it cleans up the
terminal. If your function fails for any reason, the wrapper function has a try/exception
routine that handles the clean up.
Program 10-2 Using the wrapper function
#!/usr/bin/env python3
#prog_10_02.py
import curses
def main(stdscr):
stdscr.addstr(5, 20, 'Curses can write anywhere on the screen')
stdscr.addstr(7, 10, 'Curses can write anywhere on the screen')
stdscr.getch()
curses.wrapper(main)
There is more to it than just writing text anywhere on the screen. Separate windows can
● 164
Appendix A • Arduino Uno Slave Source Code
/*Arduino_Slave_17_03_26a.ino*/
#include <EEPROM.h>
#define STATE_IDLE 0
#define STATE_CHECK_TELEGRAM 1
#define STATE_CONFIGURE_IO 2
#define STATE_DIG_READ 3
#define STATE_DIG_WRITE 4
#define STATE_AN_READ 5
#define STATE_AN_WRITE 6
#define STATE_FAIL_SAFE 7
#define STATE_TX_IDS 8
#define STATE_SET_IDS 9
#define STATE_RECEIVING_BYTES 10
#define FUN_CODE_CONFIG 2
#define FUN_CODE_DIG_READ 3
#define FUN_CODE_DIG_WRITE 4
#define FUN_CODE_AN_READ 5
#define FUN_CODE_AN_WRITE 6
#define FUN_CODE_TX_IDS 8
#define FUN_CODE_SET_IDS 9
#define ERROR_CHECK_SUM 1
#define ERROR_FUN_CODE 2
#define ERROR_ADDRESS 3
#define ERROR_PROJECT_ID 4
#define SLAVE_ADDRESS_EEPROM_LOCATION 0
#define PROJECT_ID_H_EEPROM_LOCATION 1
#define PROJECT_ID_L_EEPROM_LOCATION 2
● 185
Appendix B • The Python Uno Slave
#!/usr/bin/python3
import serial
import os
H = 1
L = 0
FUN_CODE_DIG_READ = 3
FUN_CODE_DIG_WRITE = 4
FUN_CODE_AN_READ = 5
FUN_CODE_AN_WRITE = 6
FUN_CODE_GET_IDS = 8 #maps to FUN_CODE_TX_IDs in the arduino code
FUN_CODE_CONFIG = 2
BROADCAST_ADDR = 255
DEBUG = False
class Uno:
'''Arduino Uno as an IO slave.
'''
address -- 1 - 254.
project -- 0 - 65535
config_digital -- List of integers detailing the pins configured as outputs.
'''
self.project = project
self.address = address
self.config_digital = config_digital
self.port = None
self.rw_available__flag = False
self.ser = serial.Serial()
self.ser.timeout = 0.1
self.ser.bytesize = 8
self.ser.stopbits = 2
self.ser.baudrate = 9600
self.ser.xonxoff = False
self.write_digital_dict = {}
self.write_analog_dict = {}
self.read_digital_dict = {0:0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0, 11:0, 12:0, 13:0, }
self.read_analog_dict = {0:0, 1:0, 2:0, 3:0, 4:0, 5:0}
def connection(self):
'''This function checks for connection and digital configuration and calls connect() if necessary.
Is called by read_digital(), read_analog(), write_digital(), and write_analog() to check for connection to slave.
Return True or False.
'''
● 193
Index
Index bytesarray 54
Byte slicing 55
Symbols
C
__init__ () 73
Calculate() 67
__init__() 137
calibration() 141
__main__ 104
Calibration Program 136
__name__ 103
Callbacks 61
A Calling box() 168
Adapting Project 161 Canvas() 143
administrative rights 18 Canvas Widget 70
after() 90 capture() 142
Analogue gauge 172 C compiler 22
Analogue Input Pins 87 Checkbutton() 68
Analogue Inputs 93 Check buttons 68
Analogue Output Pins 87 CherryPy Web Framework 146
Analogue Outputs 91 Class 73
Apache Web Server 11 Class BmpDraw 128
append() 143 Colour 165
Arduino Sketch 185 Commands
Arduino Slave 134 cat 17
Arduino Uno 81 cd 16
ASCII 21, 51, 96 cp 17
assembler 21 df 17
AVRDUDE 81 less 17
B ls 16
lsusb 17
Bash Scripts 19
mkdir 17
Binary 50
mv 17
Binary Files 121
rm 17
binary system 47
rmdir 17
Bit and Bytes 46
communications functions 87
Bit Map 119
Communications Protocol 95
bitwise logic operators 47
Comparators 73, 77
bitwise operators 47
Comparison Operators 48
Bitwise OR Operator 173
Compiled Python 51
bkgd() 167
Configuring the router 161
BmpDraw() 144
Configuring Wi-Fi 158
Button Widget 178
Control Variables 68
bytearray() 55
● 219
Python 3: Programming and GUIs for Electronic Engineers
● 220
Index
M Redirection 18
Remote Sensing Head 131
mainloop() 114
row.configure() 63
Master Slave Design 81
method test() 114 S
micro SD 158 save_calibration() 142
Mint 11 Scaleable Vector Graphics 145
Modified Image 124 Scale to display 67
Mouse Events 173 Scale Widget 66
Mousepad 15, 22 Schmitt trigger 75
Moving graphics 45 Slave State Diagram 95
N sleep() 151
Split function 40
Nested Layout 64
Splitting Strings 39
Newline 31
start_test() 114
"no file" error 33
stdscr.refresh() 165
Number crunching 43
Strings 26
O Struct Module 126
Object Orientation 79 struct.pack() 126
Object Oriented Programming 73 Switching() method 75
Opening file 31
T
P Telegram Formats 97
permission number 19 Terminal Emulator 13
Persistence of Objects 50 test() 114
PIC connections 134 Test results 114
pickle.dump() 142 Text input 67
PIC Microcontroller 133 textvariable 68
privileges 18 Threading 116
Probe Sensing Head 131 Thumbwheel Widget 174
Python 2 11, 21 Time() 44
Python 3 11, 21 time.sleep() 90
● 221
Python 3: Programming and GUIs for Electronic Engineers
U
Ubuntu 11, 13
Unicode 21
Unicode Strings 51
Uno Class 84
Uno Slave 193
USB Serial 81
utf-8 53
utf-16 53
V
Variable assigned 43
Variable names 57
variables 141
VirtualBox 13
Voltage comparators 73
W
Web Forms 148
Web Server 157
Widgets 61, 65
Wild Cards 17
win.doupdate() 182
win.noutrefresh() 182
win.refresh() 182
Wrapper Function 164
X
X-Server 20
● 222
175 × 235 SPINE: 11.4 FLAPS: 0
PYTHON 3 - PROGRAMMING
FOR ELECTRONICS ENGINEERS
PYTHON 3
PROGRAMMING AND GUIS
PYTHON 3
Andrew Pratt PROGRAMMING AND GUIS
AND
Andrew Pratt served for
that is required to produce Python programs.
25 years in the Royal
Air Force as an Aircraft Hardware interfacing is achieved using an Arduino Uno as
LEARN
LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIG
SHARE
N • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHA
SIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LE
• LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN
RN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SHARE • LEARN • DESIGN • SH