Silicon ChipMax’s Cool Beans - April 2025 SILICON CHIP
  1. Contents
  2. Publisher's Letter: Equivalent Series Resistance testers are very useful
  3. Feature: Net Work by Alan Winstanley
  4. Feature: Max’s Cool Beans by Max the Magnificent
  5. Project: Calibrated MEMS Microphones by Phil Prosser
  6. Feature: The History of Electronics, part four by Dr David Maddison
  7. Subscriptions
  8. Feature: Circuit Surgery by Ian Bell
  9. Feature: The Fox Report by Barry Fox
  10. Project: ESR Test Tweezers by Tim Blythman
  11. Feature: Audio Out by Jake Rothman
  12. Feature: Techno Talk by Max the Magnificent
  13. Back Issues
  14. Project: Low-Noise Mains Fan Speed Controller, Mk2 by John Clarke
  15. Feature: Precision Electronics, part four by Andrew Levido
  16. PartShop
  17. Market Centre
  18. Advertising Index
  19. Back Issues

This is only a preview of the April 2025 issue of Practical Electronics.

You can view 0 of the 80 pages in the full issue.

Articles in this series:
  • Win a Microchip Explorer 8 Development Kit (April 2024)
  • Net Work (May 2024)
  • Net Work (June 2024)
  • Net Work (July 2024)
  • Net Work (August 2024)
  • Net Work (September 2024)
  • Net Work (October 2024)
  • Net Work (November 2024)
  • Net Work (December 2024)
  • Net Work (January 2025)
  • Net Work (February 2025)
  • Net Work (March 2025)
  • Net Work (April 2025)
Articles in this series:
  • Max’s Cool Beans (January 2025)
  • Max’s Cool Beans (February 2025)
  • Max’s Cool Beans (March 2025)
  • Max’s Cool Beans (April 2025)
  • Max’s Cool Beans (May 2025)
  • Max’s Cool Beans (June 2025)
Articles in this series:
  • The History of Electronics, Pt1 (October 2023)
  • The History of Electronics, Pt2 (November 2023)
  • The History of Electronics, Pt3 (December 2023)
  • The History of Electronics, part one (January 2025)
  • The History of Electronics, part two (February 2025)
  • The History of Electronics, part three (March 2025)
  • The History of Electronics, part four (April 2025)
  • The History of Electronics, part five (May 2025)
  • The History of Electronics, part six (June 2025)
Articles in this series:
  • Circuit Surgery (April 2024)
  • STEWART OF READING (April 2024)
  • Circuit Surgery (May 2024)
  • Circuit Surgery (June 2024)
  • Circuit Surgery (July 2024)
  • Circuit Surgery (August 2024)
  • Circuit Surgery (September 2024)
  • Circuit Surgery (October 2024)
  • Circuit Surgery (November 2024)
  • Circuit Surgery (December 2024)
  • Circuit Surgery (January 2025)
  • Circuit Surgery (February 2025)
  • Circuit Surgery (March 2025)
  • Circuit Surgery (April 2025)
  • Circuit Surgery (May 2025)
  • Circuit Surgery (June 2025)
Articles in this series:
  • The Fox Report (July 2024)
  • The Fox Report (September 2024)
  • The Fox Report (October 2024)
  • The Fox Report (November 2024)
  • The Fox Report (December 2024)
  • The Fox Report (January 2025)
  • The Fox Report (February 2025)
  • The Fox Report (March 2025)
  • The Fox Report (April 2025)
  • The Fox Report (May 2025)
Articles in this series:
  • Audio Out (January 2024)
  • Audio Out (February 2024)
  • AUDIO OUT (April 2024)
  • Audio Out (May 2024)
  • Audio Out (June 2024)
  • Audio Out (July 2024)
  • Audio Out (August 2024)
  • Audio Out (September 2024)
  • Audio Out (October 2024)
  • Audio Out (March 2025)
  • Audio Out (April 2025)
  • Audio Out (May 2025)
  • Audio Out (June 2025)
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)
Articles in this series:
  • Precision Electronics, Part 1 (November 2024)
  • Precision Electronics, Part 2 (December 2024)
  • Precision Electronics, part one (January 2025)
  • Precision Electronics, Part 3 (January 2025)
  • Precision Electronics, part two (February 2025)
  • Precision Electronics, Part 4 (February 2025)
  • Precision Electronics, Part 5 (March 2025)
  • Precision Electronics, part three (March 2025)
  • Precision Electronics, part four (April 2025)
  • Precision Electronics, Part 6 (April 2025)
  • Precision Electronics, Part 7: ADCs (May 2025)
  • Precision Electronics, part five (May 2025)
  • Precision Electronics, part six (June 2025)
