Silicon ChipKickStart - October 2023 SILICON CHIP
  1. Outer Front Cover
  2. Contents
  3. Subscriptions: PE Subscription
  4. Subscriptions
  5. Back Issues: Hare & Forbes Machineryhouse
  6. Publisher's Letter: Time for some new PICs
  7. Feature: Holy Spheres, Batman! by Max the Magnificent
  8. Feature: Net Work by Alan Winstanley
  9. Project: Automatic Level Crossing and Semaphore Control by LES KERR
  10. Project: Multi-Stage Buck-Boost Battery Charger by Tim Blythman
  11. Project: PIC & AVR Chips from Microchip by Tim Blythman
  12. Project: PIC AND AVR Breakout Boards by Tim Blythman
  13. Feature: Arduino Bootcamp – Part 10 by Max’s Cool Beans
  14. Feature: AUDIO OUT by Jake Rothman
  15. Feature: KickStart by Mike Tooley
  16. Feature: Circuit Surgery by Ian Bell
  17. PCB Order Form
  18. Advertising Index by Ian Batty

This is only a preview of the October 2023 issue of Practical Electronics.

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

Articles in this series:
  • (November 2020)
  • Techno Talk (December 2020)
  • Techno Talk (January 2021)
  • Techno Talk (February 2021)
  • Techno Talk (March 2021)
  • Techno Talk (April 2021)
  • Techno Talk (May 2021)
  • Techno Talk (June 2021)
  • Techno Talk (July 2021)
  • Techno Talk (August 2021)
  • Techno Talk (September 2021)
  • Techno Talk (October 2021)
  • Techno Talk (November 2021)
  • Techno Talk (December 2021)
  • Communing with nature (January 2022)
  • Should we be worried? (February 2022)
  • How resilient is your lifeline? (March 2022)
  • Go eco, get ethical! (April 2022)
  • From nano to bio (May 2022)
  • Positivity follows the gloom (June 2022)
  • Mixed menu (July 2022)
  • Time for a total rethink? (August 2022)
  • What’s in a name? (September 2022)
  • Forget leaves on the line! (October 2022)
  • Giant Boost for Batteries (December 2022)
  • Raudive Voices Revisited (January 2023)
  • A thousand words (February 2023)
  • It’s handover time (March 2023)
  • AI, Robots, Horticulture and Agriculture (April 2023)
  • Prophecy can be perplexing (May 2023)
  • Technology comes in different shapes and sizes (June 2023)
  • AI and robots – what could possibly go wrong? (July 2023)
  • How long until we’re all out of work? (August 2023)
  • We both have truths, are mine the same as yours? (September 2023)
  • Holy Spheres, Batman! (October 2023)
  • Where’s my pneumatic car? (November 2023)
  • Good grief! (December 2023)
  • Cheeky chiplets (January 2024)
  • Cheeky chiplets (February 2024)
  • The Wibbly-Wobbly World of Quantum (March 2024)
  • Techno Talk - Wait! What? Really? (April 2024)
  • Techno Talk - One step closer to a dystopian abyss? (May 2024)
  • Techno Talk - Program that! (June 2024)
  • Techno Talk (July 2024)
  • Techno Talk - That makes so much sense! (August 2024)
  • Techno Talk - I don’t want to be a Norbert... (September 2024)
  • Techno Talk - Sticking the landing (October 2024)
  • Techno Talk (November 2024)
  • Techno Talk (December 2024)
  • Techno Talk (January 2025)
  • Techno Talk (February 2025)
  • Techno Talk (March 2025)
  • Techno Talk (April 2025)
  • Techno Talk (May 2025)
  • Techno Talk (June 2025)
Items relevant to "Stewart of Reading":
  • Bookshelf Speaker Passive Crossover PCB [01101201] (AUD $10.00)
  • Bookshelf Speaker Subwoofer Active Crossover PCB [01101202] (AUD $7.50)
  • Bookshelf Speaker Passive and Active Crossover PCB patterns (PDF download) [01101201-2] (Free)
  • Bookshelf Speaker System timber and metal cutting diagrams (PDF download) (Panel Artwork, Free)
