Silicon ChipMax’s Cool Beans - January 2021 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: Nutube by John Clarke miniature valve stereo preamplifier by John Clarke
  11. Project: Complete Arduino DCC Controller by Tim Blythman
  12. Project: Using Cheap Asian Electronic Modules by Jim Rowe
  13. Feature: KickStart by Mike Tooley
  14. Feature: PICn’Mix by Mike Hibbett
  15. Feature: AUDIO OUT by Jake Rothman
  16. Feature: Make it with Micromite by Phil Boyce
  17. Feature: Interference and noise by Ian Bell
  18. Feature: Max’s Cool Beans by Max the Magnificent
  19. Feature: Visual programming with XOD by Julian Edgar
  20. Advertising Index: Max’s Cool Beans by Max the Magnificent
  21. PCB Order Form

This is only a preview of the January 2021 issue of Practical Electronics.

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

Articles in this series:
  • (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)
Max’s Cool Beans By Max the Magnificent Flashing LEDs and drooling engineers – Part 11 G ood grief! I am bubbling over with excitement. I have so many things I want to talk about that I don’t have a clue where to begin. I know, I know... I need to sit down, take a deep breath, start at the beginning, work my way through the middle, and eventually stagger my way to the end. The problem is deciding what to talk about first. Ah, I can see in your eyes that you are desperate for me to commence with gamma correction. Well, if you insist... 0 ° P rim ary 330 ° T ertiary F F F F R ose 30 ° T ertiary 0 0 0 0 F lush O range 0 0 8 0 F F 30 0 ° S econdary F F 8 0 0 0 6 0 ° S econdary Magenta 0 0 F F 11 10 27 0 ° T ertiary Electric I ndigo Feeling off-colour R ed 9 0 Y ellow F F 1 2 F F 0 0 9 0 ° T ertiary C hartreuse 3 58 B rightness B rightness B rightness 8 0 F F 0 0 Way back in the mists of time when we started this mega-mini4 8 8 0 0 0 F F series (PE, March 2020), we introduced the concept of pulse7 5 6 width modulation (PWM). Since we can turn an LED on and 24 0 ° P rim ary 120 ° P rim ary off very quickly, the way we control its brightness is to vary B lue Green the proportion of on time to its off time. We refer to this as the 0 0 0 0 F F 0 0 F F 0 0 ‘duty cycle.’ A 20% duty cycle means the LED is on 20% of 210 ° T ertiary 150 ° T ertiary the time and off for the other 80%, while an 80% duty cycle A z ure 18 0 ° S econdary S pring Green means the LED is on 80% of the time and off the other 20%. 0 0 8 0 F F 0 0 F F 8 0 C yan 0 0 F F F F In the case of the microcontroller unit (MCU) we are working with – the Seeedunio XIAO – we can use values from 0 (0x00 Fig.1. The colour wheel we’ve been using in our experiments. in hexadecimal) being fully off (0% brightness) to 255 (0xFF in hexadecimal) being fully on (100% brightness). Using this I created a quick test sketch (program) to see how this would PWM technique, a value of 128 (0x80 in hexadecimal) means affect the colours on my 12×12 array (the full sketch is presented the LED will be on half of the time and off the other half, rein file CB-Jan21-01.txt – it and the other files associated with this sulting in 50% brightness. article, are available on the January 2021 page of the PE website). In a later column (PE, September 2020), we introduced the Since the folks at Adafruit were conscious that some of their users colour wheel (Fig.1) that we decided to use for our 12×12 pingwould be using low-end Arduinos with limited SRAM, they store pong array experiments (Fig.2). If you have built one of these their table in PROGMEM (the Flash program memory). By comarrays yourself, or if you are playing with tricolour LEDs in parison, my Seeedunio XIAO has so much memory that I can general, you may have noticed that some of the colours seem afford to flaunt it, so I dispatched the butler to fetch my flauntto be a tad ‘off’. For example, the rose may appear very close ing trousers and stored my table in SRAM (Fig.3.). to magenta, while the flush orange may appear more yellow Previously (PE, October 2020), we met the GetRed(), Getthat one might expect. Green(), and GetBlue() functions that extract and return the On the bright side (no pun intended), the red, green, and 8-bit red, green, and blue components from a 32-bit colour value. blue elements in our tricolour LEDs work as expected and Also, we introduced the BuildColor() function that accepts 8-bit provide a linear response such that a 50% duty cycle does red, green, and blue components and returns a 32-bit colour value. indeed result in 50% brightness (Fig.2a). The problem is that The thing is, we have to apply our gamma correction to each our eyes have evolved to accommodate a huge dynamic range, of the colour channels individually. Thus, in our new sketch, from moonlight to sunlight and – as part of this – they have a we’ve added a GetGammaCorrectedColor() function that sort of built-in non-linearity (Fig.2b). accepts a 32-bit colour value, splits it into its red, green and Although not immediately obvious from my diagram, the blue components, uses our GammaXref[] look-up-table to curve of this non-linearity is defined by a somewhat tricky apply gamma correction to each component, and then returns power-law function. In order to address this, we need to drive the gamma-corrected 32-bit result. the red, green, and blue LEDs using the inverse of this function, which results in our eyes per10 0 % ceiving what we were hoping for in the first W hat our eyes perceiv e T he LED place (Fig.2c). We call the process of applying W hat our work s as eyes perceiv e ex pected this inverse function, ‘gamma correction.’ 50 % There’s a great article on Adafruit’s website covering all of this in depth (https://bit.ly/31zaSLK). H ow the LED H ow the LED is driv en is driv en As part of this, they provide what they call ‘The H ow the LED is driv en Quick Fix’ in the form of a cross-reference lookP W M P W M P W M 0 % up table that we can use to remap the linear 0 x 0 0 0 x 8 0 0 x F F 0 x 0 0 0 x 8 0 0 x F F 0 x 0 0 0 x 8 0 0 x F F values we would like to use into their gamma( a) W hat we ex pect to see ( b ) W hat we actually see ( c) A pplying gam m a correction corrected counterparts that will provide us with the colours we want to see. Fig.2. Gamma correction. Practical Electronics | January | 2021 gammaCorrectedColor = BuildColor(tmpRed, tmpGreen, tmpBlue); The idea is that you have two programs fighting each other in a virtual machine known as the Memory Array Redcode Simulator (MARS). The objective is to be the last program standing. To that end, each program can try to sabotage the other one and/or try to defend itself by self-repairing. You can get a really good feel as to what this is all about by reading the Beginner’s Guide to the Redcode pseudo assembly language that is used to create the warrior programs (https://bit.ly/34m5YUo). As Ken said in his email, ‘I figure this can be made visually appealing by presenting the memory array on a screen (or ping-pong ball array) and colour-coding each cell either ‘Neutral,’ ‘Last written for or by Program A,’ or ‘Last written for or by Program B’ — using green, blue, and red respectively, for example — and running the programs at only a few steps per second so progress can be followed.’ Initially, I was a tad skeptical that a 144-element MARS would suffice but – having looked at the Redcode Beginner’s Guide – I’ve changed my mind. Now I’m thinking about creating a MARS simulator to run on the Seeeduino XIAO that I’m using to power my 12×12 array. I’m also thinking about creating a Redcode assembler utility that can generate the warrior programs to run on the simulator. But wait, there’s more! Do you remember me talking about the NeoPixel Simulator that you can use to test your own programs to run on my 12×12 array (PE, November 2020)? Well, if I manage to find the time to get a MARS simulator up and running, we could combine it with our NeoPixel Simulator, thereby allowing you to create and test your own Code War warrior programs and then send them to me to be run on the real array. return gammaCorrectedColor; Keep your balance const uint8_t GammaXref[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 10, 5, 6, 6, 6, 6, 7, 7, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68, 69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89, 90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 109, 110, 112, 114, 115, 117, 119, 120, 122, 124, 126, 127, 129, 131, 133, 135, 137, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 167, 169, 171, 173, 175, 177, 180, 182, 184, 186, 189, 191, 193, 196, 198, 200, 203, 205, 208, 210, 213, 215, 218, 220, 223, 225, 228, 231, 233, 236, 239, 241, 244, 247, 249, 252, 255 }; Fig.3. Gamma-correction cross-reference look-up table. uint32_t GetGammaCorrectedColor (uint32_t uncorrectedColor) { uint8_t tmpRed; uint8_t tmpGreen; uint8_t tmpBlue; uint32_t gammaCorrectedColor; tmpRed = GammaXref[ GetRed(uncorrectedColor) ]; tmpGreen = GammaXref[ GetGreen(uncorrectedColor) ]; tmpBlue = GammaXref[ GetBlue(uncorrectedColor) ]; } The rest of the sketch is used to load the left-hand side of the array with uncorrected colours directly from our colour wheel and the right-hand side with their gamma-corrected counterparts, starting with red at the bottom and ending with rose at the top (Fig.4). Although it’s not easy to see from this image, in the real world the gamma-corrected values do present what appears to be a richer colour palette. For example, the gamma-corrected orange (second row from the bottom) looks more orange and the gamma-corrected rose (top row) appears more vibrant. War, what is it good for? According to Edwin Starr in his 1970 hit single ‘War’ – and Frankie Goes to Hollywood more than a decade later – the answer is ‘Absolutely nothing.’ Of course, it may be that neither of these luminaries were familiar with the concept of ‘Code War’. Actually, if the truth be told, neither was I until my chum, Ken Wood, who has been following these columns, sent me an email telling me all about this idea. In 1984, Alexander Dewdney wrote a column in Scientific American magazine about a programming game called Core War that he had created with DG Jones. A scan of this original article, along with a lot of supporting material, can be found on the CoreWars.org website and Wikipedia. Fig.4. Uncorrected colours (left) vs. gamma-corrected colours (right). Fig.5. 9DOF BoB (Image source: Adafruit.com) Practical Electronics | January | 2021 When I was a kid, my parents bought me a wooden marble maze toy. I just found something quite similar on Amazon (https://amzn.to/2HwZg4M), although the one I owned had larger mazes and used smaller ball bearings. The reason I mention this here is that a reader emailed me to suggest I attach a sensor to my 12×12 array such that, if the array is held in a horizontal plane, I could control the ‘rolling’ of a lit pixel by detecting the tilt of the array. By some strange quirk of fate, I just happened to have one of Adafruit’s BNO055-based 9DOF (nine degrees of freedom) Fusion breakout boards (BOBs) in my treasure chest (junk box) of spare parts (Fig.5) (https://bit.ly/3dP8EwU). This little beauty is based on a BNO055 microelectromechanical system (MEMS) sensor from Bosch. In turn, the BNO055 contains a 3-axis accelerometer, a 3-axis gyroscope, and a 3-axis magnetometer (they also throw in a temperature sensor for good measure). The really cool thing about this device is that it also contains a 32-bit Arm Cortex M0+ processor, which performs all sorts of mindbogglingly complicated sensor algorithms for you and provides you with data in a form you can use without your brains leaking out of your ears. As usual, the folks at Adafruit provide a wealth of information on this sensor, including pinouts, wiring, and how to download the required libraries (https://bit.ly/35sVvpz). Also included is some sample Arduino Code, which I used to create my first test program. The purpose of this initial sketch was to make sure I could get my XAIO microcontroller to talk to the BNO055. All we do is loop around reading the x, y, and z orientation values from the BNO055 and display them as floating-point values on the Arduino’s Serial Monitor. Note that the XIAO communicates with the BNO055 via an I2C bus, which uses pins 5 and 6 on the XIAO, but we don’t declare these pins in our sketch because Adafruit’s libraries handle all of this for us (file CB-Jan21-02.txt). The next step involved some mental gymnastics to visualize how I was going to mount my breadboard in the 12×12 array case, and which (sensor) values corresponded to what (left-right and forward-backward) tilts. Eventually, I determined that the 59 Size does matter! y values from the sensor would reflect To paraphrase an old saying, ‘It’s not tilting the array to the left or right, while the size of your array, it’s what you do the z values from the sensor would rewith it that counts.’ In reality, of course, flect tilting the array to the front or back. we all know in our heart of hearts that Thus, my second test program involved size does indeed matter. If you have two my taking the floating-point y and z values people standing next to each other, one from the sensor and converting them into clutching a paltry array and the other integer tilt values for use in my sketch. staggering under the weight of a garganWith a little manipulation, I ended up tuan offering, which one do you think with an integer tiltLeftRight value the punters are going to be looking at? that ranges from −90 (tilted left so much ‘Great minds think alike,’ as they say. Of as to be vertical), through 0 (horizontal), course, they also say that ‘Fools seldom to +90 (tilted right so much as to be verdiffer,’ but I’m sure that doesn’t apply to tical). Similarly, I ended up with an inus. For example, a guy who goes under teger tiltFrontBack value that ranges the moniker ‘Bitluni’ created a 20×15 = from −90 (tilted down to the front – that Fig.6. The Prognostication Engine’s main 300 ping-pong ball display using tricois, to the user – so much as to be verticontrol panel. lour LEDs (https://bit.ly/3jmltjj). Somecal), through 0 (horizontal), to +90 (tilted time later, the attention-grabbing Bitluni to the back so much as to be vertical). In We’ve discussed some of the effects followed up with a 40×30 = 1200 ball this case, all we do is loop around readwe could employ with the switches and array (https://bit.ly/31Bv8g0). ing the y and z orientation values from pushbuttons in previous columns, so In an earlier column, when I was buildthe BNO055 and display them as my malet’s now turn our attention to the LEDs ing my 12×12 array, I noted that if I ever nipulated integer values on the Arduino’s associated with the pots. did this again, I would build 8×8 sub-arSerial Monitor (file CB-Jan21-03.txt). As an aside, the pots are motorised, rays and then link them together to form a Now things start to get more interestso if some unauthorised person were to larger array. Well, the over-achieving Biting. In our next sketch, we commence attempt to change the engine’s settings, luni is of like mind, because he recently by setting one of the pixels – our ‘ball’ as soon as they go ‘hands-off,’ the pots created a 48×40 = 1920 ball array using this – in the center of the array to white. We will automatically return to their offivery technique (https://bit.ly/3jrwKyV). then loop around using the readings cially designated positions under proI can think of so many things we could from the sensor to make this pixel ‘roll gram control. do with such an array. For example, can around’ in response to tilting the array. Remember that we are using 16-element you imagine using a machine vision system The ‘ball’ stops ‘rolling’ when it hits one NeoPixel rings from Adafruit (https://bit. based on artificial intelligence (AI) to of the sides or gets trapped in one of the ly/37RtFpQ). In front of each ring (Fig.7a) detect and recognize gestures as we wave corners until we tilt the array in the opwe have a brass bezel and an antique our arms around controlling a wall-size posite direction (file CB-Jan21-04.txt). Bakelite knob (Fig.7b). Mounted in the version of the game Tetris? All I can say For your delectation and delight, I just bezel, in front of each pixel, we have a is that I hope to meet up with the nefaricaptured a short video showing this prosmall pseudo-mother-of-pearl ‘dot’ which ous Bitluni one day (and appropriate his gram in action (https://bit.ly/3mXHZS3). adds to the steampunk look-and-feel. wall-sized array while he’s not looking). Of course, this is only the beginning. Since we have 16 pixels, we can considCurrently, the ‘ball’ simply ‘rolls’ at a coner each as spanning (or representing) an stant rate once the tilt has passed a certain arc of 360°/16 = 22.5°. Now, different pots Prognostication revisited threshold. The next step will be to add have different physical ranges for how far I don’t know if you recall (I can barely some physics into the mix such that the they can rotate. The ones I’m using support remember myself), but this entire saga speed of the ‘roll’ varies as a function of rotations of 290°, which means there are commenced with my wishing to illuthe angle of the tilt. three pixels to which the pointer on the minate the controls on my PedagogiAfter that, we are limited, as usual, only knob cannot, in fact, point (Fig.8). cal and Phantasmagorical Inamorata by our own imaginations. For example, we Of course, although these pixels are Prognostication Engine. In addition to could make green ‘food’ pixels randomly shown as being dark gray in the figure, the lighting the furnace in the upper conappear on the array and then try to guide fact that we can’t point to them doesn’t trol panel and the ginormous vacuum our rolling pixel to hit them and ‘eat’ them mean we can’t light them up. One option tubes sitting on top of the engine, the before they randomly disappear again. The would be to simply paint the white line main control panel features eight toggle more you ‘eat,’ the more points you get. and dot on the knob black, and then map switches and six pushbuttons, each of Also, we could add red ‘hole’ pixels into (translate) the 290° rotation of the knob which is accompanied by two tricolour which our rolling pixel would ‘fall’ if they into a 360° range on the ring. LEDs. Also, there are five potentiometers were to come into contact (these ‘hole’ However, I like the white line and dot (pots), each surrounded by a ring of 16 pixels could be stationary, or we could on the knob. We could just turn the three tricolour LEDs (Fig.6). make them randomly appear and disappear like the ‘food’ pixels). We could come up with all sorts of cool games based on this technology if we put out heads together. Speaking of which, if you think of anything, please ( a) Neopix el ring f rom A daf ruit ( b ) W ith b ez el and k nob ( a) K nob rotated f ully anticlock wise ( b ) K nob rotated f ully clock wise drop me an email and Fig.7. 16-pixel rings. Fig.8. The rotation of the knob. share the good word. 60 Practical Electronics | January | 2021 6 1 pixels at the bottom off, but where would 5 7 2 0 W hat we’ v e got be the fun in that? My solution will be to 8 4 3 15 W hat we want use a separate colour for these three pixels. 3 9 4 14 New P ix el O ld P ix el C alculation Initially this will just be a steady colour, but 0 4 ( 0 + 4 ) % 5= 4 it may be that later we use different colours, 13 2 10 5 1 0 (1+ 4 ) % 5= 1 fades, and flashes on these three pixels to 2 1 (2+ 4 ) % 5= 1 3 2 (3+ 4 ) % 5= 2 provide us with additional information 6 12 1 11 4 3 (4 + 4 ) % 5= 3 about the state of the machine. 11 0 12 7 W hat we’ v e got The way I want to visualise things is 15 13 8 10 Num b er of pix els - 1 9 14 with pixels 0 and 12 corresponding to Modulo operator ( a) W hat I want ( b ) W hat I got the maximum anticlockwise and clockNum b er of pix els wise rotations of the knob, respectively Fig.9. You can’t always get what you want. W hat we want (Fig.9a). However, the way in which I creFig.10. Thought experiment with 5-pixel ring. ated my prototype resulted in the pixels being presented in a different manner (Fig.9b). Still prognosticating furiously To be honest, I don’t recall how the rings are oriented on Although lighting the pixels the way we’ve just done won’t form the main Prognostication Engine, but it really doesn’t matter part of the Prognostication Engine’s primary function, it helps because we are going to perform a simple cross-reference opus to wrap our brains around some of the nitty-gritty details, eration, and we can easily modify the cross-reference values and we will be able to use all of this stuff as part of a flamboylater. In the case of our prototype, we will declare our crossant power-up display. reference values as follows: In this vein, suppose we want to modify our previous program such that we have only a single pixel lit at any one time. int RingXref[NUM_NEOS_RING] = In this case, when we turn our new pixel on, we also want to {7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8}; turn the previous pixel off. Remembering that we are cycling the pointer to our pixels, iNeo, from 0 to 15, we would ideThe way this works is really simple, if we want to light what ally like to modify our core for() loop do something like we like to think of as pixel i in our imaginary world, we will the following (the new code is shown in bold): access RingXref[i], which will return the number of the corresponding pixel in the real world; for example, RingXref[0] for (int iNeos = 0; iNeos < NUM_NEOS_RING; iNeos++) will return 7 (tra-la!). { So, just to illustrate where we’re at thus far, what we are // Turn the new pixel on going to do is create a simple sketch that lights our pixels tmpNeo = RingXref[iNeos]; from 0 to 15, first red, then blue, then green, then start all NeosRing.setPixelColor(tmpNeo, tmpColor); over again. Since these LEDs are so bright, we’re going to add a ModifyBrightness() function that will dim them down // Turn the old pixel off to a specified percentage of their full value, which will allow tmpNeo = iNeos – 1; us to keep our original colour definitions as-is. The heart of tmpNeo = RingXref[tmpNeo]; this program is a function called LightMultiple(), which NeosRing.setPixelColor(tmpNeo, COLOR_BLACK); we will call from our loop() function (file CB-Jan21-05.txt). NeosRing.show(); void LightMultiple (uint32_t thisColor) delay(InterPixelPadDelay); { } int tmpNeo; uint32_t tmpColor; This would work great for every value of iNeo except 0 because 0 – 1 = –1, which will cause our program to do sometmpColor = ModifyBrightness(thisColor, BRIGHTNESS); thing excruciatingly painful when we attempt to use this value as an index into RingXref[]. It’s always the ‘end conditions’ for (int iNeos = 0; iNeos < NUM_NEOS_RING; iNeos++) that bite you when you are least expecting it. One alternative { would be to add a test for this end condition as shown below: tmpNeo = RingXref[iNeos]; NeosRing.setPixelColor(tmpNeo, tmpColor); for (int iNeos = 0; iNeos < NUM_NEOS_RING; iNeos++) NeosRing.show(); { delay(InterPixelPadDelay); // Turn the new pixel on } tmpNeo = RingXref[iNeos]; } NeosRing.setPixelColor(tmpNeo, tmpColor); As you can see, we first modify the brightness of the colour (I’ve cut things down to only 20% for this experiment, and they are still bright). Next, we cycle round lighting each of our pixels, using our RingXref[] to cross-reference the pixel numbers, upload the new values, and pause for a short delay that we’ve called InterPixelPadDelay. If you look at the code, you’ll see that I’ve defined a CYCLE_TIME of one second. Also, I’m assuming that it takes only 1ms (one millisecond, represented by CALC_UPLOAD_DELAY) to perform all my calculations and upload the new values. If you look at the setup() function, you’ll see how we used these values, along with the number of pixels in the ring, to calculate the InterPixelPadDelay. Practical Electronics | January | 2021 // Turn the old pixel off if (iNeos == 0) tmpNeo = 15; else tmpNeo = iNeos – 1; tmpNeo = RingXref[tmpNeo]; NeosRing.setPixelColor(tmpNeo, COLOR_BLACK); NeosRing.show(); delay(InterPixelPadDelay); } Now, although this would be a perfectly acceptable solution, it still feels a bit ‘graunchy,’ if you know what I mean. What I usually do in this sort of case is perform thought experiments 61 5 6 5 7 10 2 11 1 12 0 15 14 13 ( a) Using a single pix el 7 8 9 3 9 3 6 4 8 4 10 2 11 1 12 0 15 14 13 ( b ) Using m ultiple pix els Fig.11. Two ways to reflect the position of the knob. with pencil and paper. The first thing is to reduce the scope of the problem to a smaller number of pixels. Our original ring contains 16 pixels, which is an even number and a power of two (2^4 = 24). Given a choice, we want to come up with a generic solution that can work for any number of pixels, so we will play with a non-power of two. Furthermore, for this sort of thing, I prefer an odd number and a prime number on the basis that, if our solution works for this, it will work for anything. So, purely for this thought experiment, let’s assume that we have a 5-pixel ring. I start by drawing out a table (Fig.10). My first column lists what we’ve got (ie, what we know in the form of the information we have to hand), which is the number of the new pixel we’re going to turn on. The next column lists what we want, which is the number of the old pixel we want to turn off. I then dork around with various equations until I come up with a calculation that satisfies my needs. In this case, a simple calculation using the modulo operator % satisfies our requirements (this operator returns the integer remainder from an integer division). At this point, I transferred the equivalent over to my real-world code (file CB-Jan21-06.txt). Now, our programs thus far have involved lighting our pixels in a clockwise fashion. Just for giggles and grins, let’s suppose we want to modify our most recent sketch such that it lights the pixels in a widdershins (anticlockwise) pattern. Can you create your own table to determine the necessary calculation? – you can check out my solution in file CB-Jan21-07.txt Turning the knob Finally, for the moment, let’s consider how we are going to translate the turning of the knob, which we read via our potentiometer, into the lighting of the pixels in our ring. Remember that we’ve decided not to access the bottom three pixels, which we will light magenta. Let’s assume that our On colour will be yellow and our Off colour will be red. Two main possibilities immediately spring to mind. The first is that we could light a single pixel to indicate the position of 62 Fig.12. Steve Manley’s array of ten 21-segment displays. the pot (Fig.11a). The second is that we could light multiple pixels to indicate the position of the pot (Fig.11b). You can take a look at my programs for both of these implementations in files CB-Jan21-08.txt and CB-Jan21-09.txt, respectively. You will observe that I’ve also added the gamma correction we introduced earlier into these final two sketches. Also, I just created a short video that shows all of the effects we’ve discussed here in action (https://bit.ly/360O2hw). 21-Segment Victorian Displays Do you remember watching Monty Python when they said, ‘And now for something completely different’? Well, hold onto your hat because here we go. Way back in 1898 (123 years ago as I pen these words), someone called George Lafayette Mason filed a patent for a 21-segment display. These devices used 21 small incandescent bulbs (one per segment) to create letters, numbers, and symbols. A complicated electromechanical switch could be used to activate various groups of segments as required to represent the different characters. The way I heard about this is that I have some friends (stop laughing; it’s true) called Steve Manley and Paul Parry, where Paul is the owner of Bad Dog Designs (https://bit.ly/2FTSBBk). Paul and Steve ran across a group called Smartsockets (https://bit.ly/2HOeFhw), which was founded by Chris Barron and is moderated by Chris and John Smout. In fact, it was John who came up with the idea of resurrecting these displays, but John and Chris are focused on their Smartsocket implementations in which each display has its own PIC microcontroller. By comparison, Paul, Steve, and myself prefer to drive all of our displays with a single Arduino-compatible microcontroller. As a result, the two sub-groups are heading in slightly different implementation directions, although they still communicate what they are doing with each other. Steve has done a tremendous amount of work creating the circuit boards and 3D printed shells for these displays (Fig.12). Steve, Paul, and I each have ten of these displays, although I’ve not had the time to do anything with mine thus far. In fact, Steve has created a fantastic video that illustrates everything he’s done in exquisite detail (https://bit.ly/3oJwZcm). As we see in this image, Steve has used his 3D printer to make a pseudo-brass faceplate for his display. In my case, Paul introduced me to one of his friends, Kevin McIntosh. Kevin’s company, the Laser Hut (https://bit.ly/2Gf8qmg) offers laser cutting and engraving services, and he’s going to laser my pseudo-brass faceplates for me. I will, of course, be documenting all of this in excruciating detail in future columns. Coming soon As I’ve been known to say on occasion, ‘Show me a flashing LED and I’ll show you a man drooling’ (hence the title of this miniseries). When we first started discussing the topic of flashing LEDs and drooling engineers (PE, March 2020), I really had no idea as to the myriad topics into which we were going to stick our snouts. In reality, of course, we’ve barely scratched the surface of this multifaceted topic, but I hope that the stuff we have covered has sparked your imagination and tempted you to toy with your own creations. In the not-so-distant future, we’re going to take a break from LEDs and turn our attention to other topics, but turn that frown upside down and turn it into a smile, because that time is not yet come. Next month, for example, we will be using our 12×12 array to implement a version of Conway’s Game of Life – see: https://bit.ly/pe-jan21-cgol Until then, as always, I welcome your questions, comments, 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 Practical Electronics | January | 2021