Silicon ChipTeach-In 2024 – Learn electronics with the ESP32 - November 2024 SILICON CHIP
  1. Contents
  2. Publisher's Letter: The challenges of making electronics work worldwide
  3. Feature: The Fox Report by Barry Fox
  4. Feature: Net Work by Alan Winstanley
  5. Project: Ideal Diode Bridge Rectifiers by Phil Prosser
  6. Feature: Practically Speaking by Jake Rothman
  7. Back Issues
  8. Feature: Max’s Cool Beans by Max the Magnificent
  9. Project: Multi-Channel Volume Control, part one by Nicholas Vinen
  10. Feature: Teach-In 2024 – Learn electronics with the ESP32 by Mike Tooley
  11. Feature: Techno Talk by Max the Magnificent
  12. Project: Coin Cell Emulator by Tim Blythman
  13. Feature: Circuit Surgery by Ian Bell
  14. Review: MG4 XPower electric vehicle by Julian Edgar
  15. Subscriptions
  16. Feature: 14-segment, 4-digit LED Display Modules by Jim Rowe
  17. PartShop
  18. Advertising Index
  19. Market Centre
  20. Back Issues

This is only a preview of the November 2024 issue of Practical Electronics.

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

Articles in this series:
  • The Fox Report (July 2024)
  • The Fox Report (September 2024)
  • The Fox Report (October 2024)
  • The Fox Report (November 2024)
  • The Fox Report (December 2024)
  • The Fox Report (January 2025)
  • The Fox Report (February 2025)
  • The Fox Report (March 2025)
  • The Fox Report (April 2025)
  • The Fox Report (May 2025)
Articles in this series:
  • Win a Microchip Explorer 8 Development Kit (April 2024)
  • Net Work (May 2024)
  • Net Work (June 2024)
  • Net Work (July 2024)
  • Net Work (August 2024)
  • Net Work (September 2024)
  • Net Work (October 2024)
  • Net Work (November 2024)
  • Net Work (December 2024)
  • Net Work (January 2025)
  • Net Work (February 2025)
  • Net Work (March 2025)
  • Net Work (April 2025)
Articles in this series:
  • Practically Speaking (November 2024)
  • Practically Speaking (February 2025)
Articles in this series:
  • Max’s Cool Beans (April 2024)
  • Max’s Cool Beans (May 2024)
  • Max’s Cool Beans (June 2024)
  • Max’s Cool Beans (July 2024)
  • Max’s Cool Beans (August 2024)
  • Max’s Cool Beans (September 2024)
  • Max’s Cool Beans (October 2024)
  • Max’s Cool Beans (November 2024)
  • Max’s Cool Beans (December 2024)
Items relevant to "Multi-Channel Volume Control, part one":
  • Multi-channel Volume Control volume PCB [01111221] (AUD $5.00)
  • Multi-channel Volume Control control PCB [01111222] (AUD $5.00)
  • Multi-channel Volume Control OLED PCB [01111223] (AUD $3.00)
  • PIC16F18146-I/SO programmed for the Multi-Channel Volume Control [0111122B.HEX] (Programmed Microcontroller, AUD $10.00)
  • PIC16F15224-I/SL programmed for the Multi-Channel Volume Control [0111122C.HEX] (Programmed Microcontroller, AUD $10.00)
  • Pulse-type rotary encoder with pushbutton and 18t spline shaft (Component, AUD $3.00)
  • 0.96in cyan OLED with SSD1306 controller (Component, AUD $10.00)
  • 2.8-inch TFT Touchscreen LCD module with SD card socket (Component, AUD $25.00)
  • Multi-channel Volume Control control module kit (Component, AUD $50.00)
  • Multi-channel Volume Control volume module kit (Component, AUD $55.00)
  • Multi-channel Volume Control OLED module kit (Component, AUD $25.00)
  • Firmware (C and HEX) files for the Multi-Channel Volume Control (Software, Free)
  • Multi-channel Volume Control PCB patterns (PDF download) [01111221-3] (Free)
Articles in this series:
  • Multi-Channel Volume Control, Pt1 (December 2023)
  • Multi-Channel Volume Control Part 2 (January 2024)
  • Multi-Channel Volume Control, part one (November 2024)
  • Multi-Channel Volume Control, Part 2 (December 2024)
