Silicon ChipTeach-In 2024 - March 2024 SILICON CHIP
  1. Outer Front Cover
  2. Contents
  3. Subscriptions: PE Subscription
  4. Subscriptions
  5. Back Issues: Hare & Forbes Machineryhouse
  6. Publisher's Letter: Teach-In 2024
  7. Feature: The Wibbly-Wobbly World of Quantum by Max the Magnificent
  8. Feature: Net Work by Alan Winstanley
  9. Feature: The Fox Report by Barry Fox
  10. Project: Digital Volume Control POTENTIOMETER by Phil Prosser
  11. Project: Advanced SMD Test Tweezers by Tim Blythman
  12. Project: Active Mains Soft Starter by John Clarke
  13. Project: Teach-In 2024 by Mike Tooley
  14. Feature: Circuit Surgery by Ian Bell
  15. Feature: Max’s Cool Beans by Max the Magnificent
  16. Project: Audio Out by Jake Rothman
  17. PCB Order Form
  18. Advertising Index by Mohammed Salim Benabadji
  19. Back Issues: Bush MB60 portable radio by Ian Batty

This is only a preview of the March 2024 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)
Articles in this series:
  • Computer Storage Systems, Pt1 (February 2024)
  • Computer Storage Systems, Pt2 (March 2024)
  • Flowcode (March 2024)
Articles in this series:
  • Pico Digital Video Terminal (March 2024)
  • ETI BUNDLE (March 2024)
  • Pico Digital Video Terminal, Pt2 (April 2024)
