Silicon ChipMax’s Cool Beans - September 2023 SILICON CHIP
  1. Outer Front Cover
  2. Contents
  3. Subscriptions: PE Subscription
  4. Subscriptions
  5. Back Issues: Hare & Forbes Machineryhouse
  6. Publisher's Letter: Super-accurate analogue clock
  7. Feature: We both have truths, are mine the same as yours? by Max the Magnificent
  8. Feature: The Fox Report by Barry Fox
  9. Feature: Net Work by Alan Winstanley
  10. Project: GPS-Synchronised Analogue Clock by Geoff Graham
  11. Project: MINI LEDRIVER by Tim Blythman
  12. Project: Wide-Range OHMMETER by Phil Prosser
  13. Feature: Make it with Micromite by Phil Boyce
  14. Feature: Max’s Cool Beans by Max the Magnificent
  15. Feature: AUDIO OUT by Jake Rothman
  16. Feature: Circuit Surgery by Ian Bell
  17. Feature: Electronic Building Blocks by Julian Edgar
  18. PCB Order Form
  19. Advertising Index

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:
  • (November 2020)
  • Techno Talk (December 2020)
  • Techno Talk (January 2021)
  • Techno Talk (February 2021)
  • Techno Talk (March 2021)
  • Techno Talk (April 2021)
  • Techno Talk (May 2021)
  • Techno Talk (June 2021)
  • Techno Talk (July 2021)
  • Techno Talk (August 2021)
  • Techno Talk (September 2021)
  • Techno Talk (October 2021)
  • Techno Talk (November 2021)
  • Techno Talk (December 2021)
  • Communing with nature (January 2022)
  • Should we be worried? (February 2022)
  • How resilient is your lifeline? (March 2022)
  • Go eco, get ethical! (April 2022)
  • From nano to bio (May 2022)
  • Positivity follows the gloom (June 2022)
  • Mixed menu (July 2022)
  • Time for a total rethink? (August 2022)
  • What’s in a name? (September 2022)
  • Forget leaves on the line! (October 2022)
  • Giant Boost for Batteries (December 2022)
  • Raudive Voices Revisited (January 2023)
  • A thousand words (February 2023)
  • It’s handover time (March 2023)
  • AI, Robots, Horticulture and Agriculture (April 2023)
  • Prophecy can be perplexing (May 2023)
  • Technology comes in different shapes and sizes (June 2023)
  • AI and robots – what could possibly go wrong? (July 2023)
  • How long until we’re all out of work? (August 2023)
  • We both have truths, are mine the same as yours? (September 2023)
  • Holy Spheres, Batman! (October 2023)
  • Where’s my pneumatic car? (November 2023)
  • Good grief! (December 2023)
  • Cheeky chiplets (January 2024)
  • Cheeky chiplets (February 2024)
  • The Wibbly-Wobbly World of Quantum (March 2024)
  • Techno Talk - Wait! What? Really? (April 2024)
  • Techno Talk - One step closer to a dystopian abyss? (May 2024)
  • Techno Talk - Program that! (June 2024)
  • Techno Talk (July 2024)
  • Techno Talk - That makes so much sense! (August 2024)
  • Techno Talk - I don’t want to be a Norbert... (September 2024)
  • Techno Talk - Sticking the landing (October 2024)
  • Techno Talk (November 2024)
  • Techno Talk (December 2024)
  • Techno Talk (January 2025)
  • Techno Talk (February 2025)
  • Techno Talk (March 2025)
  • Techno Talk (April 2025)
  • Techno Talk (May 2025)
  • Techno Talk (June 2025)
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