Articles in this series:
  • Teach-In 2024 (April 2024)
  • Teach-In 2024 (May 2024)
  • Teach-In 2024 – Learn electronics with the ESP32 (June 2024)
  • Teach-In 2024 – Learn electronics with the ESP32 (July 2024)
  • Teach-In 2024 – Learn electronics with the ESP32 (August 2024)
  • Teach-In 2024 – Learn electronics with the ESP32 (September 2024)
  • Teach-In 2024 – Learn electronics with the ESP32 (October 2024)
  • Teach-In 2024 – Learn electronics with the ESP32 (November 2024)
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:
  • Circuit Surgery (April 2024)
  • STEWART OF READING (April 2024)
  • Circuit Surgery (May 2024)
  • Circuit Surgery (June 2024)
  • Circuit Surgery (July 2024)
  • Circuit Surgery (August 2024)
  • Circuit Surgery (September 2024)
  • Circuit Surgery (October 2024)
  • Circuit Surgery (November 2024)
  • Circuit Surgery (December 2024)
  • Circuit Surgery (January 2025)
  • Circuit Surgery (February 2025)
  • Circuit Surgery (March 2025)
  • Circuit Surgery (April 2025)
  • Circuit Surgery (May 2025)
  • Circuit Surgery (June 2025)
Articles in this series:
  • El Cheapo Modules From Asia - Part 1 (October 2016)
  • El Cheapo Modules From Asia - Part 2 (December 2016)
  • El Cheapo Modules From Asia - Part 3 (January 2017)
  • El Cheapo Modules from Asia - Part 4 (February 2017)
  • El Cheapo Modules, Part 5: LCD module with I²C (March 2017)
  • El Cheapo Modules, Part 6: Direct Digital Synthesiser (April 2017)
  • El Cheapo Modules, Part 7: LED Matrix displays (June 2017)
  • El Cheapo Modules: Li-ion & LiPo Chargers (August 2017)
  • El Cheapo modules Part 9: AD9850 DDS module (September 2017)
  • El Cheapo Modules Part 10: GPS receivers (October 2017)
  • El Cheapo Modules 11: Pressure/Temperature Sensors (December 2017)
  • El Cheapo Modules 12: 2.4GHz Wireless Data Modules (January 2018)
  • El Cheapo Modules 13: sensing motion and moisture (February 2018)
  • El Cheapo Modules 14: Logarithmic RF Detector (March 2018)
  • El Cheapo Modules 16: 35-4400MHz frequency generator (May 2018)
  • El Cheapo Modules 17: 4GHz digital attenuator (June 2018)
  • El Cheapo: 500MHz frequency counter and preamp (July 2018)
  • El Cheapo modules Part 19 – Arduino NFC Shield (September 2018)
  • El cheapo modules, part 20: two tiny compass modules (November 2018)
  • El cheapo modules, part 21: stamp-sized audio player (December 2018)
  • El Cheapo Modules 22: Stepper Motor Drivers (February 2019)
  • El Cheapo Modules 23: Galvanic Skin Response (March 2019)
  • El Cheapo Modules: Class D amplifier modules (May 2019)
  • El Cheapo Modules: Long Range (LoRa) Transceivers (June 2019)
  • El Cheapo Modules: AD584 Precision Voltage References (July 2019)
  • Three I-O Expanders to give you more control! (November 2019)
  • El Cheapo modules: “Intelligent” 8x8 RGB LED Matrix (January 2020)
  • El Cheapo modules: 8-channel USB Logic Analyser (February 2020)
  • New w-i-d-e-b-a-n-d RTL-SDR modules (May 2020)
  • New w-i-d-e-b-a-n-d RTL-SDR modules, Part 2 (June 2020)
  • El Cheapo Modules: Mini Digital Volt/Amp Panel Meters (December 2020)
  • El Cheapo Modules: Mini Digital AC Panel Meters (January 2021)
  • El Cheapo Modules: LCR-T4 Digital Multi-Tester (February 2021)
  • El Cheapo Modules: USB-PD chargers (July 2021)
  • El Cheapo Modules: USB-PD Triggers (August 2021)
  • El Cheapo Modules: 3.8GHz Digital Attenuator (October 2021)
  • El Cheapo Modules: 6GHz Digital Attenuator (November 2021)
  • El Cheapo Modules: 35MHz-4.4GHz Signal Generator (December 2021)
  • El Cheapo Modules: LTDZ Spectrum Analyser (January 2022)
  • Low-noise HF-UHF Amplifiers (February 2022)
  • A Gesture Recognition Module (March 2022)
  • Air Quality Sensors (May 2022)
  • MOS Air Quality Sensors (June 2022)
  • PAS CO2 Air Quality Sensor (July 2022)
  • Particulate Matter (PM) Sensors (November 2022)
  • Heart Rate Sensor Module (February 2023)
  • UVM-30A UV Light Sensor (May 2023)
  • VL6180X Rangefinding Module (July 2023)
  • pH Meter Module (September 2023)
  • 1.3in Monochrome OLED Display (October 2023)
  • 16-bit precision 4-input ADC (November 2023)
  • 1-24V USB Power Supply (October 2024)
  • 14-segment, 4-digit LED Display Modules (November 2024)
  • 0.91-inch OLED Screen (November 2024)
  • The Quason VL6180X laser rangefinder module (January 2025)
  • TCS230 Colour Sensor (January 2025)
  • Using Electronic Modules: 1-24V Adjustable USB Power Supply (February 2025)