Teach-In 2024 Learn electronics with the ESP32 by Mike Tooley Part 1 – Getting started W elcome to Teach-In 2024! In this first article of the series, we will start with an overview of the ESP32 and how to use the development environment. We will move on to show you how to use your PC to monitor the ESP32’s built-in capacitive touch sensors and our practical project involves using the ESP32 in a portable emergency beacon. The learning objectives for this part are to know and understand: n Installation and use of Arduino IDE n How to enter and test code n Use of a breadboard with the ESP32. Why ESP32? There are several good reasons why we’ve chosen the ESP32 as a platform for this series. Put simply, the ESP32 is well-established (launched in 2016), powerful and easy to use. The device is highly configurable and can be used in applications ranging from the most basic application – controlling an LED display – to the most demanding uses – MP3 streaming and decoding. The device offers extensive analogue and digital I/O, a serial UART, compatibility with popular and universal SPI and I2C devices. It also has Ethernet, dual-mode Bluetooth, and Wi-Fi connectivity. At well under £10 for a development board (see Fig.1.1) that’s really hard to beat! A really handy plus point is that the ESP32 has excellent built-in RF technology. This avoids the tricky problem of having to add external RF components, which, because of the signal frequencies involved, can often be challenging and problematic in terms of circuit layout. The device incorporates an RF power amplifier (with an output of up to 20dBm), a low-noise receiver amplifier, an antenna switch and RF filters. That’s a lot of tricky electronics avoided. In recent years the feature rich ESP32 has become firmly established as the starting point for a wide range of lowcost control and IoT (Internet of Things) applications. The reasons for its success include, in no particular order: Exceptional connectivity The ESP32 boasts multiple connectivity options based on 2.4GHz Wi-Fi, Bluetooth Fig.1.1. A low-cost ESP32 development board. 42 About Teach-In Our latest Teach-In series is about using the popular ESP32 module as a basis for learning electronics and coding. We will be making no assumptions about your coding ability or your previous experience of electronics. If you know one but not the other, you have come to the right place. On the other hand, if you happen to be a complete newbie there’s no need to worry because the series will take a progressive handson approach. There will be plenty of time to build up your knowledge and plenty of opportunity to test things out along the way. We’ve not included too much basic theory because this can be easily found elsewhere, including several of our previous Teach-In series, see: https://bit.ly/pe-ti https://bit.ly/pe-ti-bundle There will be projects and challenges to help you check and develop your understanding of the topics covered each month. Fig.1.2. ESP8266 and ESP32 boards. Practical Electronics | March | 2024 and Ethernet, as well as basic serial UART connectivity. The Bluetooth interface supports both ‘classic’ and Bluetooth Low Energy (BLE) operation. The IEEE 802.1-compatible Wi-Fi can be configured in access point (AP) mode as well as client and station mode. The former allows the ESP32 to set up its own local wireless network, while the latter provides a way to connect to the Internet using your existing Wi-Fi network. Extensive I/O The ESP32 supports a wide variety of external hardware. It has inbuilt DAC, ADC, PWM and touch sensing functionality, as well as I2C, SPI and serial UART interface compatibility. Low-power operation The ESP32’s minimal power requirements are ideal for applications that need battery power. The ESP32 can be put into ‘deep sleep’ mode requiring only a few microamps from a battery supply. Low-coast and wide availability ESP32-based modules and Devkits are available from several suppliers at very low cost (typically around £5 to £10 for a complete development board). Dual-core processor Most ESP32 modules and boards are based on dual-core architecture and, where necessary, code can be run simultaneously and independently on the two cores. Firmware The ESP32 board is supplied with FreeRTOS firmware installed. This powerful, well-documented opensource OS (operating system) supports multi-tasking and provides a vast array of API (application programming interface) functions. Ease of coding Coding is straightforward and can be based on the Arduino IDE or other popular software development tools (see later). What is an ESP32? ESP32 is a generic name that describes Espressif’s family of powerful System on Chip (SoC) devices. The name has also been used to describe modules and a plethora of development boards (Devkits) based on this processor. The ESP32 SoC follows on from the success of its predecessor, the ESP8266, but incorporates several important new features (see Fig.1.2). Supplied as an SoC package, the ESP32 is designed to be embedded in systems designed for specific applications, such as access control, environmental monitoring, machine control and home automation. When supplied in the form of a module, the ESP32 is mounted on a small daughter board that typically includes external circuitry such as a printed Wi-Fi antenna. Taking it one step further, development boards, known as ‘Devkits’, offer an enhanced experience for experimentation and learning. They provide a generous subset of the ESP32’s I/O pins, along with a USB programming interface and a voltage regulator. Our Teach-In series focuses on the most popular Devkits using the ESP-WROOM-32 module. These boards are available in both 30and 36-pin versions. Although either version can be used to follow our series, we have used the smaller 30-pin board in most of our practical layout diagrams. The ESP-WROOM-32 has the impressive specification listed in Table 1.1. Finally, if you happen to already have experience of the Arduino UNO, you will find that the ESP32 has been made available in board configurations matching that of the UNO (see Fig.1.3). This neat arrangement makes it possible to use peripheral hardware designed for the UNO with an ESP32 SoC. The ESP32 has even been integrated into the latest Arduino UNO R4 Wi-Fi. This merges the RA4M1 processor from Renesas with the ESP32-S3 from Espressif, a really powerful and versatile combination. Table 1.1 ESP-WROOM-32 specification Feature Specification Notes Processor 32-bit dual core, 40nm process Single-core versions are also available Processor speed 160 or 240 MHz ROM 448kB Booting and core function storage SRAM 520kB Instructions and data storage External memory Up to 32Mb of flash memory DAC 2 × 8-bit ADC 18 channels × 12-bit SAR type ADC GPIO 34 programmable pins See Table 1.2 for limitations SPI Four channels I2S Two channels 2-wire connection I2C Two channels 3-wire connection UART Three serial ports Wi-Fi IEEE 802.11 b/g/n Bluetooth V4.2 BR/EDR and BLE 1 Ethernet MAC interface with dedicated DMA RTC Time is retained in various sleep modes Memory controller SD/SDIO/CE-ATA/MMC/ MMC host controller LED and motor PWM Up to 16 channels IR remote controller TX/RX up to 8 channels For external memory Touch sensors 10 capacitive touch sensor inputs Via GPIO pins Power +3.3V or +5V from a USB connector Deep sleep supply current can be as low as a few µA Practical Electronics | March | 2024 43 Fig.1.3. (left) An Arduino UNO and an ESP32 development board sharing the same form factor. Fig.1.4. (right) Typical ESP32 development board layout. What we will be covering Regular features of this new Teach-In series will include the following sections and features: Check it out! Put simply, this will be the point at which you can stop reading and start your practical investigation of the concepts that we’ve introduced in the text. Check it out! will reinforce your learning by putting ideas and techniques into context. Practical project Our practical project will showcase the topics covered each month. Most practical projects can be completed in a couple of hours and parts can be saved for use in later projects. Coding workshop We will develop coding skills progressively throughout the series and, while this isn’t a series about coding, it’s important to be able to understand what the code does and how your coding style can be improved. Teach-In challenge After completing our practical project you might be keen to try something yourself. Our monthly Teach-In challenge will set you a task and give you something to get your teeth into. We will provide a few pointers along the way, but the solution will always be in your hands. Finally, and to help you avoid some potential pitfalls along the way, we’ve included some short Gotcha! hints and tips, providing pointers and solutions to problems that you might encounter in your projects. We’ve added these at the points at which you are most likely to need them. You will find five of them in this first part – hopefully they will help you avoid the painful head scratching that we experienced when putting the series together! What you will need Just like previous Teach-In series, you will need a few basic items to explore the showcased examples and to construct the projects featured each month. We’ve strived to ensure that the requirements are simple, inexpensive and we suspect that most of our readers will already have many of the items to hand. If that’s not the case, you will find numerous suppliers online, mentioned in the pages of PE, and listed in our Going further feature each month. To get started this month you will need: n  L ow-cost ESP32 microcontroller development/Devkit board (see later) n  Low-cost breadboard with jumper leads for connecting to external circuitry n USB cable to connect the development board to your PC n Copy of the freely available Arduino integrated development environment (IDE) installed on your PC (see later) n  5V USB charging power pack for remote and stand-alone operation of some of your projects n Standard red LED and a 150Ω resistor. Coding and the ESP32 The ESP32 can be used with several popular programming environments, including: n Arduino IDE n PlatformIO IDE (VS Code) n LUA n MicroPython n  E spressif IDF (IoT Development Framework). Since many readers will already be familiar with the Arduino IDE, this is Fig.1.5. Pin connections for a typical 30-pin ESP32 development board. 44 Practical Electronics | March | 2024 Table 1.2 Recommended GPIO pins for general use Designation Function Direction Comment GPIO0 TX0 (serial port) O Serial programming and debugging GPIO2 User LED I/O Avoid external connection GPIO3 RX0 (serial port) I Serial programming and debugging GPIO4 I/O I/O Available for general use GPIO5 I/O I/O Strapping pin – avoid GPIO6-11 Flash memory n/a Avoid external connection GPIO12 I/O I/O Strapping pin – avoid GPIO13-14 I/O I/O Available for general use GPIO15 I/O I/O Mutes debugging messages GPIO16-33 I/O I/O Available for general use GPIO34-39 I/O I Input only the ESP32’s onboard LED on and off at 1s intervals. /* On-board LED flasher */ You should be int ledPort = 2; // GPIO2 is connected to the LED able to get an idea of what the // Initialise the port code does even void setup() { if you’ve never pinMode(ledPort, OUTPUT); seen it before! } Notice that this // Loop forever code includes void loop() { some comments digitalWrite(ledPort, HIGH); // Set LED on (insertedbetween delay(1000); // 1s delay the ‘/*’ and ‘*/’ digitalWrite(ledPort, LOW); // Set LED off characters and delay(1000); // 1s delay also after the ‘//’ } characters). Even though they have no impact on the execution of your code, the platform that we will be using. The these comments are invaluable – top tip, IDE is reasonably intuitive and is free to do keep them short and meaningful. download and use. It is also exceptionally Coding is an iterative process based on well supported with reference tutorial a repeated cycle of entering (or editing) material and extensible with code code, uploading to the target system, libraries for a huge variety of peripheral executing, debugging and optimising devices. To give you some idea of just your code. You may find that you have to how easy ESP32 programming can be, loop through this cycle many times before above is some example code that will flash Example code your code executes in the way that you need. You will also find that once you’ve developed a block of code that works well you will be able to reuse it in other situations. This is another reason why it is important to comment your code so that you can understand what it does, how to use it, and – where necessary – adapt it. What’s on the board? Fig.1.4 shows a typical development board. We’ve labelled the board to show you the most important features. You will notice that the external pin connections run along the two longer sides of the board, while the printed Wi-Fi antenna and USB connector are located at the opposite ends. Adjacent to the USB connector are two small buttons, labelled EN (enable) and BOOT. These buttons are used to restart the system and for uploading code respectively. There are two LEDs on the board. The Power LED indicates that power is present, while the User LED is available for test purposes. We will make use of this later. Gotcha! Ther are many ESP32 development boards available from different suppliers and manufacturers. The features, layout and pinout may vary from those shown in Fig.1.4. We’ve used the most common subset of pins and connections in this series, but it is important to check the layout and configuration of your board before making any connections to it, or applying power. The ESP32’s GPIO pin configuration is summarised in Table 1.2. Note that GPIO pins have multiple functions, and some are unsuitable for general use. Those shown shaded in green are recommended for general purpose use. Fig.1.6. Pin connections for a typical 36-pin ESP32 development board. Practical Electronics | March | 2024 45 Fig.1.7. Two (slightly modified) breadboards provide a convenient space for a 30-pin ESP32 development board. Gotcha! Several different pin configurations are found on ESP32 development boards. The most common of which use either 30 or 36-pins. There may also be minor differences in the way in which the pins are marked on the boards. You may also find that not all the GPIO pins listed in Table 1.2 are available on your board. The ones that are ‘safe’ for general purpose use are shaded in green. Pin connections for typical 30- and 36pin ESP32 development boards are shown in Figs.1.5 and 1.6 respectively. We have shown the different signal functions for the GPIO pins on this diagram. Notice how the GPIO pin numbering is not always consecutive and how some pins can have up to five different functions. For example, GPIO4 can be configured for use: n As a normal digital I/O pin n As an analogue input (Channel 0 of ADC2) n As a touch sensing input n  In conjunction with the real-time clock (RTC) n As a means of connecting an SPI (serial peripheral interface) device. This may sound baffling at first, but it will become clearer when we look at some practical examples of how the chip is used and interfaced to external devices. Breadboards You will need a breadboard to connect electroniccomponentstoyourdevelopment board. These are available in various sizes and with different numbers of connecting points. For Teach-In, and because of the size of the ESP32 development board we’ve standardised on an arrangement based on two separate breadboards placed side-byside. We’ve also modified one of the boards by unclipping and removing one of the supply rails (red and blue) before glueing the two boards onto a small piece of MDF. Fig.1.7 shows how this is done, and Fig.1.8 shows a typical breadboard circuit arrangement with ESP32 and external components connected. Gotcha! Whatever breadboard you use it’s important to have plenty of space available for mounting components. A cramped layout can quickly become confusing. Fig.1.9. Selecting the IDE installer for your computer. 46 Fig.1.8. A typical breadboard circuit arrangement ready for testing. Installing and configuring the Arduino IDE Before you can begin to enter code into your ESP32 you will need to connect it to a PC that has a copy of the Arduino’s integrated development environment (IDE) installed on it. The process is quite painless, but it requires an Internet connection so that you can download the latest version of the IDE package. We’ve installed the IDE package successfully on a whole host of different computers, including some running 32- and 64-bit versions of Windows and also a couple running different flavours of Linux. The step-by-step procedure described here was carried out on a computer running Windows 10, but the process is similar, if not quite identical, on other machines. Note that an installation under Linux may require the installation of the Java run-time environment (JRE) if not already installed. 1 O  pen your Web browser and go to www.arduino.cc (the official Arduino home page). When the page has loaded click on ‘Software’ to open the downloads page. Then scroll down to the latest version of the Arduino IDE (currently 2.2.1) which usually appears at the top of the list. Next, select the installer for your machine (we chose the Windows 10 64-bit installer) from the list on the right. Fig.1.10. Selecting the destination folder for your installation. Practical Electronics | March | 2024 Fig.1.11. The Arduino IDE has been successfully installed and is ready to run. 2 A  t this point you will be asked if you would like to make a contribution (see Fig.1.10). You can either click on ‘Just download’ or ‘Contribute and download’. When you’ve made your choice the installation file will be downloaded to your computer. The download is quite large, so, depending on the speed of your Internet connection, you may have to wait for a minute or two for the download to complete. 3 Next, click on the installer or unzip the file (depending on which version you have chosen) and simply follow the prompts. You can choose a destination folder (see Fig.1.10) or just accept the default. Finally, click on ‘Install’ to start the installation process. 4  Depending on the speed of your computer the installation process may take as little as 30 seconds or up to several few minutes. You may also be given the option of installing a USB driver. This driver will allow your computer to communicate with a standard Arduino by means of the USB port. We recommend that you click on ‘Install’ to install this additional system software (this is not part of the IDE itself). 5  When the installation is complete (and when any USB driver has been added) you can click on ‘Finish’ and either return to your normal desktop or, if you’ve checked the ‘Run Arduino IDE’ (see Fig.1.11) you can run the IDE and get started right away. 6 T  o install the extra libraries and code for the ESP32 you will need to tell the IDE where to go to fetch the required files. Run the IDE (if not already running), select ‘File’ from the menu bar and then ‘Preferences’. Next, you will need to manually enter the URL in the dialogue Fig.1.12. A URL is used to locate the code needed to box (see Fig.1.12). configure the IDE for the ESP32. The URL is rather serial COM port has been identified long but here it is: and allocated to your ESP32. Click on https://raw.githubusercontent.com/ ‘OK’ to complete the set-up process and espressif/arduino-esp32/gh-pages/ your ESP32 is ready for some code! package_esp32_index.json 9 You should now be rewarded with a window like the one shown in Just enter the above URL (exactly as Fig.1.16. The message in the ‘Output’ shown in Fig.1.12) and then click on ‘OK’. field (at the bottom of the screen) confirms that the ESP32 platform has 7 Next, select ‘Tools’, ‘Board’ and ‘Board been installed successfully. Note also Manager’ from the drop-down menu. that the status bar (also at the bottom Scroll down the list of supported boards of the screen) is reporting that the IDE to the entry headed ‘esp32 by Espressif’ is connected to an ‘ESP32 Dev Module and then click on ‘INSTALL’ as shown on COM4’. If that’s not the case, click in Fig.1.13. It may take several minutes on ‘Tools’, scroll down to ‘Board’ and for the library files to be downloaded, ‘Port’, and hover your mouse over but during that time the progress them. If the settings are not correct bar should be active, and a list of you will be able to change them. downloaded files should be displayed. 10  If you are ready to try some code, After these additional tools have been here’s a simple ESP32 application automatically configured the IDE will that flashes the built-in LED. Just type be ready for use with the ESP32. the code in Listing 1.1, or download 8 Now connect your ESP32 development it from March 2024 page of the PE board to your PC using one of its website: https://bit.ly/pe-downloads (powered) USB ports. Note that the Next, click on the large right arrow USB port supplies +5V power so there’s (below the menu bar) to verify, compile no need for a separate DC supply for and upload the code to the ESP32 in the ESP32. With the IDE still open, executable form. Note that if there click on ‘Select Board’ and ‘Select are any errors in the entered code the other board and port’ (Fig.1.14). Scroll compilation will fail and you will need down the list of ESP32 boards (there are to locate and correct the errors before quite a few!) until your ESP32 board trying again. Note also that you can use is listed (usually this will be ‘ESP32 the ‘File’ menu to save your code (and Dev Module’). Click to select the board also rename it, if required). and a tick will appear against it (see Fig.1.15). You should also see that a Check it out! Now for an exercise that will introduce you to the ESP32’s touch sensors without needing any additional hardware (other Fig.1.13. (left) Using the IDE’s Board Manager to install support for the ESP32. Fig.1.14. (right) Selecting the ESP board and port. Practical Electronics | March | 2024 47 + Listing 1.1 Test code that flashes the ESP32’s on-board LED /* Flash the built-in LED via GPIO2 */ int ledPort = 2; // ESP32 built-in LED int timeOn = 200; // On time (ms) int timeOff = 800; // Off time (ms) void setup() { // Initialise the LED port as an output. pinMode(ledPort, OUTPUT); } void loop() { // This loop runs forever! digitalWrite(ledPort, HIGH); delay(timeOn); digitalWrite(ledPort, LOW); delay(timeOff); } // Turn the LED on // Turn the LED off Gotcha! Fig.1.15. Choose your board from the list of supported hardware. If you receive a message of the form ‘A fatal error occurred: Failed to connect to ESP32’ check first that you have the correct board and port selected. If that doesn’t solve the problem, wait for the IDE’s ‘Connecting….’ message to appear then press and hold the BOOT button until the next message confirming that the connection has been made, at which point the flash memory will be erased and rewritten. This can be tedious, but it usually works. way of replacing pushbuttons and toggle switches. You can check this out using the code in Listing 1.2. Enter (or download) the code shown in Listing 1.2 and then execute it in the same way as before. The user LED on GPIO2 should become illuminated whenever you touch a jumper lead connected to GPIO15 (see Fig.1.17). Fig.1.16. The IDE is communicating with the ESP32 Dev Module on COM4 and ready for some code (the code displayed is just a blank template). Coding workshop To get your hardware to do something useful you will need to have some code that will tell it what to do and how to respond when something happens. The process of producing code (ie, ‘coding’) is not particularly difficult but it does require a structured and systematic approach. If you’ve ever had to provide someone with a detailed set of instructions for travelling somewhere you will know how important it is not to forget any steps and to give your instructions in a clear Listing 1.2 Code for checking the ESP32’s in-built capacitive touch sensing inputs /* Checking out the ESP32’s touch sensors */ int ledPort = 2; //ESP32 built-in LED void setup() { // Initialise the LED port as an output pinMode(ledPort,OUTPUT); } Fig.1.17. The on-board LED should operate when touching a jumper lead connected to GPIO15 (D15 on most boards). than a breadboard and jumper wire). Ten of the ESP32’s GPIO pins can be configured as capacitive touch sensitive inputs. Simply placing a finger on one of these pins is sufficient for an input to be generated. This can be a great 48 void loop() { // This loop runs forever delay(100); // Wait for 100ms if (touchRead(15)<40) // Touch! { digitalWrite(ledPort,HIGH); // LED on } else if (touchRead(15)>=40) // No touch { digitalWrite(ledPort,LOW); // LED off } } Practical Electronics | March | 2024 and unambiguous way. The same applies to computer coding, but with the added complication that we need to present our instructions in a way that can be interpreted by a machine rather than a human being. Coding is easy to learn if you ‘start simple’ and build up your skills progressively and systematically. We start this month with a look at the ways in which data is handled and manipulated. Boolean data Data that can only take one of two possible values is referred to as ‘Boolean data’. Inside the Arduino this type of data can be represented using a single byte (8-bits) of data and it can take a value of either TRUE or FALSE, HIGH or LOW or simply ‘on’ and ‘off’. These two states are mutually exclusive and we refer to them as ‘Boolean’ because they conform to the rules of Boolean Logic (much more of this in a later instalment). The variables that we use in our code need to be declared before they can be used. An example of a Boolean declarations is as follows: boolean powerGood = FALSE; // power status At some later point in the code (within the main loop that executes forever) you might encounter the following line: powerGood = !powerGood; // toggle the power status Note that the ‘!’ in the foregoing code fragment can be read as ‘not’ and the line of code simply changes the state of the Boolean variable to the opposite of what it was before. In other words, if powerGood had previously been HIGH it will now become LOW, and vice versa. Unfortunately, there’s some potential for confusion here. The Arduino uses a byte (8-bits) of memory to store Boolean data, but since Boolean data can only exist in one of two possible states and where available memory is limited (as it is with the Arduino) it would be advantageous to use just a single bit of data rather than an entire byte because seven of the eight bits used to store the Boolean data are just not being used (a stored binary value of 0000000 will be interpreted as FALSE and anything else will be interpreted as TRUE). This is rather wasteful and so it’s important to remember that using a Boolean data type is no more efficient in terms of memory usage than using integer values (see later). That said, it can often be neat and convenient to use Boolean data types. Integer data Whole numbers (ie, numbers with no decimal point) are frequently stored as integers (or ‘ints’). Integers require two bytes (16 bits) of storage and the most significant bit (MSB) is used to indicate the sign of the number. When this bit is 0 the value is positive and when it is 1 the value is negative. The method of representing numbers is referred to as ‘2’s complement’ notation and with 16bits of data it yields a range that extends from –32768 to +32767. A typical extract from a program’s setup code might be: int powerLED = 11; // Output pin used for the power good LED This line of code defines and initialises a variable that we’ve named powerLED. We’ve told the Arduino that it is to be handled as an int (ie, an integer) and that it is to be given an initial value of 11. The statement ends with a semicolon (;) and this is followed by a brief comment designed to act as a reminder of what the purpose of the statement is. Brief comments like this can be invaluable later on when the time comes to do some software maintenance and also when code is shared among several authors. Later on in the program code you might find a line that takes the form: Practical Electronics | March | 2024 digitalWrite(powerLED, HIGH); // Illuminate the power good LED Even if you’ve never done any coding before you can probably make a reasonable guess of what this statement does. At another point in the code you might find something like this: if(powerGood = = FALSE) { digitalWrite(powerLED, LOW); } The above code fragment turns the ‘power good’ LED off when the system has sensed a problem with the power supply. It does this by examining the state of the powerGood Boolean variable (see earlier) and, if found to be FALSE (in other words, not good) the ‘power good’ LED is turned ‘off’ by writing a low (0V) to its digital output pin (pin-11 as defined within the integer declaration earlier in the code). The syntax for the declaration (in this particular case it’s a constant rather than a variable) is simply the name followed by the value that you’ve assigned to it. Note that the name takes the form of a meaningful description (two words with no space included between them). Note also that the first word begins with a lower-case character and the second word with a single upper-case character. This convention helps make the code easier to read and it avoids the need to include a space character in the name (which would be invalid). At some point later in the code you might find something like this: if(powerGood = = FALSE) { digitalWrite(powerLED, LOW); } There’s often a need to increment or decrement a variable within a program loop (for example, when counting events) but, because of the use of 2’s complement notation, it is very important to be aware that when a variable is incremented or decremented, the variable will roll-over whenever it reaches the maximum allowable size. So, for example, incrementing 32767 (the maximum allowable positive value) will cause the value to become –32768 (note the change of sign). In a similar manner, decrementing a value of –32768 (the maximum allowable negative value) will cause a variable to take a new value of +32767. Finally please be aware that the use of two bytes to store an integer is not consistent over all Arduino versions. For example, the Arduino Due uses four bytes (32-bits) to store integer values. This provides a range of values extending from –2,147,483,648 to +2,147,483,647. Floating point data As the name implies, floating point numbers, or ‘floats’, are numbers that include a decimal point. They offer a much larger range from –3.4028235E+38 to +3.4028235E+38. Floats are stored using four bytes (32 bits) of data. Floats are often used to represent analogue values from sensors. Due to the need for four bytes of data, floating point mathematics can be significantly slower than when integers are used (where only two bytes of data are involved). Consequently, it is advisable to use integers rather than floats whenever speed of execution is important. A typical extract from a program’s setup code might be: float peakConvert = 1.4159; // To convert from RMS to peak We could then determine the peak voltage and peak current present in a 50Ω load using something of the form: 49 Listing 1.3 Code for the portable emergency beacon /* Listing 1.3 ESP 32 emergency beacon */ char message[] = “SOS”; int ledPort = 2; // ESP32 built-in LED int dotLen = 100; // length of a dot int dashLen = dotLen * 3; // length of a dash int gap = dotLen * 5; // length of a space void setup() { pinMode(ledPort, OUTPUT); } byte inputStatus = 0x00; byte inputFailure = 0xFF; void loop() { for (int i = 0; i < sizeof(message) - 1; i++) { char tempChar = message[i]; GetChar(tempChar); } LEDOff(gap); // Extra gap between repeats } // DOT void MorseDot() { digitalWrite(ledPort, HIGH); delay(dotLen); } limited in range. The minimum value that can be represented is 0 when all of the bits are 0 (hexadecimal 0x00) and the maximum value is 255 (hexadecimal 0xFF) when all of the bits are set to 1. Despite the restricted range, byte data can be useful in a variety of applications, particularly when dealing with the status of eight input or output lines. For example: // LED on // DASH void MorseDash() { digitalWrite(ledPort, HIGH); delay(dashLen); } // LED on // LED Off void LEDOff(int holdTime) { digitalWrite(ledPort, LOW); delay(holdTime); } // LED off // Morse code void GetChar(char temp) { switch (temp) { case ‘S’: // Three dots MorseDot(); LEDOff(gap); MorseDot(); LEDOff(gap); MorseDot(); LEDOff(gap); break; case ‘O’: // Three dashes MorseDash(); LEDOff(gap); MorseDash(); LEDOff(gap); MorseDash(); LEDOff(gap); break; } } peakVoltage = rmsVoltage * peakConvert; peakCurrent = peakVoltage / 50; Byte data Byte is used to store 8-bits of data as unsigned binary numbers. So, for example, a binary value of 10000001 (equivalent to 81 in hexadecimal or 128 in decimal) might be defined as follows: // initialise input port status // all port lines have gone high At some later point in the code, we might encounter a line of the form: if(inputStatus = = inputFailure) { Serial.print(“Warning: Input failure!”); } In this example a fault is present if all of the input lines are simultaneously in the HIGH state and in this condition the value of the inputStatus variable will be 0xFF. If this condition is detected a brief warning message will be sent via the serial port (more of using the serial monitor later in the series). Character data The character data type is used when we just need to represent alphanumeric information such as plain text. The character data type uses a single byte of memory to store each character. Thus, the word ‘character’ would need nine bytes of storage. Character literals are enclosed within single quotes (eg, ‘A’), while double quotes are used for strings comprising several characters (eg, “Power Good”). Character data is encoded using the American Standard Code for Information Interchange (ASCII). Each character is represented by a corresponding signed 8-bit value. ‘A’ for example is encoded as 01000001 in binary. This is equivalent to 41 in hexadecimal or 65 in decimal. The basic ASCII character set uses only seven bits (equivalent to a decimal range that extends from 0 to +127. When the leading bit is set (ie, 1 and not 0) the signed byte becomes negative with a range extending from –1 to –128. These 128 values can be used to represent special characters. Note that the following three lines of code are equivalent: char testChar = ‘A’; char testChar = 65; char testChar = 0x41; Also note how the number base in the last example is indicated by the prefix 0x, which indicates that the number that follows is written in hexadecimal format. The Serial.println() function provides you with a way of printing data using several different representations: Serial.println(analogValue); // print as ASCII-encoded decimal Serial.println(analogValue, DEC); // print as ASCII-encoded decimal Serial.println(analogValue, HEX); // print as ASCII-encoded hex Serial.println(analogValue, OCT); // print as ASCII-encoded octal Serial.println(analogValue, BIN); // print as ASCII-encoded binary byte bitMask = 0x81; // mask unwanted bits Note that the ‘0x’ prefix denotes a value expressed in hexadecimal (base 16) format. Because only eight bits are used, byte data is 50 This concludes our brief look at the way that data is represented. Next month we will be getting to grips with some data manipulation. Practical Electronics | March | 2024 Fig.1.18. Off-board circuit for the prototype emergency beacon. Fig.1.21. LED pin connections. Practical project Our first practical project involves the design, construction, and coding for a simple portable emergency beacon. We will develop the circuit using an ESP32 Devkit and development board. The finished version could use an ESP32 module, a highintensity LED and a rechargeable battery, but for now we will do the development using a standard Devkit, LED and USB power from the host computer. The minimal circuit and wiring layout for our prototype emergency beacon are shown in Figs.1.18 to 1.20. The pin connections for the LED are shown in Fig.1.21. (Note that it is important to connect LEDs with the correct polarity.) The 150Ω resistor is used to set the current that will be supplied to the LED (in this case about 7mA). Having connected the circuit, made the USB connection to your PC, and started the IDE, you can enter (or download) the code shown in Listing 1.3. When you run the code, you should see the LED repeatedly flashing an ‘SOS’ message in Morse code. Now let’s walk through the code. The first few lines of code define the variables (explained earlier). Note that we have the dashlen and gap variables in terms of the dotlen variable that was previously defined. Thus, to change the speed of the Morse code beacon we only need to change dotlen and the other two variables will change in proportion. Next, we enter the main loop which examines each character in our message in turn and determines the pattern of dots and dashes that represent the character in Morse code (see Fig.1.22). If a dot is required, the LED is switched on (ledPort goes HIGH) for a time defined by dotlen before being switched off for a time defined by gap. Alternatively, if a dash is required, the LED is switched on (ledPort goes HIGH) for a time defined by dashlen before being switched off for a time defined by gap. Note that the voltage present at a GPIO pin voltage will be approximately 3.3V when in the HIGH state and 0V when in the LOW state. Thus, when our code takes GPIO2 HIGH current will begin to flow in the LED and it will become illuminated. Conversely, the current will stop when GPIO2 is taken LOW. This allows us to switch the LED on and off. Don’t worry if you don’t fully understand the code at this stage. The most important thing to grasp for now is how the GPIO pins are controlled through digitalWrite(). We will be taking a more detailed look at this when we explain digital I/O next month. Teach-In challenge Our Teach-In challenges will provide you with something to test the knowledge that you’ve acquired. This month, starting with Fig.1.19. Wiring for the prototype emergency beacon based on a 30-pin board. Practical Electronics | March | 2024 Fig.1.22. Morse code. the emergency beacon code that we met earlier, modify and extend the code so that it continuously flashes a ‘HELLO’ message in Morse code. Gotcha! Code can be pretty darn picky and unforgiving! Common errors are forgetting to end lines with ‘;’, not terminating a multi-line comment with ‘*/’ and failing to pair opening and closing braces, ‘{’ and ‘}’. As time goes on you will undoubtedly become proficient and learn to avoid these basic errors. Next month In the next part of our Teach-In series We will take a close look at digital input and output. We will provide a detailed look at the relationship between digital signals and logic levels, and explain how the GPIO ports are configured. We will learn how to interface buttons and switches, and develop simple code to sense and display their state. Coding workshop will introduce logical constructs and decision making. We will also introduce flow charts, and explain the design and construction of a simple traffic light controller. Fig.1.20. Wiring for the prototype emergency beacon based on a 36-pin board. 51