Silicon ChipMax’s Cool Beans - March 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: Important advice
  7. Feature: It’s handover time by Mark Nelson
  8. Feature: The Fox Report by Barry Fox
  9. Feature: Net Work by Alan Winstanley
  10. Project: Capacitor Discharge Welder by PHIL PROSSER
  11. Feature: Mini PIC Training Course – Part 2 by Peter Brunning
  12. Project: Raspberry Pi Pico BackPack by Tim Blythmhman
  13. Project: Semaphore Signal by LES KERR
  14. Feature: AUDIO OUT by Jake Rothman
  15. Feature: Make it with Micromite by Phil Boyce
  16. Feature: Circuit Surgery by Ian Bell
  17. Feature: Max’s Cool Beans by Max the Magnificent
  18. PCB Order Form
  19. Advertising Index

This is only a preview of the March 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 3 I I like things to be logical. One of the reasons I enjoy playing with microcontroller units (MCUs) like the Arduino is because the way they work inside is based on logical functions and the programs we run on them behave in a logical manner (on a good day… if we’re lucky). would be mega-cool to be performing the experiments in these columns on an Arduino Uno we’d actually built ourselves. Great Scottish bagpipes! left everything ‘as is’ from our previous experiments, the green power LED on the right-hand side of the breadboard should light up. Also, the last program we loaded into the Arduino should start randomly lighting the segments on the 7-segment display. AREF GND 13 12 ~11 ~10 ~9 8 7 ~6 ~5 4 ~3 2 TX-1 RX-0 Speaking of bagpipes (we weren’t, but we are now), let’s pretend we are in a marching band, in which case it’s important to ensure we’re all marching in I also enjoy mulling over logical conunToo much power! step to the same drumbeat. drums. For example, did you ever see the We’re not going to go through the calculaAs you may recall, in Part 1 of this 1986 fantasy film Labyrinth? This movie is tion to determine the minimum value of mega-miniseries (PE, January 2023), we full of riddles and puzzles, including one an LED’s current-limiting resistor again plugged a single green light-emitting involving two doors, each with a guard. because – as we discussed in Part 2 – you diode (LED) into our breadboard, along One door leads to where we want to go should have this documented in your logwith a 100Ω current-limiting resistor. We while the other leads to certain death. We book. Suffice it to say, our green LED’s use this LED (a) because we love LEDs can pose a single question to just one of forward-voltage drop (VF) is specified and (b) to provide a visual indication the guards to help us determine which as being 3V and its maximum forward that power is reaching the breadboard. door we wish to use. The problem is, alcurrent (IF) is 20mA. Based on this, we In Part 2 (PE, February 2023), we though we know one guard always tells decided to use a 100Ω resistor (Fig.1). plugged a single-digit common-caththe truth and the other always lies, we This value is reflected in the resistor’s ode 7-segment display into our breaddon’t know which is which. So, what brown-black-brown colour bands (Fig.2). board, connected 150Ω current-limiting question should we ask? (The answer Using the maximum current isn’t a resistors to each of this device’s anode is at the end of this column.) problem per se, except for the fact that terminals, and connected the other side the LED may be a tad too bright for our of those resistors to some of the Arduiviewing pleasure. On the other hand, Roll your own no Uno’s digital input/output (I/O) pins, it’s not good practice to drive an elecBy some strange quirk of fate, shortly after which we configured to act as outputs. tronic component at any of its maximum I commenced penning this piece, my old A circuit diagram reflecting the currated values. For example, LEDs tend to chum Alvin Brown sent me a link to a rent state of play is shown in Fig.1. This dim with age and this dimming is exreview on the Tom’s Hardware website is obviously an abstraction that reflects acerbated if we constantly run them at (https://bit.ly/3WbawFo). You can only much-simplified views of our real-world their maximum rated current value. In imagine my surprise and delight to disArduino and 7-segment display. Differthis situation, we might want to double cover that this review features a Build ent people will draw these diagrams Your Own Arduino Uno Kit. (In addiin different ways, but the gist will tion to the Uno itself, the kit includes an We’ll discuss this later always be the same. It’s important Audio Synthesiser ‘shield’ (a board that for you to learn how to parse this plugs on top of the Arduino) that you can A F sort of diagram and wrap your brain build and use to make sounds or music. around the underlying functionality If you are just starting out with microconB G it’s intended to convey. trollers (which would explain your barely A more ‘real-world’ depiction of our controlled excitement at the thought of E DP breadboard’s layout and wiring – inreading this column), you might want to cluding the connections between the leave building your own Arduino for later. breadboard and the Arduino Uno – On the other hand, you must agree that it D C is illustrated in Fig.2. Take a moment to compare and Arduino 7-Segment Display contrast the different views 150Ω E 5V A 1 7 of the design provided by D 2 6 a F B C these two representations 4 5 DP G 5 and make sure that every4 k B 6 E GND 5V 3 C thing makes sense. A 7 2 From F 100Ω D Before we proceed, con9 DIGITAL IN/OUT (PWM ~) 9 Arduino G 10 3 8 GND 8 nect the USB cable powering your Arduino. Assuming your host computer is Fig.2. Actual layout and wiring (Arduino shown Fig.1. Circuit diagram showing the current state of play. powered up and you’ve in blue). DP Practical Electronics | March | 2023 61 Experiments from Part 1 Experiments from Part 3 5V a 220Ω a a k k k 220Ω D6 a D6 D10 a D10 330Ω k k a 330Ω GND k (a) (b) (c) (d) Fig.3. Experiments with individually packaged LEDs. the resistance to 200Ω, thereby halving the current to 10mA. Unfortunately, the closest value I have in my variety pack of resistors is 220Ω (with colour bands of red-red-brown), but ‘that’s close enough for government work,’ as they say. You might wish to experiment further by gradually increasing or decreasing the resistor value until you achieve a brightness that pleases your eye (don’t go lower than 100Ω, or you will end up with a dead LED). If you do decide to perform this experiment, remember to keep track of the results in your logbook. In the case of our 7-segment display, since each of this display’s red LEDs has a VF of 2V and an IF of 20mA, we decided to use 150Ω resistor values on its anode terminals (Fig.1). These resistors have brown-green-brown colour bands (Fig.2). Based on our discussions above, we could decide to double the values of these resistors to 300Ω. In this case, the closest value I have is 330Ω (with colour bands of orange-orange-brown). We will use a 330Ω resistor with the individual red LED we are going to experiment with in a moment. In the case of our 7-segment display, however, for reasons that will be made clear in the fullness of time, we are going to stick with our existing 150Ω current-limiting resistors. One LED (how sad) Before we return to experimenting with our 7-segment display, let’s take a little diversion that will help increase our understanding of what’s happening inside the Arduino. Remember that an LED will turn on and light up if its anode (a) terminal is at a more positive potential than its cathode (k) terminal (this assumes that the potential difference is greater than the LED’s VF value, of course). In Part 1, we created our own version of the standard Arduino Blink program (‘sketch’ in the vernacular of the Arduino community). As part of this, we configured the Arduino’s digital input/ output (I/0) pin 6 to act as an output. We 62 then used this output to drive the anode terminal of an LED whose cathode terminal was connected to GND (0V) via a current-limiting resistor (Fig.3a). In the most current version of this program, we commence with three #define statements – you can access this program, file CB-Mar23-01.txt, and all the others mentioned here from the March 2023 page of the PE website at: https:// bit.ly/pe-downloads #define PIN_LED #define LED_ON #define LED_OFF 6 HIGH LOW Later, in the body of the program, we use these definitions in calls to the Arduino’s digitalWrite() function to turn our LED on for 100ms and off for 900ms, thereby providing a 1/10th-second flash once each second. // Turn the LED on digitalWrite(PIN_LED, LED_ON); delay(100); // Turn the LED off digitalWrite(PIN_LED, LED_OFF); delay(900); When we compile our source code into the machine code that will run on the Arduino, the preprocessor will replace any instances of PIN_LED, LED_ON, and LED_OFF with 6, HIGH, and LOW, respectively. In the case of an Arduino Uno, when they are presented to the outside world, HIGH equates to 5V and LOW equates to 0V. In a variation of this experiment, we used the same output to drive the cathode terminal of an LED whose anode terminal was connected to 5V via a current-limiting resistor (Fig.3b). As part of this, we modified our LED_ON and LED_OFF definitions as follows (file CB-Mar23-02.txt): #define LED_ON LOW #define LED_OFF HIGH Had we not performed this modification, instead sticking with our original version of the program, then the LED in Fig.3b would have been on for 9/10th of a second and off for 1/10th of a second. also connected to the Arduino’s digital I/O pin 10. The reason we are using pin 10 in this case is that we’re already using pins 2 through 9 to drive our 7-segment display. So, what do you think will happen if the Arduino drives a LOW or a HIGH on pin 10. While you are pondering this question, let’s take a moment to note that the circuit in Fig.3d is functionally equivalent to that in Fig.3c. The only reason for showing Fig.3d is to remind ourselves that (in a series circuit) the ordering of an LED and its current-limiting resistor doesn’t matter. Returning to our question. If there’s a LOW (0V) on pin 10, then the green LED will have 5V on its anode and 0V on its cathode, so it will start conducting and light up. Meanwhile, the red LED will have 0V on both its anode and cathode, which means it will do nothing at all. Contrariwise, if the Arduino drives a HIGH (5V) on pin 10, then the green LED will have 5V on its anode and 5V on its cathode, which means it won’t do anything. By comparison, the red LED will have 5V on its anode and 0V on its cathode, which means it will start conducting and light up. Unplug the USB cable from your Arduino, and then implement the circuit from Fig.3c in an unused area of your breadboard. However, in the case of the jumper wire connected to the centre point between the two LEDs, let’s not connect that to pin 10 on the Arduino just yet. Instead, let’s leave it as a flying lead (Fig.4). The reason for keeping this as a flying lead is because – as we discussed in Part 2 – we can make our lives a lot easier by making sure our hardware is working as planned before we start trying to drive it with our software. Once you’ve wired this circuit up, plug the USB cable back into the Arduino. Once again, our original green LED will light up and we will see the random lighting of the segments on the 7-segment display. In the case of our two new LEDs, since their combined forward-voltage drop as specified in their data sheets is 5V (3V for the green LED plus 2V for the red LED), these LEDs should both be turned off. In the real world, however, their forward voltage drops may be Two LEDs (twice the fun) Now look at Fig.3c. In this case, we have a green LED whose anode is connected to 5V via its current-limiting resistor. We also have a red LED whose cathode is connected to 0V via its current-limiting resistor. Observe that, in this case, we are using our new 220Ω and 330Ω resistor values as discussed earlier in this column. The green LED’s cathode is connected to the red LED’s anode, and this point is Fig.4. Two LEDs is twice the fun. Practical Electronics | March | 2023 Let’s create an updated version of our early Blink program to drive our red-green LED combo. In the past, we associated definitions of LED_ON and LED_OFF with HIGH and LOW (or LOW and HIGH) respectively, but these definitions no longer cut the mustard, as it were. We need to employ more meaningful definitions, as shown in Listing 1 (see also file CB-Mar23-03.txt). Observe that we’ve changed our PIN_LED definition to be associated with pin 10 on the Arduino. Also, we are now associating RED_ON_GREEN_ OFF and RED_OFF_GREEN_ON with HIGH and LOW, respecListing 1. Using definitions more suited to our red/green tively. Although our new definitions are a tad more verbose LED combo. (perhaps ‘robust’ would be a better word), they make it easy for people less than stated on their datasheets, in to understand the tasks this program is which case both LEDs may light up to intended to accomplish. some extent. Use the Arduino’s IDE to capture this If you plug the free end of the flying code, click the Verify icon (or use the lead into one of the holes on the breadSketch > Verify/Compile command) to board’s 5V rail (the one with the red make sure things are as they should be, line), the green LED should turn off and then click the Upload icon (or use the the red LED should light up. If you now Sketch > Upload command) to upload unplug the flying lead from the 5V rail the resulting machine code into the Arand plug it into one of the holes on the duino and feast your orbs on your flashbreadboard’s 0V rail (the one with the ing LEDs. blue line), the green LED should light up and the red LED should turn off. Just for giggles and grins, unplug the Layers of abstraction flying lead from the breadboard’s 0V I don’t know about you, but I always rail and plug it into the hole indicated like to have an idea as to what’s going by the red circle in Fig.2 (the one anon ‘under the bonnet’ as we say in the notated with the words ‘We’ll discuss UK (or ‘under the hood’ in the vernacuthis later’). Observe that our new red lar of the US). There’s a huge amount to LED will now flash in time with the ‘A’ wrap our brains around here, but a racing segment on our 7-segment display (the version is as follows. new green LED will be in the opposite It’s common to hear computer boffins state to the red LED). Congratulations! say that digital computers like our ArduYou’ve just created a basic logic probe ino microcontroller are based on 0s and – see: https://bit.ly/3YJbIl6 1s (‘zeros and ones’), but what does this really mean? Well, at the interface where the microcontroller meets the real world HIGH or LOW? in the form of its digital I/O pins, we are Now, unplug the flying lead from the 0V working with real voltages, such as 0V rail and connect it to pin 10 on the Arand 5V in the case of an Arduino Uno. duino. At this time, as discussed above, Everything else is an abstraction inboth of our new LEDs should either be tended to make our lives easier. For exoff (if their combined forward voltage ample, we use 0 and 1 as abstractions for drops are greater than or equal to 5V) 0V and 5V, respectively. Similarly, we or dimly illuminated (if their combined use LOW and HIGH as abstractions of 0 voltage drops are less than 5V). and 1, and we use definitions like RED_ This is what we’ve been seeing when OFF_GREEN_ON and RED_ON_GREEN_OFF the end of our flying lead isn’t connected as abstractions of LOW and HIGH. to anything, but we just connected it to But why do we use 0 and 1 in the first pin 10 on our Arduino. What gives? Well, place? Well, let’s start with the fact that a as we discussed in Part 1, when a microdigital quantity is one that can be reprecontroller is first powered up, all its pins sented as being in one of a finite number are set to be inputs by default. This means of states. The simplest digital systems that, as far as what used to be our ‘flying employ only two states, which we might lead’ is concerned, it’s not currently being refer to as 0 and 1, UP and DOWN, IN driven by anything, which is the same as and OUT, OFF and ON, and so on. it not being connected to anything. Practical Electronics | March | 2023 Next, let’s note that sometime around the 1850s, a British mathematician called George Boole established a new mathematical field known as symbolic logic, which we now know as Boolean algebra. Unfortunately, outside mathematical circles, no one really cared. In the early part of the 20th century, inventors started to create electrical circuits based on switching elements that could perform simple arithmetic functions and/ or execute sequences of operations to control things like industrial machinery. These switching elements included regular switches, electromagnetic switches in the form of relays, and electronic switches in the form of vacuum tubes. However, there was a limit to the complexity of the systems those inventors could achieve because they didn’t have appropriate mathematical tools at their disposal. In the late 1930s, a graduate student at MIT called Claude Shannon submitted a master’s thesis that revolutionised electronics. In this thesis, Shannon showed that Boolean algebra offered an ideal technique for representing the logical operation of digital systems. Shannon had realised that the Boolean concepts of false and true could be mapped onto the binary digits 0 and 1, and that both could be easily implemented by means of electronic circuits. Most materials are conductors, insulators, or something in-between. A special class of materials called ‘semiconductors’ can be persuaded to exhibit both conducting and insulating properties; silicon is one such material. The first transistor was made in 1947 from another semiconductor material called ‘germanium’ and these were made commercially available in the early 1950s. In the case of digital computers, we think of transistors as acting like switches. Today’s transistors can be very small (we can build billions of them on a silicon chip) and very fast (they can be activated and deactivated billions of times a second). Also, the output from one transistor can drive the inputs of other transistors. We can connect small groups of transistors together to form simple logical building blocks that can detect the difference between two voltage values and can present the results of their operations in terms of these voltages. These simple building blocks can be connected to create larger logical functions, which can themselves be connected to realise sophisticated systems such as digital computers. Rather than think in terms of two actual voltages, we prefer to abstract things and talk in terms of 0s and 1s. When we write a program for an Arduino, we can make use of built-in functions like digitalWrite(), which writes a value to one of the Arduino’s digital input/output (I/O) pins. This function 63 accepts two integer 5V 5V arguments (think parameters): the first is the number D10 D10 Arduino Arduino of the pin we wish Uno Uno to control and the second is the value we wish to output, 0V 0V where this value digitalWrite (10, 0) digitalWrite (10, 1) can be a 0 or a 1. If we wanted to write Fig.5. Visualising how the digitalWrite() 0 or 1 values to pin function performs its magic. 10, for example, we could do so as follows: digitalWrite(10,0); digitalWrite(10,1); As we’ve already discussed, these 0 and 1 values will appear on the Arduino Uno’s pin as 0V and 5V, respectively. One way to visualise how this works is illustrated in Fig.5. In the same way, we can make a single transistor behave like a simple switch, we can use a couple of transistors to implement the equivalent of a single-pole, double-throw (SPDT) switch. By means of our digitalWrite() commands, we can cause this switch to connect the output pin to the 0V or 5V rails inside the Arduino, thereby presenting these values to the outside world. The creators of the Arduino decided that, rather than use 0 and 1, it would be easier for beginners to work with the keywords LOW and HIGH. The only problem is that the C/C++ programming languages used by the Arduino’s integrated development environment (IDE) don’t support these keywords. Based on what we’ve already learned, we could define these keywords ourselves as follows: #define LOW 0 #define HIGH 1 Listing 2. Using a for() loop to pulse the LEDs 6 times. As we will come to realise, this opens the door to a wide range of possibilities. For example, if we wish to write a 0 to pin 6, we could do so using: digitalWrite(6, false); Although they decided to employ a slightly different approach, this is essentially what the folks who set up the Arduino IDE did behind the scenes. If you are interested in learning more about all of this, I’ve penned and posted a frankly fulsome column for your delectation and delight – see: https://bit.ly/3GacoZv True or false? As we previously noted, the Arduino IDE supports a combination of the C/C++ programming languages. Some computer languages support the bool and/or boolean data types, which are used to represent the Boolean concepts of false and true. Unfortunately, C doesn’t natively support either of these types (sad face). Fortunately, C++ does support the bool data type (happy face). And, just to add to the fun and frivolity, the Arduino IDE supports both types. A variable of type bool (or boolean) can be assigned values of true and false. We will be running into these values a lot in the not-so-distant future. Before we do, however, it’s worth noting that the bool data type is essentially an alias of the int (integer) data type that’s restricted to having values of 0 (false) and 1 (true). Furthermore, the boolean data type is essentially an alias of the bool data type. Once again, based on what we’ve already learned, we could define these keywords ourselves as follows: #define false 0 #define true 1 And, once again, although they decided to employ a slightly different approach, this is essentially what the folks who set up the Arduino IDE did behind the scenes. 64 Alternatively, if we wish to write a 1 to pin 6, we could do so using: digitalWrite(6, true); Similarly, if we declare a variable as being of type bool (or boolean), in addition to assigning it values of false and true, we can also assign it values of 0 and 1 and LOW and HIGH. For() better or worse There are three types of loop control statements in C/C++. These statements can be used to perform the same group of actions multiple times. One of them is the for() statement, which we introduced in Part 2. Just to remind ourselves, the general form of this statement is as follows: for (initialize; condition; update) { // Do stuff } Suppose we wish to quickly pulse (flash) our red-green LED combo six times, wait a second, and then do it all again. We could achieve this using a for() statement as illustrated in Listing 2 (see also file CB-Mar23-04.txt). We won’t go through this code in detail because we’ve seen variations of all these statements before. However, one point worth noting is that, in this example, we’ve declared our loop control variable, iPul, outside the for() Practical Electronics | March | 2023 statement. As you may recall, my preference is to declare this as part of the for() statement as shown in red below: for (int iPul = 0; ... The rationale for declaring this variable as part of the for() statement is this limits the scope (ie, the visible range) of the variable to the loop. And the reason for our declaring it outside the for() statement in this example is that it will help us wrap our brains around what’s happening when we compare what we are doing here with the other loop control statements, which we will look at in a moment. It’s the condition portion of the for() statement that’s of interest to us here. In this case, we used iPul < NUM_FLASH (that is, ‘iPul is less than NUM_FLASH’), where we previously defined NUM_FLASH (‘the number of flashes’) as being 6. This condition will evaluate to a Boolean value of true (if iPul is indeed less than NUM_FLASH) or false (if iPul is greater than or equal to NUM_FLASH). The body of the loop will be executed so long as the condition returns true, and the loop will be terminated as soon as the condition returns false. In this case, our loop will execute six times for iPul = 0, 1, 2, 3, 4, and 5, and it will terminate as soon as iPul reaches 6. Enter this program into your Arduino IDE and click the Verify icon to check you haven’t made any mistakes. Next, click the Upload icon to upload the machine code version of this program into your Arduino and count the number of flashes to check that all is as we expect. As a point of interest, try changing your for() loop’s initialise statement to int iPul = 1 and its condition statement to iPul <= NUM_PULSES (that is, ‘iPul is less than or equal to NUM_FLASH’). In this case, our loop will execute six times for iPul = 1, 2, 3, 4, 5, and 6, and it will terminate as soon as iPul reaches 7. While() we’re here In addition to the for(), there are two more loop control statements in C/C++. The first is the while(), in which a condition is checked before executing the body of the loop. Once again, the body of the loop will only be executed if the condition returns a Boolean value of true, otherwise the loop will be terminated. while (someCondition) { // Do stuff } The second is the do-while() in which a condition is checked after executing the body of the loop. In this case, the body of the loop will always be executed at least one time, after which it will continue to be executed only so long as the condition returns true. do { // Do stuff } while (someCondition); Let’s create, contrast, and compare two programs using these different approaches to flash our red-green LED combo six times, as shown in Listing 3 (see also files CB-Mar23-05.txt and CB-Mar23-06.txt). In both of these examples, we increment the loop counter iPul at the end of the loop (previously, we did this as the update portion of the for() statement itself). Remember that iPul++ is the same as saying iPul = iPul + 1. With respect to the examples shown here, there doesn’t really seem to be much to choose between these loop control forms. Practical Electronics | March | 2023 NEW! 5-year collection 2017-2021 All 60 issues from Jan 2017 to Dec 2021 for just £44.95 PDF files ready for immediate download See page 6 for further details and other great back-issue offers. Purchase and download at: www.electronpublishing.com However, sometimes it is critical to evaluate the condition prior to executing the loop, in which case we could choose to use the while() loop. On other occasions, as we will soon see, it is advantageous to execute the loop before evaluating the condition, in which case the do-while() is the way to go. There’s a condition Thus far, we’ve considered only simple conditions involving the relational operators < (‘less than’) and <= (‘less than or equal to’). There are two more relational operators, > (‘greater than’) and >= (‘greater than or equal to’). Also, there are two equality operators, == (‘equal to’) and != (‘not equal to’). Furthermore, we can create more complex expressions using the && (‘logical AND’) and || (‘logical OR’) operators. For example, assume that a, b, c and d have all been declared as being of type int and assigned values, we could have a condition looking something like the following: (a > b) && (c <= d) This condition will return true only if a is greater than b AND c is less than or equal to d, otherwise it will return false. All of the operators mentioned here are summarised in Fig.6. Who takes precedence? When we were kids studying math at school, we were taught the convention that multiplication and division are performed before addition and subtraction. This means, for example, that we evaluate the result of the expression 2 + 2 × 3 as being 8 rather than 12. We say that the multiplication and division operators have ‘higher precedence’ than the addition and subtraction operators. If we wanted to, we could emphasise the conventional precedence in the preceding calculation using parentheses, eg, 2 + (2 × 3). Alternatively, we could force a different precedence, eg, (2 + 2) × 3. Similarly, in the context of computer programming languages like C/C++, the term ‘precedence of operators’ refers 65 Listing 3. Using while() and do-while() loops to pulse the LEDs 6 times: (left) while() loop; (right) do-while() loop. to the order in which operations are performed. For example, the multiplication, division, and modulo operators (*, /, and %) have higher precedence than the addition and subtraction operators (+ and –), and all of these arithmetic operators have higher precedence than the relational, equality, and logical operators discussed above. Well, that all seems pretty simple, doesn’t it? So, assuming once again that a, b, c and d have all been declared as being of type int and assigned values, how would you expect the condition a + 6 > b / 2 && c * 3 < d – 5 to be evaluated? Suffice it to say that many a programmer (both inexperienced and experienced) has been bitten by an unexpected precedence problem. For myself, I prefer to employ copious quantities of parentheses to make clear to future users and to the compiler just what I wish to occur, which means I would capture the aforementioned condition as ((a + 6) > (b / 2)) && ((c * 3) < (d – 5)) (you can call me an old fuddy-duddy if you will, but at least my code works as planned). If you wish to learn more about this topic, you’ll be delighted to discover that it is documented in excruciating detail on Wikipedia at: https://bit.ly/3GdcG1M Type Relational Equality Logical Operator Description Example < Less than a < b <= Less than or equal to a <= b > Greater than a > b >= Greater than or equal to b >= b == Equal to a == b != Not equal to a != b && Logical AND a && b || Logical OR a || b Fig.6. Table of Boolean operators available in C/C++ for use with the Arduino. 66 A long pause Now it’s time to put some of the things we’ve learned in this column to use with our 7-segment display. As you may recall, the final program we created in our previous column randomly lit the segments on the display. The original version of this program is shown in Listing 4a (file CB-Mar23-07.txt). As you’ll see, I’ve added a few blank lines to aid in our comparison with an updated version of the program, as reflected in Listing 4b (file CB-Mar23-08.txt). Let’s start with our original program. As a reminder, the Arduino pins used to drive our segments are defined in the PinsSegs[] array on Lines 5 and 6. There are eight elements in this array, numbered from 0 to 7. This is why we generate a random number with a value between 0 and 7 on Line 24. Upload the original program into your Arduino and carefully observe what happens on the 7-segment display. As promised, all eight segments (including the decimal point) light up in a random fashion. If we look closely, however, we will see that some of the segments randomly stay lit longer than others. The reason for this is that, when we generate a random number on Line 24, we don’t check to see if this new number is different to the previous number. If the values are the same, then the current segment will remain lit longer than if the values are different. What we want to do is force the values to be different. Now consider the new version of the program in Listing 4b. The first change occurs on Line 8 where we declare an integer variable called OldSeg (‘old segment’) and assign it a value of –1. Observe that, since OldSeg is declared outside of any of the functions, it is a global variable whose scope is the whole program. This means it can be seen and modified by any of the functions. It also means that whatever value it contains will be retained irrespective of which function is being executed (or not, as the case might be) at any particular time. Furthermore, as was noted in the previous column, my personal preference is to use initial uppercase letters to indicate global variables and initial lowercase letters to reflect local variables. Practical Electronics | March | 2023 Listing 4. Using a do-while() loop to ensure a different random number: (left) original program; (right) updated program. Part 3 is for you to think about what seg(not equal) to the ments we need to activate to represent old value, this conthe digits 0 through 9. Have you been dition will return LEDs (assorted colours) https://amzn.to/3E7VAQE thinking about this? Good. Hold that false and the loop Resistors (assorted values) https://amzn.to/3O4RvBt thought because this is what we will be will terminate. Solderless breadboard https://amzn.to/3O2L3e8 doing in Part 4. As soon as we are Multicore jumper wires (male-male) https://amzn.to/3O4hnxk Meanwhile, the answer to the question out of the loop, baskComponents (from Part 2) posed at the beginning of this column ing in the confident 7-segment display(s) https://amzn.to/3Afm8yu is that we can ask either of the guards: glow of knowing we ‘Which door will the other guard say is have a new segment the one that will take us where we wish that is different to to go?’ Both guards will respond with the old one, we copy this new value The reason we assign OldSeg a value the same door, which is the one we don’t into OldSeg in Line 27 for use the next of –1 is because we know this is differwant to use. time we wish to generate a new segment. ent to any of the random numbers we I was just wondering if it would be Upload this new version of the prowill be generating in the range 0 to 7. We possible to represent this riddle and its gram into your Arduino and observe that could, of course, use any value other than possible outcomes in the form of a truth all of the randomly selected segments 0 through 7, but –1 is a common choice table, but I’m exhausted after writing this now remain illuminated for the same in this sort of thing. column, so I’ll leave that to you (please amount of time. The cunning part comes in Lines 22 feel free to email me with your solution). to 25 where we use a do-while() loop Until next time, as always, I welcome to control the generation of our random What’s next? your insightful comments, perspicacious number. The way this loop is set up is that We closed last month’s column by saying: questions, and sagacious suggestions. we will keep on generating new random ‘What would be useful while we wait for numbers as long as the condition evaluates as true, which will be the case if the newly genCool bean Max Maxfield (Hawaiian shirt, on the right) is emperor of all he erated segment value stored in surveys at CliveMaxfield.com – the go-to site for the latest and greatest iSeg is the same as the old segin technological geekdom. ment value stored in OldSeg. As Comments or questions? Email Max at: max<at>CliveMaxfield.com soon as the new value is different Components (from Part 1) Practical Electronics | March | 2023 67