This is only a preview of the July 2022 issue of Practical Electronics. You can view 0 of the 72 pages in the full issue. Articles in this series:
|
Flowcode
Graphical
Programming
Flowcode
C
v oid interrupt( v oid)
{
if ( intc on & 4 )
{
c lear_ bit( intc on, 2 ) ;
F C M _ IN T E R R U P T _ T M R
o( ) ;
Assembly
movlw
bsf S T A T U S , R P 0
bc f S T A T U S , R P 1
m ov wf _ adc on1
movlw 1 2
m ov wf _ option_ reg
Hex
:0 4 0 0 0 0 0 0 8 A 0 1 1 2 2 8 3 7
:0 8 0 0 0 8 0 0 F 0 0 0 F 0 0 S 0 3 0
E F 1 0 0 0 0
:1 0 0 0 1 0 0 0 0 4 0 E F 2 0 0 0 A 0
E F 3 0 0 B A 1 1 0 A 1 2 2 9 2 8 3 5 2
8 6 C
:2 0 0 0 2 0 0 D 9 2 8 F E 2 8 0 7 3
Programming with Flowcode – Part 4: Designing a Digital Clock
W
e are going to start a new
project this month. It will
build on ideas from previous columns but also introduce two
new and very useful components, plus
we’ll refresh some earlier programming
ideas and incorporate some new ones.
First a little housekeeping – as always, all the parts in this project come
from the free-to-use component library
of Flowcode, so you can build this in
Flowcode without making any code
purchases. For more details, do see the
Flowcode try-before-you-buy box at the
end of this article.
Project overview
It’s no secret that one of the most useful
and widely used applications of digital
technology is timekeeping. So, for our
next Flowcode project we will assemble
and program a system to create a simple
digital clock. This will help to extend
your understanding of Flowcode and
illustrate ideas and techniques you can
use in your designs.
The Flowcode Digital Clock hardware
will consist of four main parts: a microcontroller, a display, an RTC module and
a keypad. The microcontroller is our usual
Arduino Uno clone, the RedBoard. The
display will be the same 16x2 LCD we
used last month. The two new components are the RTC (real-time clock), an
inexpensive module based on a DS1307,
DS3231 or DS3232 IC, and a simple, lowcost membrane keypad.
Whichever IC the RTC module uses,
it keeps time with a precisely repeating
pulse (the ‘clock’) plus some initialising
set-up data which is stored in non-volatile SRAM. It uses the stored data and
clock pulse to accurately calculate the
time and date, which are then sent out
via its I2C bus. The module generates seconds, minutes, hours, day, date, month
and year information. The end of the
month date is automatically adjusted
for months with fewer than 31 days, including corrections for leap year up to
2100. Plus, it works with the 24-hour or
12-hour format via an AM/PM indicator.
48
Fig.1. Typical inexpensive RCT module
based on the DS3231 IC
You can also set alarms. So, all in all, it’s
quite a handy device for clock builders.
As explained, the free Flowcode RTC
component can support each of the
DS1307, DS3231 or DS3232 ICs, and I
used one with the DS3231 – see Fig.1.
At the time of writing, you can buy a
module based on this IC for under £5,
for example eBay item 125318625863,
but there are many other vendors.
Naturally, you need a way to set up
and initialise the RTC with the current
time/date, and to do that we will use a
membrane keypad. These simple and
inexpensive devices are a great way to
interface with digital projects, and learning how to use it in this Flowcode project
will help you in a host of other designs. I
used the 4x4 type shown in Fig.2. There
are many sources for these; for example,
eBay item 275255946762.
This won’t be a PIC project. Unlike more
modern PIC devices, the free Flowcode
PIC16F88 we have been using does not
support the I2C protocol, which rules it
out for communication with our RTC
of choice.
As well as the two new Flowcode
components, we will also use some new
Flowcode programming techniques, in
particular we will learn about:
n Byte-to-string conversion
n Global and local variables
n The difference between == and =
n The logical operators && and ||, plus
comparison operators > and <
n Calling a User Macro and passing input parameters
n Returning a value from a User Macro.
Naturally, all the Flowcode for this project
can be downloaded from the July 2022
Fig.2. 4x4 membrane keypad.
page of the PE website, and don’t forget that
if you get stuck there are helpful forums at:
https://flowcode.co.uk/forums/index.php
Fig.3. Project Explorer with the main
components added.
Practical Electronics | July | 2022
Fig.4 (left) Keypad before editing, and (right) after editing.
Digital Clock parts list
The parts you will need for the Flowcode clock project are
as follow:
n Solderless breadboard
n DS1307/DS3231/DS3232 Real-time clock (RTC) module
n Keypad – 4x4 membrane type (note, only 3x4 buttons used)
n 16x2 LCD – LCD 1602 (or 2004) with HD44780 chipset (see
PE, April 2022)
n Trimmer resistor – 10kΩ contrast adjustment for LCD
n 4x 100Ω resistors – pull-downs for RedBoard ports
n 3x 10kΩ resistors – in series with keypad, protects RedBoard
n Jumper wires.
Adding Flowcode components
To start, load Flowcode and set the target as the RedBoard (see
PE, January 2022). Next, the components are added from the
Components ribbon, either via search or by selecting a component category. To add components using search, use the following
terms in quotes and then select the item listed on the right:
Item
Term
Keypad
‘key’
LCD
‘lcd’
Real-time clock ‘rtc’
Choice
Keypad (Generic)
LCD (Generic, 16x2)
Real Time Clock (Internal, DS1307,
DS3231, DS3232)
After all the components have been added to the 2D panel,
Project Explorer should look like Fig.3 (with the component
functions minimised). Now look at the keypad on the 2D panel
– it will look like Fig.4 (left). So why only a 3x4 device when
I’ve specified 4x4? The reason is that this Flowcode keypad
component was originally designed just for a 3x4 device.
However, it has now been updated to cover both 3x4 and 4x4
versions. It also works with both decimal and hex keypad varieties. We have a 4x4 keypad as it offers greater flexibility for
future project expansion, but initially we will only use it as a
3x4 device, as explained below.
Fig.5. Editing the keypad’s properties
If you don’t make this change the keypad will not work as
expected with the program. After the change has been implemented, the keypad will look like Fig.4 (right).
When it comes to wiring the keypad, its cable connector
terminals have the row (R) and column (C) connections from
left to right shoen here: R1, R2, R3, R4, C1, C2, C3 and C4.
(This is the usual arrangement, but if possible, do check with
a datasheet or vendor specification.)
Now we need to set one RTC property. Select the properties of the RTC and make sure Simulate Comms is set to No.
Programming foundations
Next, we are going to lay some foundations for the Flowcode
program which we will build next month. This will be a
more involved program than the ones we have looked at so
far, and we need to expand our repertoire of Flowcode tools
to build a useable digital clock. We will expand some of the
concepts used in the Traffic Lights (PE, February 2022) and
LCD Temperature Monitor (PE, April 2022) projects, plus introduce some brand new ideas.
Variable and operators
Two of the most important concepts in programming are the
ideas of ‘variables’ and ‘operators’. We’ve already met some
kinds of variables in our earlier programs, but now would be
a good time to clarify some of their properties. Also, we will
make use of operators in the clock program, so we will provide an overview of those too.
Setting properties
Variables
Next, we need to set some component properties in our keypad
and RTC. We want to change the keypad so that its Flowcode
image matches the three left-hand columns of our actual keypad. This means changing the bottom row so that left to right,
it will read * 0 # instead of 0 A B.
Referring to Fig.5, we do this by changing the properties of
the keypad component. Open the properties window and edit
the Return Values. In the ASCII box, change:
1234567890ABCDEF to:
123456789*0# (ie, replace 0ABCDEF with *0#)
A variable is a value that can change, depending on conditions, a calculation or based on information passed to the
program. It can represent the value of something physical –
say temperature – or it can be something more conceptual, say
an interest rate. Such variables have a numerical value and
there is a choice of numerical formats (floating point, integer,
byte). Alternatively, a variable can indicate a system’s logical
status (eg, True/False, yes/no, on/off, 1/0). Another important
category of variable is a particular ordering of characters, typically called a ‘string’, or less formally, ‘text’.
In the Numbers box, change:
1,2,3,4,5,6,7,8,9,11,10,12,13,14,15,16 to:
1,2,3,4,5,6,7,8,9,11,0,12 (ie, delete ,13,14,15,16)
Global and local variables
Practical Electronics | July | 2022
Whatever the variable type or whatever it represents, variables can be classed as either ‘global’ or ‘local’. If it is global,
49
String variables are used for storing and
comparing text. (In fact, a short piece of
text is called a ‘string’.) When defining
them, the string must start and finish
with double quotation marks. For example, suppose we want a global string
variable called MyString, and we want
it to contain the string Hello World,
then we would type:
MyString = "Hello World"
Fig.6. Adding a new global variable in
Project Explorer.
then the variable is available for use in
in any User Macro within the whole program. On the other hand, if it is a local
variable then it will only be available
within the User Macro in which it was
created. Furthermore, once the User
Macro has finished (ie, the program has
moved on to a different User Macro) the
local variable will be erased, and it is
not available for other User Macros. If
the User Macro is accessed again then
the local variable is created afresh, starting with whatever initial value the User
Macro assigns.
Top programming tip: it is good programming practice to use local variables
whenever you can. Global variables use
more memory resources and local variables encourage better programming and
more reliable programs.
You can spot a local variable because
it must always start with full stop / period; eg, .MyLocalVariable
You add variables from the Project
Explorer (as shown in Fig.19 and Fig.20
in the PE, February 2022 Flowcode article). Fig.6 below shows the result of
clicking on the ‘Globals’ icon. Next, click
on <Add new> under Variables and then
enter your variable data in the resulting
variable window.
Local variables are added in a similar
way by clicking on the icon to the right
of ‘Globals’in the Project Explorer. Note
that when creating a local variable you
must be in the User Macro where the local variable is to reside.
String variables
We mentioned numerical and logical
(True/False, on/off, 1/0…) variables above,
and since we covered these in previous
articles (see: PE, February 2022) we won’t
expand on these here. However, although
we introduced string variables in the LCD
Temperature Monitor (PE, April 2022),
we didn’t go into a great deal of detail,
so let’s a take a closer look.
50
The default size of a string variable is
20 bytes, which is 20 characters. This
can be changed by entering the number
of required bytes into Array Length
in the Create A New Variable window,
you then click Add Array Dimension.
The square brackets at the end of the
string name will be the number of
bytes used.
Always bear in mind that the more
bytes assigned, the more memory is
used within the microcontroller, so it’s
best to keep the assigned string length
as short as possible. (Again, see Fig.19
and Fig.20 in the PE, February 2022
Flowcode article.)
String conversions
Things start to get more interesting when
you manipulate string variables. You
might want to convert a string to a byte
variable or a byte to a string variable.
For example, suppose you wanted to enter the time ‘09’ to be displayed on the
LCD; entering the numeric value ‘09’ as
a byte will result in just 9 being stored,
so only 9 will be displayed. However, if
09 is a string, then it will be stored and
displayed as ‘09’.
There are quite a few functions that operate on strings, and they can be found
by selecting the f$ icon, top right of the
calculation icon. In this project we will
use two of these: ToString$() and
StringToInt$()
ToString$() converts bytes or integers into a string, for example:
TempString = TempString +
ToString$ (.ReadKeypad)
This expression (see below for an explanation of the term ‘expression’) will
take the number that is assigned to the
local variable .ReadKeypad, convert
it to a string and ‘add’ it to whatever is the current value of the string
TempString. If TempString is the string
1 and .ReadKeypad is the number 6,
then ToString$ converts the number
6 to the string 6 and adds it to the contents of TempString creating the string
16. It’s important to note that this new
16 is a piece of text, it is not a number.
Likewise, StringToInt$() converts
a string to an integer. Naturally, it can
only convert strings written with number
characters. So to converts the string
123 to the integer 123, you would use
StringToInt$(123)
Operators
Variables are clearly useful, but you need
a variety of ways to manipulate them
– just as we did with the simple string
‘addition’ example above. This is where
operators come into the picture. An operator is a process which ‘operates’ on a
variable or value. For example, you will
recognise these basic arithmetic operators: +, –, /, * and =.
Operators are applied to ‘operands’
(variables and constants) and these combinations are used to create an ‘expression’,
which can reduce multiple variables to
a single value. For example, 6 + 4 = 10
is an expression that takes two operands
and reduces it to one value. Likewise,
you could add together two numeric
variables to create a new value:
CostofProject = Parts + PCB
Also, as we saw above, you can use some
operators on strings to create useful
expressions, and in this case, the expression’s output would also be a string.
Comparison operators
In programming, an essential class of
operator make comparisons between operands (variables and constants). There
are five varieties of these, and they each
ask one of five questions about the relative size of the two operands, here
generalised to x and y:
x > y is x greater than y
x < y is x less than y
x >= y is x greater than or equal to y
x <= y is x less than or equal to y
x == y is x equal y
These operators are used in decision
making branches, and their outputs are
the characteristic ‘yes’ or ‘no’ that you
see in flowcharts.
Use == or = for comparisons?
Notice that for the equals comparator above
I wrote a double-equals sign. The equals
sign (=) has more than one use in Flowcode.
For example, a single = is used for all assignment operations, so to set a variable
to a value we use: SetTime = 11. You
can use the single version in comparisons,
but to avoid ambiguity it’s best to use the
double version for a comparison operator.
Logical operators
Flowcode has operators that act like the
familiar logic gates ICs, producing logical AND and logical OR:
||
&&
Flowcode OR
Flowcode AND
Practical Electronics | July | 2022
The character ‘|’ is known as the ‘pipe’ symbol. You can
find it to the left of the key Z on a standard UK computer
keyboard. Note that you must type two pipes or two ampersands (&) to create an OR operator or AND operator – one
won’t work.
Brackets
When you combine several operators and operands in one
expression, it can become difficult to work out exactly what
the expression is supposed to mean. A simple example from
arithmetic is: x = 2 + 3 x 4. There are two possible ways of
looking at this. Do you multiply 3 times 4 and then add 2
to create 14; or, do you add 2 to 3 and then multiply by 4 to
produce 20? Now, although there are strict rules for interpreting this kind of expression this example does highlight
that ambiguity can creep into expressions and it’s easy to
make mistakes, which can be a nightmare to troubleshoot.
The best approach is to use brackets to effectively create
sub-expressions; for example, x = (2 + 3) x 4 or x = 2 + (3 x
4), depending on what you want to calculate. It never hurts
to liberally sprinkle brackets in your expressions and thereby make it clear to yourself (and anyone else who might use
or edit your code) what you intend the expression to do.
You can use brackets with logical operators too – in fact
they are especially useful with this type of expression. For
example, here is an expression from some code which we
will meet later in a User Macro called TimeSetValidity
(KeypadValue == 1 && SetTime > 23) || (KeypadValue
== 2 && SetTime > 59) || (KeypadValue == 3 &&
SetTime > 59)
This might look a little daunting at fi rst, but the use of
brackets makes it much easier to understand; all it is doing is asking if:
The KeypadValue is 1 AND the SetTime variable is greater than 23
Fig.7. Setting up the .Return facility of a User Macro
value of (for example) the Hours variable to be available,
then the last expression within a calculation icon must be:
.Return = Hours
The local variable is only ‘Returned’ on exit from its User
Macro and only one local variable can be returned. Any
kind of variable (float, string, byte, integer) or just a number can be returned.
User Macros often also need to receive parameters – this
is called ‘passing’ parameters and allows a User Macro to
be given values from other sources. You can pass as many
different parameter as you like. These parameters are set
up in the Parameters box of the same User Macro Properties
window as the Return item (Fig.8)
OR
The KeypadValue is 2 AND the SetTime variable is greater than 59
OR
The KeypadValue is 3 AND the SetTime variable is greater than 59
The answer to this whole expression will be ‘yes’ or ‘no’,
and from there the program will branch one way or another. Try writing out the expression without brackets and you
will see that it becomes much harder to understand – do
you apply AND or OR first? Remember, when it comes to expressions, brackets are your friends – use them!
Call macro parameters and return values
I mentioned above that it’s always better to use local variable
where possible – but that a local variable is erased when the
program exits the User Macro where it is used. This does
of course present a problem if the value of the local variable is of potential use in a different User Macro. The way
round this conundrum is to ‘Return’ the value.
When you create a new User Macro, if you require a value to be delivered to another User Macro then go to the
Properties window and enter the local variable in the dropdown of the Return Value box (see Fig.7). Also, the value
of the variable will only be passed back if it’s assigned to
the .Return local variable. For example, if you want the
Practical Electronics | July | 2022
Fig.8. Adding a parameter
51
Program overview
5. If not, it waits for 100ms and then returns to item 3 and repeats.
6. If a key press has been detected then
the microcontroller checks if key 1, 2
or 3 was pressed via the next three decision boxes. If not, it returns to item
3. Note: at this point in the flowchart
the program is designed to only move
on if 1, 2 or 3 is pressed. All other keys
will be seen as an error and ignored.
7. If 1, 2 or 3 has been pressed the program passes this information to the Run
set time routine. A 1 means Hours are
to be set; a 2 means Minutes; and a 3
indicates Seconds.
We’ve covered a lot of useful theoretical
material. Now, we return to the project and
discuss program operation. Fig.9 shows an
overview of the Digital Clock’s flowchart.
1. At power up, the program commences
with Start.
2. The microcontroller initialises the
RTC and LCD.
3. The microcontroller retrieves Hours,
Minutes and Seconds data from the LCD
and sends it for display on the LCD.
4. The microcontroller checks the keypad value and determines if a key has
been pressed.
Start
Initialise LCD
and RTC
8. The Run set time routine waits for the
Hours, Minutes or Seconds data, plus
a terminating # key press. If a # is not
detected, then the program returns to
the start of the Run set time routine.
9. If you enter the wrong digit you can
exit and re-enter the Run set time toutine by pressing the the * key.
10. When the # key is detected a time
validation is performed. This is to
check if a nonsense value has been
entered, for example 83 Seconds. If
a false value has been entered then
the digits are cleared and the program returns to the start of the Run
set time routine.
11. I f valid time data has
been entered then these
are written to the RTC
and the program returns
to item 3.
The program continues to
loop round from item 3 to
11 until the circuit is powered down.
Set RTC time
Retrieve time
from RTC, send
time to LCD
Has key 1
been
pressed?
Read keypad
value
Has a
key been
pressed?
Run set
time routine
Y
For Hours
N
Y
Has key 2
been
pressed?
Next month
That’s all for this month except to say that the Digital
Clock Flowcode program
which we will cover in detail
next month is available for
download from the July 2022
page of the PE website. Do
have a look at it now before
we dive into all its details
in the August issue!
N
Y
For Minutes
Has key *
been
pressed?
Y
Clear digits
N
N
Delay 100ms
Has key 3
been
pressed?
N
Y
For Seconds
Enter time digits,
followed by * or #
N
Has key #
been
pressed?
N
Y
Time
validation
check OK?
Fig.9. Flowchart of the Flowcode Digital Clock program.
Y
Martin Whitlock is an
Applications Engineer
at Matrix TSL – the
company which is
behind Flowcode.
Try Flowcode for free!
We hope you found this article
interesting. If you’d like to try
Flowcode for free then just go to
https://flowcode.co.uk/download/ and download the code.
You’ll get a 30-day free trial of the
full version – but that’s not all. Even
after the 30 days are up your copy
of Flowcode will continue to work,
but at a reduced level with a limit
on the size of program you can run
and access to a more basic set of
parts. However, for beginners it is
still an ideal platform with which
52
you can build and run programs,
on for example, the Arduino Uno/
RedBoard or a PIC 16F88 that we
are using in this project.
Only when you are sure that you
want to use Flowcode do you need
to buy inexpensive access to say
a Raspberry Pi or Bluetooth module. (See: https://flowcode.co.uk/
buy/process/ for all the modules
available and what they contain.)
What’s more, as soon as you buy
any module, the restrictions on the
size of your code are removed.
If you get stuck with anything
relating to Flowcode use (installation, software, creating flowcharts,
compiling to hardware, hardware
not working…) then there are forums set up to help you: https://
www.flowcode.co.uk/forums
PE discount!
One more thing – Flowcode is
deliberately designed to be inexpensive, but PE readers can get
a further 20% discount when they
use the code PE20 at checkout.
Practical Electronics | July | 2022
|