Silicon ChipMax’s Cool Beans - August 2020 SILICON CHIP
  1. Outer Front Cover
  2. Contents
  3. Subscriptions: PE Subscription
  4. Subscriptions: PicoLog Cloud
  5. Back Issues: PICOLOG
  6. Publisher's Letter
  7. Feature: The Fox Report by Barry Fox
  8. Feature: Techno Talk by Mark Nelson
  9. Feature: Net Work by Alan Winstanley
  10. Project: Micromite LCD BackPack V3 by Tim Blythman
  11. Project: Steering Wheel audio BUTTON TO INFRARED Adaptor by John Clarke
  12. Project: JUNK MAIL REPELLER! by Allan Linton-Smith
  13. Back Issues by Jim Rowe
  14. Project: Bargain Modules Class-D Stereo Plus Subwoofer Amplifier by Allan Linton-Smith
  15. Feature: Circuit Surgery by Ian Bell
  16. Feature: AUDIO OUT by Jake Rothman
  17. Feature: Make it with Micromite by Phil Boyce
  18. Feature: Practically Speaking by Mike Hibbett
  19. Feature: Max’s Cool Beans by Max the Magnificent
  20. Feature: Electronic Building Blocks by Julian Edgar
  21. PCB Order Form
  22. Advertising Index

This is only a preview of the August 2020 issue of Practical Electronics.

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

Articles in this series:
  • Techno Talk (August 2020)
  • Techno Talk (August 2020)
  • Techno Talk (September 2020)
  • Techno Talk (September 2020)
  • Techno Talk (October 2020)
  • Techno Talk (October 2020)
  • (November 2020)
  • (November 2020)
  • Techno Talk (December 2020)
  • Techno Talk (December 2020)
  • Techno Talk (January 2021)
  • Techno Talk (January 2021)
  • Techno Talk (February 2021)
  • Techno Talk (February 2021)
  • Techno Talk (March 2021)
  • Techno Talk (March 2021)
  • Techno Talk (April 2021)
  • Techno Talk (April 2021)
  • Techno Talk (May 2021)
  • Techno Talk (May 2021)
  • Techno Talk (June 2021)
  • Techno Talk (June 2021)
  • Techno Talk (July 2021)
  • Techno Talk (July 2021)
  • Techno Talk (August 2021)
  • Techno Talk (August 2021)
  • Techno Talk (September 2021)
  • Techno Talk (September 2021)
  • Techno Talk (October 2021)
  • Techno Talk (October 2021)
  • Techno Talk (November 2021)
  • Techno Talk (November 2021)
  • Techno Talk (December 2021)
  • Techno Talk (December 2021)
  • Communing with nature (January 2022)
  • Communing with nature (January 2022)
  • Should we be worried? (February 2022)
  • Should we be worried? (February 2022)
  • How resilient is your lifeline? (March 2022)
  • How resilient is your lifeline? (March 2022)
  • Go eco, get ethical! (April 2022)
  • Go eco, get ethical! (April 2022)
  • From nano to bio (May 2022)
  • From nano to bio (May 2022)
  • Positivity follows the gloom (June 2022)
  • Positivity follows the gloom (June 2022)
  • Mixed menu (July 2022)
  • Mixed menu (July 2022)
  • Time for a total rethink? (August 2022)
  • Time for a total rethink? (August 2022)
  • What’s in a name? (September 2022)
  • What’s in a name? (September 2022)
  • Forget leaves on the line! (October 2022)
  • Forget leaves on the line! (October 2022)
  • Giant Boost for Batteries (December 2022)
  • Giant Boost for Batteries (December 2022)
  • Raudive Voices Revisited (January 2023)
  • Raudive Voices Revisited (January 2023)
  • A thousand words (February 2023)
  • A thousand words (February 2023)
  • It’s handover time (March 2023)
  • It’s handover time (March 2023)
  • AI, Robots, Horticulture and Agriculture (April 2023)
  • AI, Robots, Horticulture and Agriculture (April 2023)
  • Prophecy can be perplexing (May 2023)
  • Prophecy can be perplexing (May 2023)
  • Technology comes in different shapes and sizes (June 2023)
  • Technology comes in different shapes and sizes (June 2023)
  • AI and robots – what could possibly go wrong? (July 2023)
  • AI and robots – what could possibly go wrong? (July 2023)
  • How long until we’re all out of work? (August 2023)
  • How long until we’re all out of work? (August 2023)
  • We both have truths, are mine the same as yours? (September 2023)
  • We both have truths, are mine the same as yours? (September 2023)
  • Holy Spheres, Batman! (October 2023)
  • Holy Spheres, Batman! (October 2023)
  • Where’s my pneumatic car? (November 2023)
  • Where’s my pneumatic car? (November 2023)
  • Good grief! (December 2023)
  • Good grief! (December 2023)
  • Cheeky chiplets (January 2024)
  • Cheeky chiplets (January 2024)
  • Cheeky chiplets (February 2024)
  • Cheeky chiplets (February 2024)
  • The Wibbly-Wobbly World of Quantum (March 2024)
  • The Wibbly-Wobbly World of Quantum (March 2024)
  • Techno Talk - Wait! What? Really? (April 2024)
  • Techno Talk - Wait! What? Really? (April 2024)
  • Techno Talk - One step closer to a dystopian abyss? (May 2024)
  • Techno Talk - One step closer to a dystopian abyss? (May 2024)
  • Techno Talk - Program that! (June 2024)
  • Techno Talk - Program that! (June 2024)
  • Techno Talk (July 2024)
  • Techno Talk (July 2024)
  • Techno Talk - That makes so much sense! (August 2024)
  • Techno Talk - That makes so much sense! (August 2024)
  • Techno Talk - I don’t want to be a Norbert... (September 2024)
  • Techno Talk - I don’t want to be a Norbert... (September 2024)
  • Techno Talk - Sticking the landing (October 2024)
  • Techno Talk - Sticking the landing (October 2024)
  • Techno Talk (November 2024)
  • Techno Talk (November 2024)
  • Techno Talk (December 2024)
  • Techno Talk (December 2024)
  • Techno Talk (January 2025)
  • Techno Talk (January 2025)
  • Techno Talk (February 2025)
  • Techno Talk (February 2025)
  • Techno Talk (March 2025)
  • Techno Talk (March 2025)
  • Techno Talk (April 2025)
  • Techno Talk (April 2025)
  • Techno Talk (May 2025)
  • Techno Talk (May 2025)
  • Techno Talk (June 2025)
  • Techno Talk (June 2025)
  • Techno Talk (July 2025)
  • Techno Talk (July 2025)