MAX’S COOL BEANS By Max the Magnificent WEIRD & WONDERFUL ARDUINO PROJECTS Part 4: full power ahead (to the main array)! M y head hurts; I’m about to make your head hurt too (you’re welcome.) As you may recall, in our previous column, we used our strip of 144 tricolour light-emitting diodes (LEDs) to create the 14 × 10 (width × height) array that will form the main display area for our retro games console. This left us with four unused LEDs; fear not, we’ll find a use for these later (so don’t lose them). We decided to refer to each of the LEDs in our array as ‘pixels’ (short for picture elements), each of which has red, green, and blue (RGB) subelements. We also decided to view our array in terms of (x, y) coordinates and to employ a ‘bottom-left’ origin system, in which (x, y) = (0, 0) is in the lowerleft corner, and (x, y) = (13, 9) is in the upper-right corner. We noted that it’s possible to connect our ten 14-pixel segments in a variety of different ways and to sort things out in software later. To this end, once we’d verified that everything worked, we created a GetNeoNum() function that accepts x and y integer values as arguments and returns the number n of the corresponding pixel in the string. As I noted in that column, the great thing about this is that it doesn’t matter if you organise your segments differently to me. So long as we both have GetNeoNum() functions that work with our own arrays, and with identical external interfaces, all you need to do to run one of my programs is to exchange your version of this function for mine. After performing various experiments, we ended by creating a program that repeatedly (a) lit each row from bottom to top, (b) lit each row from top to bottom, (c) lit each column from left to right, and (d) lit each column from right to left. Since we are currently powering our array from the Arduino, we made sure that only a single row or column was active at any time. To refresh your memory, you can download a copy of this code in the file named CB-Apr25 Code-01.txt. As usual, all the files mentioned in this column are available from the April 2025 page of the PE website: https:// pemag.au/link/ac44 I left you pondering how we could extend our program to light the pixels in diagonal lines, one line at a time, starting with the one-pixel diagonal ‘line’ in the bottom left corner at (x, y) = (0, 0) and ending with the 1-pixel diagonal ‘line’ in the top right corner at (x, y) = (13, 9). This is what we are poised do shortly but we’ll take things step-by-step to ensure we are all dancing to the same tune. Black and white Listing 1(a): a code snippet to light rows of LEDs using 8-bit RGB values. 8 Let’s start by looking at the portion of our existing program that lights each row from bottom to top as illustrated in Listing 1(a). The listing number (1 in this case) corresponds to part of the name of the matching code file (“01” here). Remember that Neos is the identifier we’ve chosen for our pixel strings. Observe the calls to the Neos.setPixelColor() function on lines 41 and 49. This function accepts two arguments. The first is the number of the pixel whose colour we wish to change. The second is a 24-bit colour value comprising 8 bits each for the RGB components. Also remember that this function only modifies the colour of the pixel stored in the Arduino’s memory. Nothing changes in the outside world until we call the Neos.show() function on lines 43 and 51 to stream the values from memory into the physical string of pixels forming our array. Practical Electronics | April | 2025 Currently, we are generating these 24-bit values using the Neos.Color() function, which accepts three 8-bit RGB values and combines them into a single 24-bit value. Our compiler understands only 8-bit, 16-bit, and 32-bit integer values (most computers have no native support for three-byte [24-bit] integers). As a result, our 24-bit colours are stored in 32-bit variables and we simply ignore the most-significant (uppermost) eight bits, which remain unused. Each of our 8-bit RGB fields can have values ranging from 0 to 255 in decimal, which equates to 0b00000000 to 0b11111111 in binary (the ‘0b’ indicates binary) or 0x00 to 0xFF in hexadecimal (the ‘0x’ indicates hexadecimal). Driving the RGB fields with all the same values results in white light. The reason we are using RGB values of 32 (0x20) on line 41 is to reduce the amount of power we are consuming to 32 ÷ 255 ≃ 12.5% of full power. The data sheet tells us that, when fully on, each of our pixels consumes 60mA (milliamperes); that’s 20mA for each of the RGB components. So, when displaying white light at 12.5% of full power, each pixel consumes 60mA × 0.125 = 7.5mA. This calculation assumes everything is linear, which may not be the case, but this approximation is ‘close enough for government work’, as they say. In the case of our existing program, our worst case is for all 14 pixels on the same row to be lit up at the same time. The resulting 7.5mA × 14 = 105mA is well within the capabilities of our Arduino. As opposed to using the Neos.Color() function, we can simply define our colours as 24-bit values: Listing 2(a): a code snippet to light LEDs in rows using 24-bit colour values. #define WHITE 0x202020 #define BLACK 0x000000 This allows us to modify (and simplify) the calls to our Neos.setPixelColor() functions, as seen in lines 45 and 53 of Listing 2(a). You can download the new version of our program in the file named CB-Apr25 Code-02.txt. Although this may not appear to be a great leap forward, working with 24-bit colour values will make our lives a lot easier in the future. Declaring utility functions Most of the code in the main body of our program currently lives in the loop() function. Instead of writing things as one large ‘blob’ of code (I hope I’m not getting too technical), a fundamental practice in programming is to create a suite of low-level utility functions. These functions can then be called Practical Electronics | April | 2025 Listing 3(a): declaring utility functions. from other parts of the program (they can even call each other). Employing utility functions improves the readability, reusability, and scalability of our code. It also makes our programs easier to debug and maintain. What’s not to love? We already have one utility function in the form of our GetNeoNum() routine. The next iteration of our program (in the file named CB-Apr25 Code-03. txt) contains three more, as seen in Listing 3(a). The SetPixelColorXY() function at line 92 sets the colour of a single pixel (once again, it modifies the pixel value stored in the Arduino’s memory, not in the physical string). This function accepts three parameters: the x and y coordinates of the pixel in question, and 9 Listing 3(b): using our utility functions. the color we wish to assign to that pixel. The SetRowColor() function at line 100 sets all the pixels in a row to the same colour. It accepts two parameters: the row in question (from 0 to 9) and the color we wish to assign to the pixels in that row. Similarly, the SetColColor() function at line 110 sets all the pixels in a column to the same colour. It accepts two parameters: the col in question (from 0 to 13), and the color we wish to assign to the pixels in that column. Observe that, in all three functions, we’ve declared the colour variable as being of type uint32_t, which refers to a 32-bit (4-byte) unsigned (non-negative) integer. Ideally, we would prefer to use a uint24_t, but this type isn’t supported by most compilers. Happily, when we pass a 24-bit value into our function, the compiler will automatically pad the unused eight most-significant bits with 0s to generate the 32-bit value expected by the function. You may be wondering why we used a data type of uint32_t instead of an unsigned long, which is what we would expect to see in most Arduino documentation. We don’t want to get into this here, but we will discuss the various integer data types in excruciating exhilarating detail in next month’s column. Observe that our SetPixelColorXY() function calls our existing GetNeoNum() function. Similarly, both our SetRowColor() and SetColColor() functions call our SetPixelColorXY() function. The result is a cascading hierarchy of function calls. Using our utility functions Now that we’ve declared our utility functions, we can modify our loop() function to take advantage of them. Let’s consider the new incarnation of the portion of our program that lights each row from bottom to top as illustrated in Listing 3(b). As is always the case with programming, there are many different approaches we could use. For example, in our SetRowColor() function, we could move 10 the show() and delay( ) function calls on lines 41 and 42 (and on lines 45 and 46) into the body of the SetRowColor() function itself. Since we use different delay values at different times, we could pass the delay duration into the SetRowColor() function as an additional argument. As tempting as this may be, Listing 4(a): controlling multiple rows and columns of LEDs. it would place limitations on how we on line 42 and the delay() function on could use our SetRowColor() function line 43. Similarly, we set the two rows for oth­­­er tasks in the future. For exam- to be BLACK on lines 45 and 46 before ple, suppose we decided that we wished calling the show() function on line 47 to modify our loop() function to start and the delay() function on line 48. by lighting rows 0 and 9 (bottom and The point of all this is that we are top), then turn these rows off and light performing a programming balancing rows 1 and 8, then 2 and 7, then 3 and act. In one possible scenario, we don’t 6, ending with 9 and 0. create any utility functions, but instead This is easy-peasy lemon squeezy implement everything as a great big glob with our existing SetRowColor( ) of code in the main loop() function. function, but we would be stressed­At the other end of the spectrum, depressed lemon zest if we had modi- we stick everything into separate funcfied our function as discussed above. tions, but this could make them clunky To illustrate this in action. I created a and unwieldy, possibly requiring us dual-row version of the program using to create multiple versions of each our existing SetRowColor() function (in function to satisfy the needs of differthe file named CB-Apr25 Code-04.txt). ent use cases. As illustrated in Listing 4(a), the The ‘Goldilocks’ solution is to put modified manipulation of our rows just the right amount of code into our occurs from line 38 to line 49. I’ve utility functions (not too much and not also implemented a similar treatment too little). The trick is knowing where to work with dual columns, as seen to draw the metaphorical line. from line 53 to line 64. Since we are now lighting two rows Dutch angles This is where we return to the task (or two columns) at the same time, our new worst-case current draw will be of lighting our pixels in diagonal lines 210mA, which is still well within the across the display, one line at a time. We will start with what I think of as capabilities of our Arduino. Observe the way in which we set ‘backward slash diagonals’ (like the \ two rows to be WHITE on lines 40 and character). That is, starting with the 41 before calling the show() function one-pixel ‘line’ in the bottom left corner Practical Electronics | April | 2025 0 1 Fig.1: determining the number of diagonals based on the number of rows and columns. 2 1 4 0 3 0 0 0 1 2 1 5 0 4 2 0 1 2 3 4 5 1 2 3 d = (x + y – 1) = 6 6 7 8 9 10 11 12 13 9 8 22 7 21 6 20 5 19 4 18 3 17 2 16 1 15 0 14 0 1 2 3 4 5 6 7 8 9 10 11 12 13 Fig.2: lighting diagonal lines on our full-size LED array. at (x, y) = (0, 0) and ending with the 1-pixel ‘line’ in the top right corner at (x, y) = (13, 9). Once we have this working, your homework assignment this month will be to implement what I think of as ‘forward slash diagonals’ (like the / character). That is, starting with the 1-pixel ‘line’ in the top left corner at (x, y) = (0, 9) and ending with the 1-pixel ‘line’ in the bottom right corner at (x, y) = (13, 0). Before we proceed, for any maths nerds amongst us, I should admit to being a little loose with my use of the word “diagonal”. In mathematics, a diagonal is a line that connects two vertices of a polygon or a solid where these vertices are not on the same edge. In the case of a square or rectangle, for example, we are talking about the line that connects the top left and bottom right corners or the line that connects the bottom left and top right corners. In our case, by comparison, I’m using ‘diagonal’ to mean a line 45° from horizontal. Actually, even this isn’t Practical Electronics | April | 2025 1 2 3 3 1 d = (x + y – 1) = 5 0 x=3 2 y=3 y=3 2 x=4 true because our pixels aren’t spaced equally in the horizontal and vertical dimensions. But let’s not worry about that too much. In the case of ‘backward slash diagonals’, diagonal 0 would be at pixel (x, y) = (0, 0); diagonal 1 would follow the (x, y) pixel path (0, 1), (1, 0); diagonal 2 would follow the (x, y) path (0, 2), (1, 1), (2, 0); diagonal 3 would follow the (x, y) path (0, 3), (1, 2), (2, 1), (3, 0); and so forth. Our array has 10 horizontal rows and 14 vertical columns, so how many of our 45° diagonals do we have? As I’ve mentioned on previous occasions, I often find that sketching pictorial representations gives me insights that aid in my program creation activities. For example, consider the three small arrays shown in Fig.1. From this we can deduce that, irrespective of the size of the array, the number of diagonals is one less than the sum of the number of rows and number of columns. In the case of our 14 × 10 array, this means we will have y=4 x=3 2 5 1 4 0 3 0 1 2 d = (x + y – 1) = 6 (14 + 10 – 1) = 23 diagonals. As you may recall, our existing programs currently have four definitions associated with the number of rows and columns in our array. To these we can now add a definition associated with the number of diagonals, resulting in the following: #define NUM_ROWS 10 #define NUM_COLS 14 #define NUM_DIAGS 23 #define MAX_X 13 #define MAX_Y 9 Instead of 23, if we wanted to be really clever, we could put (NUM_ ROWS + NUM_COLS – 1). Then we wouldn’t need to change the value if we changed the number of rows or columns. Now let’s scale things up to our fullsize array (Fig.2). In the real world, since we can perform only one task at a time, when we ‘draw’ our backward slash diagonals on the display, we must start at one end and work our way to the other. There are two ways to do this: either we start with the upper­-left pixel and end on the lowerright pixel (the approach I opted for), or vice versa. So, what algorithm are we going to use? The way I usually approach this sort of thing is to pick an element at random and see if I can deduce anything from it. We’ll start with diagonal d = 6 (highlighted in orange) because 6 is my lucky number. In this case, our start x value will be 0, our end x value will be 6, and our start y value will also be 6. Hmmm, this means that end x and start y are both equal to d. Well, that’s convenient, but when we delve a little deeper, we discover that it doesn’t work for all the diagonals. Another tool I often use to provide insights for my program creation activities is to create tabular representations of things. For example, 11 Diag d Start x End x Start y 0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 10 11 12 13 1 2 3 4 10 11 12 13 9 9 9 9 14 15 16 17 18 19 20 21 22 5 6 7 8 9 10 11 12 13 13 13 13 13 13 13 13 13 13 9 9 9 9 9 9 9 9 9 Listing 5(a): our ‘backward slash’ diagonal LED lighting utility function. < NUM_ROWS < NUM_COLS < NUM_DIAGS Fig.3: a table representing our diagonal algorithm. based on the full-size array in Fig.2, I created the table shown in Fig.3. Three distinct areas jump out at us from the table shown in Fig 3. These areas are associated with the diagonal d being (a) less than NUM_ROWS, (b) greater than or equal to NUM_ROWS and less than NUM_COLS, or (c) greater than or equal to NUM_COLS and less than NUM_DIAGS. This new intelligence allows us to create an updated representation of our array as illustrated in Fig.4. More importantly, the algorithm we are going to use practically jumps out of our tabular representation. Still, before we go there… Foxy for() loops As I mentioned many yonks ago (PE, May 2020), there’s something rather clever about for() loops in C/C++ that professional programmers don’t even think to mention, which may explain why many non-professional program0 1 2 3 4 5 6 7 8 mers don’t know anything about it. Consider the following: for( initialisation; condition; modification ) As we see, there are three semicolon­ separated parts to this statement: initialisation, which is where we initialise our control variable; condition, which is where we test our control variable; and modification, which is where we modify our control variable. For example, we wouldn’t be surprised to see a statement looking something like the following: for ( int i = 0; i < 10; i++ ) 9 10 11 12 13 9 8 22 7 21 6 20 5 19 4 18 3 17 2 16 1 15 0 14 0 1 2 3 4 5 6 7 8 9 10 11 12 13 Fig.4: full-size array reflecting the info from our table. 12 There are several aspects to this that aren’t immediately obvious to beginners. Firstly, the modification isn’t obliged to be a simple increment (++) or decrement (--), but can instead be a more complex expression, such as “i = i + 3”. Secondly, the condition can be as complicated as required, such as “( (i < 10) && (j == 0) )”, for example. Thirdly, both the initialisation and modification sections can comprise multiple comma-separated elements. We could have something like “i = 0, j = 0” in the initialisation section. Similarly, we could have something like “i++, j--” in the modification section. Let’s keep all this in mind as we proceed to our… Awesome algorithm I created a new version of our program in the file named CB-Apr25 Code05.txt. The first thing I did was to create an additional utility function called SetBwdSlashDiagColor(), illustrated in Listing 5(a). This sets all the pixels in a backward slash diagonal to the same colour. It accepts two parameters: the diag (‘diagonal’) in question, from 0 to 22, and the color we wish to assign to the pixels in that diagonal. Observe that on line 148, we declare three local integer variables: startX, endX, and startY. These reflect the columns in our table from Fig.3. We set the values of these variables based on the number of the diagonal we’re working with. This occurs on lines 150 to 167. I dare to hope that the way this works is self-explanatory—just compare this portion of the code to the three sections of our table. Practical Electronics | April | 2025 Photo 1: a 7805 linear voltage regulator in the TO-220 package. Listing 5(b): modifications to the loop() function. Last, but certainly not least, we use the for() loop on line 169 to cycle through all the pixels forming our diagonal. This is a prime example of such a loop employing multiple elements in its initialisation and modification sections. All that remains is to augment our loop() function to cycle through the diagonals on the display. This is illustrated in Listing 5(b). In lines 91 to 100, we illuminate the diagonals, one at a time, from bottom-left to top-right. Next, in lines 104 to 113, we reverse the process, illuminating the diagonals, one at a time, from top-right to bottom-left. I’m running this on my array as we speak - it looks awesome! I can’t wait for you to see it running you your own array. Scotty, I need more power! I don’t know about you, but I’m tired of not being able to light all the pixels on my array simultaneously. That’s about to change. To do so, however, we are going to need more power. Of course, as is usually the case in engineering, there are multiple options open to us. As I’ve mentioned in previous columns, my chum Joe Farr has already built a prototype version of our retro games console. Before we turn our attention to my own solution, it will be instructive for us to consider the decisions Joe made. The first key point is that Joe is using a PIC microprocessor from Microchip Technology. A related point is that Joe’s PIC runs at 5V, which is the same as his main LED array. This means that Practical Electronics | April | 2025 ‘dropout’ nomenclature is that, if the input voltage falls below the required level, the regulator cannot maintain the desired output voltage. Instead, the output will begin to ‘drop out’ and follow the input voltage, resulting in an unregulated output. According to its data sheet, the absolute maximum input voltage for the 7805 is 35V, but the recommended input voltage range is 7–25V. The amount of heat dissipated by a linear voltage regulator is a function of the difference between input and output voltages and how much current we are drawing. If we are pulling a lot of power, these devices can get hot. Hotter than one can touch without shouting “Ouch!”. As a result, it’s common to attach them to a heatsink (Joe used a strip of metal mounted inside his console). As seen in Photo 1, the 7805 is a 3-terminal device. Many (but not all) of these are prefixed with “LM”, which stands for “Linear Monolithic”. These originated with National Semiconductor, which was acquired by Texas Instruments (TI) in 2011. Other versions of this regulator have related names, like the L7805CV shown in the photo. All the 7805 needs is a couple of extra components in the form of capacitors, and you are ‘off to the races’. A typical 7805-based circuit is shown in Fig.5. The voltage rating of the capacitors should be at least a few volts higher than the maximum they are Joe’s console requires only a single 5V supply. Another consideration is that Joe decided his console should be capable of being powered either from an external source or from internal batteries. Since the battery-based solution is a limiting factor, that’s where Joe started. He opted to use six high-capacity, rechargeable, AA nickel metal hydride (NiMH) batteries, whose combined 6 × 1.2V gave him 7.2V to play with. Furthermore, Joe decided to employ a linear voltage regulator in the form of a 7805 (Photo 1). Why this particular device? Joe happens to have a drawer full of these little scamps in his workshop. This provides a prime example of how our decisions are sometimes made for us. A linear voltage regulator is an electronic device that maintains a constant output voltage regardless of variations in the input voltage or load current (within certain limits). It achieves this by dissipating any excess power as heat. One important term associated with linear voltage regulators is ‘dropout voltage’. This is the minimum difference between the input voltage and the output voltage that the regulator requires IN (7V to 35V) to maintain a stable, LM7805 regulated output. The 7805 supplies an output 100µF 0.1µF 0.1µF voltage of 5V, and its dropout voltage is 2V, which means its input voltage must be at least GND (0V) 5V + 2V = 7V. The reason for the Fig.5: a typical LM7805 regulator-based circuit. OUT (5V) 10µF 13 expected to see. As always, consult the data sheet for whatever regulator (and manufacturer) you are using. A simplified representation of Joe’s setup is illustrated in Fig.6. As we previously discussed, the input voltage must be greater than 7V, and this input can either come from an external source or from batteries mounted inside the console. The 5V output from Joe’s regulator feeds both his microcontroller and his LED array. This scheme has the virtues of low cost and simplicity. The biggest downside is the fact that the 7805 can generate a substantial amount of heat when its output is loaded, which will occur if we light all the LEDs on our array, for example. 14 3.3V 5V GND GND Vin A0 A1 A2 A3 A4 A5 RESET IOREF AREF GND 13 12 ~11 ~10 ~9 8 7 ~6 ~5 4 ~3 2 TX-1 RX-0 We are assuming >7V 5V that the current used LM7805 by the shift registers themselves will be MCU LED negligible for this (PIC) Array application. It’s hard to get data sheets for 0V these modules, but we are assuming Fig.6: Joe’s power supply setup using a linear regulator. 5mA per segment, which equates to 40mA if all the seg- reserve the right to change my mind ments (including the decimal point) are later, in our existing programs, I’m currently running my LEDs with values lit on a display. This gives us 80mA of 32 (0x20), which is ~12.5% of their per module, or 240mA for all three maximum value (that’s twice the brightmodules. Let’s add this 240mA to the 50mA ness being used by Joe). This means that if I’m driving all for the PIC board and round things up to 300mA, thereby leaving Joe with the pixels on my array white, this will result in a current draw of 8400mA × 700mA for his main array. Remember that we have 140 pixels, 0.125 = 1050mA (1.05A). If we add Back of an envelope each containing R, G, and B LEDs, each 250mA to cover my six 7-segment disThe phrase “back-of-an-envelope of which is specified as consuming plays, this comes to 1300mA (1.3A). calculation” refers to the practice of 20mA at full power (so 60mA per pixel). I’m going to round this up to 1500mA performing quick, rough calculations This means that if we actually ran our (1.5A) ‘just to be sure’. on any piece of paper that’s close to Note that I’ve excluded the Arduino LEDs at full power, this would equate hand, such as the back of a postage to 140 × 60mA = 8400mA (8.4A). Wow! from these calculations because—as envelope. After some experimentation, Joe de- we will see—it’s covered by a differIn his version of these calculations, termined that a value of 16 (0x10) out ent power budget. Joe allocated himself a total power of a maximum of 255 (0xFF) results budget of 1A. Starting with the micro- in a display that’s more than bright Powering an Arduino Unlike Joe, I’m using an Arduino Uno controller, Joe used an old PIC board enough for gaming without being dazfrom a previous project. This board al- zling. Assuming a linear universe, this R3 to drive my retro games console. ready had one LED on it. Joe thinks the means he’s running his LEDs at 16 ÷ Also, unlike Joe, I’m not planning on powering my prototype console using LED probably consumes more power 255 (or 0x10 ÷ 0xFF) ≃ 6.3%. than the PIC, but he allocated 50mA This means that if Joe instructs all batteries; I’m more than happy to use to the board as a worst-case scenario. the pixels on his array to display white an external power supply. There are several ways to power Joe’s console boasts a total of six 7-seg- light, this will result in 8,400mA × ment displays. As we previously dis- 0.063 ≃ 530mA, well within his 700mA an Arduino Uno R3 (Fig.7). One is to feed 7–12V into the power jack. Also cussed in the February issue, Joe and budget. note the bank of header pins marked I are both using dual-digit 7-segment POWER. For all intents and purposes, display modules that include 74HC595 No restraint! I must admit that I’m impressed with the VIN pin on this bank is connected to shift registers. Also, we’re both using three of these modules in our consoles, Joe’s self-restraint. Sad to relate, how- the positive terminal of the power jack. ever, I never ran an LED at only 6.3% This means that, as opposed to using which means a total of six 7-segment of its rated value in my life. Whilst I the power jack, we can feed 7–12V didisplays and six shift registers. rectly into the VIN pin. The Arduino has two onboard regulators. The first takes the voltage from the power jack (or VIN pin) and delivers 5V to the board’s internal 5V power rail. In addition to powerDIGITAL IN/OUT (PWM ~) ing the Arduino itself, this 5V power USB rail is also presented as an output on the POWER section of the Arduino’s Orange LED 5V header pins. Green LED Via its header pin, this 5V supply can be used to drive external circuits, like ATmega328P the breadboard-based clock we created in our Arduino Bootcamp columns. Although the Arduino Uno R3 runs on 5V, many sensors, displays, and Power POWER ANALOG IN other chips use 3.3V. Thus, the 5V Jack power rail feeds the input to a second onboard regulator, which produces 7V to 3.3V. This 3.3V supply is also present12V ed as an output on the POWER section of the Arduino’s header pins. 3.3V 5V 7V to 12V Last, but certainly not least, we can power the Arduino via its USB port. Fig.7: this shows a few different ways you can powering the Arduino. Practical Electronics | April | 2025 9V BUCK MCU (Arduino) Fig.8: my power supply setup. 5V LED Array 0V When USB is connected, the Arduino automatically selects USB as its power source, overriding any external power sources. Since USB provides a stable 5V supply, this power source bypasses the board’s 5V regulator and directly drives the board’s 5V power rail. As we already discussed, this powers the Arduino, drives the input to the 3.3V regulator, and appears on the POWER header. Now, here’s the tricky part. Since the 5V pin on the POWER header is directly connected to the board’s 5V power rail, as opposed to using it as an output, it is possible to treat it as an input. However, I wouldn’t recommend doing this. The 5V pin bypasses the Arduino’s onboard voltage regulators and protection circuits. This means that if the power supply you feed into this pin is unregulated or noisy, it can damage the microcontroller and other components on the board. Also, if you connect a 5V power source to the 5V pin and simultaneously connect the Arduino to a computer via USB, the two power sources can conflict, possibly damaging your Arduino and/or your computer. A well-regulated microcontroller Based on what we just discussed, I decided to feed my console with a 9V power supply. Inside the console, I’m going to feed this 9V signal directly to the Arduino’s power jack while prototyping (and to its VIN pin once we’ve started implementing our games cartridge boards). I’m also going to feed this 9V signal through a 5V regulator and use the output from the regulator to power my LED array and other console components requiring a 5V supply, like my 7-segment displays, for example. The next question is how to convert my 9V source into the 5V I need to power my array. I could use a linear regulator like Joe, but I’m not keen on generating a lot of heat inside my console. There are two types of DC-to-DC converters that rely on high­-frequency switching to transfer energy efficiently from input to output (there are more, but let’s stick with the two most common types). DC stands for ‘direct current’, which means a current that is steady and flows in one direction only. Practical Electronics | April | 2025 Photo 2: a 5V buck (stepdown) DC/DC converter module that claims to be able to deliver 5A with an input voltage of 9–24V. Spoiler: it can’t achieve its rated output power... A ‘boost converter’ steps up the input voltage to a higher-level output voltage. By comparison, a ‘buck converter’ steps down the input voltage to a lower-level output voltage. The main consideration for me is that these devices generate negligible heat (at least, as compared to their linear regulator counterparts). Why “buck”? I think this is like the way a horse bucks to get someone off their back; in this case, the buck regulator is relieving the circuit of some unnecessary voltage, rather than an unwanted rider. I found some buck converter modules on Amazon here in the USA (Photo 2). At two for only $15, this seemed like a reasonably good deal. There are equivalents to these modules on Amazon UK (https://pemag.au/link/ac2m). These really are rather handy. On the input side, we have a 2.1mm jack socket (centre pin positive) and a twoway screw terminal block that’s wired in parallel with the jack socket. On the output side, we have another a two-way screw terminal block wired in parallel with a USB-A connector, which means you can also use this to charge your USB devices if you wish. These converters purport to accept anywhere from 9–24V DC as input and generate up to 5A at 5V at the output. Since I require only 1.5A (as per our earlier discussions), these are more than adequate for my design (Fig.8). All the 0V rails on the Arduino, buck converter, and LED array must be connected (0V is equivalent to GND for the purposes of these discussions). The reason why these must all be connected was discussed in detail in the September 2024 issue. One point that may prove puzzling to a beginner involves the buck converter. Let’s look at the bottom of this board as shown in Photo 3 (remember this is my board, yours may vary slightly). The VIN+ and VIN- annotations correspond to the screw terminal block on the input side of the board. The 5V and GND annotations correspond to the screw terminal block on the output side of the board. The point is that the VINand GND pins are directly connected on the board, and these correspond to the 0V rail in Fig.8. Photo 3: the underside of the buck converter module. 15 This is designed to ‘sink’ current and BUCK absorb power from a 0V VINMCU power source. It’s used (Arduino) to simulate a device 0V that would draw electricity from that source, Fig.9: another way of looking at my power supply arrangment. thereby allowing the user to test the perforWhat this means is that we could re- mance of power supplies, batteries, draw my setup as illustrated in Fig.9. solar panels, and other energy sources Although they look a little different, under different load conditions. the circuits in Fig.8 and Fig.9 are funcWhen Joe applied his electronic tionally the same. load to the output of his DC-to-DC converter, he found it held steady at Too good to be true 5V up to a load of about 1.7A. How“Caveat emptor” is a Latin phrase that ever, the output sagged to 4.7V when translates to “let the buyer beware”. It the load reached around 1.8A, and it refers to the fact that people can and started to fall off rapidly (ie, collapsed) will try to sell you any old nonsense; by the time the load reached approxiit’s up to you to make sure you’re get- mately 2.1A. ting what you want. On the one hand, this is disappointI must admit that when I saw the ing compared to its claims of deliveraforementioned buck converter mod- ing 5A (you can’t trust anyone these ules—especially their claim to be able days). On the other hand, since I’ve set to supply up to 5A at 5V—I thought, my maximum power budget at 1.5A, “that sounds too good to be true”. my converter will satisfy my requireJoe agreed, so he purchased some ments, even if it has the same limitasimilar modules of his own for test- tions as Joe’s modules. ing purposes. Joe has a pretty handy Note that the output current likely piece of test equipment called a ‘DC depends on the input voltage, but if electronic load’. it can’t even deliver 2A with a 12V 9V VIN+ 5V Photo.4: I love my new bench power supply. 16 LED Array input, there’s no way it will manage 5A even with the maximum 24V supply voltage applied. As one final point, Joe’s electronic load is an expensive piece of professional equipment, but cheaper hobbyist versions are available. I just found one on Amazon here in the USA for only $42.99 (https://pemag.au/link/ ac45), which is around £34.50. This isn’t something most of us need on a daily basis, but I can see how it could come in handy one day, so I’ve added one to my birthday wish list. I’ve got the power! Returning to my setup (Fig.9), the next thing I’m going to need is a 9V DC power supply that can deliver at least 2A. I know we set the maximum at 1.5A earlier, but I always like to give myself some headroom. I could purchase yet another standalone power supply, like the 9V 2A unit I just found on Amazon in the UK for about £10 (https://pemag.au/link/ ac46). If you decide to go this route, make sure to buy the centre-positive version, which means the centre pin of the barrel jack carries the positive voltage while the outer sleeve has the negative voltage. This is because the power jacks on both the Arduino Uno and our DC-to-DC converter module are centre-positive. Connecting a centre-negative supply will either do nothing or do something very bad, depending on how well designed the powered device is. To be honest, I’ve bought loads of different power supplies over the years, but I still never seem to have the one I need. Joe has a couple of bench power supplies in his workshop, but I don’t have the room for one of these in my study at home (which is where I’m writing these columns). I don’t know why it took me so long, but I looked on Amazon here in the USA and found an awesome bench power supply for only about $45 (https:// pemag.au/link/ac47 & Photo 4). I just found the same unit on Amazon UK for £50 (https://pemag.au/link/ac48). This can supply up to 30V and up to 10A (you set the voltage you want and the maximum current you wish the supply to… well, supply). When in operation, it reports the actual output voltage along with how much current your load is sinking, and even the amount of power it’s delivering. This little rascal comes with a bunch of bells and whistles. Best of all, it’s only around 3.5 inches (9cm) wide, 6 inches (15cm) tall, and 7.5 inches (19cm) deep, which means it occupies a negligible amount of space on my desk. Practical Electronics | April | 2025 One step at a time I always like to take things step by step. I’m going to describe what I did with my setup; you can vary these steps to reflect your own situation as required. First, with its output disabled, I set my bench power supply to 9V DC and limited the output current to 250mA (just in case). Then I connected two pairs of black (0V) and red (5V) leads to the black and red terminals on my power supply. The other ends of these leads were connected to 2.1mm power jack plugs. Before I connected these plugs to anything, I activated the power supply’s output and used my multimeter to confirm I was seeing 9V on each jack’s inner connector. Then I disabled the power supply’s output, plugged one of my cables into my DC-to-DC converter’s input jack, and re-enabled the power supply’s output. The power supply showed it was delivering 9V and 5mA, so now we know that the converter draws 5mA even when it’s not driving anything. I used my multimeter to confirm that I was seeing 5V at the output of the converter. I want to protect my array at all costs. So, before I did anything else, I disconnected it from my Arduino. Next, I connected the USB cable from my PC to the Arduino, and loaded the standard “Blink” program that comes with the Arduino (you can use the Arduino IDE to find this under the File → Examples → 0.1.Basics → Blink menu item). This repeatedly flashes the Arduino’s onboard LED on for a second and off again for a second. Once the Blink program was running, I unplugged the USB cable from the Arduino, disabled the power supply’s output and plugged the second cable from the power supply into the Arduino’s input jack. When I reactivated the power supply’s output, the Arduino powered up and returned to running its Blink program. Also, the power supply now showed it was delivering 9V and 55mA. Subtracting the 5mA for the converter shows the Arduino is pulling 50mA, which is as expected. I disabled the power supply’s output, reconnected the LED array to the Arduino and enabled the power supply’s output once again. Remember that I’m still running the Blink program. Also, all the pixels in the array power up in their off condition. Now, my power supply shows it’s delivering 9V and 125mA. This is interesting. If we subtract 5mA for the DC-to-DC converter (whose output we still aren’t using) and 50mA for the ArPractical Electronics | April | 2025 duino, this leaves 70mA being consumed by the array. Since we have 140 pixels, this means each pixel consumes half a milliamp, even when it’s not displaying anything. I must admit, I wasn’t expecting that. Next, I plugged the USB cable back into the Arduino. As we discussed earlier, when a USB cable is connected, the Arduino automatically selects USB as its power source, overriding any Listing 6(a): activating all the pixels simultaneously. external power sources. Thus, it wasn’t surprising that on working as before. The only differthe power supply returned to deliver- ence was that the Arduino was being ing only 5mA to power the converter. powered with 9V directly from the I reloaded our current latest-and- power supply, while the array was greatest program into the Arduino— being powered by the 5V from the DCthe one that displays single rows, col- to-DC converter. umns, and diagonals (in the file named CB-Apr25 Code-05.txt). This program It’s go time! Now that we have sufficient power, continued to work as expected. Finally, I disabled the output from we can activate all the pixels in our the power supply. I left the control array at the same time. I’ve modified signal from digital pin 12 on the Ardui- our existing program to do this. The no feeding the array, but I removed the new version is in the file named CBred (5V) and black (0V) leads from the Apr25 Code-06.txt. Arduino—the ones that were powering First, I changed the definitions for the array—and connected these to the ON_TIME and GAP_TIME to be 2000 output from the DC-to-DC converter. and 1000 or two seconds and one When I re-enabled the output from second, respectively. the power supply, everything carried Next, I changed the loop() function Here I am, using my new power supply for the first time! 17 to repeatedly turn all the pixels on (for ON_TIME) and off again (for GAP_ TIME). This portion of the program is shown in Listing 6(a). Remember that we are currently driving our pixels at 12.5% of their full power. The data sheet says full power is 60mA per pixel, so when our 140-pixel array is fully lit at 12.5%, that would equate to 140 × 60mA × 0.125 = 1050mA. If we add 5mA for the converter, 50mA for the Arduino, and 70mA for the intrinsic current draw of the array with no pixels lit, this should give a grand total of 1175mA. Interestingly enough, my bench power supply reports a maximum value of only 450mA when all the pixels are driven white at 12.5%. That’s less than half of the expected current draw. Part of the reason for this is that 450mA <at> 9V is 4.05W, and if the buck converter is, say, 90% efficient, that equates to a 5V output of 4.05W ÷ 5V = 810mA. In other words, you get more current out of the buck converter than you put in because you’re reducing the voltage by more than you’re reducing the power. Still, it’s a little on the low side. I will investigate this further, and I’ll report back next month. For shame! I fear I must hang my head in shame. In my previous column, I promised that we would be performing some more experiments with our eightsegment bar graph display in conjunction with a shift register. Sadly, I got carried away with our retro games console, but we will certainly do this in my next column (no, my fingers aren’t crossed behind my back—why would you ask?). Until that frabjous day, if you have any thoughts that you’d care to share on anything you’ve read here, please feel free to drop me an email at max<at> clivemaxfield.com. Until next time, PE have a good one! Useful Bits and Pieces from Our Arduino Bootcamp series Arduino Uno R3 microcontroller module Solderless breadboard 8-inch (20cm) jumper wires (male-to-male) Long-tailed 0.1-inch (2.54mm) pitch header pins LEDs (assorted colours) Resistors (assorted values) Ceramic capacitors (assorted values) 16V 100µF electrolytic capacitors Momentary pushbutton switches Kit of popular SN74LS00 chips 74HC595 8-bit shift registers https://pemag.au/link/ac2g https://amzn.to/3O2L3e8 https://amzn.to/3O4hnxk https://pemag.au/link/ac2h https://amzn.to/3E7VAQE https://amzn.to/3O4RvBt https://pemag.au/link/ac2i https://pemag.au/link/ac2j https://amzn.to/3Tk7Q87 https://pemag.au/link/ac2k https://pemag.au/link/ac1n Other stuff Soldering guide Basic multimeter https://pemag.au/link/ac2d https://pemag.au/link/ac2f Components for Weird & Wonderful Projects, part 1 4-inch (10cm) jumper wires (optional) 8-segment DIP red LED bar graph displays https://pemag.au/link/ac2l https://pemag.au/link/ac2c Components for Weird & Wonderful Projects, part 2 144 tricolour LED strip (required) Pushbuttons (assorted colours) (required) 7-Segment display modules (recommended) 2.1mm panel-mount barrel socket (optional) 2.1mm inline barrel plug (optional) 25-way D-sub panel-mount socket (optional) 25-way D-sub PCB-mount plug* (optional) 15-way D-sub panel-mount socket (optional) 15-way D-sub PCB-mount plug^ (optional) https://pemag.au/link/ac2s https://pemag.au/link/ac2t https://pemag.au/link/ac2u https://pemag.au/link/ac2v https://pemag.au/link/ac2w https://pemag.au/link/ac2x https://pemag.au/link/ac2y https://pemag.au/link/ac2z https://pemag.au/link/ac30 * one required for each game cartridge you build ^ one required for each auxiliary control panel you build Components for Weird & Wonderful Projects, part 3 22 AWG multicore wire kit 20 AWG multicore wire kit https://pemag.au/link/ac3m https://pemag.au/link/ac3n Components for Weird & Wonderful Projects, part 4 5V Buck converter module 9V 2A power supply (optional) Bench power supply (optional) https://pemag.au/link/ac2m https://pemag.au/link/ac46 https://pemag.au/link/ac48 1551W IP68 miniature enclosures Learn more: hammondmfg.com/1551w uksales<at>hammfg.com 01256 812812 18 Practical Electronics | April | 2025