Articles in this series:
  • Easy-to-build Bookshelf Speaker System (January 2020)
  • Building the new “bookshelf” stereo speakers, Pt 2 (February 2020)
  • Building Subwoofers for our new “Bookshelf” Speakers (March 2020)
  • Stewart of Reading (October 2023)
  • Stewart of Reading (November 2023)
  • ETI BUNDLE (December 2023)
  • Active Subwoofer For Hi-Fi at Home (January 2024)
  • Active Subwoofer For Hi-Fi at Home (February 2024)
KickStart by Mike Tooley Part 13: Using low-cost colour LCD displays with the Raspberry Pi Pico Our occasional KickStart series aims to show readers how to use readily available low-cost components and devices to solve a wide range of common problems in the shortest possible time. Each of the examples and projects can be completed in no more than a couple of hours using ‘off-the-shelf’ parts. As well as briefly explaining the underlying principles and technology used, the series will provide you with a variety of representative solutions and examples, along with just enough information to be able to adapt and extend them for their own use. This thirteenth instalment shows you how to add a low-cost colour LCD to your Raspberry Pi Pico microcontroller-based projects. Using IPS and TFT technology, these inexpensive devices can really bring your project to life; providing you with a A quick trawl through back issues of PE will reveal that simple microcontroller projects can often be built using nothing more than a few sensors and a couple of LED indicators. However, when things get a bit more complex there’s a need for a better way of displaying information and, while this can be achieved using a simple 16×2 or 20×4-character alphanumeric display, there’s now a range of highly affordable colour LCD modules that offer a much more flexible and attractive solution. Using the appropriate driver software these displays are delightfully easy to use and programming couldn’t be simpler. For example, to display a line of yellow text against a red background you would just need to include these statements in your code: LCD.fill(LCD.RED) LCD.text("CPU TEMPERATURE",6,16,LCD.YELLOW) To display a blue rectangle containing white text you could use: LCD.fill_rect(0,40,160,20,LCD.BLUE) LCD.text("Pico-LCD-1.8",2,48,LCD.WHITE) Display types and technologies Two closely related technologies are used in low-cost colour LCD displays. They are TFT (thin-film transistor) and IPS (inplane switching). Modern, cost-effective TFT displays offer good efficiency coupled with compact dimensions, while more complex IPS displays provide improved colour reproduction coupled with wider viewing angles. Fig.13.1. Colour bars displayed on the Waveshare 1.8-inch colour LCD. 54 means of displaying prompts, messages and colour graphics, as well as adding touchscreen buttons that will let you interact with the Pico. To show you just how easy these modules are to use, we will take you step-by-step through the design and coding of a useful audio application for a microcontroller in the form of an analogue recording level indicator. Unlike OLED displays, TFT and IPS displays are transmissive and thus require a separate back-light source. The intensity (or brightness) of the display can be controlled by setting the duty cycle of the waveform applied to the backlight. This can be a useful feature when a display is to be used in situations where there can be wide variations in ambient light. Several manufacturers have responded to the need for lowcost TFT displays capable of interfacing with today’s popular microcontrollers with the necessary driver and serial peripheral interface (SPI) incorporated into a range of ‘backpack’ modules. Those currently available from Waveshare (based on TFT and IPS technologies) are summarised in Table 13.1, so you need look no further if you need a colour LCD for use with your Raspberry Pi Pico (RPi Pico). The colour LCD selected for use in our sample application (see later) is the Waveshare 1.44-inch module. This low-cost display offers the following specification: n6 4K RGB colours n1 28 × 128 pixels (0.2mm pixel size) nS PI four-wire microcontroller host interface n I nterconnection compatibility with the RPi Pico via an onboard female pin header. nE mbedded ST7735S display driver Fig.13.2. The 1.8-inch colour LCD module attaches neatly to the rear of the RPi Pico. Practical Electronics | October | 2023 Table 13.1 Waveshare low-cost colour LCD modules Display Type Colours Pixels Dimensions Interface Driver Board size (mm) Pico-LCD-0.96 IPS 65K 160×80 21.70×10.80 SPI ST7735S 52.00×25.00 Pico-LCD-1.14 IPS 65K 240×135 24.91×14.86 SPI ST7789 52.00×25.00 Pico-LCD-1.3 IPS 65K 240×240 23.40×23.40 SPI ST7789 52.00×26.50 Pico-LCD-1.44 TFT 65K 128×128 25.50×26.50 SPI ST7735S 52.00×26.50 Pico-LCD-1.8 TFT 65K 160×128 35.04×28.03 SPI ST7735S 52.00×34.50 Pico-LCD-2 IPS 65K 320×240 40.80×30.60 SPI ST7789VW 52.00×35.00 Pico-ResTouch-LCD-2.8 IPS 262K 320×240 57.60×43.20 SPI ST7789 70.20×50.20 Pico-ResTouch-LCD-3.5 IPS 65K 480×320 73.44×48.96 SPI ILI9488 86.00×57.20 nO perating voltage over the range 3.15V to 5V nO verall dimensions 52.0 × 30.0mm nC /C++ and MicroPython development resources nF our configurable buttons for user input. Connecting to the RPi Pico The 1.44-inch Waveshare LCD modules require connection to the Pico’s supply as well as a subset of its I/O lines. The 1.44-inch module needs to access the following Pico pins: GP8 to GP13 for SPI (see Fig.13.3) together with GP2, GP3, GP15 and GP17 if you wish to make use of the four user-definable button keys. This still leaves plenty of connectivity available for other external hardware (all unmarked pins shown on Fg.13.3 remain available for use. Table 13.2 summarises the required connections and corresponding signal functions for the 1.44-inch module. Note that these connections are all made for you when the backpack module is attached to the Pico. Thus, if you’ve already fitted headers to your RPi Pico then there’s no need for any additional soldering or wiring. Using colour Before we launch into the subject of colour handling, it is important to be aware that display data is assembled and held in a memory buffer before it is sent to the LCD. Each time the display needs updating the relevant commands must be followed by lcd.show(). If you fail to include lcd. show() in your code nothing new will appear on screen. This is an important point which can be easily forgotten. In your code, colour can be expressed in various ways, but for most purposes a 16-bit hexadecimal value is convenient. For example, the display background colour can be set using the LCD.fill() command. This command accepts a single parameter used to determine the background colour. The colour parameter is a 16-bit value with hexadecimal values in the range 0000 to FFFF. As an example, LCD.fill(0x0000) (or simply LCD. fill(0)) is used to set a white background whereas LCD.fill(0xFFFF) is used to set a black background. Practical Electronics | October | 2023 Fig.13.3. Pico pins required for the Waveshare 1.44-inch colour LCD module. Unfortunately, using Table 13.2 Wiring to the RPi Pico for a Waveshare hexadecimal values to 1.44-inch LCD module specify red, green and blue RPi Pico LCD Function (RGB) colour intensities can sometimes be a little VSYS VSYS Power supply (3.15 to 5V) tricky. The Waveshare GND GND Ground/0V modules use a clever coding GP2 KEY_2 User key 2 scheme designed to reduce memory overhead. In this GP3 KEY_3 User key 3 scheme, three-byte colour Data/command (high for values (24-bits per pixel) GP8 LCD_DC data, low for command) are reduced to two-bytes (16-bits) thus reducing the GP9 LCD_CS Chip select (active low) memory overhead by 33%. GP10 LCD_CLK SPI clock Since the human eye is GP11 LCD_DIN SPI data more sensitive to green light than other colours of the GP12 LCD_RST Reset (active low) spectrum (red and blue) we GP13 LCD_BL LCD backlight can use six of the available 16-bits to represent green GP15 KEY_0 User key 0 and five of the remaining GP17 KEY_1 User key 1 bits to represent each of the remaining colours (red and blue). Thus 64 possible levels of green Do note that the RGB colour data used are possible and 32 levels for both red for each pixel in the display is stored in and blue. a way that might not seem very logical 55 Fig.13.4. Two different ways of storing the same RGB colours. at first sight. This is compounded by the fact that different displays may exhibit different coding schemes compared to the 1.44-inch and 1.8-inch modules used here. Their colour data may be in a different sequence, thus necessitating a different set of colour values to represent identical colours on two different modules. Figs.13.4 and 13.5 illustrate this anomaly. Providing you pay attention to this you will be fine – just do be aware that colour coding is not a ‘one-size fits all’. Naming the colours Although low-cost TFT displays can display a huge range of colours, a smaller range is perfectly adequate for most applications and rather than having to remember hexadecimal values it’s useful to refer to those most frequently used by name. The following code fragment defines the author’s 16 preferred colours for use with the Waveshare 1.44-inch LCD display module, but the names/ values that you use for your own colours is entirely up to you. # Define 16 colour values for the 1.44-inch LCD module self.CYAN = 0xE0FF self.BLACK = 0x0000 self.BLUE = 0x00F8 self.MAGENTA = 0x1FF8 self.GREY = 0x1084 self.GREEN = 0x0004 self.LIME = 0xE007 self.MAROON = 0x1000 self.NAVY = 0x0080 self.OLIVE = 0x1004 self.PURPLE = 0x1080 self.RED = 0x1F00 self.SILVER = 0x18C6 self.TEAL = 0x0084 self.WHITE = 0xFFFF self.YELLOW = 0xFF07 Other ways to express colour data It’s useful to have some means of converting colour data from one format to another. 24-bit colour data (occupying three bytes) is often referred to as RGB888 because 8-bits are used to represent each of the three colours. Instead of using 24-bit hexadecimal values it can sometimes be handy to employ decimal numbers (referred to as RGB dec.). The Fig.13.5. Format of the 16-bit colour data used for the 1.44-inch and 1.8inch Waveshare LCD modules (note the different hexadecimal values used for identical colours). 56 Practical Electronics | October | 2023 16-bit representation (with just two bytes mentioned earlier) is referred to a RGB565. Table 13.3 shows how 16 of the most commonly used colours can be expressed in different formats. Converting RGB colour values To help with the conversion of RGB dec colours to RGB565 hex colours we’ve provided some simple Python utilities for both the 1.44-inch and 1.8-inch displays. These can be downloaded from the PE website (see Going further). These utilities are simple to use but an example might help. Let’s assume that you need to display a gold colour (corresponding to 255, 202, 0 in RGB888 dec) on the Waveshare 1.44-inch module. If you enter these values into our colour code application, you will find that the required RGB565 hex data is 5F06. You could then define this new colour as: LCD.GOLD = 0x5F06 Alternatively, just include it earlier in the driver’s list of colour definitions as: self.GOLD = 0x5F06 It really is that simple. Controlling the display intensity As briefly mentioned earlier, the intensity or brightness of the display can be adjusted by varying the duty cycle of the pulse-width modulated (PWM) signal applied to the display. This is achieved by means of the pwm. duty_u16() command. The parameter passed by this command can take any value between 0 and 65535 (or 0xFFFF in hexadecimal), with the largest value corresponding to maximum brightness. Listing 1 shows how the intensity of a display can be reduced from maximum to zero and vice versa. The code assumes that you have imported the required libraries (Pin and u t i m e ) and that the colour definitions for LCD.RED and LCD.CYAN have been included in your driver code (see Going further). Display layout Before you attempt to design a layout for your LCD it is important to be aware of the parameters that you will be working with. Taking the 1.44-inch LCD as an example, this comprises a 128×128 matrix of individual pixel elements. Individual pixels can be identified by referring to their column (x-axis) and row (y-axis) position. Thus, the Table 13.3 Comparison of colour values Colour (Note 1) RGB888 hex (24-bit) RGB dec (24-bit) RGB565 hex (16-bit) (Note 1) LCD colour name (Note 2) Aqua 0x00FFFF 0,255,255 0xFF07 LCD.AQUA Black 0x000000 0,0,0 0x0000 LCD.BLACK Blue 0x0000FF 0,0,255 0x1F00 LCD.BLUE Fuchsia 0xFF00FF 255,0,255 0x1FF8 LCD.FUCHSIA Gray 0x808080 128,0,128 0x0F78 LCD.GRAY Green 0x008000 0,128,0 0xE003 LCD.GREEN Lime 0x00FF00 0,255,0 0xE007 LCD.LIME Maroon 0x800000 128,0,0 0x0078 LCD.MAROON Navy 0x000080 0,0,128 0x0F00 LCD.NAVY Olive 0x808000 128,128,0 0xE07B LCD.OLIVE Purple 0x800080 128,0,128 0x0F78 LCD.PURPLE Red 0xFF0000 255,0,0 0x00F8 LCD.RED Silver 0xC0C0C0 192,192,192 0xF7BD LCD.SILVER Teal 0x008080 0,128,128 0xEF03 LCD.TEAL White 0xFFFFFF 255,255,255 0xFFFF LCD.WHITE Yellow 0xFFFF00 255,255,0 0x1FF8 LCD.YELLOW Notes: 1. Values are shown for the Waveshare 1.8-inch LCD module 2. Colour names can vary. Listing 13.1. Fading the display # Fade the display LCD.fill(LCD.RED) # Red background LCD.text("Fading >>>>",16,48,LCD.WHITE) pwm = PWM(Pin(BL)) pwm.freq(1000) intensity = 0xFFFF # Start with maximum brightness for i in range(16): # Fade out pwm.duty_u16(intensity) intensity -= 0x0FFF LCD.show() utime.sleep(0.25) for i in range(16): # Fade in pwm.duty_u16(intensity) intensity += 0x0FFF LCD.show() utime.sleep(0.25) # Finished notification pwm.duty_u16(0xFFFF) LCD.fill(LCD.BLACK) LCD.text("Finished!",24,48,LCD.WHITE) LCD.show() Fig.13.6. (left) Screen template for the 1.44-inch colour LCD. Fig.13.7. (right) Screen template for the 1.8-inch colour LCD. Practical Electronics | October | 2023 57 Listing 13.2. Scrolling text # Scroll a message def scroll(my_string,xpos,ypos,colour): x = 0 while x < len(my_string): char = my_string[x] LCD.text((my_string)[x],xpos,ypos,colour) LCD.show() utime.sleep(0.2) x += 1 xpos = xpos + 8 # Scroll wait message x = 0 xpos = 0 ypos = 16 scroll("Please wait >>>",8,48,LCD.WHITE) utime.sleep(4) # Finished notification pwm.duty_u16(0xFFFF) LCD.fill(LCD.BLACK) LCD.text("Finished!",24,48,LCD.WHITE) LCD.show() Fig.13.10. Circuit of the signal level detector. coordinates of the pixel at the top left of the screen (column 0, row 0) are (0,0) and to set this pixel to white (0xFFFF) you could use: LCD.pixel(0,0,0xFFFF) # Top left corner pixel to white Similarly, to set the pixel at the exact centre (64,64) of the 1.44-inch LCD to black you could use: LCD.pixel(64,64,0x0000) # Centre pixel to black Since the 1.44-inch display uses 128×128 pixels the total number of pixels available is 16,384. With two bytes of colour data allocated to each pixel the memory required for storing screen data will thus be 32,768 bytes. To assist you with your own screen layouts we’ve provided templates for the 1.44-inch and 1.8-inch LCD. We’ve also made these available as a PDF so that you can download and print them (see Going further). Fig.13.8. Selecting Thonny’s Options sub-menu from the main menu bar. Displaying text The low-cost LCD modules use an 8×8 font so each character displayed requires 64 pixels. With a 1.44-inch LCD up to 16 characters can appear in a single line of text, but with a 1.8-inch module this increases to a maximum of 20 characters. For example, to display ‘Hello Pico World’ in white text starting at the top left corner of the screen (0,0) you could use: LCD.text("Hello Pico World",0,0, LCD.WHITE) These 16 characters will exactly fill the top line of a 1.44-inch display. Notice in this example that we’ve used a colour value that we’ve previously defined (LCD. WHITE) but instead we could have used: LCD.text("Hello Pico World",0,0, 0xFFFF) Fig.13.9. Interpreter and USB port selection. 58 Scrolling your text Text can easily be made to scroll across the display – see Listing 2. Practical Electronics | October | 2023 Lines and rectangles Lines and rectangles can be easily created, as in the following examples: 1. Draw a 1-pixel yellow line from (32,32) to (64,96) LCD.line(32,32,64,96,LCD.YELLOW) 2. Draw a red rectangle starting at (16,16) with a width of 96 and a height of 16 pixels LCD.rect(16,16,96,16,LCD.RED) 3. Draw a green-filled rectangle starting at (0,48) with a width of 112 and a height of 16 pixels LCD.fill_rect(0,48,112,16,LCD. GREEN) Further examples (appropriately commented) can be downloaded from the PE website (see Going further). User keys The Waveshare 1.44-inch display has the added bonus of providing you with four key buttons that can be given user-defined functions. These buttons (key0 to key3) are accessible from GP2, GP3, GP15 and GP17 and the keys can be defined using code along the following lines: # Set up buttons key0 = Pin(15,Pin.IN,Pin.PULL_UP) key1 = Pin(17,Pin.IN,Pin.PULL_UP) key2 = Pin(2 ,Pin.IN,Pin.PULL_UP) key3 = Pin(3 ,Pin.IN,Pin.PULL_UP) Notice that the four key buttons are active in the low state and have thus been given pull-up resistors using Pin.PULL_UP. Once defined, the state of the four keys can be interrogated. Listing 3 is a complete example of how to perform some typical key functions with the results displayed on the LCD. It is available for download from the PE website (see Going further). A recording level indicator using the RPi Pico To conclude and to put this month’s KickStart into context, we will show you how a humble RPi Pico can be used with a 1.44-inch colour LCD module and be used to as an analogue recording level indicator. Traditionally, this task would have required dual moving coil meters, one for the left and one for the right channel. However, a colour LCD is well suited to the task because its appearance and behaviour can be easily customised using just a few lines of code. If you don’t already have a coding environment installed, you will need to get hold of a copy of Thonny (see Going further). Instructions for installing and running Thonny with the RPI Pico appeared in PE for May 2022 (see Going further). Simply connect the USB cable and then select Tools and Options from Practical Electronics | October | 2023 Listing 3. Temperature indicator # Set up the analogue input and temperature sensor channels analog_input = machine.ADC(26) # Pico's GP26 is mapped to ADC0 sensor_temp = machine.ADC(4) # Pico's temperature sensor start = utime.ticks_ms() def handle_key1(): # Read data from the analogue input data = analog_input.read_u16() # Convert the data to voltage # and display the result LCD.fill(LCD.BLUE) LCD.text("ANALOGUE INPUT",6,16,LCD.YELLOW) LCD.text("ADC(0)",40,32,LCD.YELLOW) LCD.line(0,56,127,56,LCD.YELLOW) LCD.text(str(convert_voltage(data)) + " V",20,64,LCD.WHITE) LCD.line(0,80,127,80,LCD.YELLOW) LCD.show() utime.sleep(2) LCD.fill(0) def handle_key2(): now = utime.ticks_ms() elapsed = utime.ticks_diff(now, start) LCD.fill(LCD.NAVY) LCD.text("ELAPSED TIME",18,16,LCD.YELLOW) LCD.line(0,56,127,56,LCD.YELLOW) LCD.text(str(elapsed) + " ms",32,64,LCD.WHITE) LCD.line(0,80,127,80,LCD.YELLOW) LCD.show() utime.sleep(2) LCD.fill(0) def handle_key3(): LCD.fill_rect(0,0,16,128,LCD.RED) LCD.fill_rect(16,0,32,128,LCD.BLUE) LCD.fill_rect(32,0,48,128,LCD.LIME) LCD.fill_rect(48,0,64,128,LCD.YELLOW) LCD.fill_rect(64,0,80,128,LCD.CYAN) LCD.fill_rect(80,0,96,128,LCD.MAGENTA) LCD.fill_rect(96,0,112,128,LCD.MAROON) LCD.fill_rect(112,0,128,128,LCD.PURPLE) LCD.show() utime.sleep(2) LCD.fill(0) def get_temperature(): reading = sensor_temp.read_u16() * 0.0000504 temperature = 27 - (reading - 0.706)/0.001721 temperature = round(temperature, 2) return temperature def convert_voltage(data): voltage = (data - 336) * (3.3 / 65198) return voltage the Thonny’s menu bar (see Fig.13.8). Next, select the RPi Pico interpreter and the appropriate USB port (see Fig.13.9). It’s best to start with some of the sample code that we’ve provided from the PE website (see Going further). Transfer the code to the directory of your choice, open it in Thonny and then click on the ‘Run’ icon (the green circled arrow). The recording level indicator uses two of the Pico’s analogue channels, ADC0 and ADC1. These need to be fed with the outputs of a simple detector arrangement which converts a lowlevel audio signal to a peak DC level (see Fig.13.10). The components can be assembled using a small piece of stripboard. Layout and wiring are not especially critical, but unless the audio inputs are kept reasonably short then it 59 Listing 4. Recording level indicator # Recording level indicator LCD.fill(0) # Clear the LCD to black LCD.show() scale = 184 # Scale factor for adjusting signal level delay = 0.1 # 100 ms delay between readings while True: # Left and right pointer positions left_input = machine.ADC(26) # Pico's GPIO GP26 is mapped to ADC0 right_input = machine.ADC(27) # Pico's GPIO GP27 is mapped to ADC1 left_data = left_input.read_u16() right_data = right_input.read_u16() lpos = int(left_data / scale) # Convert float to int rpos = int(right_data / scale) # Meter legend LCD.text("RECORD LEVEL",16,8,LCD.CYAN) LCD.line(16,18,112,18,LCD.CYAN) LCD.text("Left",0,40,LCD.CYAN) LCD.text("Right",0,72,LCD.CYAN) LCD.text("0dB",88,40,LCD.OLIVE) LCD.text("0dB",88,72,LCD.OLIVE) # Two green areas LCD.fill_rect(0,48,112,16,LCD.GREEN) LCD.fill_rect(0,80,112,16,LCD.GREEN) # Two yellow areas LCD.fill_rect(96,48,16,16,LCD.YELLOW) LCD.fill_rect(96,80,16,16,LCD.YELLOW) # Two red areas LCD.fill_rect(112,48,16,16,LCD.RED) LCD.fill_rect(112,80,16,16,LCD.RED) # Left channel pointer LCD.line(lpos,46,lpos,66,LCD.WHITE) # Right channel pointer LCD.line(rpos,78,rpos,98,LCD.WHITE) # Display the meter face LCD.show() utime.sleep(delay) LCD.fill(0) Fig.13.11. Signal-level detector stripboard. would be beneficial to use screened cable. Simply connect the USB cable and then select Tools and Options from the Thonny’s menu bar (see Fig.13.8). Next, select the RPi Pico interpreter and the appropriate USB port (see Fig.13.9). When this has been done you can transfer your code by clicking on Thonny’s ‘Run’ icon. Coding With a project like this it’s worth starting by sketching your required layout and identifying all the features that need to be displayed (see Fig.13.12). To assist with this task, you may find one of the templates shown earlier useful. Coding for the audio signal level meter is straightforward. We used the RPi Pico’s ADC0 and ADC1 inputs for the left and right channels respectively. These are respectively mapped to the RPi’s GP26 and GP27 pins. The returned data values, (left_data and right_data) are used to determine the horizontal axis deflection of the two pointers (corresponding to lpos and rpos respectively). The display buffer is then created, starting with the legend text before adding the coloured areas for each of the meter scales. The two pointers are added to the display using the lpos and rpos positional information before finally sending the buffer to the LCD for one second, after which the entire process is repeated with the pointers updated to a new position where appropriate. The code fragment in Listing 4 shows how this is done. Parts To build the recording level signal indicator you will need: Perforated copper stripboard (9 strips, each with 25 holes) 2 3-way headers 2 10kΩ miniature pre-set resistors (RV1 and RV2) 2 1μF 35V radial lead electrolytic capacitors (C1 and C2) 2 47μF 25V radial lead electrolytic capacitors (C3 and C4) 4 BAT42 Schottky signal rectifier diodes (D1 to D4) Going further This section details a variety of sources that will help you locate the component parts and further information that will allow you to acquire and get the best out of your Raspberry Pi Pico display. It also provides links to relevant underpinning knowledge as well as some manufacturers’ data. Fig.13.12. Screen layout (using the template shown earlier in Fig.13.6). 60 Practical Electronics | October | 2023 Fig.13.14. The finished RPi Pico recoding level indicator (the four button keys can be used for a variety of other functions such as dimming the display or changing the display appearance). Fig.13.13. Close-up view of the display. Table 13.3 Going further with the low-cost colour LCD displays and the RPi Pico Topic Source Notes RPi Pico boards Numerous suppliers: eg, The Pi Hut (www.thepihut.com) offer RPi Pico boards, both with and without headers Boards with headers cost more than those without. Soldering skills will be required to solder your own headers! RPi Pico, MicroPython and Thonny KickStart Part 8 (PE, May 2022) provides a general introduction to the RPi Pico and it includes details of installing the MicroPython firmware as well as coding using MicroPthyon and Thonny For back issues of PE please visit: https://bit.ly/pe-backissues Back-pack display modules Part 38 of Phil Boyce’s popular Make it with Micromite series (PE August 2022) provides useful information on selecting and using different types of display backpack displays (including the larger 2.8-inch and 3.5-inch Waveshare modules offering resolutions of 320×240 and 480×320 pixels respectively) For back issues of PE please visit: https://bit.ly/pe-backissues 1.4-inch Pico LCD Documentation and demonstration programs (including display driver) from: https://bit.ly/pe-oct23-144 1.8-inch Pico LCD Documentation and demonstration programs (including display driver) from: https://bit.ly/pe-oct23-18 Driver and sample code Driver and sample code for the 1.44-inch and 1.8-inch Waveshare LCD modules is available for download from the PE website: https://bit.ly/pe-downloads MicroPython and Thonny RPi Pico books The latest documentation for MicroPython at: https://docs.micropython.org/en/latest/ The latest version of Thonny for Windows, Mac or Linux from: www.thonny.org The official RPi Pico guide is Get Started with Micropython on Raspberry Pi Pico by Gareth Halfacre and Ben Everard (ISNB 978-1-912-04786-4). It provides an introduction to the RPi Pico; plus, using Thonny, it describes a variety of simple projects suitable for beginners. Programming the Pico – Learn Coding and Electronics with the Raspberry Pi Pico (ISBN 979-8-464-88217-1) – another excellent introductory book from Simon Monk. Waveshare colour LCD RPi Pico projects RGB colour conversion utilities and PDF layout templates are available from the PE website: https://bit.ly/pe-downloads These two books are intended for complete beginners and they both assume little previous knowledge of electronics and coding Details of the full range of Waveshare displays is available from: https://bit.ly/pe-oct23-wave A wide variety of Waveshare colour LCD modules are available from on-line suppliers https://bit.ly/pe-may22-pico1 This useful beginners’ guide shows you how to connect a RPi Pico to a computer, install the Thonny Python IDE and write a MicroPython program to blink the Pico’s onboard LED Practical Electronics | October | 2023 61