Learn Programming and Electronics With Proteus Visual Designer A Beginners Guide To Programming Arduino Using Proteus Visual Designer
Learn Programming and Electronics With Proteus Visual Designer A Beginners Guide To Programming Arduino Using Proteus Visual Designer
Query (ask) whether milk should be added, remember the answer (as Add_Milk)
Yes Yes
Fill cup with hot water Boil kettle
Add teabag
Subtract 1 from
Is the
Yes Num_Sugars_To_Still_Add
Num_Sugars_To_Still_Add
more than zero?
Add a sugar to the cup
No
Yes
Should we Add_Milk? Add milk
No
Proteus also features a module called “Visual Designer for Arduino”, which is
a flowchart designer for Arduino, and which we will be using in this book.
Note that this entire book can be completed using only Proteus, without the
need for any physical hardware boards – however if hardware boards are
available, then they can be easily programmed from within Proteus (this is
described in section 2.7.4).
1.3. What to Expect
This book starts with the very basics, with step-by-step instructions;
beginning with simple projects and then moving onto progressively more
advanced topics. The bulk of this book focuses on flowchart programming,
with an introduction to C at the end. As previously mentioned, all of the
flowcharts can be converted to C/C++ code with a few clicks (the exact
method for doing so is explained towards the end of this book, in section
9.8). All of the projects in this book can be completed and simulated entirely
within Proteus without the need to purchase any physical hardware,
however they can also be downloaded to physical hardware (if available)
very easily if desired (section 2.7.4).
Without further ado, let's get started!
2. Creating Your First Project
To get started, we are going to jump right in and see how easy it is to create
our first working project!
2.1. Pre-Requisites
- This chapter assumes that you already have some basic computer
knowledge and experience (that you know how to use a computer).
- Please ensure that Proteus is installed on your computer before
proceeding.
2.2. Creating a New Project
Step 1: To start with, please ensure that Proteus is running (this can
normally be done by double-clicking on the Proteus icon on your Windows
desktop). When Proteus starts, the Proteus Home Page is shown, as
illustrated in the following figure.
Figure 2-1: Proteus “Home Page”
By default the project is named “New Project” (note that the file extension
(.pdsprj) should not be modified); however for our new project please use
the name “BlinkLED” (“BlinkLED.pdsprj”).
The path location can be chosen by using the “Browse” button to navigate
to the folder in which you would like to save the project files. Please choose
any folder which makes sense to you, such as a new folder called “Proteus”
on your Desktop or in your Documents folder.
Once you have set the project name and path, please click the “Next”
button at the bottom of the New Flowchart Project Wizard in order to
proceed further through the New Flowchart Project Wizard process.
(Tip: The “Back” button obviously allows you to go back to the previous step
in the New Project Wizard process, and the “Cancel” button obviously
allows you to exit the New Project Wizard.)
Step 3: The next step of the New Flowchart Project Wizard process is the
Firmware setup step (see Figure 2-3). “Firmware” is the name for a
microcontroller3 software program – it is the instructions (which we will be
developing) which tell the microcontroller what to do. This step in the
wizard is used to specify which microcontroller we would like to develop
firmware for.
(Tip: The term “Software” is typically used for computer code, whilst the
term “Firmware” is typically used for microcontroller code. The short
explanation of the reason for this is as follows: It is typically more difficult to
change or replace the code in a microcontrollers’ memory, than it is to
change the code in a computers memory. Thus, the microcontroller code
could be considered to be more “firm” (less changeable). For our purposes
however, we can consider the terms Firmware and Software to mean about
the same thing.)
Click the “Finish” button at the bottom of the screen to finalise the wizard
process. After clicking the Finish button, Proteus will automatically open the
newly created project (Figure 2-5). Once you have reached this stage, you
have successfully created a Proteus project and can commence flowchart
design.
Figure 2-5: New flowchart project
2.3. Familiarisation with the Proteus Environment
After creating your new project using the Wizard process, Proteus will have
two tabs open – the Visual Designer tab and the Schematic Capture tab –
with the Visual Designer tab selected by default.
When a new flowchart project is created then the flowchart area contains by
default a “Setup” and a “Loop” routine (these will be explained in greater
detail shortly). The small “Projects” area on the left lists all of the flowchart
sheets in the project, as well as the “peripherals” used in the project. More
information on these concepts is presented next.
2.3.3. Flowchart Sheets
A flowchart sheet is a “page” on which you can design a flowchart. For many
projects only one flowchart sheet is needed, but for larger projects more
flowchart sheets can be added in order to provide more space for designing,
or to better organise the project.
2.3.4. Peripherals
In short, in Visual Designer, peripherals are largely objects which we can
interact with – for example a button or a display screen. Peripherals have
“methods” (instructions), such as “clear the screen” or “display this text on
the screen”. The longer, and more technically correct, explanation is as
follows:
As mentioned in the introduction (section 1.2.3), a microcontroller is a
microprocessor with some extra features (“peripherals”) built-in. Whilst a
microprocessor can only process instructions, peripherals provide additional
functionality – such as a timer peripheral for (obviously) timing things. The
peripherals work independently from the microprocessor, and as such don’t
slow it down from processing instructions. This is like having a GPS in your
car – you can focus on driving, whilst the GPS “peripheral” handles the
navigation. Besides for the peripherals which are built into the
microcontroller, additional external peripherals can also be added.
Proteus Visual Designer includes a peripheral gallery which contains dozens
of devices, such as temperature sensors and displays. Peripherals contain
methods, which are flowchart blocks applicable to that specific peripheral –
such as “on” and “off” commands for a light.
The default peripherals included in a new Arduino project are the “cpu” and
“timer1” peripherals:
For our first project we won’t be using any special additional peripherals
(these will be covered in later sections).
2.3.5. Navigating around a Design
Navigating a design refers to zooming in/out of it, as well as panning around
it (moving the view left/right/up/down). The same tools are used to navigate
both flowchart designs as well as schematic designs.
2.3.5.1. Zooming
The most common method used for zooming is:
- Point the mouse where you want to zoom in / out of, and roll the
middle mouse button (roll forwards to zoom in and backwards to
zoom out).
- Point the mouse where you want to zoom in or out of and press the
F6 or F7 keys respectively.
- Hold the SHIFT key down and drag out a box with the left mouse
button around the area you want to zoom in to.
- Use the Zoom In, Zoom Out, Zoom All or Zoom Area icons on the
toolbar.
Note that the F8 key can be used as a shortcut at any time to display the
whole design (“zoom extents”).
2.3.5.2. Panning
Panning refers to navigating left/right/up/down. Usually, if using the mouse-
wheel for zooming, then this can be used for panning as well (by zooming
out and then zooming in again to the specific area which you would like to
view). Panning can also be performed explicitly however. The most common
method used for panning is:
- Click on the middle mouse button to “pick up” the design. Move the
mouse to move the design, and then click the middle mouse button
again to “put down” the design.
Other options include the below, although these generally only work within
the schematic capture tab:
- To simply “pan” the Editing Window up, down, left or right; position
the mouse pointer over the desired part of the design and press the
F5 key.
- Hold the SHIFT key down and bump the mouse against the edges of
the design area to pan up, down, left or right.
- Use the Pan Icon on the toolbar.
Take some time now to practice zooming and panning around the flowchart
sheet (and possibly the schematic sheet as well, if you feel so inclined).
2.4. Essentials of Flowchart Programming
A flowchart consists of a sequence of actions and decisions required to
accomplish a task, drawn in a graphical way. For an example, see the
flowchart from section 1.2.1 in the Introduction again. A flowchart is
generally easier to understand than written (text) code (e.g. C code). By
using flowcharts for programming we can focus on getting results, without
first having to tackle the complexity of learning for example C or C++ code.
2.4.1. Types of Flowchart Blocks
Flowcharts are constructed from “blocks”. Traditionally, flowcharts are built
out of only action and decision blocks:
Proteus however has a richer set of flowchart blocks to choose from, which
offer some additional features; as listed in the following table. Don’t worry
about understanding or remembering all of the blocks right now – they will
be covered in greater detail in the following sections, and are listed here
only for the sake of completeness.
2.4.2. Flowlines
Flowchart blocks are linked, or joined, by lines called “Flowlines” (see Figure
2-9).
“Flowlines” highlighted in red
Figure 2-10: Default flowchart program with setup and loop routines
Step 1: Drag a “setBuiltInLED” method from the CPU peripheral into the
flowchart Loop routine (Figure 2-12). The method is named “setBuiltInLED”
because it can be used to turn a built-in LED on the Arduino Uno board on or
off (this is discussed in section 2.7.1 – feel free to read that section and then
come back if you are curious).
Figure 2-12: Adding the "setBuiltInLED" method to the flowchart
When correctly aligned, black dots will appear where the block intersects
the flowline (Figure 2-13).
Flowline coming in
Arrow at end of flowline
By default, the “setBuiltInLED” method will switch the LED “on” (“state :=
ON”). This is the correct operation for now, so we do not need to change it.
How to change a setBuildInLED block so that it switches the LED off again
will be covered in steps 4 and 5.
Step 2: The next step is to add a delay, before we switch the LED off again.
This is done using a delay block; so drag a delay block into the flowchart,
inserting it after the setBuiltInLED block (Figure 2-15).
Figure 2-15: Inserting a delay block
Step 3: Next, we want to set the time of the delay to be 1 second. Right-click
on the new delay block which was just added to the flowchart, and select
“Edit” from the popup menu (Figure 2-16). An alternative method is to left-
click on the delay block twice.
Specify “1 second” for the delay (Figure 2-17), and click “OK” when done.
Figure 2-17: Specifying the delay time
Step 4: After switching the LED on for 1 second, we now need to switch it off
again for another 1 second.
In order to switch the LED off again we need another setBuiltInLED block –
so drag another setBuiltInLED method from the cpu peripheral into the
flowchart (similar to Step 1), inserting it after the 1s delay.
By default, the setBuiltInLED method switches the LED “on”; we need to
change our newly added block so that it instead switches the LED “off”. In
order to do so, right click on the block and select “Edit” from the popup
menu.
Step 5: In the Edit I/O Block dialog, enter “OFF” for the “State:” argument.
(Tip: For readers who have some prior programming experience, you may be
interested to know that “ON” in Proteus Visual Designer is a defined alias for
“TRUE”.)
Step 6: Now that the LED has been switched off again, we need to keep it off
for 1 second before the loop repeats and switches the LED back on again. In
order to do so, add a 1s delay after the second setBuiltInLED routine (similar
to steps 2 and 3).
Once done, the Loop routine of the flowchart should look like the following
figure.
Figure 2-23: Blink LED flowchart
Check that the sequence and details of the blocks in your flowchart exactly
match those of Figure 2-23 (if not, then please go through the steps of this
tutorial again to check that nothing has been missed). The flowchart Setup
routine should still be empty.
Congratulations! The “Blink LED” program flowchart is now complete.
2.6. Running the Simulation
To see our flowchart program in action, we can proceed to running the
simulation. To do so, click the blue “Play” button at the bottom-left of the
Proteus window (Figure 2-24).
Figure 2-24: Starting the simulation
Upon clicking the blue triangular play button, Proteus first compiles the
flowchart so that it can be simulated (please see Step 3 of section 2.2 if you
need a reminder of what a compiler does).
If there are any problems with the flowchart, error messages will be
displayed in the compiler output. If not, then a green “Completed
successfully” message will be displayed.
(Tip: Compilation can also be triggered manually by selecting “Build Project”
from the “Build” menu.)
Once the project has compiled successfully, the simulation will start (Figure
2-26).
Figure 2-26: Running simulation
You should see a yellow LED flashing on and off with a 1 second delay in-
between, as specified by our flowchart program.
Once done, click the blue rectangular “Stop” button (see Figure 2-26) to end
the simulation. Congratulations! You have now built and simulated a
working program.
(Tip: You may wish to save your work. This can be done using the “Save
Project” command available from the File menu, by clicking on the Save
button ( ) on the toolbar, or by pressing Ctrl + S on your keyboard.)
If you would like to experiment a little more, then try changing the time of
the delays and see how this changes the timing of the LED blinking.
If you are wondering how your program can be transferred to “real world”
hardware, then please note that this is discussed in section 2.7.4.
2.7. Further Information
2.7.1. What LED Are We Blinking?
The Arduino Uno which we selected for use in our project during the “New
Project Wizard” (see Figure 2-3) is a low-cost “development board”; it
essentially features a microcontroller, some supporting electronic circuitry
(such as circuitry for handling the power supply to the board), and a built-in
on-board LED. Connectors (“headers” or “sockets”) are also featured around
the edges of the board, which can be used to more easily connect external
peripheral circuits to the microcontroller (see Figure 2-27).
Connections
Microcontroller
Built-in LED
The “Tear Off” command is also available from the main Edit menu. Blocks
can also be detached by holding down the Ctrl key on the keyboard, then
clicking on them and dragging them out of the flowchart.
You may wish to try out some of the above techniques now, to make sure
that you are familiar with them.
2.7.4. Uploading the Program to Physical Hardware (Optional)
If you have the physical hardware for a project available (in this case, just an
Arduino Uno board), then your program can be uploaded to that hardware
with ease straight from within Proteus. The commands needed to
accomplish this are available from the Build menu (when the Visual Designer
tab is open).
First, the correct settings should be set for uploading. This is done in the
“Project Options” dialog, which can be opened by selecting the “Project
Settings” option from the Build menu (when the Visual Designer tab is
open). The Project Options dialog is displayed in the following figure (Figure
2-31).
Figure 2-31: Project Options dialog
Action Yes
Decision
No
Actions (“Telling”) Decisions (“Asking”)
Whilst our first project introduced actions (by “telling” a light to turn on and
off), this chapter introduces decisions (“asking”). Whilst actions only have
one flowline coming in and one flowline going out, decisions have one
flowline coming in and two flowlines going out. Depending on the answer to
the question which the decision block asks, the program will choose to
follow one of the two outgoing lines.
“Question”: Path to follow if the answer is “NO”
“Is the temperature
greater than 30?”
When the loop starts, the program asks the button (B1) whether it is
pressed or not (decision block). If the answer is “Yes” then the program goes
the route of switching the LED on, and if the answer is “No” then the
program goes the route of switching the LED off. Since these flowchart
blocks are placed within the “Loop” routine (see section 2.4.3), the process
will obviously repeat continually.
3.3. Starting the Project
To get started building the flowchart, please complete the following steps:
1. Save ( ) any existing project which you may have open (if you do not
want to lose it). This can be done using the “Save Project” command
available from the File menu.
2. Close ( ) any existing project which you may have open. This can be
done using the “Close Project” command available from the File menu.
You should now see the Proteus Home Page ( ) tab, as illustrated in
Figure 2-1.
3. Start a new flowchart project, using “Button-LED” as the project name
(if you need a reminder on the steps, then please see section 2.2).
3.4. Adding Peripherals to the Project
As discussed in section 2.3.4, peripherals are largely objects which can be
added to the project, such as buttons / display screens / temperature
sensors / etc. For this project, we are going to add a button and an external
LED (different to the built-in LED which we used in the previous chapter) to
the project.
Peripherals are added to the project using the “Peripheral Gallery”, which
can be accessed by selecting “Add Peripheral” from the Project menu. The
Peripheral Gallery can also be accessed by right-clicking on the Peripherals
section of the project summary, and then selecting “Add Peripheral” from
the popup menu (see Figure 3-2).
The “Peripherals” section of the Project Summary should now contain “BTN1
(Grove Button)” and “LED1 (Grove LED)” peripherals (as illustrated in the
following figure).
Figure 3-4: Peripherals added to Project
If you have accidentally added more peripherals than were required, then
these can be removed from the project again by right-clicking on them and
then selecting “Remove Peripheral” from the popup menu.
More information regarding what exactly the “Grove” peripherals are is
included at the end of this chapter (sections 3.8.1 and 3.8.2).
3.5. Drawing the Flowchart
Once the peripherals have been added to our project, then the next step is
to add the decision block, which asks the button whether it is pressed or
not, to our flowchart. This can be done by clicking on the button peripheral
and then dragging it into the Loop routine (as illustrated by the following
figure).
Now that the decision block has been added, the next steps are to add the
actions to be taken based on the possible outcomes of the decision. To
proceed, drag an “on” method from LED1 into the flowchart, inserting it
after the button decision block (as illustrated in the following figure).
Figure 3-6: Inserting LED "on" method
The last block needed to complete the flowchart is an “off” method from
LED1. Add it as depicted in the following figure.
Whilst the “off” block has now been added to the flowchart, it is still not
“connected” to it yet. To connect it to the button decision block, please
complete the following sequence:
Click once on the black dot on the right of the button decision block, and
then click again on the black dot on the top of the “off” action block. This
procedure is illustrated in the following figure.
Figure 3-8: Connecting flowchart blocks
The “off” block can now be reached from the button decision block,
however the flowchart doesn’t have anywhere to go from there (once it has
reached the “off” block, it is “stuck”). In order to complete the connection
process, add a flowline from the “off” block back to the main loop routine,
as illustrated in the following figure:
Now, if the program flow reached the “off” block, it can carry on back to the
loop routine, and continue program execution. Your flowchart should now
look similar to the following figure.
Figure 3-10: Completed Button-LED flowchart
Don’t worry if the positions of the blocks don’t exactly match those of Figure
3-10. So long as the ordering (“sequence”) of the blocks is the same, the
program will work.
3.6. Running the Simulation
Once ready, click on the blue triangular “Play” button (at the bottom-left of
the window) to run the simulation. If you receive any error messages, then
double-check that the flowchart matches Figure 3-10, and that it was a
“Grove LED (Green)” peripheral which was added to the project (the reason
for this is discussed at the end of this chapter, in section 3.8.2). Once the
simulation starts, you can click on the Grove Button to turn the Grove LED
on (see Figure 3-11; the Grove Button and LED would normally appear at the
bottom-right of the screen).
Remember to stop the simulation when done (blue square “Stop” button at
the bottom-left of the window).
3.7. Inverting the Logic
Next, let’s swop things around so that the LED is off when the button is
pressed, and on when it is not pressed. To do so, first make sure that the
simulation has been stopped (blue rectangular stop button at the bottom-
left of the window). Next right-click on the decision block in the project and
select “Swap Yes/No” (Figure 3-12).
Run the simulation again, and you should now find that the button does the
opposite of what it did before – the LED should now turn on when the
button is not pressed, and turn off when it is pressed (Figure 3-14 and Figure
3-15).
That concludes the project for this chapter! If you have completed and
understood the chapter, then you now know how to use decision blocks in a
project!
3.8. Further Information
3.8.1. The “Grove” System
“Grove” is a system of add-on peripheral boards produced by Seeed Studio
(www.seeedstudio.com). The system includes many interface and sensor
boards, such as the button and LED boards which we have just used in this
project. The peripheral boards are connected to a “Base Board” via cables.
The “Base Board” is plugged in on top of the Arduino Uno.
The peripherals for this project were carefully chosen, as the Grove Button is
connected to “D2” by default, and the Grove LED (Green) is connected to
“D3” by default. The Blue, Red and Yellow Grove LEDs are however
connected to “D2” by default – obviously it is not possible to plug two
boards into the same connector, and so if we had tried to use one of these
LEDs then Proteus would have reported:
Watermelons 21
Bags of Potatoes 35
Lettuces 39
To start off with, let’s imagine that they initially counted that there were 21
watermelons in stock, and wrote this down on their sheet.
Next, a customer comes in and purchases 3 watermelons. The number of
watermelons in stock is now 3 less. To put this another way, the new
watermelon count is equal to the old watermelon count minus 3:
Watermelons = Watermelons - 3
The new watermelon stock count is thus now 21 – 3 = 17. Imagine that the
person keeping stock is writing the stock counts in pencil, so they can erase
them and write new stock counts as they change. They erase the old count
of 21, and write the new count of 17 instead.
Next, the store receives a delivery from the supplier of another 9
watermelons. The number of watermelons in stock is now plus 9, or put
another way the new watermelon count is equal to the old watermelon
count plus 9:
Watermelons = Watermelons + 9
The new watermelon stock count is thus now 17 + 9 = 26. The person
keeping stock erases the old count of 17, and writes the new count of 26.
The watermelon count in the previous example is a “variable”. The name of
the variable is “Watermelons” and the value of the variable is the number of
watermelons in stock (starting at 21, then becoming 17, and then 26).
4.1. Displaying Text on an LCD
To illustrate the use of variables in a flowchart program, let’s start with an
example:
1. Save ( ) any existing project which you may have open (if you do not
want to lose it).
2. Close ( ) any existing project which you may have open. You should
now see the Proteus Home Page ( ) tab, as illustrated in Figure 2-1.
3. Start a new flowchart project, using “Variables” as the project name (if
you need a reminder on the steps then please see section 2.2).
4. Add a “Grove RGB LCD Module” peripheral to the project from the
project gallery (“Grove” Peripheral Category). If you need a reminder
on how to add a peripheral to the project, then please see section 3.4.
Once added, the peripheral should be listed as “LCD1 (Grove RGB
LCD)”.
“LCD” stands for “Liquid Crystal Display9”, and is a type of electronic display
which you will surely have encountered many times in everyday life.
The Grove RGB LCD module has two lines (rows) of text, and up to 16
characters can be displayed on each row.
To start constructing our flowchart, drag the “print” method from the Grove
RGB LCD into the flowchart “Setup” routine.
Run the simulation (“Play” button), and you should see the text “Hello
World!” displayed on the LCD.
Note that the row and column (“col”) values are “zero-based”. This means
that the top row is “row 0” and the bottom row is “row 1”; the leftmost
column is “column 0” and the rightmost column is “column 15”.
Columns
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Rows
0 H e l l o W o r l d !
1
In order to display text at the start of the second row on the LCD, we need
to specify row 1 and column 0, as depicted in the previous figure (Figure 4-
7). Once done, click “OK”.
You may be wondering why we didn’t need to do this when we displayed
the “Hello World!” text originally; the answer is that the LCD is set to start
displaying text at the top-left by default (“home” position).
Now that we’ve told the LCD where we want to display text next (using the
setCursor method), we can proceed to telling the LCD what we’d like to print
there. Drag another “print” method into the flowchart, and insert it after the
setCursor block. Edit the properties for the new cursor block (please see the
steps for this described earlier in this chapter if you need a reminder), and
specify "Count:" (including the quotations) as the text to be displayed. Your
flowchart should now look like the following figure:
Run the simulation, and you should see that “Count:” is now displayed on
the bottom line of the LCD (in addition to the “Hello World!” text on the top
line).
Congratulations! You have now created your new variable called “counter”,
which should appear under the list of variables.
Under “Assignments”, select the “counter” variable from the dropdown, and
type 0 into the box to the right of the dropdown. This means that we are
going to set “counter” to a value of 0 in this assignment block. When done,
click “OK”. Your flowchart should now look like the following figure:
Figure 4-13: Flowchart with variable assignment
4.3. Types of Variables
In the previous section, when creating a new variable, you may have noticed
that there was an option to choose the variable “type”.
Name:
Date
of
Birth:
Note: Insert only one letter or number per block
You may be able to fill your name in within the number of blocks provided,
but there is no way that you could fill your date of birth in with just 3 blocks!
The form should rather have 10 blocks:
Date of / /
Birth:
This way you could fill in a full date, such as 05/08/1983.
In much the same way, the computer only has a certain number of blocks
available depending on the variable type. A Boolean variable can only be 1
or 0 (interpreted as “Yes” or “No” / “True” or “False”) – you cannot store the
number 972 in it, because there just isn’t enough space in it.
As mentioned however, so long as you simply choose the right type of
variable for the type of information which you would like to store, you
needn’t worry about how much space the computer has available to store it
for practical purposes – this section has just been inserted for the curious.
4.4. Using Variables in a Project
Now that we have added the “counter” variable to our project, we can
proceed to using it in the program.
We essentially want to perform the following steps in our program:
1. Increment the value of the number stored in the counter variable
(increase it by 1).
2. Tell the LCD where we would like to display something next (on which
row and column, “setCursor” method.).
3. Tell the LCD to display the value of the counter variable.
4. Wait 1 second.
(Repeat)
This is represented by the following flowchart:
Click “OK” once done. The full statement now reads counter := counter + 1 (
). When this instruction is executed during flowchart
operation, it takes the old value of the counter, adds 1 to it, and stores the
new value back into the counter variable. So if counter was 0, the computer
adds 1 to it; 0 + 1 equals 1, so the computer stores the new value of 1 back
in the counter variable. The next time the statement is executed the counter
is currently 1, so the calculation becomes 1 + 1 which equals 2. The next
time the calculation becomes 2 + 1 which equals 3, and so forth. Many other
mathematical operations besides for + 1 can be constructed – for example
counter := counter - 1, counter := counter + 5 or counter := counter * 3
(multiplied by 3) – a summary of the mathematical operators which can be
used is provided in section 4.6.
4.4.2. Displaying the Value of a Variable on an LCD
The next steps after incrementing the counter is to tell the LCD where we
would like to display text next (“setCursor” method), and then display the
value of the counter variable at that location. At this stage in the program,
we are already displaying the following on the LCD:
Columns
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Rows
0 H e l l o W o r l d !
1 C o u n t :
A good place to display the value of our counter variable at is therefore
going to be row 1 and column 7 (highlighted in red). To tell the LCD that we
would like to display text at row 1 and column 7 next, drag a setCursor
method into the flowchart, inserting it after the assignment block which was
added in the previous step. Then, edit the setCursor block and set the row to
1 and column to 7. If you need a reminder on how to add a setCursor
method to the flowchart and edit its properties, then please see the latter
part of section 4.1.
Next, drag a “print” method into the flowchart, inserting it after the
setCursor method which was inserted in the previous step. Edit the print
block and enter “counter” (excluding the quotes) under “Arguments”, as
illustrated in the following figure:
You may be wondering why we sometimes enter text under the print
methods arguments with quotes, and sometimes without – this will be
discussed in a following section (section 4.5), but the short answer for now is
that variable names are entered without quotes.
4.4.3. Completing the Flowchart which Displays an Incrementing
Variable on the LCD
The final step is to wait 1 second before repeating the process (otherwise it
would happen so fast that we wouldn’t be able to see anything!). Drag a
delay block ( ) into the flowchart after the print block, and set the delay
time to 1000ms (by editing the delay block).
Your flowchart should now look like the one in Figure 4-15. If it does not,
then please go through go through the steps again carefully.
Once ready, run the simulation. There should now be a number displayed
next to “Count:”, which increments each second!
4.5. Using Text in Arguments
You may have noticed that when we wanted to display text on the LCD then
we placed it in quotes (e.g. "Counter:"), but when we wanted to display the
value of a variable we entered the variable name without quotes (just
counter). The reason for this can be explained by the following problem:
What if we wanted to display the actual text “counter” on the display, rather
than the value of the variable called “counter”? This is a problem which the
designers of computer programming languages faced, and the solution was
to place text within quotes (" "). The quotes do not form part of the
interpreted text – in this case they are not displayed on the LCD – they
simply help the compiler to understand whether we mean the variable
counter, or the text counter.
Variable Text
4.6. Mathematical Operations Using Variables
As we saw when incrementing the counter variable (counter := counter + 1),
it is possible to perform mathematical calculations using variables. The
following mathematical operations can be performed:
Symbol Operation
(Operator)
+ Add
- Subtract
* Multiply
/ Divide
% Modulus13 (remainder after division)
Note that mathematical operations can become much more complex than
simply incrementing a variable, and brackets can be used within equations.
For example, to calculate the area of a triangle, using variables “area”,
“base” and “height”, the following equation could be used: area = (base *
height) / 2 (“area equals base times height, divided by two”).
4.7. Using Variables in Conditions
Variables can also be used when asking questions (such as in decision
blocks). For the next part of our project, we will build on our flowchart so
that the text “More than 10!” is displayed on the top line of the LCD when
the value of the “counter” variable becomes greater than 10. The flowchart
needed to accomplish this is detailed in the following figure:
The following flowchart blocks have been added (highlighted in Figure 4-18):
1. A decision block which checks whether the value of the counter
variable is greater than 10.
2. The LCD “home” method, which is a shortcut for (equivalent to) the
setCursor method with row and column values of 0.
3. An LCD “print” method to display the text “More than 10!” on the LCD.
In order to update your flowchart so that it matches the one in Figure 4-18,
start by adding a decision block into the flowchart, above the 1000ms delay
block:
Right-click on the decision block and select “Edit” from the popup menu (or
left-click on the decision block twice), in order to bring up the “Edit Decision
Block” dialog. Enter “counter>10” (without the quotations) under the
“Condition” section of the dialog (as illustrated by the following figure).
Figure 4-20: Inserting the condition in the Edit Decision Block dialog
Once completed click “OK”. Next add the LCD “home” and “print” methods
to the flowchart, so that it matches the one in Figure 4-18. The LCD “print”
block should be edited and the text "More than 10!" inserted under
“Arguments” (for a reminder on how to do this, please see section 4.1).
Swap the “Yes” and “No” on the decision block so that “Yes” it matches
Figure 4-18 (right click on the decision block and then select “Swap Yes/No”
from the popup menu).
Once ready, run the simulation. Once the counter reaches the number 11,
the text “More than 10!” is displayed on the top line of the LCD. (If the
simulation does not perform as expected, then please check that your
flowchart exactly matches the one from Figure 4-18.)
4.8. Relational Operators
Relational operators are used in conditions (such as in the decision block), to
ask a question which will have an answer of “Yes” or “No”. In the example,
we asked the question “Is the value of counter greater than 10?” (“counter >
10”). Other relational operators besides for “greater than” are also available
however.
Symbol Operation
(Operator) (Question)
= Equal to?
!= Not equal to?
> Greater than?
< Smaller than?
>= Greater than or equal to?
<= Smaller than or equal to?
4.9. Logical Operators
Logical operators can be used in conjunction with relational operators to ask
more complex questions, and include the operators AND, OR and NOT. For
example, “If the kettle is boiled AND there is a mug on the counter, then
pour the hot water into the mug”. Brackets can also be used when creating
more complex conditions, in much the same way as they can be used with
mathematical operators. The result achieved by using logical operators can
also be achieved by using multiple decision blocks, so do not worry if you do
not understand them. We will not be using them in this book, and they are
mentioned only for the sake of being thorough.
Symbol Operation
(Operator) (Question)
&& And
|| Or
! Not
For example, (distance > 5 && distance < 10) || (weight > 15) (“distance
greater than 5 and distance smaller than 10, or weight greater than 15?”).
4.10. Final Project Step
For the final project step, we will be adding a button which sets the value of
the counter variable to 20 whenever it is pressed. The final flowchart, after
adding this feature, is detailed in the following figure.
Once the project opens, it should look like the following figure.
Figure 5-2: Schematic capture tab with “Basic Electricity 1” sample project open
The Schematic Capture tab, and how to draw your own schematics, will be
covered in more detail in a following chapter. For now we only need to know
how to open a sample project, navigate around it if necessary (zoom and
pan), and run the simulation. Zooming and panning works the same as in the
Visual Designer (flowchart) environment – in case you would like a refresher
on this, please see section 2.3.5 in the “Creating Your First Project” chapter.
5.2. Simple Electrical Circuit
This section assumes that the project opened in the previous section is still
open (if not, then please open it again).
Switch
Battery Lamp
Figure 5-3 illustrates the project’s circuit. This circuit essentially consists of a
battery, a switch and a lamp. The battery stores electrical energy that can be
used to power the lamp. The purpose of the switch is to complete or break
the circuit, thus turning the lamp ON or OFF. This circuit can be simulated in
Proteus and can be interacted with during the simulation – i.e. the switch
can be closed or opened by clicking on it. To run the simulation, click the
“Play” button (blue triangle) in the bottom-left corner of the Proteus
Schematic Capture window.
When running the simulation, it can be observed that when the switch is in
the closed (ON) state, this allows for electricity to flow from the battery
through the lamp. The battery is said to have the “potential” to supply
electricity.
The positive side of the battery is said to have a “high potential” and the
negative side of the battery a “low potential”.
An analogy for this is water in a high dam (positive side of the battery),
which can flow to water in a low dam (negative side of the battery), via a
water-wheel (“load”, in this case a lamp). Note that it doesn’t matter how
big the dams are. The water flows because of the difference in height of the
dams, not because of how big or small they are. The flow of water can be
started or stopped by a sluice gate (switch). Whilst the water is in the high
dam it has the potential (high potential) to “do work”, by turning the water-
wheel as it flows down to the lower dam. Once it has flowed down to the
lower dam however, it does not have that potential anymore (low
potential). In a similar way, electricity is said to flow from a point of high
potential (positive side of the battery) to a point of low potential (negative
side of the battery), when the two points are connected by a circuit.
The difference in potential (between high and low) is called “potential
difference” (PD).
For electricity, the unit used to measure potential difference is called
Voltage.
As a consequence of this potential difference or “pressure” exerted by the
battery, electrical energy flows through the lamp and is converted into light
(when the switch is ON). When the switch is turned OFF, it can be observed
that the lamp remains OFF as the electricity is not able to flow through it.
5.3. Ohms Law (Voltage, Current and Resistance)
Consider the following experiment, involving a bucket with a pipe connected
to it, and a tap at the end of the pipe.
Bucket with
Table water
Pipe Tap
Chair
- Voltage is the height of the bucket. The higher we lift the bucket, the
greater the “potential difference” (height difference between the
bucket and the outlet tap). Note that it doesn’t matter how big or
small the bucket is, it is the height of the bucket which matters.
- Resistance is the tap. If we close the tap then it presents a greater
resistance to the flow of water, and if we open the tap then it
presents less resistance to the flow of water.
- Current is the amount of water coming out of the tap outlet – how
much is coming out (millilitres per second, for example). The current
would determine how long it would take to fill a glass, for example.
Lower current means that it would take longer to fill a glass, and
higher current means that it would take shorter to fill a glass.
I R
If Voltage remains the same, and the resistance is decreased, then the
current increases (and vice versa).
If Resistance remains the same, and the voltage is increased, then the
current increases (and vice versa).
You may be wondering about things like what the amount of water in the
bucket represents. In electricity, the total amount of water in the bucket can
be measured in “Coulombs” or “Amp-Hours”. “Amps” are the unit of
measurement for current, and will be discussed in the next section. “Amp-
Hours” refers to how many hours a power source can supply 1 “Amp” of
current for. Referring back to the water example, if we can supply 2 litres of
water per hour for 3 hours, then the total “amount” of water will be 2 x 3 =
6 litres. You may have been batteries which have a milliAmp-Hour (mAh)
rating before.
To proceed to a Proteus simulation demonstrating Ohm’s Law in action,
open the “Interactive Simulation: Basic Electricity 2” sample project (using
the procedure described previously in section 5.1).
The Basic Electricity 2 sample project is another interactive simulation,
which demonstrates the effect of introducing “variable resistance” into the
lamp circuit from section 5.2. Whilst a switch is either “on” or “off”, a
variable resistor can be thought of as a “tap” or “valve” in the circuit, which
can be adjusted to control the flow through the circuit. Opening the tap
allows for more or quicker flow, whilst closing the tap results in less or
slower flow.
Variable
resistor
Decrease Increase
current current
12 V 12 V
Battery Lamp
If you should feel so inclined then there are also further sample projects
available demonstrating electronic components and concepts such as
capacitors, diodes, transistors, OpAmps, Logic Gates, Sequential Logic
Circuits, Oscillators and more. For the purposes of this course however, a
grasp of the basic electrical concepts just covered is sufficient.
6. Drawing and Simulating Circuits
Whilst we have been using sample designs for circuit simulation up till now,
this chapter aims to teach how to draw your own circuits (schematics).
Besides for being a useful skill on its own, this will also allow us to draw
custom circuits to interact with our microcontroller and flowcharts.
6.1. For the Curious, an Overview of the Electronic Design
Process
As mentioned in the introduction, a schematic is an electronic wiring
diagram. It shows what is connected to what, but not exactly how.
In the electronic design process, after designing a schematic the circuit is
generally converted into a PCB (printed-circuit-board) layout, which is a
physical circuit implementing the “theoretical” connections specified in the
schematic. Note that it is obviously possible to create multiple different PCB
layouts from the same schematic. Below is an example of a schematic as
well as a possible PCB layout thereof.
Figure 6-2:
Figure 6-1: Example schematic Example PCB
Layout
Once a schematic has been drawn, it is converted into at least one PCB
Layout. The PCB design is then sent to a PCB manufacturer, who
manufactures the printed-circuit-board. At this stage, the PCB contains only
the “wires” on the schematic, but none of the components. The PCB is then
“populated” by soldering components onto it.
Proteus can be used to design schematics as well as layout PCBs, however
PCB layout is beyond the scope of this book as we will be using ready-made
PCBs such as the Arduino UNO board.
(Tip: Besides for the instructions listed in this chapter, a Schematic Capture
Tutorial and Help File are also available from the Help menu in Proteus when
the Schematic Capture tab is open.)
6.2. Schematic Capture Environment Overview
To start with, please ensure that you have any project open which contains a
schematic (if you’re unsure of what to do then simply open the “Blinking LED
for Arduino Uno” sample project by selecting “Open Sample Project” from
the File menu, and then selecting it from the “Visual Designer for Arduino”
category).
Figure 6-4: Proteus schematic capture tab
The schematic capture tab screen essentially consists of three main areas;
the Overview area, Object Selector area and Editing area.
The editing area is where components are placed and connected (“wired-
up”), in order to construct the electrical circuit. When a new Visual Designer
project is created, Proteus automatically adds the microcontroller board
(Arduino UNO in this case) to the schematic capture editing area (illustrated
in the previous figure).
The overview area gives (as its name suggests) an overview of the entire
schematic. When a new object is selected from the Object Selector however,
then the Overview area is used to preview the selected object (this will be
described in more detail later).
The Object Selector area normally contains a list of components (e.g.
buttons, LEDs, buzzers) which have been selected (or “picked”) for use in the
project / schematic (the procedure for picking parts will be described
shortly). If a tool mode other than Selection Mode or Component Mode
(more on this shortly) is selected however, then the Object Selector will
change depending on which tool is selected.
Figure 6-5: Schematic capture toolbars
The schematic capture tab has essentially two main toolbars, a horizontal
toolbar and a vertical toolbar (Tool Mode Toolbar). The horizontal toolbar
contains buttons pertaining to project file management (e.g. opening a new
project, saving the project) as well as tools such as zooming, etc. The vertical
toolbar (Tool Mode Toolbar) contains all the tools which can be used to
draw the schematic.
6.3. Picking, Placing and Wiring Up Components
6.3.1. Picking Components
If not already available in the Object Selector list, then new components can
be picked for use in the schematic from the Parts Library. With Selection tool
mode ( ) or Component Mode ( ) selected; click on the P button above
the Object Selector area (see the following figure) or alternatively use the
keyboard shortcut (i.e. “P” key).
Components (e.g. LEDs, resistors, lamps, etc) can then be added to the
Object Selector from the Parts library, so that they are available for use in
the schematic.
Figure 6-7: Overview of the Proteus Parts Library
Note that you must click on the component “drawing” or “body” (Figure 6-
9), rather than on the reference text or value text, in order to properly bring
up the “Edit Component” dialog. Clicking on the reference or value texts will
instead bring up an “Edit Label” dialog for that particular text, which allows
for editing of just the specific label which was selected (reference label or
value label). The full “Edit Component” dialog, which is brought up by rather
clicking on the component body, allows for editing of the component
reference and value (as well as other advanced parameters) at the same
time.
Left-clicking on a component once it has already been tagged (is red) will
have the same effect as the “Edit Component” command available from the
right-click popup menu (will also bring up the “Edit Component” dialog).
Thus, left-clicking twice on an untagged component is a shortcut to the “Edit
Component” dialog.
Proteus automatically increments the component references of newly
placed components to ensure that they are unique, so there is normally no
need to edit these manually. You may however wish to edit the value of, for
example, a resistor (in order to change its resistance).
6.3.6. Making Electrical Connections between Components (“Wiring
Up”)
Once the required components are all added to (placed on) the schematic,
these components can then be electrically connected together – or “wired
up” – as required.
6.3.6.1. “Follow-Me” Wire Routing
The “Follow-Me” Wire Router is available in all tool modes. Components
contain “pins”, which are normally fairly obviously visible but which can be
verified by hovering the mouse pointer over them. When the mouse is
hovered over a component pin, then a green pencil ( ) will appear,
indicating that a wire can be drawn from/to this point. Wiring is started by
clicking on the start point for a wire and then clicking again on the end point
for the wire. The following figure illustrates this procedure.
Figure 6-13: Making an electrical connection with a wire – from start to finish
(Tip: Clicking along the route whilst tracing the wire will anchor it at that
specific point. After the wire has been drawn, it can be moved by first
selecting it (after which it will turn red to indicate that it has been “tagged”),
and then dragging it – or by right-clicking on the wire and then selecting
“Drag Wire” from the popup menu. A wire can also be deleted by using the
applicable command available from the right-click popup menu, or by right-
clicking on it twice.)
6.3.6.2. Making Connections with Terminals
Because having many wires running all over a schematic can get messy and
confusing, an alternative method for making a connection between two pins
also exists, called “Terminals”.
Two or more terminals will be considered electrically “connected” if they
have the same name. This allows for an electrical connection to be made
between two pins without having to draw a wire between them. Figure 6-14
illustrates a connection made via terminals between the PB5/SCK/PCINT4
pin on the Arduino Uno microcontroller, and the resistor next to the LED
(with the terminals bearing the common name of “IO13”). This connection
enabled us to blink the LED in our first project.
Terminals should be wired up in the normal way (section 6.3.6.1) to the pins
of the components which they should be connected to. Note that simply
placing two components or terminals so that their pins “look” connected
(overlap) does not mean that they are actually connected – they must be
joined by a wire!
Note that an alternative method for placing a terminal (as well as other
components) on the schematic is to right-click on an empty spot in the
editing area, and then select Place – Terminal from the popup menu (Figure
6-17).
Figure 6-17: Adding a terminal point to the schematic from the right-click popup menu
Drawing this schematic will test all the skills learned in this chapter, and will
also allow us to simulate the principles learned in the previous chapter
(Ohm’s law).
(Tip: Besides for the instructions listed in this chapter, a Schematic Capture
Tutorial and Help File are also available from the Help menu in Proteus when
the Schematic Capture tab is open.)
To draw the schematic illustrated in Figure 6-19, follow the below steps.
1. Save ( ) any work which you may have open and don’t want to lose,
and then close ( ) any open project (File menu and then Close
Project).
2. Click on the Schematic Capture icon ( ) to open the Schematic Capture
tab (you may also start a new project if you wish, however the
aforementioned method is a quick shortcut – the project can be called
“SimpleCircuit” if using the New Project wizard, and could also be saved
under this name by using the Save command if using the former
method).
3. Pick the following components from the Component Library (if you
need a reminder on how to pick components then please section 6.3.1
– when in Component Mode ( ), click the button above the Object
Selector). The easiest method for finding the components in the library
is to type their names into the “Keywords” box.
a. RES (“Resistor”)15.
b. POT-HG (“Potentiometer”, another name for a variable resistor).
c. SW-SPST (a switch – technically a “single-throw single-pole”
switch, the explanation for which is beyond the scope of this
book).
4. Place the components and terminals (one power terminal and one
ground terminal) on the schematic.
5. Also select “Virtual Instrument” tool mode ( ) on the vertical toolbar,
and place a DC Ammeter and 2 x DC Voltmeters on the schematic
(these will be listed in the Object Selector when “Virtual Instrument”
tool mode is selected).
6. Change the following properties of the components / terminals /
instruments:
a. Set the Power Terminal for +5V.
b. Change the resistance of the resistor to 1k.
c. Change the Display Range of the DC Ammeter to “Milliamps” (this
can be done from the Edit Component dialogue for the DC
Ammeter, by the “Display Range” option which is below the Part
Reference and Part Value settings).
7. Move, rotate and flip components as necessary, and wire everything
up, till your schematic looks like the previous figure. Note that some
components, such as the SW-SPST, can be difficult to “get hold of” for
moving due to having interactive elements (which “interact” when
clicked on rather than allowing for moving) – in this case it can be
easier to right-click on the component and then select “Drag Object”
from the popup menu, or drag a box around the component and then
move it.
8. Save your work! (As mentioned, the project can be called
“SimpleCircuit”, if it has not already been assigned a filename.)
We are now ready to simulate the circuit. This circuit allows us to
experiment with the principles of voltage, current and resistance described
in the previous chapter.
(Tip: If you would like your circuit to have arrows on it indicating current
flow, like the circuits in the Interactive Simulation sample projects do, then
do the following: With the simulation stopped, click the System Menu, select
Animation Options, tick the “Show Wire Voltage by Colour?” and “Show
Wire Current with Arrows?” options, and then click ok – when you run the
simulation again, then the arrows will appear.)
7. Drawing Custom Peripherals
Up till now, we have been using ready-made circuits in our flowchart
projects. Proteus automatically inserts the microcontroller circuitry onto the
schematic when starting a new project, and automatically inserts the
circuitry for a peripheral (button, LED, LCD, etc) when it is added to the
project from the peripheral gallery in Visual Designer. This mimics the way in
which rapid-prototyping boards (such as the Arduino Uno board itself, and
the Grove system of peripherals or add-on boards) can be used to construct
a project in the “real-world”. It is also obviously possible however, both in
simulation and in the real-world, to construct custom circuits to interact
with the microcontroller.
In the world of Arduino, custom circuits are sometimes built using a
technique called “breadboarding”.
Figure 7-1: Breadboarding16
The previous figure may look somewhat complicated, but don’t worry –
drawing custom circuits in Proteus is a lot less confusing, less prone to errors
(such as incorrect or loose connections), and easier to debug in the case of a
problem.
A breadboard is a plastic board with holes in it, which are electrically
connected in a certain pattern. Components and jumper-wires (jumper-
wires are simply wires with pins on the ends) can be inserted into the
breadboard holes in order to build a circuit. Other options for building a
real-life custom circuit include stripboard such as Veroboard (which is similar
to a breadboard, but not reusable), or designing your own PCB (as
mentioned in a previous chapter). Since we can and will be building and
simulating our circuit in Proteus, and because the focus of this course is
mostly circuit and software design, it is not necessary to cover
breadboarding in depth. If you would however like to construct a “real-life”
version of the circuit we will be building in this tutorial, then there are plenty
of resources regarding how to breadboard online.
7.1. Project Summary: Sequencing LEDs
For this chapter, we will be drawing circuitry and constructing a flowchart to
sequence some LEDs (flash them one after another). We will also control the
speed of sequencing using a potentiometer (variable resistor – this will be
described in more detail shortly). The final circuitry is illustrated in the
following figure (note how much tidier this looks than the breadboard
situation!):
Digital pin
terminals
Arduino Uno
circuitry
(inserted
automatically) Potentiometer
for controlling
speed of
sequencing
5 x LED circuits
Terminal
connecting to
digital pin 7 on the
Arduino UNO GROUND terminal
Figure 7-3: LED circuit
The basic principle is that when the Arduino Uno sets an output pin “high”
(“on” or “true”) in the software (flowchart), then it generates an output
voltage of 5 volts on that pin. Because of the potential difference between
the output pin (5 volts) and ground (0V), electricity flows from that pin,
through the LED and resistor (lighting up the LED in the process), and down
to ground (0V). When the pin is set “low” (“off” or “false”), then it generates
an output voltage of zero volts (0V) on that pin – because there is no
potential difference between zero volts and ground (both 0V), no electricity
flows (and the LED turns “off”). LEDs themselves are diodes (LED stands for
“light-emitting-diode”). We won’t go in-depth into what diodes are here, but
by way of explaining the need for the resistor we should know that diodes
do not have any resistance as such. Without an “extra” resistor in the circuit,
there is not much resistance to the flow of electricity in the circuit, and this
can result in “too much” electric current flowing through the circuit. Too
much electric current flowing through the LED can damage it. Thus, the LED
needs a resistor in its circuit (“in series” with it), in order to limit the amount
of current which will flow through it (in accordance with Ohm’s law). This
resistor is called a “current-limiting resistor”, due to its application in the
circuit. Does it matter if the resistor is “before” or “after” the LED? The
answer is “no”. Whether you place a tap at one end of a pipe or the other,
you can still control/limit the amount of water flowing through the pipe
using the tap. In mathematical terms, the current flowing through the circuit
is I = V / R (see section 5.3). Since the LED does not have any resistance as
such, the amount of current (I) flowing through the circuit is determined by
the voltage (V, 5V from the Arduino pin) and the resistance in the circuit
(330R). Without the resistor the resistance in the circuit would be very small,
resulting in a small R value and thus large I value in the equation – meaning
a large current (which could cause the “magic smoke”17 inside the LED to
escape).
7.4. Analogue and Digital Electronics
You may have noticed in the previous section that we have connected the
LEDs to “IO3”-“IO7” (standing for input/output 3 to 7), and that we have
connected the potentiometer (variable resistor) to “AD0” (standing for
analogue/digital zero).
Digital electronics refers to electronics which think of everything in ones and
zeroes – on or off, true or false, high or low. Inside a microprocessor, this is
how things work. For the Arduino, this corresponds to five (5) volts (“on” /
“true” / “high”) and zero (0) volts (“off” / “false” / “low”).
Analogue electronics refers to electronics which looks at something in-
between – it could be 1 volt, 2.5 volts, 3 volts, etc – much more specific.
Technically (for the Arduino Uno at least), anything below 1.5V would be
considered a “zero”, and anything above 3V would be considered a “one” –
in-between would be “undefined” (could go either way), and outside of
those ranges could damage the microcontroller.
7.4.1. Analogue-to-Digital Converters
Because the microprocessor itself only understands ones and zeroes, there
is a peripheral built into the microcontroller called an “analogue to digital
converter” (ADC). The analogue to digital converter takes an analogue
voltage, and converts it into ones and zeroes which the microprocessor can
understand (please see section 1.2.3 if you need a reminder on the
difference between a microprocessor and a microcontroller).
Without going in-depth into the binary number system (in which numbers
are represented using only ones and zeroes), it is sufficient to understand
that the ADC converts the analogue voltage into a number inside the
microcontroller.
The number doesn’t exactly correspond to the voltage (i.e. it is not “1” for 1
volt or “5” for 5 volts); but rather represents a “scale” of where the voltage
is between two reference points. Because the Arduino Uno works on 5 volts,
the top of the scale is 5V and the bottom of the scale is 0V.
The biggest number which the ADC can produce is 1,023, so this is at the top
of the scale and (in this case) means 5 volts (this is called the “resolution” of
the ADC – how precisely it can measure the analogue voltage). So for an
analogue voltage of 5 volts the ADC would output a number of 1023. For
zero volts (0V) it would be zero (0). For 1 volt it would be about 205. 2.5V
would be about 512, 3V would be about 614, and so on.
This can be represented using the following equation: ADC_Output =
(Input_Voltage / 5) x 1023.
Different ADC resolutions and reference voltages are possible in the
electronics world, but for our purposes with the Arduino Uno the
aforementioned numbers and equations are applicable.
7.4.2. Using the Potentiometer to Generate an Analogue Input
Voltage
The potentiometer (variable resistor) in our circuit is used to generate an
analogue input voltage which we will use to determine the speed of
sequencing of our LEDs.
In real-life, a potentiometer is usually a knob, like a volume knob.
Figure 7-4: Potentiometer with knob
Figure 7-5: Potentiometer knobs on electronic device18
Medium pressure
High pressure
Figure 7-7 depicts an experiment which can be conducted with water which
can help to act as an illustration. Water is placed in a container (such as a tall
bottle), with equal-sized holes cut into it at different heights along the side
of the container. Water pressure at the bottom of the container is higher
than the water pressure at the top of the container (this is because the
water at the bottom of the container is being “squeezed” or “pressed on” by
the weight of all of the water on top of it). This can be seen visually because
the high-pressure water at the bottom of the container (which is being
“squeezed” or “pressed on” more) shoots out further than the low-pressure
water at the top of the container, which does not shoot out as far. In-
between the top and bottom of the container, the water pressure is also
somewhere in-between what it is at the top and bottom of the container. In
electrical terms, the “potential difference” (electrical “pressure”) is greater
when measured between the top and bottom, than it is when measured
between (for example) the top and middle. The “pressure” (“voltage”) is
distributed evenly along the height of the container. This ties in with what
we learnt in section 5.3 (“Ohm’s Law”). Note that whilst water pressure in
the experiment is determined by gravity, and thus pressure will always be
higher at the bottom of the container, electrical “pressure” is determined by
voltage, which could be drawn any way around in our circuit. In Figure 7-6,
the “high pressure” (+5 volts) is at the top, whilst the “low pressure”
(ground, or 0 volts) is at the bottom (opposite to our water experiment).
Suffice to say, when connected up as it is in our present circuit, the
potentiometer will “output” an analogue voltage which is somewhere
between zero and 5 volts (which is then “input” into our Arduino Uno
microcontroller).
7.5. Inputs and Outputs
The pins on a microcontroller can be either “listening” (input), or “speaking”
(output). By default, the pins are “listening” (inputs). If we would like to
change some of the pins to be outputs however, such as to control our LEDs,
then we need to manually tell the microcontroller to set these pins as such;
this is done using the “pinMode” method available under the cpu peripheral.
Once a pin has been set as an output (using the pinMode method), we can
switch it on or off using the “digitalWrite” method available under the cpu
peripheral.
Interconnect Block
Figure 7-10 depicts the flowchart program for this project. Don’t worry
about drawing the flowchart just yet, we will get around to that shortly; for
now, let’s just study it to see how it works:
The steps in the programs are as follows.
1. Set all of the pins which the LEDs are connected to as outputs. This is
done using the “pinMode” method (section 7.5) – one block for each
pin which we would like to set as an output. The blocks are placed in
the Setup routine, since this action only needs to be done once (at
startup). Note that it is not necessary to explicitly set the pin which the
potentiometer is connected to as an input, as all pins are inputs by
default (until you set them as an output).
2. In our Loop, we start by having all the LEDs switched off. This is done by
using digitalWrite blocks to set the state of each pin to “FALSE” (“Off”).
3. Next we read the analogue value from the pin connected to the
potentiometer (analogue pin 0, or AD0), and store it in a variable called
“ain”. This is done using an “analogRead” block (available under the cpu
peripheral).
4. After jumping through the “Interconnect” (to be discussed shortly), the
next step is to delay for a certain amount of time; the amount of time
to delay being specified by the “ain” value which we read from the
potentiometer. After the delay, switch the first LED on (by setting the
pin which it is connected to with a state of “TRUE”, meaning “On”,
using the digitalWrite method again). This “delay-then-switch-on”
process is then repeated for each LED (from pin 3 to pin 7).
5. The program then automatically goes back to the start of the loop, and
the LEDs are switched on again from the start (step 2) – this process
repeats indefinitely (forever).
Some things to note about the flowchart / program:
- Comment blocks have been added, to help explain to the reader what
is happening in the program. These comment blocks do not affect the
program at all, but are simply there as “notes” for a human reader.
- The flowchart features an “interconnect block”. Because the flowchart
routine is too long to fit in the page / sheet (without changing the
sheet size), we can use an interconnect block to “split it up”. The
procedure for doing so is illustrated in the following figure (taken from
the Visual Designer help file, note that it illustrates a different
flowchart to the one which we are busy with).
Figure 7-11: Splitting into two separate lines wits interconnect blocks
Note that, even with interconnect blocks, it is possible to run out of space on
the sheet. This can be overcome however by adding additional sheets (click
the Project menu and then select New Sheet) – interconnect blocks can then
be used to connect between sheets. There are also further methods
available for better organising larger flowcharts, such as sub-routines, and
these will be covered in the next chapter.
We will now proceed to constructing our flowchart so that it matches the
one in Figure 7-10.
1. Drag 5 x pinMode methods / blocks from the cpu peripheral into the
flowchart, placing them in the Setup routine. Set the “pin” and “mode”
arguments of the blocks so that they set pins 3 to 7 as outputs (as per
Figure 7-10). Remember that the arguments of a block can be changed
by right-clicking on the block, and then selecting “Edit” from the popup
menu.
2. Drag 5 x digitalWrite methods / blocks from the cpu peripheral into the
flowchart Loop routine. Set the arguments of these so that they will
switch all of the pins (3 to 7) off (“FALSE”).
3. Drag an analogRead method / block from the cpu peripheral into the
flowchart Loop routine, placing it after the digitalWrite blocks which
were added in the previous step.
4. Edit the analogRead block. Set the “Ain” argument to 0 – this is the
analogue pin which we would like to read from (“AN0”). Create a new
variable called “ain” (this may have been automatically created
already), and select for the result of the analogRead to be stored in this
variable (as per the following figure).
Note that the similarity between the argument name “Ain” and the
variable name “ain” is purely coincidental – we could name the variable
“potentiometer_reading” for example.
5. Split the flowchart by right-clicking on the flowline below the
analogRead routine, and selecting “Split” from the popup menu.
6. Add a delay block as the next step in the Loop routine (inserting it after
the “interconnect”), setting its delay to “ain” milliseconds.
This will delay for the amount of milliseconds specified by the “ain”
variable.
7. Add a digitalWrite method / block as the next step in the Loop routine,
in order to switch the first LED on. Set it’s pin and state arguments to 3
and TRUE respectively.
8. Add another delay and digitalWrite method / block for each of the
remaining 4 LEDs, including a final additional delay block at the end. We
now have a sequence of blocks which will switch the LEDs on one-by-
one, with a delay inbetween (the time of which is determined by the
“ain” variable, which was set by reading the potentiometer voltage).
Once done ensure that your flowchart looks functionally like Figure 7-10
(remembering that comment blocks, for example, do not affect the function
of the flowchart), but do not run the simulation just yet.
7.7. Active Popups
When running a flowchart simulation, the components which the program
uses (buttons, LEDs, etc) can be seen and interacted with on either the
Visual Designer tab or the Schematic Capture tab. When components are
seen on the Visual Designer tab during simulation, Proteus is in fact just
“copying” certain parts of the schematic into the Visual Designer tab. The
way in which Proteus knows which parts of the schematic to copy over, is by
using something called “Active Popups”. Active Popup areas can be seen on
the schematic as blue labelled rectangles, as illustrated in the following
figure.
You can also add your own Active Popups to your schematic using the Active
Popup tool mode ( ), which is available from the vertical toolbar. To add an
Active Popup, simply select Active Popup mode and then draw a rectangle
over the area which you would like to create an Active Popup over. You can
then also give the Active Popup a unique label (name) to identify it (by right-
clicking on it and then clicking Edit Properties). If you like, then you could try
adding Active Popups to your schematic, as illustrated in the following
figure.
Added Active
Popup Regions
If the Active Popup regions are added to your schematic then you will be
able to view and interact with these regions from the Visual Designer tab
(when the simulation is running). Either way, you will be able to view and
interact with the components from the Schematic Capture tab.
(Tip: If an Active Popup region is not appearing in the Visual Designer tab
when the simulation is running, then try clicking the Debug menu – if it is
listed there, then clicking on it in the menu will make it visible again. Note
that Active Popups can also be moved, resized and detached (into separate
windows) within the Visual Designer tab (when the simulation is running).)
7.8. Testing the Project
Once the flowchart has been completed as per Figure 7-10, and optionally
Active Popup regions added, the “Play” button (blue triangle in the bottom-
left corner of the screen) can be pressed to test the simulation. You should
see the LEDs flashing in sequence, and changing the setting on the
potentiometer (using the arrows, or by clicking on it) should change the
speed (rate) of the flashing. If anything doesn’t work as expected, then it is
recommended to go through this chapter again to check if anything has
been missed or set incorrectly.
7.9. Chapter Summary
Using the skills taught in this chapter, it is possible to draw exact custom
circuits to interact with our microcontroller (as opposed to being limited to
the selection of peripherals available from the Peripheral Gallery).
8. Sub-Routines and Conditional Loops
Congratulations! If you have completed and understood the previous
flowchart design chapters, then you now have all the tools needed to solve
any programming problem which can be solved with a flowchart in Visual
Designer19! This chapter introduces two new (but separate) concepts: sub-
routines, and conditional loops. Whilst these two new concepts do not
enable us to do anything which we could not do before, they do make it
easier to do so.
We will be using both sub-routines and conditional loops to better organise
more complex flowcharts. They will enable us to make the flowcharts
shorter, simpler, and easier to read / understand.
(Note: Sub-routines and counting loops are separate concepts (they are not
related). We will however be taking the opportunity to introduce both of
them in just one chapter, instead of having a separate chapter for each.)
Figure 8-1: Adafruit NeoPixel shield for Arduino20
We will be using the “Adafruit NeoPixel shield for Arduino” in this chapter. A
NeoPixel is a fancy LED, the colour of which can be precisely controlled. The
NeoPixel shield features 40 of these LEDs, in 8 columns and 5 rows (or 5
columns and 8 rows, depending on how you look at it – this setup can also
be called an “array” or “matrix”). The “shield” (a name used to describe
some Arduino add-on peripheral boards) plugs in on top of the Arduino Uno.
We will start off with a small project which switches just one of the
NeoPixels on, and then build on that project till we have all of the NeoPixels
on and changing colours. In the process we will introduce and explain sub-
routines and conditional loops. You may wish to save the project under a
different filename at each completed “step”, in case you would like to keep
a copy of each of these “steps”.
8.1. Setting up the Starter Project
1. Start a new flowchart project. If you need a reminder on how to do so,
then please see section 2.2, 3.3 or 4.1 (remember to save ( ) any work
which you may have open and don’t want to lose, close ( ) any open
project, and then select “New Flowchart” from the Home ( ) screen).
The project filename can be “NeoPixel1”.
2. Add an “Adafruit NeoPixel Shield” to the project from the Peripheral
Gallery in Visual Designer. If you need a reminder on how to add a
peripheral to the project, then please see section 3.4. (The Peripheral
Gallery can be accessed by right-clicking the Project menu and then
selecting Add Peripheral. The “Adafruit NeoPixel Shield” can be found
under the Adafruit category.)
After adding the “Adafruit NeoPixel Shield” peripheral from the
Peripheral Gallery, the Visual Designer Projects Area should contain a
peripheral with a number of methods available for controlling the
NeoPixels (as illustrated in the below figure).
Figure 8-4: Edit I/O block dialogue for the setPixelColor method
Four arguments (or parameters) are available: “N”, “R”, “G” and “B”.
- “N” is the number of the pixel, from zero (0) to 39. Computers often
use something called a “zero-based-index”, which means that they
start counting something from zero (0) instead of from 1. Because of
the way in which computers work inside, using this technique helps
them to be more efficient. There are 40 NeoPixels. If we started
counting them from 1, then the first pixel would be pixel # 1 and the
last pixel would be # 40. Because the computer starts counting them
from zero however, the first pixel is called pixel # 0 and the last pixel is
called pixel # 39. The NeoPixels on our shield in Proteus are arranged
in rows, in a zig-zag fashion which starts at the top-left and ends at the
bottom right (this is illustrated in the following figure).
- R is the red component of the light, specified as a number from zero
(0) to 255.
- G is the green component of the light, specified as a number from
zero (0) to 255.
- B is the blue component of the light, specified as a number from zero
(0) to 255.
Remember that the red, green and blue colours combine to form a single
colour. Red and green combined (at the same intensity), for example, would
produce yellow.
NeoPixel #0 #7
(first NeoPixel)
#14
#8
#15
#16 #9
NeoPixel #39
(last NeoPixel)
Leave the number of the pixel (“N”) as 0. Set the intensity of the red colour
(“R”) to 255 (full intensity), and leave the intensities of the green and blue
colours (“G” and “B”) as 0 (off). This should produce a red colour on the first
NeoPixel.
Once ready, run the simulation (click “OK” to accept the settings in the
setPixelColor dialogue before trying to run the simulation, if you have not
done so already). NeoPixel #0 should turn on with a red colour.
8.4. Setting 3 Pixels
Next, let’s set the colour of NeoPixels #1 and #2 as well, so that the first 3
pixels will all be red.
If you would like to save each completed step of this project under a new
filename, then click the File menu and then select “Save Project As”. The new
filename “NeoPixel2” can be used.
Drag two more setPixelMethods onto the flowchart, above the “show”
method. Set the parameters for these methods so that they set pixels 2 and
3 to a red colour. The following figure illustrates the flowchart.
The previous figure illustrates a flowchart which sets all 40 pixels, using only
1 setPixelColor block (rather than 40). The flowchart works by using a
variable to specify which pixel should be set, and looping that variable from
0 to 39 in order to set all 40 pixels. The program works by first setting the
pixel number to zero (0), and then setting the colour of the pixel specified by
the pixel number variable (which is currently set to 0). Next, it adds one to
the value of the pixel number variable, so that the variable now equals 1.
The program then checks if the pixel number variable is less than or equal to
39 – if it is (“YES”) then it routes back to setting the colour of the pixel
specified by the pixel number variable (which is now set to 1). This process
continues until all of the pixels from 0-39 have been set, at which point the
value of the pixel number variable will become 39 + 1 = 40. 40 is not less
than or equal to 39, so at the decision block the program then routes in the
“NO” direction and proceeds to the “show” block so that the set NeoPixel
colours will all take effect. Once you have set your flowchart up as per the
previous figure, run the simulation in order to check that the program works
as expected (all 40 NeoPixels set to a red colour). If you need a reminder on
how to add a variable to your program, please see section 4.2.
8.6. “For” Conditional Loops
Because the need to count a variable through a sequence of numbers occurs
quite often in programming, there is a “shortcut” for it – called a “For” loop
(or “For-Next” loop).
If you would like to save each completed step of this project under a new
filename, then click the File menu and then select “Save Project As”. The new
filename “NeoPixel4” can be used.
The flowchart illustrated in the previous figure (Figure 8-8) does exactly the
same thing as the flowchart illustrated in the previous section (Figure 8-7),
however it is quicker and easier to design, and is tidier and easier to
understand.
We will now update your flowchart to use a “For” loop, as per the previous
figure.
Figure 8-9: Loop construct
To start with, drag a “Loop Construct” onto your flowchart. Next, right-click
on the newly added “LOOP” blocks and select “Edit” from the popup menu
(alternatively click twice on the “LOOP” blocks). The following figure depicts
the Edit Loop dialogue.
Figure 8-13: Flowchart for setting all NeoPixels to red, green and then blue
The previous figure illustrates the flowchart which we will build for this
project step. We essentially need to make two more copies of our existing
flowchart routine (note that Visual Designer does include copy-and-paste
facilities, available from the right-click popup menu or from the main Edit
menu once one or more flowchart blocks have been selected). We also need
to adjust the parameters in the copied setPixelColor methods in order to set
the different colours, and add a delay in-between each colour change. In
order to get the flowchart to fit within the space available, it is also
necessary to add some Interconnect Blocks (please see the previous chapter
covering these if you need a reminder on how to use them). Note that the
“Red”, “Green” and “Blue” comments above the For loops are for human
readers only and do not affect the operation of the program. Once you have
updated your flowchart so that it looks like the one in the previous figure (as
mentioned, the comment blocks are optional), run the simulation and check
that it behaves as expected. The NeoPixels should first all turn red, then
after 1 second they should all turn green, and after another 1 second they
should all turn blue. After a further 1 second delay the process repeats, and
continues indefinitely.
8.9. Sub-Routines
Notice how we had to reproduce, or copy-and-paste, a section of flowchart
blocks in the previous project step. Whenever you find yourself reproducing,
or copying-and-pasting, sections of a program, then you should know that it
may be better to use a sub-routine instead. As mentioned, sub-routines, like
conditional loops, are completely optional and you can complete a program
without them. They do however make it easier to build more complex
programs. The section of flowchart which we have reproduced in the
previous project step is relatively short (4 or 5 blocks, depending on whether
you count the “next” in the For loop as a separate block), but as the size of
the section which is being reproduced becomes bigger (perhaps 10, or 20 or
50 blocks), sub-routines start to present more and more of an advantage.
For this project step, we will place the reproduced sections of the flowchart
(which update the pixels) into a separate sub-routine.
If you would like to save each completed step of this project under a new
filename, then click the File menu and then select “Save Project As”. The new
filename “NeoPixel6” can be used.
Sub-Routine
Sub-Routine
“Calls”
The previous figure illustrates the flowchart for this project step. Notice how
the reproduced sections of the flowchart from the previous project step
have been copied out and replaced by a single copy in the sub-routine called
“UpdatePixelsAndDelay”. The next thing to notice in the flowchart is that we
have added three new variables, called “red”, “green” and “blue”. Because
we now only have one copy of the For loop which set all the NeoPixels to a
particular colour, we need a way to tell it which colour to use. We can do
this using variables (the colour “varies” each time, hence “variables”).
In order to update your project so that it looks like the previous figure, you
will need to add the “UpdatePixelsAndDelay” subroutine. To do so, drag an
Event Block onto the flowchart.
Figure 8-15: Event (sub-routine) block
Note that an “End” block is also automatically added. Change the name of
the event block to “UpdatePixelsAndDelay”, by right-clicking on it and
selecting “Edit” from the popup menu (or by clicking on it twice), then
changing the name appropriately.
Move one of the flowchart sections which updates all the pixels from the
main loop into the new subroutine (remember the “Tear Off” function from
section 2.7.3), as per the previous flowchart figure. Delete the other two
copies of the flowchart section (as well as the interconnect blocks).
Add a new Assignment Block into the now-empty main loop. Edit the
assignment block and create 3 new variables; “red”, “green” and “blue”.
Assign values to these variables as illustrated in Figure 8-14 (red:=255,
green:=0, blue:=0). If you need help remembering how to create variables
and assign values to them, then please see section 4.2.
Drag a “Sub-Routine Call” block into your main loop, after the variable
assignment block.
Edit the properties of the Sub-Routine call block, and select the
“UpdatePixelsAndDelay” method as the sub-routine to call.
Add two more variable assignment blocks and sub-routine calls, as
illustrated in Figure 8-14. Note that the comments in the figure are optional.
Update the setPixelColor flowchart block so that it uses the newly created
“red”, “green” and “blue” variables for the “r”, “g”, and “b” values (i.e.
instead of using “255” for the “R” argument, use “red” (without quotes)).
The flowchart has now been adapted so that there is a sub-routine which
can be used to update all of the NeoPixels (and delay for 1 second after
doing so), using the “red”, “green” and “blue” variables to set the colours of
the NeoPixels. From the main loop, we simply set the colour we want using
the variables, and then call the “UpdatePixelsAndDelay” sub-routine.
Once ready, run the simulation and check that it behaves as expected. If not,
then carefully compare your flowchart to the previous flowchart figure.
Sub-routines can be difficult to understand, but just remember that
whenever you see a sub-routine call in a flowchart, it is as-if you copied-and-
pasted the flowchart blocks contained in the subroutine into the flowchart
where the sub-routine call is (in other words, replaced the sub-routine call
block with the blocks contained in that sub-routine).
Note that many of the peripheral methods which we have been using till
now, including the setPixelColor method, are in fact sub-routine calls
themselves! The only difference is that the details of those sub-routines are
hidden from us within Proteus, so that we don’t need to worry about the
details of them.
From an understandability (conceptual) point of view, it is generally easier to
“forget” about the exact details of how a subroutine works, including sub-
routines which we make ourselves. The sub-routine should be named well,
so that we can understand from its name what it does, without looking at
the details of it. This is another big advantage of sub-routines, even if they
are not used to replace duplicated code – they can help to break a program
up into smaller bits and pieces, which are much easier for the human brain
to understand. For example, it is much easier to say “please make some
tomato soup, bread, salad and chocolate cake” than it is to specify the exact
steps needed to perform each of those tasks. Each of those tasks have their
own recipe, or “sub-routine”, which we can summarise by using their name.
Imagine if we had to try and make the same request, specifying the exact
steps needed! “Please take some tomatoes, chop them up, put some water
in a pan”, etc, etc – it would take forever and become really confusing for
the human brain to understand.
Sub-Routines thus serve two purposes:
1. Replacing repetitive sections of a program.
2. Breaking a program up into smaller bits, which makes it easier for a
human to understand.
8.10. Getting Fancy
Using the new skills of sub-routines and conditional loops which we have
just learned, we will now construct a flowchart which cycles the NeoPixels
smoothly between all the colours of the rainbow!
If you would like to save each completed step of this project under a new
filename, then click the File menu and then select “Save Project As”. The new
filename “NeoPixel7” can be used.
The previous figure depicts the flowchart for this final project step. A new
routine called “DoTransition” has been added, which handles the transition
from red to green, green to blue, and blue back to red. In the process, all the
colours of the rainbow are displayed. Three new variables have been added
– two new Integer (number) type variables called “from_intensity” and
“to_intensity”, and a string (text) variable called “transition”.
The “DoTransition” sub-routine counts the “from_intensity” from 255 (full
strength intensity) down to 0 (no intensity, or “off”). The “to_intensity”
variable is set to the inverse (opposite) of the “from_intensity” variable,
using the equation “to_intensity = 255 - from_intensity”. Thus if
“from_intensity” is 255, then to_intensity will be “255 minus (-) 255”, which
equals zero. If “from_intensity” is 0, then to_intensity will be “255 minus (-)
0”, which equals 255. The result is that as from_intensity is counted from
255 down to zero (0), to_intensity will simultaneously be counted from 0 up
to 255. You can write down and calculate each of the values using the
equation if you are not yet convinced of this. Intensity means the same thing
as “brightness”, so the brightness of the “from” colour is slowly decreased
whilst the brightness of the “to” colour is slowly increased. In order to know
which colour to assign the “from_intensity” to and which colour to assign
the “to_intensity” to, the sub-routine looks at the “transition” variable,
which can be one of 3 cases – “red_to_green”, “green_to_blue” or
“blue_to_red”. Depending on the case, the sub-routine will choose which
way to assign the intensities. Once the intensities have been assigned, the
“UpdatePixelsAndDelay” sub-routine is called in order to update all of the
NeoPixels with the new colour. The delay in the “UpdatePixelsAndDelay”
subroutine has been decreased to 10ms (10 milliseconds), so that the
transition can take place at a reasonable speed. If the delay were left at
1000ms (1000 milliseconds, or 1 second) then it would take 255 x 1 second,
or 4 minutes and 15 seconds, to complete a single transition. By setting the
delay to 10ms it takes 255 x 10ms, which equals 2550ms or 2.55 seconds, to
complete a transition.
The main loop has been updated to simply set the “transition” variable to
the name of the transition which should be performed, and then call the
“DoTransition” sub-routine.
Update your flowchart to match the one from the previous figure. If you get
stuck, then please check the relevant previous sections of this book. The
following diagram illustrates the detail regarding the “transition” STRING
type variable.
Figure 8-18: String variable creation and assignment
Once ready, run the simulation. The NeoPixels should smooth transition
between all the colours of the rainbow. If the program does not work as
expected, then carefully compare it to the previous flowchart figure (Figure
8-17).
Hopefully you are impressed by the result achieved with this final flowchart
program step! This result could have been achieved using only setPixelColor
blocks, but without the use of conditional loops or sub-routines it would
take 3 x 255 x 40 = 30,600 blocks to achieve this. That is thirty thousand six
hundred blocks. We have managed to achieve this with only 19 blocks.
There are many more possibilities for things which could be displayed on the
NeoPixel shield. For example, we have been setting the whole shield to a
single colour at the same time, but each pixel could in fact be set / animated
individually. With some imagination and ingenuity, many more projects
could potentially be created.
9. Introduction to C
Note: Depending on your preferences, you may wish to complete the
“Robotics” Bonus Chapter before completing this chapter.
Congratulations! If you have successfully completed and understood the
preceding chapters, then by now you have acquired a new skill: the ability to
write a computer software program. “C” is a programming language which
can be used to build software programs, just like Visual Designer can be
used to build software programs. This is a matter of syntax however: you
could instruct somebody how to bake a cake in English, or you could instruct
somebody how to bake a cake in French, but the actions required would still
be the same. In much the same way, C is simply a different “language” for
constructing computer programs. Whereas Visual Designer uses flowchart
blocks to construct a program, C programs are written purely in text (letters,
numbers, words, etc). As you will see however (as C is introduced), it is
easier and less intimidating to get started with programming using
flowcharts than it is with C!
C is an “industry standard” programming language, which means that it is
very commonly used within the software development industry. The
advantages of learning C thus include:
- You will be able to find C compilers for many more devices besides for
Arduino.
- There are many C resources available, such as “libraries”. A library is a
set of sub-routines, which somebody else has already written, and
which can help you to accomplish a task (without “reinventing the
wheel”). Visual Designer includes libraries itself, in the form of
peripherals which can be picked from the Peripheral Gallery (section
3.4).
void setup () {
void loop() {
void loop() {
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
}
The similarities between the C code and the flowchart should be obvious,
remembering that “HIGH” means the same thing as “TRUE” and “LOW”
means the same thing as “FALSE”. Note that the comments have been
removed from the C code. Copy the code into your program, and once ready
run the simulation (which will now simulate the C code); check that the
results are the same as those obtained with the flowchart project (LED
toggling on and off with a 1 second delay). If any problems are encountered,
then please ensure that your code exactly matches the code listed here.
9.2. C Language Syntax Introduction
C code requires correct syntax in order for code to compile correctly
(otherwise, the compiler will report an error). A flowchart program and the
equivalent C code are listed below – the C code provides examples of the
syntax rules which will be covered next. For interests’ sake, the program
flashes an LED whenever a button is pressed, incrementing the number of
flashes each time.
#define BUTTON_PIN 2
Variable
declarations
int times;
int counter;
Sub-Routine
void FlashLED() {
for (counter=1;counter<=times;counter=counter+1) {
digitalWrite(13,HIGH); // Turn the LED on
Statement group, with
delay(250);
start (opening) and end
digitalWrite(13,LOW); // Turn the LED off again (closing) curly braces
delay(250);
}
}
void setup() {
Sub-Routine, with start
pinMode(13,OUTPUT);
(opening) and end
times=1; (closing) curly braces
}
Statement condition
void loop() {
if (digitalRead(BUTTON_PIN)==HIGH) { // Is the button pressed?
FlashLED(); Sub-Routine call
times=times+1;
delay(1000);
} Comment
}
C Code 1
9.2.3. Indentation
Indentation, or the practice of inserting spaces at the start of a line, is done
only to make the code easier for humans to read - indentation is completely
ignored by the computer.
void loop() {
if (digitalRead(BUTTON_PIN)==HIGH) { // Is the button pressed?
FlashLED();
times=times+1;
delay(1000);
} Indentation – for ease of human reading only
}
9.2.4. Semicolons
All commands and declarations must be followed by a semicolon (“;”). For
example:
int times; /* Variable declaration */
times=times+1; /* Command */
delay(1000); /* Command */
In some other programming languages commands and declarations are
separated by placing them on separate lines, but in C they are separated by
semicolons. The following code is the same as the former:
int times; times=times+1; delay(1000); // All on one line
C generally does not look at lines, except in some cases such as with “Rest-
of-the-line” comments and pre-processor directives. Instead, C looks at
semicolons to separate commands.
9.2.5. Variable Declarations
Before a variable can be used in a program, it must first be “declared” by
specifying what kind of variable it is as well as its name. Variable
declarations are done by first specifying the type of variable – for example
“int” for integer – and then the name of the variable (followed by a
semicolon).
int times;
There are numerous types of variables available to choose from – more
information regarding these can be found in the compiler documentation
(for Arduino, this is at
https://www.arduino.cc/en/Reference/VariableDeclaration).
9.2.6. Sub-Routines
Sub-routines are inserted into a program by first specifying the type of
variable value they return – for example “void” if they do not return
anything – and then the name of the function followed by opening and
closing brackets “()”. The instructions which the sub-routine should execute
are then inserted between curly braces (“{“ and “}”).
void MySubRoutine() {
/* Sub-routine instructions go here */
}
“Parameters” (also called “arguments”) can optionally be inserted between
the opening and closing brackets. The following example of a function which
both returns a value and accepts a parameter / argument is discussed in the
following sections.
int my_var;
Function return type (int) Parameter / argument (int Radius)
void loop() {
my_var = CircleCircumference(100); // Calculate circumference of
// circle with a radius of 100
} Function call
Example
if (count > 5) {
digitalWrite(13, HIGH);
} else {
digitalWrite(13, LOW);
}
Example
while (count < 5) {
count=count+1;
}
Example
do {
count=count+1;
} while (count < 5);
Note: The “Repeat” flowchart loop in the example has inverted logic (“count
>= 5” rather than “count < 5”, as it loops “until” rather than “while”). There
is no direct equivalent in C.
9.3.4. “For” Statement
Syntax
for ([init-expr]; [cond-expr]; [inc-expr])
instruction
You may wish to review section 8.7.3 for a reminder on how “For” loops in
flowcharts can also be built using decision and action blocks.
Example
for (count=0; count<=10; count=count+2) {
analogWrite(10, count);
}
Example
switch (count) {
case 1:
analogWrite(10, 12);
break;
case 2:
analogWrite(10, 34);
break;
case 3:
analogWrite(10, 56);
break;
default:
analogWrite(10, 0);
}
Note that if the “break” instruction is omitted, then the code will continue
executing the “cases” below the specific case which was matched, until a
break instruction is encountered, or the end of the switch statement is
reached.
An exhaustive discussion regarding the “switch” statement is beyond the
scope of this book, however for the curious there are many resources
available online – such as at
https://www.arduino.cc/reference/en/language/structure/control-
structure/switchcase/.
9.4. Next Steps for Further Learning
As C is an industry standard programming language (commonly used), there
are many learning resources available for it.
A suggested initial step would be an internet search like “Getting Started
with C”. To be Arduino specific, try “Arduino Getting Started” – results from
the official Arduino website itself
(https://www.arduino.cc/en/Guide/HomePage), as well as from Adafruit
(https://learn.adafruit.com/lesson-0-getting-started/overview), should be
near the top of the list.
Proteus also includes a number of Arduino sample projects using C code, as
well as numerous other sample projects using C code on other devices.
Opening the Sample Projects Browser (File, Open Sample Project), typing
“Arduino” as the keyword, and then selecting the VSM for AVR category, is a
suggested start. The example projects can be studied, modified and
simulated.
The official Arduino IDE (see https://www.arduino.cc/en/Main/Software)
includes numerous sample projects demonstrating various concepts.
Note that Proteus can simulate microcontroller code even if that code is not
developed within the Proteus environment! For example, you could develop
code in the Arduino IDE, and then still simulate it in Proteus. For more
information on this, please see the “Direct Simulation” topic under “Working
with Microprocessors” in the Proteus Simulation help file. The Proteus
Simulation help file is available from the Help menu in Proteus when the
Simulation tab is selected / active.
C concepts which have not been covered (or not fully covered) in this
chapter include:
- Arrays
- Pointers
- Jump Statements (“break” and “continue”)
- Strings
- Structures
- Enumerations
- Libraries
In addition, no C++ specific concepts have been covered. Note that the
Arduino compiler is a C/C++ compiler, meaning that it can compile programs
written in just C code as well as programs written in C++ code.
In general, a good way to learn is to study and modify working examples.
That way, you have something which already works, and you can start
modifying it for your case. At each modification step you should test your
modifications – if they don’t work as expected, or at all, then you can focus
on fixing a relatively small step, or doing things a different way; this is in
contrast to trying to write a large program from scratch, finding it doesn’t
work as expected, and then trying to pinpoint where exactly the problem
might be. Note that you also don’t necessarily need to understand exactly
how each part of an example project works in order to modify a certain
smaller part of it to suit your needs.
Remember that, if you have successfully completed and understood the
previous chapters, you already know how to think like a programmer.
Learning C is just a matter of learning how to communicate the instructions
to the computer in a different way.
9.5. C Operator Reference
Arithmetic
Operators
+ add
- subtract
* multiply
/ divide
% modulus
(remainder after
division)
Relational
Operators
== equal
!= not equal
> greater than
< smaller than
>= greater or equal
<= smaller or equal
Assignment
Operators
a = b; // Assignment
a += b; // a = a + b;
a *= b; // etc...
Logical
Operators
&& logical AND
|| logical OR
! logical NOT
Bitwise
Operators
& bitwise AND
| bitwise OR
^ bitwise XOR
~ bitwise Complement
<< bitwise Shift Left
>> bitwise Shift Right
Unary
Operators
i++; // i = i + 1;
i--; // i = i – 1;
a = ++b; // b = b + 1;
// a = b;
a = b++; // a = b;
// b = b + 1;
9.6. C Variable Type Reference (Arduino)
Type Size in Bytes Range
byte 1 0 .. 255
[unsigned] char 1 0 .. 255
signed char 1 - 128 .. 127
[signed] short [int] 1 - 128 .. 127
[signed] int 2 -32768 .. 32767
unsigned [int] 2 0 .. 65535
[signed] long [int] 4 -2147483648 .. 2147483647
unsigned long [int] 4 0 .. 4294967295
float 4 -3.4 * 1038 .. +3.4 * 1038
9.7. C Pointers Reference
Pointer Declaration
char* p; /* Declares “p” as a character pointer
(pointer to a character) */
As an example, let’s convert the project from section 9.1 into C/C++ code.
1. Either recreate or reopen the flowchart project from section 9.1
(“C_BlinkLED_Flowchart”). Remember to save any work which you may
have open and don’t want to lose. The filename
“C_BlinkLED_Converted” can be used for the project, either during the
“New Project Wizard” if recreating the project, or by using the “Save
Project As” command under the file menu if reopening the project.
2. Convert the project to C/C++ code, using the procedure detailed in
Figure 9-4 (right click on the project folder and then select “Convert to
Source Project” from the popup menu).
3. If not already open, double-click on the “main.ino” file on the left in
order to open it.
The resulting code should look like the following:
// Generated by Proteus Visual Designer
// Peripheral Constructors
CPU &io_cpu = Cpu;
TimerOne &io_timer1 = Timer1; “Class” declarations
// Flowchart variables:
void chart_LOOP() {
io_cpu.digitalWrite(13,true); “Shadow” setup and loop
delay(250); routines (called
io_cpu.digitalWrite(13,false); respectively from the main
delay(250); setup and loop routines)
}
void setup () {
// Peripheral initializers
void loop() {
// Poll the peripherals
You will notice that this code looks a little more complicated than the code
from section 9.1 (copied again on the next page for convenience), however
it accomplishes exactly the same thing. In fact, this is the code which the
flowchart is converted into each time it is compiled (such as before
simulation).
void setup () {
pinMode(13, OUTPUT);
}
void loop() {
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
}
C Code 3: Simplified version of “C Code 2” program
Proteus can simulate the robots driving around an obstacle course / track;
besides for this being useful in the case where physical hardware is not
available, it can also be very helpful whilst developing and debugging the
code / algorithms which should control the robots:
Figure 11-5: Proteus Robot Simulation
You can draw any track you like, using a simple graphics editor such as MS
Paint (for details on exactly how to do this please see the “Virtual
Environments / Obstacle Maps” topic in the previously-mentioned help file –
for this chapter however, we will simply use a sample map rather than
drawing our own).
In this chapter, we will develop a simple program to help the Zumo robot
follow a line. You will be able to try the program out in the simulation, and if
you have a physical Zumo robot available then you can try it out with the
“real” hardware as well (by, for example, constructing a track on the floor
using black insulation-tape).
Figure 11-6: "Real Life" Zumo and Track
11.1. Line-Following Theory
Underneath the front of the Zumo robot are 6 infra-red reflectance sensors.
Figure 11-7: Zumo Reflectance Sensors
If the line is currently under the left sensor(s), and the robot turns left, then
as the robot continues to drive the line will “move” towards the middle
sensor(s) – and vice versa.
If the robot can “keep” the line under the middle sensors, as it drives
forwards, then it will succeed in “following” the line! (It may help to look at
the previous picture of a line-track which the robot should follow, and think
about how the position of the line under the robot will change as the robot
drives forwards around the track).
This sort of control system is called “proportional”; the amount which the
robot should turn by is proportional to how far the line is from the middle
sensor(s) – the further the line is from the middle, the more sharply the
robot should turn in order to get “back on track”. Proportional control by
itself can be subject to overshoot / “wobble” / “fish-tailing”, so more
advanced control methods are also available (such as “PID”, which stands for
Proportional-Integral-Derivative).
Figure 11-10: "Fishtailing"
For our project however, “proportional” control alone will work just fine.
11.2. Constructing the Program: The Plan
For our program, we will use two of the Zumo’s methods: “drive” and
“readLinePos”.
Figure 11-12: Left and right track speed differences, and resulting turn
To turn, it is necessary to use the “drive” method twice – once for each
wheel.
To drive straight ahead, the “drive” method could be used once – with the
“Wheel” parameter set to “Both”; but we could also drive straight ahead by
using the “drive” method twice (once for each wheel), so long as the speed
and direction were the same for each wheel.
11.2.2. “readLinePos” Method
The “readLinePos” method returns a value between 0 and 5000, which
represents the position of the line underneath the sensors – “0” meaning
that the line is under the far left sensor and “5000” meaning that the line is
under the far right sensor. If the line is directly underneath the middle
sensors, then the reading will be 2500.
One way in which we can do this is to set the normal “straight forwards”
motor speeds to 50% each, and then add or subtract speed from each motor
depending on how much turning is required. This means that we could add
or subtract up to 50% speed from each motor (giving a maximum speed of
100% and a minimum speed of 0% on each motor). We will thus need to
interpret the “deviation” as a value from -50% to +50%, which should be
added-to/subtracted-from each motor speed. The mathematics for this are
below:
- We now need to adjust the motor speeds using the deviation. If the
line is on the right-hand-side of the robot then the deviation will be
positive. In order to turn right (in order to get the robot “back on
track”, with the line under the middle sensors), we will need to
increase the left “wheel” speed and decrease the right “wheel” speed,
giving the formulas:
leftWheelSpeed=127+deviation
rightWheelSpeed=127-deviation
That’s it! However complicated you may have thought it would be to put
together a program for a line-following robot, with a little clever maths we
have done it in only a few steps. Of course this is not the best or most
complex control algorithm (the sample project which comes with Proteus is
more advanced), but as an introduction it is nice and simple and should
work well (we will find out in a minute)!
11.3. Constructing the Program: Putting “The Plan” Into
Action
By now it is assumed that you know how to start a new project, add
peripherals to it, etc. If you need a refresher on these points then please
consult the relevant prior chapters of this book.
To put together the line-follower project, we need to do the following:
1. Start a new Flowchart project (using Arduino Uno; the project could be
called “ZumoLineFollower”).
2. Add the “Arduino Zumo Robot” peripheral to the project (under the
“Motor Control” category).
3. Construct the flowchart (details to follow).
4. Specify the map (track) with the line for our robot to follow (details to
follow).
Z1:LINESENSOR
readLinePos
linePosReading
deviation :=
(linePosReading-2500)/
20
Z1:DRIVE
SETUP drive
wheel := LEFT
END dir := FORWARDS
speed := 127+deviation
Z1:DRIVE
drive
wheel := RIGHT
dir := FORWARDS
speed := 127-deviation
END
Figure 11-14: Simple line-follower flowchart program
This follows the steps we put together in “The Plan” stage. Note that two
variables are needed:
Figure 11-15: Line-follower flowchart program variables
If you have any trouble constructing the flowchart (or adding the variables)
then please consult the relevant prior chapters which cover these topics.
11.3.2. Specifying the Map
To specify the map (track) for the robot:
On the Schematic sheet, go to the properties of the Zumo robot.
As mentioned previously, you can draw any track you like for the robot in a
simple graphics program such as MS Paint (exact details regarding how to do
this are in the help file). For this chapter however we will use a sample track
which comes with Proteus.
The sample track can be found under the Proteus “Samples” directory
(usually “C:\ProgramData\Labcenter Electronics\Proteus 8
Professional\SAMPLES\Visual Designer for Arduino\Virtual Turtle\”) and is
called “Line Follow.png”.
For convenience, the sample track is also available for download from
www.dizzy.co.za/zumo-st .
Figure 11-18: "Line Follow" sample track
To load the sample track into Proteus, click on the “Browse” button by the
“Obstacle Map” field:
Next – because our program is still relatively simple and doesn’t have code
to handle the case where the robot is not over any line at all – we need to
make sure that our robot is positioned over the track when it starts. To do
this; we enter the starting angle, horizontal position and vertical position of
the robot on the track:
Field Value
Angle -60
Horizontal Position 265
Vertical Position 520
Figure 11-21: Zumo "start position" fields
(These values have been pre-calculated and are known to work, but there
are many other values which could also work and you are free to
experiment.)
This positions the robot near the bottom-left of the track:
Once done, click “OK” to apply the changes to the Zumo Robot peripheral.
11.4. The Moment of Truth
We’re all ready, so hit the “Play” button to start the simulation; and let’s see
if our robot can follow the line, or if it wonders off into oblivion!
If all has been done correctly then our robot should follow the track, without
losing it.
11.5. Summary
In terms of programming, robotics is not really much more than what we
have already learned – it just has motion involved. We have created a very
simple program to help a robot follow a line as an introduction; you are free
to experiment with better (faster/tighter) algorithms, different tracks,
different applications, to study the robotics sample designs which are
included with Proteus, to try out the other type(s) of robot(s) in Proteus, and
so on. Happy experimenting and learning!
12. Author’s Notes
12.1. Topics Not Yet Covered
The following topics have not yet been covered in this book (but may be
included in a future revision). You may wish to investigate them yourself at
your leisure, as subjects of further learning.
Topic Resources for Self-Learning
Debugging - “Simulation and Debug Skills” sub-topic in the Proteus
Visual Designer help file22 (under the “VISUAL DESIGNER”
main topic).
State - https://learn.adafruit.com/multi-tasking-the-arduino-part-
Machines 1
File Access - “Tutorial 3: SD Card and TFT (Shield)” tutorial, under the
(SD Cards) “TUTORIALS” main topic in the Proteus Visual Designer
help file22.
12.2. Implementation of Technology
Technology is a tool. Like any tool, its implementation depends on the
wielder. As such, technology in itself will not make the world a better place –
it is up to us to use it wisely!
Appendix A: Challenges
Challenges are included to practice with, and to prove that concepts have
been understood (as opposed to just copied down). You will likely find that
you will need to re-read certain sections of a chapter in order to complete a
challenge; this will further assist with learning and understanding. Note that
challenges are not a pre-requisite to progress through the book (which is
why they are included as an appendix rather than in-line with the book
chapters), so if you can’t complete a challenge then don’t worry or let it hold
back your progress through the book – you can always come back to it later.
Possible solutions to the challenges can be found in Appendix B. Remember
that there are potentially many different ways to solve a challenge in
programming; so if your solution does not look exactly like the one listed
then do not worry! The important thing is whether the program works or
not (within reason; if a chapter covered an advanced technique for achieving
something then you should obviously try use that technique rather than a
simpler solution).
General Procedure for Challenges
1. Save ( ) any existing project which you may have open (if you do not
want to lose it). This can be done using the “Save Project” command
available from the File menu.
2. Close ( ) any existing project which you may have open. This can be
done using the “Close Project” command available from the File menu.
You should now see the Proteus Home Page ( ) tab (as illustrated in
Figure 2-1).
3. Unless indicated otherwise (some challenges may not be flowchart
related, but most are), start a new Flowchart project (section 2.2) – the
challenge name can be used as the project name.
Other procedures which may be necessary will have been covered in the
chapter (and/or previous chapters) to which the project relates.
Chapter 2 (Creating Your First Project)
Heartbeat on LED
Parts Needed
Qty Part Added to Proteus Design By / From
1 Arduino Uno New Flowchart Wizard
Challenge
Using the built-in LED on the Arduino Uno, design a flowchart which blinks
the LED twice quickly, then delays before repeating again (looping). This is
meant to visually mimic the sound of a human heart beating.
This can be represented graphically as (repeat cycles shown in gray):
The timings don’t need to be exact – you can use whatever seems good to
you. Suggested values are 250 milliseconds on, 500 milliseconds off, 2
second delay.
Chapter 3 (Reading Inputs and Making Decisions)
Blink on Demand
Parts Needed
Qty Part Added to Proteus Design By /
From
1 Arduino Uno New Flowchart Wizard
1 Grove Momentary Action Push Peripheral Gallery (Grove
Button Category)
1 Grove LED (Green) Peripheral Gallery (Grove
Category)
Challenge
Design a flowchart which blinks an LED, but only when a button is pressed
(the LED should be off otherwise).
The timing of the blinking is not terribly important, but a suggestion is 1
second on and 1 second off.
Blink Frequency Change
Parts Needed
Qty Part Added to Proteus Design By /
From
1 Arduino Uno New Flowchart Wizard
1 Grove Momentary Action Push Peripheral Gallery (Grove
Button Category)
1 Grove LED (Green) Peripheral Gallery (Grove
Category)
Challenge
Design a flowchart which blinks an LED slowly when a button is not pressed,
and faster when it is pressed.
Suggested timings are 1 second on / 1 second off for the slow blink, and 250
milliseconds on / 250 milliseconds off for the fast blink.
Tips
The “toggle” method of the Grove LED can be used to switch it on if it is off,
and off if it is on. You don’t need to use this method, however it can
potentially make the flowchart shorter and simpler.
Chapter 4 (Variables)
Nightlight
Parts Needed
Qty Part Added to Proteus Design By / From
1 Arduino Uno New Flowchart Wizard
1 Grove Luminance Sensor Peripheral Gallery (Grove Category)
1 Grove LED (Green) Peripheral Gallery (Grove Category)
Challenge
Design an automatic “nightlight” – a light which automatically comes on
when it gets dark. The Grove Luminance Sensor can be used to measure
whether it is light or dark; for this challenge a luminance reading from the
sensor of less than 300 can be considered “dark”, otherwise consider it to be
“light”. Our nightlight will be an LED (i.e. switch the LED on when the
luminance sensor measures that it is dark, and switch the LED off when the
luminance sensor measures that it is light).
Tips
The “readLuminance” method of the Grove Luminance Sensor can be used
to read the current luminance (light level). This method will by default
automatically place the reading into a new variable called “Lux”, which you
can use elsewhere in your flowchart (such as in a decision block).
The luminance sensor is represented by a window, which shows a sun when
it is light and stars when it is dark. To change the brightness, use the up and
down arrows at the bottom-right of the window.
Countdown to Blastoff
Parts Needed
Qty Part Added to Proteus Design By /
From
1 Arduino Uno New Flowchart Wizard
1 Grove RGB LCD Module Peripheral Gallery (Grove
Category)
1 Grove Momentary Action Push Peripheral Gallery (Grove
Button Category)
(Optional Bonus)
Challenge
Design a flowchart which counts down from 10 to 0 (with 1 second delays),
displaying the count on the top line of an LCD. When 0 is reached, then
display the text “Blastoff!” on the bottom line of the LCD. Optional Bonus:
Have a button which can be pressed to add 3 to the count.
Tips
When you print something to an LCD, it only prints as many characters as
are strictly necessary, and leaves the rest of the display unchanged. This is a
very useful feature if you only want to update a specific part of the LCD
(without changing the rest of it), but it can also result in some confusing
scenarios! For example; if you first print “10” (two characters) to the LCD,
and then try to print “9” (one character) at the same position, then the
resulting display will be “90”! This is because in order to print the “9” the
LCD only strictly needed to change one character, and it left the rest of the
display (including the “0” 2nd character from “10”) unchanged. There are
two possible solutions to this:
The first possible solution is to wipe the whole LCD clean before displaying
anything on it. This can be done using the LCD “clear” method (normally at
the top of your loop).
The second possible solution is to print blank characters (i.e. spaces; " ")
over anything which you would like cleared. So, for example, you could first
print two blank characters over the “10” in order to clear it, and then print
the “9” in the now blank space. Note that the printing of the clearing
characters and the printing of the “9” would be done in two separate
flowchart blocks, with a “setCursor” or “home” block in-between.
For the optional bonus, note that it is expected that the button will need to
be “held in” for up to 1 second in order for it to “take effect”. There are
ways to work around this (such as breaking the delay up into smaller
chunks), however they are not required for this challenge.
Chapter 6 (Drawing and Simulating Circuits)
Ohm’s Law
Starting the Project
Note that this project does not require a flowchart. For the procedure for
starting a project like this please see section 6.4.
Parts Needed
Qty Part Added to Proteus Design By /
From
1 RES (Resistor), value set to 5R (5 Schematic Components Tool
ohms) Mode
(Pick from Library)
1 POWER Terminal, set to +10V (10 Schematic Terminals Tool Mode
volts)
1 GROUND Terminal Schematic Terminals Tool Mode
1 DC Ammeter Schematic Virtual Instruments Tool
Mode
Challenge
Given a voltage of 10 volts, and a resistance of 5 ohms, calculate the
resulting current in amps (according to Ohm’s Law). Draw a circuit in Proteus
to verify your calculation by simulation.
Chapter 7 (Drawing Custom Peripherals)
Two LEDs, One Pin
Parts Needed
Qty Part Added to Proteus Design By / From
1 Arduino Uno New Flowchart Wizard
2 RES (Resistor), value set to Schematic Components Tool Mode
330R (Should already be in Object
Selector)
1 LED-RED Schematic Components Tool Mode
(Pick from Library)
1 LED-GREEN Schematic Components Tool Mode
(Pick from Library)
2 DEFAULT Terminal Schematic Terminals Tool Mode
1 GROUND Terminal Schematic Terminals Tool Mode
Challenge
Draw a custom circuit to interact with your Arduino Uno. Connect two LEDs
(one LED-RED and one LED-GREEN), with current-limiting resistors (330R), to
pin “IO7” on your Arduino Uno (both LEDs connected to the same pin).
Construct a flowchart which switches pin IO7 on the Arduino Uno on and off,
thus blinking the LEDs (1 second delays). Admittedly, this project is not very
practical in “real-life”; it is however good for practice!
Chapter 8 (Sub-Routines and Conditional Loops)
TwoTone
Parts Needed
Qty Part Added to Proteus Design By / From
1 Arduino Uno New Flowchart Wizard
1 Adafruit NeoPixel Shield Peripheral Gallery (Adafruit Category)
Challenge
Set the first 20 pixels on the NeoPixel shield as “red”, and the remaining 20
pixels as “green”.
Tips
The first 20 pixels are number 0-19, and the remaining 20 pixels are
numbered 20-39.
Checkerboard
Parts Needed
Qty Part Added to Proteus Design By / From
1 Arduino Uno New Flowchart Wizard
1 Adafruit NeoPixel Shield Peripheral Gallery (Adafruit Category)
Challenge
Display a checkerboard (alternating white and black pixels) on the NeoPixel
shield.
Tips
A white pixel is generated when all components colours (red, green and
blue) are set to full intensity (255). A black pixel is generated when all
component colours (red, green and blue) are set to zero intensity (0).
As with most programs, there are multiple ways to solve this challenge (one
of the below techniques could be used, not both):
a) A for loop with a “Step” value of 2 can be used to count “0, 2, 4,
etc”.
b) A mathematical equation like “intensity=255-intensity” can be used
to toggle “intensity” between 255 and 0.
Pulsing Glow
Parts Needed
Qty Part Added to Proteus Design By / From
1 Arduino Uno New Flowchart Wizard
1 Adafruit NeoPixel Shield Peripheral Gallery (Adafruit Category)
Challenge
Using a red colour, take all of the pixels on the NeoPixel shield smoothly
from zero intensity (red=0) to full intensity (red=255), and then smoothly
back down again (and repeat). Optional Bonus: Instead of pulsing just a red
glow, pulse a red then a green and then a blue glow (and repeat).
Tips
A delay of 5ms between display updates (“show” method) is recommended.
For the Optional Bonus:
The intensity of a pixel can be scaled using an equation like
“r=red*intensity/255”, where “intensity” is a variable somewhere between 0
and 255. Looking at this equation:
Note that “red” does not need to be 255 in this equation – any value will
“work” (so more colours could potentially be “glowed” than just red, green
and blue).
Appendix B: Solutions to Challenges
This appendix contains possible solutions to the challenges posed in
Appendix A. Remember that there are potentially many different ways to
solve a challenge in programming; so if your solution does not look exactly
like the one listed then do not worry! The important thing is whether the
program works or not (within reason; if a chapter covered an advanced
technique for achieving something then you should obviously try use that
technique rather than a simpler solution).
Chapter 2 (Creating Your First Project)
Heartbeat on LED
Chapter 3 (Reading Inputs and Making Decisions)
Blink on Demand
Countdown to Blastoff
Optional
Bonus
Chapter 6 (Drawing and Simulating Circuits)
Ohm’s Law
Chapter 7 (Drawing Custom Peripherals)
Two LEDs, One Pin
Chapter 8 (Sub-Routines and Conditional Loops)
TwoTone
Checkerboard
Possible Solution 1 Possible Solution 2
Pulsing Glow
Note: The flowchart depicted includes the Optional Bonus.
Notes
[←1]
Quote by Bill Gates, founder of Microsoft. https://code.org/quotes.
[←2]
IDE stands for “Integrated Development Environment”, and is largely a document editor with
some special features which assist in writing computer code – such as highlighting elements of
the code in different colours.
[←3]
If you need a reminder on what a microcontroller is, please see section 1.2.3.
[←4]
Usage of the timer peripheral is an advanced topic and is currently beyond the scope of this
book. Suggestions for further learning on this subject are made in section 11.1.
[←5]
Suggestions for further learning on this subject are made in section 11.1.
[←6]
“I/O” stands for “Input / Output”. Reading the temperature from a thermometer would be an
example of an input, and playing a song via an audio speaker would be an example of an
output.
[←7]
Image from https://store.arduino.cc/usa/arduino-uno-rev3
[←8]
Image from https://pmtechnologie.shost.ca/spip.php?article21, Creative Commons Attribution
2.5 License, unmodified except for labels added.
[←9]
If you are curious, please see https://en.wikipedia.org/wiki/Liquid-crystal_display for more
information.
[←10]
Product with LCD image from https://commons.wikimedia.org/wiki/File:Ensoniq_MR-
61_(LCD).jpg, Attribution-Share Alike 2.0 Generic license, unmodified except for labels added.
[←11]
The reason for using quotes or not using quotes is discussed in section 4.5.
[←12]
The reason for using quotes or not using quotes is discussed in section 4.5.
[←13]
Note that “Modulus” (remainder after division) has nothing to do with “Percentage”, although
its operator in C is a percentage symbol. Some examples of Modulus are:
7 divided by 2 is 3½ (three and one half) – thus 7 modulus 2 is 1, because 2 fits fully into 7 up to
3 times, leaving 1 remaining to actually reach 7. I.e. 7 % 2 = 1.
31 divided by 4 is 7¾ (seven and three quarters) – thus 31 modulus 4 is 3, because 4 fits full into
31 up to 7 times, with 3 remaining to reach 31. I.e. 31 % 4 = 3.
Somre more examples of modulus are:
8 % 4 = 0, 11 % 3 = 2, 12 % 3 = 0, 13 % 3 = 1, 14 % 3 = 2, 8 % 7 = 1
[←14]
“Inversely Proportional” means that as one value increases, the other decreases. In the case of
Ohm’s law, as resistance increases then current decreases.
[←15]
Note that you may see a large number of results when searching for “RES”. If you however type
exactly “RES” (without quotes) under “Keywords”, then the RES component will be selected by
default; it should show up in the preview on the right of the dialog, and can be added by simply
clicking “OK” (or pressing the “Enter” key twice).
[←16]
Breadboarding image from http://learn.adafruit.com/adafruit-arduino-lesson-4-eight-
leds/overview, Attribution Creative Commons license, unmodified except for labels added.
[←17]
Section 1.2.6.
[←18]
https://commons.wikimedia.org/wiki/File:Audio_SwitchBoxTwo_(With_Volume_Knobs)_(2011-
10-08_by_Kevin_B_3).jpg
[←19]
Technically, the advanced topic of “Interrupts” has not yet been covered. Suggestions for
further learning on this subject are made in section 11.1.
[←20]
https://www.adafruit.com/product/1430
[←21]
In this chapter we simply accept that electricity can be used to create motion (such as with an
electric motor). Details regarding exactly how electricity is used to create motion are beyond
the scope of this book, however there are many other resources available on these topics (for
example, conduct web searches for “Electromagnetism” / “Electromagnet” / “DC Motor” /
“Piezoelectricity” etc).
[←22]
The Proteus Visual Designer help file can be opened from the Help menu when the Visual
Designer tab is open and selected, or from the “Help” area on Proteus Home Page tab.