Max’s Cool Beans By Max the Magnificent Flashing LEDs and drooling engineers – Part 6 W ell hello there! How nice it is to see you again. May I make so bold as to say that, as a member of the Cool Beans community, you manage to look both awesome and highly intelligent. This isn’t a look many people can carry off successfully, so kudos to you! Out of date As I mentioned in my previous column (PE, July 2020), my current hobby project is to build a 12 × 12 = 144 array of ping-pong balls, each containing a tricoloured LED in the form of a WS2818 (aka ‘NeoPixel’). As you may recall, I also introduced the Seeeduino XIAO microcontroller with which I plan to drive my array. The XIAO is only about the size of a standard postage stamp, but it boasts a 32-bit Arm Cortex-M0+ running at 48MHz with 256KB of Flash (program) memory and 32KB of SRAM. Yummy scrummy! In fact, I’m so enthused by this little beauty that I was moved to create a video (https://bit.ly/373vPQC). One slight complication is that the XIAO’s input/outputs (I/Os) are 3.3V, but I need a 5V signal to drive my pixels. Happily, I found a rather cool hack that allows me to use a 1N4001 diode and a ‘sacrificial’ pixel to implement a cheapand-cheerful 3.3V-to-5V voltage-level converter (https://bit.ly/3cxMhcV). In anticipation of finishing my pingpong ball build (and that’s not something you expect to hear yourself saying very often), I bounced over to the XIAO’s wiki webpage (https://bit.ly/30bCyGH) to learn how to add this little scamp to my Arduino IDE. Next, I created a really simple test Fig.1. A jig to hold the ping-pong balls. Practical Electronics | August | 2020 sketch (program) to tickle my pixels, selected the XIAO as my target board, and hit the ‘Compile’ icon. Sad to relate, the compilation failed with multiple errors and grim warnings of a type I’ve never seen before. ‘Oh dear,’ I said to myself (or words to that effect). I switched the target board to an Arduino Uno and the compilation passed as expected. It also passed when I switched back to the XIAO and commented out any NeoPixel-related statements. Hmmm. By this time, I was wearing my sad face, so I emailed my sketch to the folks at Seeed Studio explaining my conundrum. The very next morning, I found an email in my InBox from field applications engineer (FAE) Anson He, who said that my test program had compiled for him with no problem. Anson recommended that I check to see if I had the latest version of the Arduino IDE (I had) and the latest version of Adafruit’s NeoPixel library (I hadn’t). After removing my old NeoPixel library, I followed the instructions on Adafruit’s NeoPixel Überguide (https:// bit.ly/2XzuqOB) to install the latest and greatest version of their library. Following this, everything compiled like a charm, at which point I dispatched the butler to fetch my happy trousers (I can’t perform my Happy Dance without them). Now, all that remained was to actually construct the array, which sounds easy if you say it fast and gesticulate furiously. experimenting unsuccessfully with a variety of different schemes, I created a jig by drilling a 6 × 6 matrix of smaller holes in a piece of scrap board and using this to position and restrain the balls (Fig.1). Next, I laid one corner of the main board on top (Fig.2), used a bit of wooden dowel to tweak the position of the holes in the ping pong balls so they pointed straight up, and used my hot-glue gun to fix everything in place. I then repeated the process for the remaining three quadrants. As an aside, I’m regarding this 12 × 12 array as being a prototype to ‘iron out the wrinkles’ in the process. In the fullness of time, I’m hoping to build a wall-size display. One thing I’ve decided is that the next time I do this, I will create smaller 8 × 8 panels and then join them together, in which case the alignment jig will be the same size as the front panel. Hot glue is my friend The boring bits While my software gremlins were underway, the hardware construction proceeded apace. Unfortunately, I hadn’t given as much thought as perhaps I should to how I was going to precisely position the ping-pong balls. As you may recall from my previous column, rather than drilling the holes in the balls to accommodate the NeoPixels, I cut them by hand using some small curved nail scissors. The thing is, that this was easier to do prior to mounting the balls on the board, but it left me with the problem of aligning everything. Prior to this, I had no idea how tricky it can be to corral 144 ping-pong balls and bend them to your will. The little rascals seem determined to escape. After Every project involves one or more boring bits, and this is where I now found myself. Fig.2. Ready to attach the first 36 balls. Fig.3. Cutting the NeoPixel Segments. 59 The problem here was that there are variations caused by things like the segments being cut to slightly different lengths and the holes in the ping pong balls not being precisely aligned. As a result, some gaps were smaller, while other gaps were larger. Rather than custom-create each piece, I decided to make the wire parts long enough to span the widest gaps, while the insulation parts were short enough to fit in the narrowest gaps (Fig.4). So, excluding the ends of the rows, we have to make 11 groups of 3 connections on 12 rows, which equals creating 396 little wires (there’s a couple of hours I’m not going to see again). My reasoning for leaving a small piece of insulation was that, while attaching these wires, I didn’t want my long-nosed pliers to act as heat sinks resulting in bad joints. In hindsight (the one exact science), I discovered this really wasn’t an issue, and I could have saved myself a lot of effort by simply using short lengths of uninsulated tinned copper wire cut from a roll. Be this as it may, I created videos showing the process of creating the wire connectors (https://bit. ly/2MCQ7al) and attaching them to the array (https://bit.ly/3dHzgPt). Each NeoPixel contains red, green, and blue sub-pixels. The data sheet says that, when full on, each sub-pixel consumes 20mA, so each NeoPixel will consume 60mA. To be honest, when I’ve measured this in the real world, I’ve never seen more than 45mA for a fully on NeoPixel, so this is the value I usually go by myself (not Fig.4. Creating linking wires to that I’m recommending this as a practice accommodate different gap sizes. for anyone else, you understand). One further consideration is that, in It started with snipping out 145 segments use, it would be rare for us to have all of from my NeoPixel strip – 144 for the the elements in the array fully on. Most array, and the ‘sacrificial’ pixel for the of the time, I would be surprised if we avvoltage-level converter (Fig.3). This is eraged more than 20%. Having said this, less fun than you might expect, because we should always design for the worstthe strip is delivered wrapped in a procase scenario (I know this goes against tective plastic cover making the pixels my using 45mA vs. 60mA. What can I waterproof so they can be deployed outsay? We live in a crazy mixed up world). side, and this cover has to be painstakWe have 145 pixels if we include the ingly removed (not that I’m complaining, ‘sacrificial’ pixel, even if we’re not planbut it all takes time). ning on using it for anything. The worstThe next step was to use more hot glue case full-on scenario according to the to attach these segments to the ping-pong data sheet would be 145 × 60 = 8.7A. By balls. Remembering that the pixels are comparison, the worst-case scenario asgoing to be daisy-chained together, the suming 45mA per pixel would be 145 × way I did this is to align alternate rows 45 = 6.6A. in different directions, first right-to-left, I had originally been planning on powthen left-to-right, then right-to-left, and so ering all of the strips on one side as illusforth. This keeps the signal wires short trated in Fig.5a (note that the reason the when connecting the end of one row to power and ground wires alternate top to the start of the next. Feel the power! bottom from strip to strip is that alternate In the case of the body of the array, I This is where things started to get interstrips have their signal paths going rightneeded three short wires to connect adesting again, because I was now on the to-left and left-to-right, which also swaps jacent pixels: 5V, 0V, and the data signal. home stretch of connecting the power. the orientation of the 5V and 0V signals. Unfortunately, the only solid-core copper wire that I had to hand in my treasure chest of bits and pieces, and that I’m using to supply the power, is rated at 3.5A. Of course, as with anything in electronics, there are myriad ways in which we could address this issue. One ( a) P ow ering all the strips on one side ( b) P ow ering all the strips on both sides ( c) D iv iding the strips into groups way would have been to stick with the scenario Fig.5. Different power wiring scenarios. depicted in Fig.5a, but 11 10 9 8 7 R ow s 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 C olumns 8 9 10 11 ( a) T he w ay I v isualiz e the array look ing at the front. ( b) T he w ay I planned on w iring things ( still look ing from the front) . ( c) T he w ay I actually w ired things ( still look ing from the front) . Fig.6. When plans meet the real world. 60 Practical Electronics | August | 2020 ‘Sacrificial’ pixel Y = R ow s 0 to 11 1N4001 diode 390Ω buffering resistor Fig.7. It’s your other left! to double up on all of the wires. This would give us a 7A capacity, which would satisfy our 6.6A requirements. An alternative would be to stick with single wires, but to wire one set on the left of the strips and the other set on the right as illustrated in Fig.5b. This scenario, which also provides a 7A capacity, has the advantage that, if one of the power or ground connections in the middle of a strip were to fail (eg, due to a bad solder joint), then all of the pixels in that strip would still be powered. The approach I eventually opted for, and which I documented in a video (https://bit.ly/2Y6L9bh), was to divide the strips into three groups of four and to power each group independently, as illustrated in Fig.5c, thereby providing me with a 10.5A capability, which more than satisfies even the worst, worst-case 8.7A requirements associated with all of the pixels being fully on while each consuming 60mA. Phew! Your other left! The way I’ve been thinking about my 12 × 12 array is as a matrix of 12 rows and 12 columns. If I’m looking at this from the front, element (0,0) will be in the bottom left-hand corner as illustrated in Fig.6a. Based on this, I was planning on wiring things such that – still looking from the front) – the first pixel in the chain was located in the bottom left-hand corner, as illustrated in Fig.6b. Unfortunately, when I sat down at the workbench (aka the kitchen table) and set to connecting all of the wires, I forgot I was looking at the back of the array and I located the first pixel in the chain in the nearside left-hand corner (Fig.7). Observe that the lone pixel nearest to us is the ‘sacrificial’ pixel that’s acting as the voltage-level converter. We can (just) see the black 1N4001 diode connected between the 5V supply and the power input to this pixel; also, the 390Ω resistor buffering the data signal from the XIAO microcontroller. So, as a result of all these shenanigans, the way I actually ended up wiring the array is as illustrated in Fig.6c. Of course, none of this really matters because we’re going to be finagling things in software anyway, but it still irritates me that I lost track of things in this way. Practical Electronics | August | 2020 13 3 13 5 13 6 13 7 13 8 13 9 14 0 14 1 14 2 14 3 10 13 2 13 1 13 0 129 128 127 126 125 124 13 4 14 4 123 122 121 9 109 110 111 112 113 114 115 116 118 119 8 108 107 106 105 104 103 102 101 100 9 9 9 8 9 7 7 8 5 8 6 8 7 8 8 9 0 9 1 9 5 9 6 8 9 9 2 117 9 3 9 4 120 6 8 4 8 3 8 2 8 1 8 0 7 9 7 8 7 7 7 6 7 5 7 4 7 3 5 6 1 6 2 6 3 6 4 6 5 6 6 6 7 6 8 6 9 7 0 7 1 7 2 4 6 0 59 58 57 56 55 54 53 52 51 50 4 9 3 3 7 3 8 3 9 4 0 4 1 4 2 4 3 4 4 4 5 4 6 4 7 4 8 2 3 6 3 5 3 4 3 3 3 2 3 1 3 0 29 28 27 26 25 1 13 14 15 16 17 18 19 20 21 22 23 24 0 12 11 10 9 8 7 6 5 4 3 2 1 0 1 2 10 11 3 4 5 6 7 8 9 X = C olumns 0 to 11 Fig.8. The ordering (numbering) of the NeoPixels in the array. void LightOneAfterAnother (uint32_t thisColor) { for (int iNeo = 1; iNeo < NUM_NEOS; iNeo++) { Neos.setPixelColor(iNeo, thisColor); Neos.show(); delay(TestCycleTime); } } The main program calls this function over and over again, first setting the colour to red, then green, then blue. If you wish, you can download the full program to peruse and ponder (file CB-Aug20-01.txt – available on the August 2020 page of the PE website). Also, for your delectation and delight, I created a video showing this in action (https://bit.ly/3dIpr3G). OK, this is where things start to get interesting again. Remember that the way I want to visualise the array – and the way I want to treat it in my programs – is as 12 rows numbered from 0 at the bottom to 11 at the top, and as 12 columns numbered from 0 on the left to 11 on the right. In the future, we want to be able to say things (programmatically speaking) like ‘light the pixel at column 4 in row 2 with the colour red.’ What we want for our second test is to start with row 0 and light the pixels in sequence from column 0 to 11, then to repeat for row 1 and work our way up to row 11. The resulting raster scan should look like the illustration in Fig.9b. Depending on one’s background, you may prefer to think of the column-row combos as X-Y coordinates. In order to achieve this, I modified my main function, which now appears as follows: void LightOneAfterAnother (uint32_t thisColor) { int iNeo; for (int yInd = 0; yInd < NUM_ROWS; yInd++) { for (int xInd = 0; xInd < NUM_COLS; xInd++) { iNeo = GetNeoNum(xInd, yInd); Neos.setPixelColor(iNeo, thisColor); Neos.show(); delay(TestCycleTime); } } Testing, testing... Once the wiring was completed, I was ready to perform my initial tests. It always pays to keep one’s first test as simple as possible, so my equivalent of the classic ‘Hello World’ program was to simply light each pixel in sequence. Normally, our 144 pixels would be numbered from 0 to 143. However, since we actually have 145 pixels, with the ‘sacrificial’ pixel occupying location 0, the pixels in our array are numbered from 1 to 144 (Fig.8). At the heart of the first test program is a function shown below. As we would expect, the result is to light the pixels in a serpentine pattern, commencing with the pixel in the bottom right-hand corner, and progressing from right-to-left and leftto-right as we work our way through the chain (Fig.9a). 11 } As we see, we have an outer loop that works its way up the rows (the Y values), and an inner loop that works its way across the columns (the X values). The interesting part is where we 61 iNeo = iNeo + (12 - xInd); } else { // Odd row iNeo = iNeo + (xInd + 1); } return iNeo; } ( a) First test pattern seq uence ( look ing from the front) . ( b) Second test pattern seq uence ( look ing from the front) . Fig.9. The results from the first and second tests. call the GetNeoNum() function, passing it the (X,Y) values and – hopefully – receiving the number of the corresponding NeoPixel in the chain. So, what sort of algorithm could we use to implement the GetNeoNum() function? I think that it would be a good exercise for you to cogitate and ruminate on this before reading further. Maybe sketch something out with pencil and paper. I don’t know about you, but this sort of thing doesn’t come naturally to me. I’m sure professional programmers could whip it out without thinking, but I’m more of a visual problem solver, so I started off by sketching the number array depicted in Fig.8. After mulling this over for a while, I decided that if I’m on row Y, my starting point is to say that I have (Y * 12) pixels. The next step is to determine if I’m on an odd or even row. If I’m on an even row, I need to add (12 - X) pixels; by comparison, if I’m on an odd row, I need to add (X + 1) pixels. The way I determine whether I’m on an odd or even row is to use the % (modulo) operator, which returns the integer remainder from an integer division. So, if I divide row Y by % 2 and the result is 0, we’re on an even row; if the result is 1, we’re on an odd row. The code for this function is as follows: int GetNeoNum (int xInd, int yInd) { int iNeo; iNeo = yInd * NUM_COLS; if ( (yInd % 2) == 0) { // Even row Let’s try this out. Suppose we want to light the pixel located at column 4 in row 2; that is, (X,Y) = (4,2). First, we multiply the row by the number of pixels, so (Y * 12) = (2 * 12) = 24. Next, we divide the row by % 2 to determine that it’s even, in which case we need to add (12 - X) = (12 - 4) = 8. So the number of the pixel in the chain that corresponds to (X,Y) coordinates of (4,2) is 24 + 8 = 32. Try this out for yourself using a few sample (X,Y) values and checking the results using Fig.8. Once again, if you wish, you can download the full program to peruse and ponder (file CB-Aug20-02.txt – available on the August 2020 page of the PE website). And, once again, I created a short video showing all of this in action (https://bit. ly/3cFcfLM). So, now we’re really ready to rock and roll. What shall we do first? I have a few ideas, which I will discuss and demonstrate in my next column. Until then, as always, I welcome your comments, questions, and suggestions. Cool bean Max Maxfield (Hawaiian shirt, on the right) is emperor of all he surveys at CliveMaxfield.com – the go-to site for the latest and greatest in technological geekdom. Comments or questions? Email Max at: max<at>CliveMaxfield.com Max’s Cool Beans cunning coding tips and tricks Crusty bits I have a retired friend, who calls himself ‘Crusty’, and who is teaching himself to program in C. A few weeks ago he emailed me with a problem. He’d created a program for his Arduino Uno with a for() loop that looked something like the following: for (i = 0; i <= 10, i++) { // Do some stuff } 62 Everything worked as expected with the loop executing 11 times. This wasn’t the issue to which I alluded. The problem arose when Crusty modified his code to look something like the following: for (i = 10; i >= 0, i--) { // Do some stuff } Crusty’s issue is that this loop never ended. Instead, it kept on executing over and over again. Any professional programmer will immediately guess the cause. With my decades of painfully gleaned experience, it was obvious to me too, but poor old Crusty simply couldn’t figure it out. Can you? You’re not my type! When people are first introduced to the C programming language, one of the first data types they meet is the int, which stands for integer; for example: Practical Electronics | August | 2020 int MyInt; Variables declared with this type, like MyInt in this example, can store positive and negative whole numbers (I know that, by definition, there aren’t any negative whole numbers, but you know what I mean). For example, −7, 0, and 42 are all valid int values. When we see a number like 42, by convention we assume it represents a positive value without having to explicitly write +42. Similarly, when we see a variable declared using the int data type, we assume we’re talking about a ‘signed’ integer that can represent both positive and negative values. We could also make this explicit using the following: sense once you understand how these values are stored, represented, and manipulated inside the computer, but that’s a discussion for another day. I explained all this to Crusty. I also asked him to add a Serial. begin(9600); statement at the beginning of his setup() function, and to modify his for() loop, as shown below: for (i = 10; i >= 0, i--) { Serial.print(“i = “); Serial.println(i); // Do some stuff } signed int MyInt; Of course, this leads us to the fact that we can also declare an integer variable as being unsigned, which means it has no sign and can represent only positive values; for example: When Crusty uploaded this new sketch and launched the Serial Monitor window, the count sequence displayed was as predicted: ‘…3, 2, 1, 0, 65,535, 65,534…’ Of course, this explains why Crusty’s loop never terminates, because i is always >= 0. unsigned int MyUint; A can of worms Unlike numbers written with a pencil on paper, which can be as big as we want, limited only by the staying power of our pencil and the endurance of our hand, the size of numbers stored in a computer is limited by the amount of memory associated with the data type we are using to represent them. Say what? Now, this is where things start to get a little tricky because – believe it or not – the C standard doesn’t explicitly define the size of an int. All it says is that an int should be a minimum of two bytes (16 bits). In the case of an Arduino Uno, the size of an int is indeed two bytes; in other computers it can by four bytes or more. A 2-byte (16-bit) field can be used to represent 216 = 65,526 different patterns of 0s and 1s. In the case of a signed int, these patterns can be used to represent negative and positive values in the range −32,768 to +32,767 (note that we also have to represent 0, so 32,768 + 32,767 + 1 [to represent 0] equals 65,536). By comparison, in the case of an unsigned int, these patterns can be used to represent only positive values in the range 0 to 65,535 (once again, we have to represent 0, so 65,535 + 1 [to represent 0] equals 65,536). All is revealed! Returning to Crusty’s problem (and remembering he only sent me the code for his for() loop), it was obvious to me that he’d declared the variable i he was using to control his loop as an unsigned data type. I assumed an unsigned int, and this indeed turned out to be the case. Since Crusty was thinking that his loop control would only ever be positive (ie, >= 0), he’d fallen into the trap of thinking ‘bigger is better,’ opting to use an unsigned int because it could hold larger positive values, even though he never actually planned on using anything bigger than 10. Now, let’s perform a little thought experiment. We know that an unsigned int on an Arduino Uno can be used to represent positive values in the range 0 to 65,565. Suppose we were to load such a variable with 0 and then keep on incrementing (adding one to) it until it contains its maximum value of 65,565. What do you think will happen if we try to increment it one more time? In fact, since the result will exceed this data type’s capacity, it will overflow and return to containing 0. Contra wise, the opposite happens in the other direction. That is, if our unsigned int contains 0 and we attempt to subtract 1 from this value, the result can’t be −1 because – by definition – our unsigned int can contain only positive values. Instead, 0 − 1 will result in 65,565. Although this may not seem particularly intuitive, it actually makes perfect Practical Electronics | August | 2020 Actually, Crusty’s question has opened up a can of worms – interesting worms, but worms nonetheless – because we also have signed and unsigned versions of other data types like short and long. We also have the char data type, whose signed or unsigned status is not actually specified by the C standard, which means it can vary from computer to computer or – more correctly – compiler to compiler because the computer just does what it’s told. (In the case of the Arduino Uno and its compiler, the char is one byte in size and behaves like a signed 8-bit integer.) And then there’s the byte data type, which doesn’t actually exist in standard C, but which the Arduino’s creators decided to throw into the mix for giggles and grins. I’m sure you will be delighted to discover that we’ll take a deeper dive into all of this in my next Tips and Tricks column. Your best bet since MAPLIN Chock-a-Block with Stock Visit: www.cricklewoodelectronics.com O r phone our friendly kn ow ledgeable staff on 0 2 0 8 4 5 2 0 1 6 1 Components • Audio • Video • Connectors • Cables Arduino • Test Equipment etc, etc V i si t ou r S h op , C a l l or B u y on l i n e a t: w w w . c r i c k l ew ood el ec tr on i c s. c om 0 2 0 8 4 5 2 0 1 6 1 V i si t ou r sh op a t: 4 0 - 4 2 C r i c k l ew ood B r oa d w a y L on d on NW 2 3 E T 63