Teach-In 2024 Learn electronics with the ESP32 by Mike Tooley Part 9 – Putting it all together I n the last part of our Teach-In series, we showed how a low-cost GPS module can be used with an ESP32 to provide location, navigation and time data. Our Practical Project involved the construction of a simple GPS location fixer using an ESP32 development board, a GPS module and a 20 × 4 LCD screen, while Coding Workshop looked at passing parameters into user-defined functions. In this final part, we begin by introducing keypad interfacing and our Practical Project deals with the construction of a simple passcode-protected entry control system. Coding Workshop deals with files and file handling, and shows how you can easily store data using an SD card interface. Checkpoint brings the series to a conclusion with another opportunity to test your knowledge of the ESP32. The learning objectives for the ninth part of our series are to know how to: n interface with a matrix keypad n set and use passcodes n read data from and write data to an SD (or microSD) card n use basic file handling techniques Keypads Many simple interfacing projects require only a few buttons and switches for user input. Where that’s the case, you can use some of the ESP32’s digital I/O pins configured as inputs as described previously in this Teach-In. However, if you need to deal with quite a few buttons or switches, things can get a little complicated, and you can Fig.9.1: A low-cost easily run out of 4 × 4 matrix digital inputs. keypad using individual button keys. 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 hands-on 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 Each month, there’ll be projects and challenges to help you check and develop your understanding of the topics covered. That’s certainly the case if you need to interface a keypad. Fortunately, those are usually arranged in the form of a matrix of rows and columns, requiring fewer of your precious I/O lines, leaving you more for other devices such as motors, relays and displays. Figs.9.1 & 9.2 show some typical low-cost matrix keypads suitable for use with the ESP32. They are both arranged as a 4 × 4 matrix, but the keypad in Fig.9.1 is based on 16 individual pushbutton keys while that shown in Fig.9.2 uses a membrane. Fig.9.3 shows their circuit arrangements, whilst Fig.9.4 shows pin numbering for the keypad’s 8-way ribbon connector in Fig.9.2. A standard 4 × 4 matrix keypad will give you a total of 16 keys to play with: 0 to 9 and A to D with additional * and # characters. The keys are placed at the intersection of the rows and columns so that, for example, when the A key is pressed, the top row is linked to the rightmost column and Fig.9.2: An alternative type of 4 × 4 matrix keypad. 42 Practical Electronics | November | 2024 Fig.9.3: The wiring diagram of the 4 × 4 matrix keypad. Fig.9.4: The ribbon cable numbering for the 4 × 4 matrix keypad. Fig.9.5: Connecting a keypad to an ESP32. consequently, pins 1 and 8 will be connected. On the other hand, if the key marked 9 is pressed, pins 3 and 7 will be joined. All we need to detect a keypress and decide which key is being pressed is code that will address the rows in turn and look for a signal returned on one of the columns. So, if pin 1 is taken high and a high level is detected on pin 8, the A key is being pressed. Similarly, if pin 3 is taken high and a high is detected on pin 7, the 9 key has been pressed. Note that in these cases, you would need some sort of pulldown on the input pins (either internal to the microcontroller or in the form of an external resistor) to ensure the pins stay low unless being pulled high via the keypad switches. Depending on your code, the key scanning could be done in a few places. If your program has an ‘inner loop’ that executes contiuously and loops frequently enough (say, at least 10 times per second), you could add a call to a function to scan the keypad within that inner loop. Alternatively, a better approach would be to use a timer to trigger an interrupt frequently (say, around 50 times per second) that could read the state of the inputs and note whether any key has been pressed (for the main loop to act on later). After that, it would update the state of the outputs to scan the next row or column. That method would work even if the code is busy with other tasks. Fig.9.6: A breadboard layout matching Fig.9.5, using joined jumper wires to make the connections. Practical Electronics | November | 2024 If that all sounds a bit complicated, fortunately, there’s no need to write your own keypad scanning code. Someone else has already performed that arduous task for you! Check it out To check out the matrix keypad, all you need is an eight-wire connection from the ESP32 development board to the keypad, as shown in Figs.9.5 & 9.6. The problem of connecting the keypad ribbon cable to the ESP32 is easily solved using a coloured ribbon multi-jumper lead with male and female connectors at the ends, as shown in Fig.9.7. When you’ve completed the wiring, you will need to download, compile and execute Listing 9.1. But before you do that, you will need to locate and install the keypad library. You can use the Library Manager to install the keypad library file. Open the Library Manager then click on “Tools”, followed by “Manage Libraries”. The Library Manager will open, and you will be presented with a list of installed libraries as well as those that are Fig.9.7: A close-up showing the wires used to connect to the keypad ribbon cable. Note the standard colour coding: 1 = brown, 2 = red, 3 = orange and so on. 43 Listing 9.1 – Keypad test code #include <Keypad.h> // Include the keypad library const byte ROWS = 4; // The keypad has four rows const byte COLS = 4; // and four columns char keys[ROWS][COLS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'}, }; // Use an array to hold the key values byte colPins[ROWS] = {16,17,18,19}; // Define the I/O byte rowPins[COLS] = {32,33,25,26}; // pin numbers Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS); void setup() { Serial.begin(9600); } // Initialize the Serial Monitor void loop() { char key = keypad.getKey(); if (key != NO_KEY){ Serial.println(key); } } Fig.9.8: Using the Library Manager to install the Keypad library. // Let's check the keypad // and if a key was // pressed, print it! available for installation. To shorten the list, enter “keypad” in the search field and then scroll down to find the keypad library, as shown in Fig.9.8. Having located the library, you just need to click on “INSTALL” and wait for the IDE to install it. Depending on the speed of your Internet connection, downloading might take a few minutes. When the installation is complete, you should notice that the “INSTALL” button has been replaced by a “REMOVE” button. You should also notice the messages that appear in the status window (see Fig.9.9). You can now close the Library Manager. To include the keypad (and before you make use of the keypad object), you will need to add this line at the beginning of the code: n n n n n an ESP32 development board on a breadboard a 4 × 4 keypad a backlit 16 × 2 alphanumeric LCD screen a 5V piezoelectric sounder a 3.3/5V relay module Practical project The ESP32 makes an ideal candidate for use in a wide range of simple security and alarm systems. Our Practical project this month shows how you can implement a simple but effective entry system. You will need the following items: The complete circuit of the simple entry system is shown in Fig.9.11. It uses low-cost, commonly available components. The 16 × 2 LCD screen and 16-key keypad are widely available from several suppliers, including those based in the Far East. The relay module is like those that we’ve used earlier in this Teach-In series: a 3.3/5V type with suitably rated contacts. Connection to the door solenoid is provided by a three-way terminal block fitted to the relay module. The breadboard layout is shown in Fig.9.12. In practise, the user enters a passcode consisting of a string of alphanumeric characters, followed by the ‘#’ key. A beep from the piezoelectric sounder provides confirmation that the user has entered a character on the keypad. When the correct passcode has been entered, the LED will illuminate and the relay will operate for a time that can be preset within the code. The passcode for access is also preset in the code. Listing 9.2 shows the complete code for the simple ESP32based entry system. As usual, we’ve added comments to help you understand what’s going on. The code requires three libraries; LiquidCrystal.h, keypad.h and Password.h. The first two of these provide functions that facilitate the use of the LCD display and the matrix keypad, whilst the third deals with setting and checking the passcode string. You could develop some of your own code to do those tasks, but there’s little point in doing that if someone else Fig.9.9: The meessages at the bottom of the window show that the Keypad library has been successfully installed. Fig.9.10: These characters in the Serial Monitor were generated by pressing buttons on the keypad. #include <Keypad.h> The keypad test code shown in Listing 9.1 is available for download from the PE website at https://pemag.au/link/abyx. When the code has been compiled and executed, you will be able to press the keys and note the characters displayed via the Serial Monitor (see Fig.9.10). 44 Practical Electronics | November | 2024 Listing 9.2 – Code for the simple ESP32 entry system Fig.9.11: The complete circuit diagram of the simple ESP32 entry system. // Include the library code: #include <LiquidCrystal_I2C.h> #include <Keypad.h> #include <Password.h> // Define the LCD display parameters int lcdColumns = 16; int lcdRows = 2; LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows); const byte ROWS = 4; // The keypad has four rows const byte COLS = 4; // and four columns char keys[ROWS][COLS] = { { '1', '2', '3', 'A' }, { '4', '5', '6', 'B' }, { '7', '8', '9', 'C' }, { '*', '0', '#', 'D' }, }; // Use an array to hold the key values byte colPins[ROWS] = { 16, 17, 18, 19 }; // Keypad byte rowPins[COLS] = { 32, 33, 25, 26 }; // pins int outPiezo = 2; // Audible transducer int outRelay = 15; // Door actuator relay has already provided a simple and elegant solution that they have shared with the rest of the community! The password library can be downloaded and installed using the Library Manager (as explained earlier). When you’ve corrected any coding errors reported by the compiler, you will be ready to execute your code. Just click on the arrow and watch the progress report. When the ESP32 performs a reset, you will see some characters appearing across the LCD for a short time, after which the display will clear and show the message, “Enter Passcode”. At this point, the ESP32 is waiting for user input from the keypad. If you then press a key, you will hear a beep from the piezoelectric sounder, which informs you that the character that you’ve pressed has been accepted. If you press several further characters in succession, followed by the ‘#’ key, the entered passcode will be checked and a message, either “Welcome” or “Invalid Passcode” will appear. If the correct passcode (ABCD) has been entered prior to the ‘#’ key, the relay module’s green LED should illuminate and the relay will operate for two seconds (sufficient to release the door). This time interval can easily be changed by modifying the value shown in the code. As usual, there’s a great deal of scope for going further with the entry control system. The most obvious enhancement would be the addition of access codes that would enable different levels of access (eg, open some doors but not others). A Fig.9.12: The complete ESP32 entry system, showing the backlit 16 × 2 LCD above the breadboard, the 4 × 4 matrix keypad at upper right and the relay at the bottom. Practical Electronics | November | 2024 Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS); Password password = Password(“ABCD”); // Can change void setup() { pinMode(outPiezo, OUTPUT); pinMode(outRelay, OUTPUT); // Initialize the LCD display lcd.init(); // Turn on the LCD backlight lcd.backlight(); // Deactivate the door relay digitalWrite(outRelay, HIGH); // High to deactivate // Set up the number of columns and rows on the LCD lcd.begin(16, 2); // Print a message to the LCD lcd.print(“Enter Passcode”); // Prompt the user keypad.addEventListener(keypadEvent); keypad.setDebounceTime(250); } void loop() { keypad.getKey(); } void keypadEvent(KeypadEvent eKey) { switch (keypad.getState()) { case PRESSED: lcd.setCursor(0, 1); lcd.print(“*”); digitalWrite(outPiezo, HIGH); // Keypress beep delay(50); digitalWrite(outPiezo, LOW); delay(50); lcd.setCursor(0, 1); lcd.print(“ “); switch (eKey) { case '#': checkPasscode(); break; // is right? default: password.append(eKey); } } } void checkPasscode() { if (password.evaluate()) { lcd.setCursor(0, 1); lcd.print(“* Welcome *”); // digitalWrite(outRelay, LOW); // Activate relay delay(2000); // and wait 2s digitalWrite(outRelay, HIGH); // Deactivate relay delay(2000); // afterwards lcd.setCursor(0, 1); lcd.print(“ “); password.reset(); // Reset passcode after valid entry } else { lcd.setCursor(0, 1); lcd.print(“* Invalid *”); delay(2000); lcd.setCursor(0, 1); lcd.print(“ “); password.reset(); // Reset after invalid entry } } 45 Next, you will need to set up the variables that you will be using with the SD library: // Set up variables for use with the SD library Sd2Card card; SdVolume volume; SdFile root; Fig.9.13: A typical microSD card module with an SPI interface. Note the onboard 3.3V regulator (on the left) and the 14-pin logic level translator IC to its right. The next step is rather important because you will need to specify the pin number that will be used for the chip select (CS) signal to the SD module. Because this varies with SD card modules and shields from different manufacturers, you will need to check the documentation supplied. Here’s a line of code that sets I/O pin 5 as the chip select line: // CS signal (change as required) const int chipSelect = 5; Reading and writing data Data can be very easily written to an SD card or read from it. lock-out feature could be incorporated to prevent multiple First you will need to initialize the card. This can be done attempts at code entry. This could enforce an obligatory time using a few lines of code: delay after, say, the third or fourth attempt. Alternatively, the system could be placed in a ‘lock down’ Serial.print("Initializing SD card..."); mode, triggering an alarm or sending a message to a remote if (!SD.begin(10)) { Serial.println("Card not ready!"); supervisory system. return; } Coding workshop For some applications, it can be useful to store data in the Serial.println("Card ready!"); form of a file that can be saved and later recalled or transNotice in this code that we’ve explicitly stated the pin used ferred to another system for further processing and analysis. This can be accomplished with the aid of an ordinary SD (or for the CS signal (in this case, pin 10). We could do this in a microSD) card and some simple code to handle the necessary more elegant way by defining the chip select pin as an integer file processing. at the start of the code, like this: The main difference between an SD card and a microSD card is the size; a microSD card can be placed in a passive const int chipSelect = 10; // CS on pin 10 adaptor for use in an SD card slot. The most convenient way of attaching an SD card is using We would then need to change the initializing code so that an outboard SD card module with an SPI bus interface like it reads as follows: that shown in Fig.9.13. We previously described the Serial Peripheral Interface (SPI) Serial.print("Initializing SD card..."); bus in Part 4 of Teach-in. The bus can operate at high speed if (!SD.begin(chipSelect)) { over short distances (faster than the I2C bus) and is thus ideal Serial.println("Card not ready!"); return; for transferring data to and from an SD card. } Serial.println("Card ready!"); Using the SD Library The Arduino’s built-in SD Library provides you with a useful Before you can write to a file you need to open it using the set of tools for reading from and writing to an SD card. The library supports the popular FAT16 and FAT32 file systems SD.open() function, as follows: commonly used with standard SD and SDHC cards. Filenames should follow the old DOS ‘8 + 3’ convention, and can include myFile = SD.open("data.dat", FILE_WRITE); paths separated by forward-slashes, ‘/’. It is worth noting that, because the working directory is always the root of the SD card, a name refers to the same file whether it includes a leading slash or not. Thus “mydata.dat” is the same as “/mydata.dat”. Note also that the SD library currently supports multiple file opening. To communicate with an SD card, you will need to make use of the SPI bus available on digital I/O pins 18, 19, and 23. A further pin must be used to select the SD card via the chip select (CS) pin. We’ve used pin 5, but an alternative pin can be specified in the call to SD.begin(). At the start of your code, you will need to include the SPI and SD card libraries: // Include the SD and SPI libraries #include <SPI.h> #include <SD.h> 46 Fig.9.14: The simple circuit of the ESP32 data logger. Practical Electronics | November | 2024 Fig.9.17(a): The pin connections for the unmounted DHT22 combined humidity/ temperature sensor. Fig.9.17(b): The pin connections for the mounted DHT22 combined humidity/ temperature sensor. Fig.9.15: The breadboard layout and wiring for the ESP32-based data logger. If the file opens without an error, you will be able to write myFile = SD.open("test.txt"); to it. If myFile returns true, the file has been opened, but if Then you need to read data from the file, sending it to the myFile returns false, an error has occurred and you will be Serial Monitor until you reach the end: unable to write to the file. Here’s some code that writes a series of values to the file if (myFile) { that we’ve (hopefully) just opened. Serial.println("test.txt:"); Note that you must close the file when you have finished while (myFile.available()) { writing to it to avoid data loss; closing the file ensures that Serial.write(myFile.read()); any data which has been buffered in RAM is written to the } SD card’s flash memory: myFile.close(); // Close the file } else { if (myFile) { // It didn’t open so print an error message Serial.print("Writing file ..."); Serial.println("Error opening the file!"); myFile.println("207, 188, 219, 155, 0"); } myFile.close(); // Close the file Serial.println(" done."); An ESP32 data logger } else { To put Coding workshop into context, let’s look at a simple // It didn’t open so print an error message ESP32 data logger that stores temperature and humidity data Serial.println("Error opening the file!"); obtained from a DHT22 sensor (described in Part 5). The data } will be written to an SD card and can then used for later Reading a file is just as easy. First, you need to open the analysis with virtually any spreadsheet package. Readings are taken and then stored periodically, allowing file for reading: you to later plot a graph showing how the temperature and Fig.9.16: The ESP32 data logger, assembled and ready to test. humidity changed over time. Having relative humidity and temperature readings also allows you to calculate absolute humidity values later, in case you are interested in that. The complete circuit of the data logging application is in Fig.9.14 and the wiring layout is given in Fig.9.15, while Fig.9.16 shows the prototype itself. The white DHT22 sensor to the right of the ESP32 is used to obtain temperature and humidity data. Fig.9.17(a) shows the pin connections for an unmounted sensor, while Fig.9.17(b) shows the pin numbering for a mounted sensor. Since there is some variation in the pin numbering Practical Electronics | November | 2024 47 Gotcha! Fig.9.18: Serial Monitor diagnostic messages confirming that an SD card is present and the data file has been found. between different manufacturers, it’s important to check your module’s pin connections before wiring it up (see the Gotcha! panel below). Listing 9.3 (opposite) shows the complete code for the ESP32 data logger. As always, we’ve included numerous comments in the code to help you understand what’s going on. The code requires three libraries: DHT.h (or dhtnew.h), SPI.h and SD.h. The first of these provide functions that facilitate the use of the DHT family of humidity/temperature sensors, whilst the second deals with the serial peripheral interface (SPI) used by the sensor, and the third provides the functions associated with reading from and writing to the SD card. Note that if you are using a very early version of the IDE, you might also need to include the mathematics library that provides the function for rounding the temperature values before they are stored on the SD card, <math.h>. The rounding function is important to remove the fractional part of the values returned from the sensor that might otherwise confuse a conventional spreadsheet program (which might regard the data as text rather than numerical). When you’ve corrected any coding errors that the compiler reports, you will be ready to execute the code. After the ESP32 performs a reset, if all is well you will be greeted by a It’s possible to substitute the lower-cost DHT11 for the DHT22 sensor. However, the 8-bit resolution of the DHT11 humidity/temperature sensor means that the readings will not have a decimal point (the fractional part will be zero). The more expensive (and more accurate) DHT22 fills the fractional parts with data. However, that isn’t crucial as the accuracy of the sensor is typically quoted as ±4% for relative humidity and ±2°C for temperature, making the data after the decimal point suspect. diagnostic message like that shown in Fig.9.18. If the SD card is not present, or if the SD card interface is not functioning correctly, the program will stop, and an error message will appear. If that is the case, the first thing to check is that you have set the chip select line correctly. Once the interface is ready, it will start to collect data, writing new information to the SD card on each pass through the loop. You should always wait until the program terminates before attempting to remove the SD card to transfer the data to a PC or other device. If you run the program several times (without removing the SD card), you will find that further data will be appended to the file (ie, added at the end). If necessary, you can always remove the SD card, place it in a card reader and simply rename the file manually if you want it to start a new file. The data stored on the SD card is in comma-delimited (CSV) format. On each pass, the data values will be displayed via the Serial Monitor and stored in the file saved to the SD card. The data displayed by the Serial Monitor should look like that shown in Fig.9.19. If you need to process or visualise this data, you can easily import it into a spreadsheet with each set of values appearing in a different column. Fig.9.19: The format of the data stored on the SD card (with the CSV format converted to columns in a spreadsheet). Fig.9.20: Similar data plotted in a chart using Microsoft Excel. 48 Gotcha! Gotcha! Some DHT22 manufacturers use different pinouts, so check the pin markings on the module that you are planning to use. If you are using a basic sensor in its fourpin package, connect a 10kΩ resistor between the data terminal (OUT) and the positive supply (VS or VCC). This ‘pull-up’ resistor is not needed if your sensor is already mounted on a PCB with an onboard pull-up resistor. Conventional SD cards are designed for operation from a 3.3V supply and thus it is necessary to ensure that the I/O levels and supply voltage are level-shifted within the hardware interface. This is normally the case with external modules, but it is important to check when modules may have been designed for operation with other systems and may have links or switches fitted. Practical Electronics | November | 2024 Listing 9.3 – A simple data logging application #include <dhtnew.h> #include <SPI.h> #include "SD.h" #include "FS.h" // DHT library // SPI library // SD library // File handling DHTNEW mySensor(16); #define SD_CS 5 const int interval = 5000; String dataMessage; String dataString = ""; // UART RXD input // CS output pin // Interval between readings // A string to hold the data void setup() { Serial.begin(115200); // Initialize the SD card Serial.println("Initializing SD card ..."); if (!SD.begin(SD_CS)) { Serial.println("SD card not mounted!"); return; } // Check the SD card type uint8_t cardType = SD.cardType(); if (cardType == CARD_NONE) { Serial.println("SD card missing!"); return; } // Open the data file File file = SD.open("/THDATA.DAT"); if (!file) { Serial.println("THDATA not found on this card!"); Serial.println("Creating the file ..."); writeFile(SD, "/THDATA.DAT", "Temperature and humidity data\r\n"); } else { Serial.println("File already exists!"); } file.close(); // Write data to the SD card void writeFile(fs::FS &fs, const char *path, const char *message) { Serial.printf("Writing the data file: %s\n", path); File file = fs.open(path, FILE_WRITE); if (!file) { Serial.println("Couldn't open file for writing"); return; } if (file.print(message)) { Serial.println("File written"); } else { Serial.println("File not written!"); } file.close(); } // Append data to the SD card void appendFile(fs::FS &fs, const char *path, const char *message) { Serial.printf("Appending to file: %s\n", path); File file = fs.open(path, FILE_APPEND); if (!file) { Serial.println("Couldn't open file for appending!"); return; } if (file.println(message)) { // ln ADDED Serial.println("Data appended to the file"); } else { Serial.println("Failed to append the data!"); } file.close(); } void readTHdata() { // Read data from the sensor mySensor.read(); } void loop() { readTHdata(); logSDCard(); delay(interval); //Wait before writing the next data } // Then display the returned data Serial.print("Temperature: "); Serial.print(mySensor.getTemperature(), 1); Serial.print(" deg.C\t"); Serial.print("Humidity: "); Serial.print(mySensor.getHumidity(), 1); Serial.println(" %\t"); // Log the current sensor readings void logSDCard() { dataMessage = dataString; Serial.print("Saving data: "); Serial.println(dataMessage); appendFile(SD, "/THDATA.DAT", dataMessage.c_str()); } // Now update the data dataString = ""; dataString += String(mySensor.getTemperature()); dataString += ","; // Comma separator dataString += String(mySensor.getHumidity()); dataString += ","; // Comma separator In common with many spreadsheet packages, if you open the data file in Excel, you will need to specify that the file uses ‘delimiters’ and that the delimiter is a comma. You may find that is the default since, while other delimiters are sometimes used, commas are the most common. Fig.9.20 shows how the data can be represented visually within Excel; other spreadsheet programs, like the free-to-use LibreOffice Calc, can be used to make similar plots. You can also perform numerical analysis, like calculating minimums, maximums, means, standard deviations and all sorts of other useful values. Check your spreadsheet’s help file or manual for details on how to perform those calculations. As always, there’s a great deal of scope for going further with the ESP32 data logger. Alarms could be set when critical values are detected and outputs could be used to operate indicators, piezoelectric sounders, and relays. Another refinement might be date/time stamping of the filename so that a unique name is generated every time the program is executed (keeping time was covered last month). Practical Electronics | November | 2024 } You could also add a column to the data generated that includes the date and time of the measurement, so that you can leave the device running long-term, then plot (for example) a full day’s worth of data by extracting that particular set of data points. The sky is the limit! Another, related improvement would be to change the main loop so that, rather than simply taking recordings at set intervals, it (for example) makes measurements every minute, on the minute. Even if you set the interval to be one minute long, it would ‘drift’ over time due to differences in how long each function call took and the exact time spent in the delay function (which can vary slightly between calls). So having a real-time clock or using a timer to determine when to make measurements would give more consistent results. All of those enhancements would be relatively simple to add and would provide you with a great opportunity to further develop your coding skills and learn more about how the ESP32 works. 49 Check Point Now that we’ve complete our Teach-in series, Check Point replaces our usual Teach-in challenge. This is a great an opportunity to test your knowledge of the ESP32. Just select one answer to each of these questions. When you’ve finished, you can check your answers at the end of the page. Good luck! 1. To use a library file called WebServer.h in your code, which one of the following lines would you use? (a) #include WebServer (b) #include “WebServer.h” (c) #include <WebServer.h> 2. Multi-line comments are enclosed within: (a) * and * (b) // and // (c) /* and */ 3. An IPv4 address requires: (a) two bytes (b) four bytes (c) eight bytes 4. On an I2C bus, the lines are: (a) usually pulled high; driven low when data is present (b) usually pulled low; driven high when data is present (c) always floating regardless of whether data is present 5. A digital input is fitted with a pull-up resistor. In the absence of any connection, this input will be in: (a) a low state (b) a high state (c) an indeterminate state 6. When using Wi-Fi, an ESP32: (a) can only be configured as a Server (b) can only be configured as an Access Point (c) can be configured either as an Access Point or a Server 7. Errors introduced in the calculations performed by a GPS/GNSS receiver are expressed in terms of: (a) dilution of precision (DOP) (b) a percentage of erroneous values (PEV) (c) received signal strength indication (RSSI) 8. Which serial bus uses SDA and SCL signals? (a) I2C (b) SPI (c) USB. 12. The individual segments of a typical seven-segment LED display are conventionally labelled: (a) a to g and decimal point (b) 0 to 9 and decimal point (c) 0 to 7 and decimal point 13. MOSI and MISO are signals present on the: (a) I2C bus (b) SPI bus (c) UART serial bus. 14. How many keys are present on a 4 × 4 matrix keypad? (a) 4 (b) 8 (c) 16 15. Internal pull-ups and pull-downs are available for: (a) all the ESP32’s digital I/O pins (b) none of the ESP32’s digital I/O pins (c) some of the ESP32’s digital I/O pins 16. Wi-Fi Protected Access (WPA) uses: (a) a pre-shared key (b) a trusted certificate (c) an encrypted passphrase 17. When x = 1 and y = 0.5, the expression pow(x, y) evalulates to: (a) 0.5 (b) 1 (c) 2 18. A Hall effect sensor responds to: (a) electric charge (b) magnetic field strength (c) temperature and humidity 19. Which one of the following lines contains an error? (a) int a == 1.59; (b) pinMode(32, INPUT); (c) const byte ROWS = 4; 20. When a function is declared void, it: (a) does not return a value (b) returns a value that’s discarded (c) generates an error when the code is executed 9. Why is an LCD panel often fitted with an I2C add-on? (a) To improve response time (b) To reduce the number of I/O lines required (c) To provide a buffer memory to retain display data. 10. To read the state of a digital I/O pin, you would use: (a) readInput(); (b) inputState(); (c) digitalRead(); Answers: 1. c 2. c 3. b 4. a 5. b 6. c 7. a 8. a 9. b 10. c 11. c 12. a 13. b 14. c 15. c 16. a 17. b 18. b 19. a 20. a How did you do? If you scored 19 or more, you’ve become 11. DHT11/DHT22 temperature/humidity interface via: an ESP32 expert! If you scored between 16 and 18, you’re (a) an I2C interface nearly there. It’s well taking another look at the earlier parts (b) an SPI bus interface PE of this Teach-in series if you scored 15 or less. (c) the ESP32’s serial UART interface 50 Practical Electronics | November | 2024