This is only a preview of the September 2023 issue of Practical Electronics. You can view 0 of the 72 pages in the full issue. Articles in this series:
|
Max’s Cool Beans
By Max the Magnificent
Arduino Bootcamp – Part 9
I
know some cynical souls say
nostalgia isn’t what it used to be but
– be that as it may – I must admit
to feeling a tad nostalgic myself at the
moment. Perhaps you would care to join
me on a little trip down memory lane
(cue audio and visual effects indicating
a trip into the past).
Just a little nybble
Shake yourself down and take a few
deep breaths. It will take only a couple
of minutes to recover from the rush of
racing through the timestream (it gets
easier the more you do it, and you do
it more the older you get).
It’s generally accepted (although not
undisputed) that the first commercial
microprocessor was the Intel 4004,
which was released into the world in
1971 when I was but 14 years of age. The
4004 was a 4-bit machine, which means
it had a 4-bit data bus and it manipulated and stored data in 4-bit ‘chunks’
called ‘nybbles’.
Comprising only around 2,300 transistors, the 4004 was a specialised device
intended for use in electronic calculators. The next wave of microprocessors
were predominantly 8-bit machines,
which means they had 8-bit data buses
and they manipulated and stored data
in 8-bit ‘bytes’ (we introduced the concepts of bits, nybbles and bytes in PE,
April 2023).
These 8-bit beauties included the Intel
8008 and 8080, which were introduced
in 1972 and 1974, respectively. Other
contenders from around that time were
the 6800 from Motorola in 1974, the
6502 from MOS Technology in 1975,
and the Z80 from Zilog in 1976 (to name
but a few). Many of these appellations
will stir fond memories in readers of a
certain age.
Byte by byte
In an earlier column (PE, July 2023)
we introduced the concept of the ‘unsigned binary’ format in which binary
values can be used to represent only
positive numbers. Also, we discussed
the ‘signed binary’ format in which
the same binary values can be used to
represent both positive and negative
44
numbers. As you may recall, a single
8-bit byte can embody 28 = 256 patterns
of 0s and 1s. In turn, these patterns can
be used to represent unsigned integer
values in the range 0 to 255 or signed
integer values in the range –128 to +127.
Unfortunately, there’s only so much
one can do with a single byte. What if
we wish to represent larger quantities?
Well, the obvious solution is to use
multiple bytes. For example, two bytes
(16 bits) can embrace 216 = 65,536 patterns of 0s and 1s, which can be used
to represent unsigned integers in the
range 0 to 65,535 or signed integers
in the range –35,658 to +35,657. Similarly, four bytes (32 bits) can encompass 2 32 = 4,294,967,296 patterns of
0s and 1s, which can be used to represent unsigned integers in the range 0 to
4,294,967,295 or signed integers in the
range –2,147,483,648 to +2,147,483,647.
Do you speak $^&*_?
In the very early days of microprocessors, it was common to enter one’s programs in machine code, which refers to
the numerical values executed by the
processor. One of the first single-board
computers (SBCs) I recall seeing was in
an advert here in Practical Electronics
sometime around 1977. I drooled with
desire when I cast my orbs on this little
beauty, but I was an impoverished
student at university at that time, so I
didn’t have two pennies to rub together, as they say.
In addition to its 8-bit processor chip,
this board had a 4x4 keypad to enter
instructions and data, some 7-segment
displays (like the ones we’re using in
our Arduino Bootcamp series) so you
could see what you were entering and
view the results when your program
stopped executing, and a couple of
pushbuttons to set the program running or single-step through the code. It
also had 1KB (one kilobyte) of randomaccess memory (RAM) and 2KB of preprogrammed read-only memory (ROM),
where each KB is 1 x 210 = 1,024 bytes.
RAM is volatile, which means it forgets its contents when power is removed
from the system. By comparison, ROM
is non-volatile, which means it retains
its contents when the system is powered down. The RAM was used to store
one’s programs and data, while the ROM
contained a monitor program that acted
as the interface between the user and
machine, watching the switches, driving the displays, and handing control
over to the user’s program when instructed to do so.
The next step up the programming
ladder was to use a low-level language
called ‘assembly’ in which each instruction is represented by a mnemonic (eg,
LDA $FF, meaning ‘load the accumulator register with the hexadecimal value
FF’). At first, it was common to capture
a program in assembly language using
pencil and paper, to assemble (translate)
that program into its corresponding machine code instructions by hand, and to
enter the machine code into the computer using toggle switches and pushbuttons, simple keypads, or similar. As
computers grew to have more memory
and better interfaces like keyboards and
screens, editor and assembler applications were employed to capture and
assemble these programs.
Irrespective of whether you were
working in machine code or assembly
language, if you wanted to use multiple bytes to represent larger values, you
were obliged to do everything by hand,
which was time consuming and prone
to error. Just to make things trickier,
each microprocessor had its own instruction set and operation codes, its
own assembly language and mnemonics, and its own way of doing things.
Oh, the fun we had!
Next on the scene came higher-level
programming languages like BASIC,
which stands for ‘Beginners’ All-purpose
Symbolic Instruction Code.’ BASIC was
originally developed at Dartmouth College in the early 1960s for use on ‘big
iron’ (mainframe) computers. However,
in 1975, Bill Gates and Paul Allen created a version that would run on one of
the early microprocessor-based personal
computers called the Altair (this was
the start of the Microsoft Corporation
we know and love to this day).
The great thing about using a higher-level language like Microsoft BASIC
Practical Electronics | September | 2023
was that you could write your programs
using large values (32-bit signed integers were the default) while leaving the
BASIC interpreter to break things up
into the 8-bit ‘chunks’ to be manipulated by the microprocessor.
How big, you ask?
This is probably a good time to remind
ourselves that, in the case of the Arduino Uno we’ve been using in our experiments, we’ve been employing its
integrated development environment
(IDE) to enter our programs in a mixture
of the C/C++ programming languages.
Thus far, the way we’ve declared integer variables is to use the int data
type, which – by default – instantiates
a signed integer. If we wish to create
an unsigned integer, we use unsigned
int. As we discussed in one of my
Cunning Coding Tips and Tricks columns (PE, September 2020), there are
three different sizes of int. In addition to the regulator int, we also have
short int and long int types.
The best way to wrap our brains
around how we use these types to declare variables is illustrated below,
where the red/bold parts are mandatory and the green parts are optional:
signed
unsigned
int Fred;
int Wilma;
signed
short int Barney;
unsigned short int Betty;
signed
long
unsigned long
int George;
int Jane;
This may seem confusing at first, but
it does make sense. If we don’t use the
signed or unsigned keywords, the
C/C++ compiler will assume signed.
Similarly, if we use the keywords short
or long, the compiler will assume we
are using these to qualify an int, even
if we neglect to explicitly say so.
Where things get a little tricky is that the
size of an int, a short int, and a long
int vary from computer to computer.
Fig.1. The Arduino Uno R3
microcontroller development board (the
big 28-pin dual-inline (DIL) chip is the
MCU (Source: Arduino)
Practical Electronics | September | 2023
This is largely a function of the computer’s internal architecture and data
bus width. All we know for sure is that
the C/C++ specifications state that the
minimum size of a short is two bytes
(16 bits), the minimum size of a long
is four bytes (32 bits), and the size of a
regular int is anybody’s guess.
In the case of an Arduino Uno R3 (the
reason for the ‘R3’ qualifier will become
apparent as we proceed), both an int
and a short are two bytes, while a
long is four bytes. Happily, the compiler understands what is required for
different processors, which is why one
of the first things we do is use the IDE
to tell the compiler which development
board we are working with.
Who’s in control?
These days, microprocessors are often
referred to as microprocessor units
(MPUs). At the heart of an MPU is its
central processing unit (CPU), which
is where all the decision making and
number crunching is performed. The
principal elements of a CPU include a
bunch of registers, an arithmetic-logic
unit (ALU) that performs the arithmetic and logical operations, and a control unit that orchestrates the fetching
(from memory), decoding, and execution
of instructions, along with the storing
(into memory) of results.
In the case of the early microprocessors that we are considering here, the
terms MPU and CPU may be considered
to be synonymous. By comparison, in
addition to one or more CPU cores, today’s MPUs also include things like onchip cache memories, memory management units (MMUs), floating-point units
(FPUs), and… the list goes on. One distinguishing characteristic of an MPU is
that it requires additional components
to realise a fully functioning computer system. These components include
memory devices, interface devices,
input/output (I/O) devices, and so forth.
By comparison, in addition to its CPU,
a microcontroller unit (MCU) also contains on-chip memory (RAM, and ROM)
along with other functions like counters, timers, pulse-width modulators
(PWMs), analogue-to-digital converters
(ADCs), and – once again – the list goes
on. As a result, an MCU is essentially
a small, fully functioning computer
implemented on a single silicon chip.
The tried-and-true Uno R3
The first Arduino Uno (known as the R1
for ‘Revision 1’) was introduced in 2010.
Following a couple of minor tweaks, the
R3 appeared in 2011, and this is the version we’ve been using ever since. Indeed,
it’s the Uno R3 that has been powering
the experiments throughout our Arduino
Bootcamp (Fig.1).
The processor chip employed by Arduino Unos R1, R2 and R3 is an 8-bit
MCU in the form of an ATmega328P.
This was created by a company called
Atmel, which was acquired by Microchip Technology in 2016. Running with
a clock frequency of 16MHz, this MCU
boasts 2KB of RAM and 32KB of Flash
memory. The RAM is used to store variables and data, the Flash (sort of equivalent to ROM) is used to store the user’s
program. When the MCU is powered up,
it immediately starts to execute whatever program is currently stored in its
Flash memory.
Now, you may be thinking to yourself that 2KB of RAM and 32KB of Flash
memory are not tremendously large
amounts in the scheme of things, and
you would not be incorrect. On the other
hand, consider the latest-and-greatest
dice rolling program that we created in
our previous column (PE, August 2023).
This program (a.k.a. ‘sketch’) waits for
the user to press a button, which triggers it to generate a series of sixteen
random values. The program presents
these values on our 7-segment display,
gradually slowing down until it settles
on the final value. If you load this program into your Arduino’s IDE and compile it, you’ll see that it uses only 71
bytes (3%) of our RAM and 2012 bytes
(6%) of our Flash memory. The bottom
line is that you can get a lot done with
only 2KB of RAM and 32KB of Flash.
You can refresh your (biological)
memory by downloading, perusing, and
pondering this code (file CB-Sep23-01.
txt). As usual, all of the files mentioned
in this column are available from the
September 2023 page of the PE website
at: https://bit.ly/pe-downloads
In addition to the processor itself, the
Arduino Uno’s printed circuit board
(PCB) includes several other devices
and connectors, which is why we refer
to the whole ensemble as being a ‘microcontroller development board.’
The Arduino Uno can be powered via
its USB-B connector or via its 2.1mm
power jack. In the latter case, a 7 to 12V
power supply is recommended (you can
go as high as 20V, but the regulator on
the development board will run hot).
In addition to powering the Arduino,
the USB-B connector can also be used
to communicate control information
and data between the Arduino and the
host computer (PE, May 2023).
Bake your own R3
Thus far, all the experiments in our
Arduino Bootcamp series have been
based on the use of a breadboard. The
advantage of this is that we haven’t been
obliged to solder anything.
Don’t worry, we are going to stick
with using our breadboard. Having said
45
Fig.2. A handy and fun soldering practice
board (Source: Gikfun)
this, the ability to solder opens a lot of
doors when it comes to creating more
involved projects. I taught myself how
to solder when I was about 12 years old,
which goes a long way to explain why
so few of my early projects worked. If
you are interested in learning to solder
yourself, there are lots of cheap-andcheerful tools available, like the Tabiger
60W Soldering Iron Kit for only £14.99
from Amazon: https://bit.ly/43gtIV2
I’d also recommend getting something
like a Gikfun Soldering Practice Board
(Fig.2) for only £11.98 from Amazon:
https://bit.ly/44gk1ay
The advantages of practising with
something like this are: (a) it’s hard
to mess things up, and (b) you end up
with a bunch of flashing light-emitting
diodes (LEDs). As I always say, show
me a LED flashing and I’ll show you a
man drooling.
Just to add a big dollop of allegorical whipped cream on top of our metaphorical cake, a few years ago, PE’s
very own Alan Winstanley created an
awesome Basic Soldering Guide Handbook – a ‘must read’ for beginners. If
this book had been available to me when
I was starting out, I would have saved
myself from much gnashing of teeth
and rending of garb, let me tell you.
It’s available for £11.49 from Amazon:
https://bit.ly/46CATKa
The reason I’m waffling on about
learning how to solder is that the nice
folks at Arduino just gifted me with
an Arduino Make Your Own Uno Kit.
The whole point about this kit is that
you get to solder all of the components yourself. The kit is available
from the Arduino store for €41.25, see:
https://bit.ly/3PKd115
I made mention of this little scamp
earlier in this series, at which time I
noted that it would be fun for all of us
to be performing our experiments on
Uno R3s that we had built ourselves.
What I hadn’t realised is that this kit
comes with a second board – a ‘shield’
that plugs into the Arduino Uno – which
acts as a music synthesiser (Fig.3).
The concept of plug-in shields has
played a large part in the Uno’s outstanding success (the folks at Arduino say 10
million Uno boards have shipped to date).
The open-source nature of Arduino has
allowed third-party vendors (both companies and individuals) to create shields
carrying sensors, actuators, and displays,
along with motor control shields, servo
control shields, relay shields, Wi-Fi
shields… the mind boggles.
I think it’s safe to say that the footprint of the headers on the Arduino
Uno has grown to be iconic. So-muchso, in fact, that it’s not uncommon to
see similar header arrangements on
other microcontroller and field-programmable gate array (FPGA) development boards, because this allows
those boards to take advantage of the
Arduino’s shield ecosystem.
Those were the days my friends…
I spent my formative years in the days
of 8-bit processors, which is one of the
reasons I’m so comfortable playing with
the Uno R3. I also like the challenge of
creating prodigious projects and implementing awesome algorithms while
working under the limitations of the Uno
R3’s 8-bit data bus, 16MHz clock, 2KB
of RAM, and 32KB or Flash memory.
I’m not alone in this. Back in the day,
computer magazines used to run competitions to see who could implement a
simple task – like counting the number
of 1s in a byte or reversing the order of
Fig.3. The assembled DIY Arduino Uno R3 (left) and music
synthesiser shield (right) (Source: Arduino)
46
0s and 1s from the least-significant bit
(LSB) to the most-significant bit (MSB)
– using the fewest number of memory
locations or the least number of clock
cycles. If you ever find yourself delving deeper into the nitty-gritty details
of low-level programming, may I recommend The Hacker’s Delight by Henry
Warren, see: https://bit.ly/3rwwdFs
Having praised the Uno R3, it must
be acknowledged that some projects require a bit more get-up-and-go on the
processor front. There are, of course, a
huge variety of Arduino boards, many
with wider data buses, more memory,
and higher clock speeds. Unfortunately, these boards fall short of the mark
if you wish to keep on using all of the
Uno shields in which you’ve invested
your hard-earned moolah. In addition to
the fact that they don’t offer the Uno’s
header footprint, their digital I/O pins
switch between 0V and 3.3V (the Uno
R3’s pins switch between 0V and 5V,
which are – therefore – the values expected by Uno shields).
What we need is a new Uno with a
32-bit data bus, a faster clock, and more
memory while maintaining the same
header footprint and using the same
5V signals as the Uno R3 so it can work
with all the existing shields that are out
roaming around the world, but where
will we find such a bodacious beauty?
Ah ha! Awe-inspiring Uno R4s
I am the bearer of glad tidings because
I have wonderful news to impart. The
folks at Arduino have just released two
shiny and spiffy new platforms called
the Uno R4 Minima and the Uno R4
Wi-Fi (Fig.4).
Right from the get-go, these bodacious
beauties have the same footprint and
support the same 5V signaling as the Uno
R3 (hurrah!). The next thing to note is
that the old USB-B connector has been
replaced with its more modern USB-C
counterpart. If you want to know more
about this connector, you may find The
A, B, C of USB for Beginners column
to be of interest: https://bit.ly/3OdIHuy
Fig.4. The Arduino Uno R4 Minima (left) and Arduino Uno R4 Wi-Fi (right)
(Source: Arduino).
Practical Electronics | September | 2023
Stiff wire
with weight
on the end
Helical
spring
Wire
to 0V
Wire to 5V via
pull-up resistor
Fig.5. DIY Trembler switch.
Also of interest is the fact that the
maximum power supply voltage via
the power jack has been increased to
24V with an improved thermal design.
Now let’s turn our attention to the
boards themselves, starting with the
R4 Minima. Some Arduino users wish
to communicate with devices using a
Controller Area Network (CAN) bus.
To do this with the Uno R3, users were
obliged to use a CAN shield, so they
will be happy to learn that the Uno R4
offers a CAN bus interface along with the
existing UART, I2C and SPI interfaces.
Of course, the part in which we are
most interested is the Uno R4’s processor, which is a RA4M1 microcontroller
from Renesas. This device is based on
a 32-bit Arm Cortex-M4F core, where
the ‘F’ indicates the inclusion of a hardware floating-point unit (FPU).
The Uno R4’s 32-bit data bus is four
times the width of the Uno R3’s 8-bit bus.
As far as the compiler is concerned, integers of type short and long are still 16
bits (2 bytes) and 32 bits (4 bytes) wide,
respectively. However, the size of a regular int with an R4 is now 32 bits, as
opposed to only 16 bits in an R3. There
are all sorts of interesting implications to
this, but nothing that would affect anything we’ve been doing, so we’ll leave
those discussions to a future column.
The R4’s clock runs at 48MHz (three
times the R3), it’s equipped with 32KB
of SRAM (16 times the R3), and it boasts
256KB of Flash memory (8 times the R3).
I ask you… what’s not to love?
Now let’s turn our attention to the Uno
R4 Wi-Fi, which is based on the same
microcontroller as the R4
Minima. However, the R4
Wi-Fi also sports an Espressif ESP32-S3 module for
Wi-Fi and Bluetooth Low
Energy connectivity. As
we see in Fig.4, this little
ragamuffin also flaunts a
super-bright 12x8 red LED
matrix, which can be used
for things like displaying
animations reflecting the
values of sensor data with- Fig.6. Testing my vibration (‘trembler’) switches.
out the need for any addiDid you build one of these? I was going
tional hardware.
to, but I got distracted by… SQUIRREL!
Using the R4 Uno Wi-Fi, we can do
So, I ended up purchasing an off-the-shelf
things like connect to the Arduino
device. Actually, I acquired three differCloud. In turn, this allows is to do
ent types from The PiHut (thepihut.com):
things like create web-based dashboards
• S l o w / h a r d - t o - t r i g g e r v e r s i o n :
packed with customisable widgets, with
https://bit.ly/3rBOgdm
which we can visualise historical or
• Medium type: https://bit.ly/3pPiadP
real-time data in the cyberworld and
• High-sensitivity/easy-to-trigger imcontrol things in the real world. Once
plementation: https://bit.ly/46SfDA4
again, however, we will leave further
discussions on this topic for a future
You can also source these slow (SWtime because we currently have other
18030P), medium (SW-18020P), and
fish to fry.
fast (SW-18010P) devices from suppliers like Adafruit and eBay.
I’m all atremble
The first thing I did when these little
We seem to have wandered off into the
rascals arrived was to mount them on a
weeds. Why didn’t you stop me from
breadboard. Each had one side connected
waffling on so much? At the end of last
to 0V and the other side connected to
month’s column (PE, August 2023) I sug5V via a 10kΩ pull-up resistor (Fig.6).
gested we might add a ‘nudge nudge’
I connected three oscilloscope probes
feature to the latest and greatest verto the tap (measurement) points besion of our dice rolling program. I also
tween each switch and its associated
noted that, to do this, we could build
pull-up resistor, and then devoted a few
a DIY ‘trembler switch’ (these are ofhappy minutes to banging the table to
ficially called ‘vibration switches’) as
see what happened. It didn’t take long
illustrated in Fig.5.
to decide that, for this application, the
We can think of this implementamost sensitive, fast-acting switch was
tion as being ‘A poor person’s accelthe one for me.
erometer/motion sensor.’ The idea is
I drooled with delight at the trace from
that a sufficient shock, like banging the
this device (Fig.7). In this case, the hortable, will cause the weighted wire to
izontal timebase is set to 50 microsecmove and complete the electrical cironds (µS) per division, which means the
cuit. Once our program is displaying
vibration continues for approximately
its final value, if our trembler switch
300µS, which is 0.3 milliseconds (ms).
is triggered (‘nudged’) anytime during
Armed with this newfound knowlthe PAUSE_AFTER_ROLL delay, then we
edge, I added my trembler switch to
could perform an additional random
the breadboard I’ve been using for our
roll of our dice.
5V
10kΩ
10kΩ
10kΩ
A0
A1
A2
SW0
SW1
SW2
GND
To the Arduino’s A0 analogue pin
To the Arduino’s A1 analogue pin
To the Arduino’s A2 analogue pin
Fig.7. Example result from the sensitive vibration switch.
Practical Electronics | September | 2023
Symbol for a vibration
(trembler) switch, closed
on rising vibration
Fig.8. Adding the vibration (trembler) switch to our breadboard.
47
Components from Part 1
Listing 1. Adding a new pin definition.
LEDs (assorted colours)
https://amzn.to/3E7VAQE
Resistors (assorted values)
https://amzn.to/3O4RvBt
Solderless breadboard
https://amzn.to/3O2L3e8
Multicore jumper wires (male-male) https://amzn.to/3O4hnxk
Components from Part 2
7-segment display(s)
https://amzn.to/3Afm8yu
Components from Part 5
Momentary pushbutton switches
Listing 2. Adding a new global variable.
https://amzn.to/3Tk7Q87
Components from Part 6
Passive piezoelectric buzzer
https://amzn.to/3KmxjcX
Components for Part 9
SW-18010P vibration switch
Listing 3. Modifying the setup() function.
Arduino Bootcamp experiments and connected its tap point
to the Arduino’s A2 analogue input (Fig.8). As usual, you
can download an image of our current breadboard layout
showing all three switches, our buzzer and our 7-segment
display – along with various pull-up and current-limiting
resistors – coupled with the connections to our Arduino
Uno – see file CB-Sep23-02.pdf
Tremble away!
To add our ‘nudge nudge’ feature, we will use our existing
dice rolling program as a starting point (file CB-Sep23-01.
txt). The first thing we are going to do is add a new pin definition on Line 22 for the pin that’s connected to our vibration switch (Listing 1). (Note that any line numbers specified here relate to the new version of our program because
the changes we are making will modify the existing code.)
Listing 4. Modifying the loop() function.
Listing 5. Modifying the RollTheDice() function.
48
https://bit.ly/46SfDA4
Next, we are going to add a new global variable on Line
47 in the form of an int called LastDiceValue (Listing
2). We are going to use this value to keep track of the final
value from the initial roll because – in this case – if we do
trigger a tremble, we want the resulting dice value to be different to the old one.
In the case of our setup() function, all we need to do is
add a new Line 65 in which we declare the pin connected
to our vibration switch as being of type INPUT (Listing 3).
Our original loop() function contains three calls to functions whose names speak for themselves. After displaying
our ‘ready’ symbol, waiting for the switch to be pressed, and
rolling the dice, we are going to add a new call on Line 82
to a function that checks to see if the vibration switch has
been triggered (Listing 4).
As you may recall, the last line of our existing
RollTheDice() function caused the program to pause for
our PAUSE_AFTER_ROLL delay, which is currently set to
two seconds. We are going to delete this statement from Line 119 and replace it with a new
statement that stores the final dice value in
our global LastDiceValue variable, as illustrated in Listing 5.
Next, we are going to take an initial stab
at the CheckTrembler() function. The first
thing we need to do is to re-implement the
PAUSE_AFTER_ROLL delay in a new form, as
shown in Listing 6.
Do you remember the unsigned long data
type we discussed earlier? Well, on Lines 125
and 126 we start by declaring two local variables of this type called currentTime and
endTime (this is uncanny – it’s almost as if
I had a plan).
On Line 128 we assign the value returned
from the Arduino’s in-built millis() function to our currentTime variable. This function returns the number of milliseconds passed
since the Arduino board began running the
current program (this number will overflow
(return to zero), after approximately 50 days).
On Line 129 we assign the sum of the value
stored in currentTime and our PAUSE_AFTER_
ROLL delay to our endTime variable, which
results in the time stored in endTime being
2000ms (two seconds) in the future.
Finally, in Lines 131 through 134, we enter
a do-while loop (we introduced these constructs in PE, March 2023). At the moment,
all we are doing is looping around loading our
currentTime variable with the latest value
Practical Electronics | September | 2023
Listing 6. First-pass CheckTrembler() function.
tremble functionality to our CheckTrembler() function, as illustrated in Listing 7. In Line 128 we declare
a swVal variable (we’re going to use this like we did in
our WaitForSwitch() function, except that this time
we will be checking the state of our vibration switch).
In Lines 129 and 130 we declare diceVal and charSegs
variables (we are going to use these like we did in our
RollTheDice() function).
In line 131 we declare a Boolean variable of type bool
called tremble to which we assign a value of false
(which we take to mean that a vibration has not yet occurred). Last month, we said the user will be able to
activate the vibration switch only a single time, and
this is the variable we’re going to use to make sure we
stay true to our word.
Our original outer do-while loop starting on Line
136 and ending on Line 158 remains the same. Inside
this loop, we first read the value from our vibration
switch on Line 138. Next, on Line 140, we check to
see if the switch has been activated (a ‘nudge’ from the
user) while also checking that we haven’t previously
detected a vibration. If both these conditions are true,
then the first thing we do on Line 142 is assign a value
of true to our tremble variable, thereby ensuring that
we won’t respond to a future ‘nudge.’
Lines 144 to 147 implement another do-while loop.
In this case we keep on generating new random numbers
as long as the new values are the same as the one that
is currently on the display. We exit this loop as soon as
our new random number is different to the old value.
We use Lines 149 to 151 to present our new (‘nudged’)
value on the 7-segment display. Finally, on Lines 153
and 154 we reset things so that we will display our new
value for the full PAUSE_AFTER_ROLL delay before returning control to the main loop() function.
All I can say is that this latest version of our code
works like a charm (file CB-Sep23-04.txt). So, what are
we going to do next? Well, one thing we could do is
create a reaction tester to see how fast we can respond
to changes on our display. Another possibility is to
employ some different types of sensors (eg, light and
temperature) to control our display. All will be revealed
next month. Until then, have a good one!
Online resources
Listing 7. Fleshed-out CheckTrembler() function.
For the purposes of this series, I’m going to assume
that you are already familiar with fundamental
concepts like voltage, current and resistance. If
not, you might want to start by perusing and pondering a short series of articles I penned on these
very topics – see: https://bit.ly/3EguiJh
Similarly, I’ll assume you are no stranger to
solderless breadboards. Having said this, even if
you’ve used these little scamps before, there are
some aspects to them that can trap the unwary,
so may I suggest you feast your orbs on a column
I wrote just for you – see: https://bit.ly/3NZ70uF
Last, but not least, you will find a treasure trove
of resources at the Arduino.cc website, including
example programs and reference documentation.
returned from the millis() function. The loop will terminate
when the value in currentTime is equal to or greater than the
value in endTime.
Feel free to peruse and ponder the current state of play (file
CB-Sep23-03.txt). Of course, all we’ve done so far is to replicate
the functionality we had in our original program. As we’ve discussed before, however, we can
make our lives a lot easier by
Cool bean Max Maxfield (Hawaiian shirt, on the right) is emperor of all he
taking things one step at a time.
surveys at CliveMaxfield.com – the go-to site for the latest and greatest
Let’s try compiling this to see if
in technological geekdom.
it works. It does. Hurray!
At this point we are ready
Comments or questions? Email Max at: max<at>CliveMaxfield.com
to actually add the nitty-gritty
Practical Electronics | September | 2023
49
|