EMC/EMI Checklist Before Your Board Goes to Certification
EMC testing is expensive, and failing it is worse than the test fee — it costs you a respin, a
Looking to build a sleek, real-time temperature monitor with a visual gauge for your workshop, greenhouse, or smart home? Combining the incredibly popular ESP32 Cheap Yellow Display (CYD) with a DS18B20 temperature sensor and the powerful LVGL graphics library is the perfect solution.
This step-by-step guide, updated for 2026, will show you exactly how to create a professional-looking interface that displays temperature readings on a text label and a dynamic, color-changing curved gauge. You'll learn how to style LVGL objects, read sensor data accurately, and have a fully functional project running in under an hour.
Whether you're a maker building a climate control system or a hobbyist learning IoT displays, this guide provides the tested code and wiring instructions you need to succeed—without the usual library headaches.

Before we dive into the code, it's worth understanding why this specific combination of hardware and software is a smart investment for your project toolkit.
The ESP32 CYD (ESP32-2432S028R) : For around $15, you get an ESP32 development board with a built-in 2.8-inch touchscreen, microSD slot, and RGB LED. It's arguably the best value display board for IoT projects.
The DS18B20 Sensor: This waterproof, digital temperature sensor is incredibly accurate and uses the simple OneWire protocol, meaning it only requires one GPIO pin. It's perfect for remote sensing. You can find genuine DS18B20 sensors here.
LVGL: This open-source graphics library is the industry standard for embedded GUIs. Learning it now allows you to build far more complex interfaces later—think touch buttons, animations, and dashboards.
Ready to build? Let's get started.
To ensure your project compiles and runs without errors, you must follow these setup steps precisely. Using incorrect library configurations is the #1 reason projects fail.
1. Hardware You'll Need
ESP32 CYD Board (ESP32-2432S028R)
DS18B20 Temperature Sensor (TO-92 package or waterproof version)
4.7k Ohm Resistor (for the sensor's data line)
Jumper wires and a breadboard, or the JST connector that came with your CYD.
Micro USB Cable (for power and programming).
2. Software Setup: The "Must-Do" Steps
You will program the ESP32 using the Arduino IDE. Complete these tutorials in order:
Install ESP32 Boards: Follow our guide to add ESP32 support to your Arduino IDE: [Install ESP32 Boards in Arduino IDE].
Get to Know Your CYD: Understanding the pinout is critical. Start with our [Getting Started with ESP32 CYD Board] guide.
Install and Configure LVGL & TFT_eSPI: This is the most important step. LVGL (version 9.2 by kisvegabor) and TFT_eSPI require specific configuration files (lv_conf.h and User_Setup.h) to work with the CYD.
⚠️ CRITICAL: Using the default configuration files from the libraries will NOT work. You must download the exact files provided in our [CYD LVGL Setup Guide].
Install DS18B20 Libraries: You'll need two libraries from the Library Manager: OneWire by Paul Stoffregen and DallasTemperature by Miles Burton.
The DS18B20 uses the OneWire protocol, which requires a single data line and a pull-up resistor.
Connection Point: The CYD has a CN1 connector (often with a small JST pigtail) that breaks out several GPIO pins. We'll use GPIO 27 for the data pin.
Circuit:
Connect the DS18B20 VDD (red) pin to the CYD's 3.3V pin.
Connect the DS18B20 GND (black/blue) pin to the CYD's GND pin.
Connect the DS18B20 DATA (yellow/white) pin to the CYD's GPIO 27.
Connect a 4.7k Ohm resistor between the DATA pin and the 3.3V pin (this is the pull-up resistor).
(You can refer to the detailed CYD Pinout Guide here for exact pin locations.)
Create a new Arduino sketch and paste the code below. After pasting, you'll need to select your temperature unit and ensure your libraries are correctly configured as per the prerequisites.
/* Rui Santos & Sara Santos - Random Nerd Tutorials Complete guide at: https://RandomNerdTutorials.com/esp32-cyd-lvgl-temperature-ds18b20/ This example displays DS18B20 temperature on a CYD screen using LVGL. Temperature is shown on a text label (with color change) and an arc gauge. */ // --- REQUIRED LIBRARIES (Install via Library Manager) --- #include <lvgl.h> // LVGL library v9.2 by kisvegabor #include <TFT_eSPI.h> // TFT driver by Bodmer #include <OneWire.h> // OneWire by Paul Stoffregen #include <DallasTemperature.h> // DallasTemperature by Miles Burton // --- DS18B20 CONFIGURATION --- // GPIO pin where the DS18B20 data line is connected const int oneWireBus = 27; // Setup OneWire and DallasTemperature instances OneWire oneWire(oneWireBus); DallasTemperature sensors(&oneWire); // --- TEMPERATURE UNIT SELECTION --- // SET TO 1 FOR CELSIUS, SET TO 0 FOR FAHRENHEIT #define TEMP_CELSIUS 1 // Automatically set gauge range based on selected unit #if TEMP_CELSIUS #define TEMP_ARC_MIN -20 #define TEMP_ARC_MAX 40 #define DEGREE_SYMBOL "\u00B0C" #else #define TEMP_ARC_MIN -4 #define TEMP_ARC_MAX 104 #define DEGREE_SYMBOL "\u00B0F" #endif // --- DISPLAY CONFIGURATION (for the CYD) --- #define SCREEN_WIDTH 240 #define SCREEN_HEIGHT 320 #define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 10 * (LV_COLOR_DEPTH / 8)) uint32_t draw_buf[DRAW_BUF_SIZE / 4]; // LVGL log function for debugging via Serial void log_print(lv_log_level_t level, const char * buf) { LV_UNUSED(level); Serial.println(buf); Serial.flush(); } // LVGL objects that need to be accessed globally lv_obj_t * arc; // --- FUNCTION TO UPDATE TEMPERATURE (called by animation) --- static void set_temp(void * text_label_temp_value, int32_t v) { // Request fresh temperature from sensor sensors.requestTemperatures(); // Read temperature based on selected unit float ds18b20_temp; #if TEMP_CELSIUS ds18b20_temp = sensors.getTempCByIndex(0); #else ds18b20_temp = sensors.getTempFByIndex(0); #endif // --- Change Text Color Based on Temperature Range --- // Define thresholds for color change #if TEMP_CELSIUS float cold_threshold = 10.0; float hot_threshold = 29.0; #else float cold_threshold = 50.0; float hot_threshold = 84.2; #endif // Apply color style to the text label if(ds18b20_temp <= cold_threshold) { lv_obj_set_style_text_color((lv_obj_t*) text_label_temp_value, lv_palette_main(LV_PALETTE_BLUE), 0); } else if (ds18b20_temp > cold_threshold && ds18b20_temp <= hot_threshold) { lv_obj_set_style_text_color((lv_obj_t*) text_label_temp_value, lv_palette_main(LV_PALETTE_GREEN), 0); } else { lv_obj_set_style_text_color((lv_obj_t*) text_label_temp_value, lv_palette_main(LV_PALETTE_RED), 0); } // --- Update Arc Gauge Value --- // Map the temperature reading to the arc's 0-100 range int arc_value = map((int)ds18b20_temp, TEMP_ARC_MIN, TEMP_ARC_MAX, 0, 100); arc_value = constrain(arc_value, 0, 100); // Prevent out-of-bounds values lv_arc_set_value(arc, arc_value); // --- Update Text Label with Temperature --- String temp_text = String(ds18b20_temp, 1) + DEGREE_SYMBOL; // One decimal place lv_label_set_text((lv_obj_t*) text_label_temp_value, temp_text.c_str()); // Debug output to Serial Monitor Serial.print("Temperature: "); Serial.println(temp_text); } // --- FUNCTION TO CREATE THE USER INTERFACE --- void lv_create_main_gui(void) { // Create an Arc (curved gauge) object arc = lv_arc_create(lv_screen_active()); lv_obj_set_size(arc, 210, 210); // Set size lv_arc_set_rotation(arc, 135); // Start angle offset lv_arc_set_bg_angles(arc, 0, 270); // Background arc angle (270 degrees for a 3/4 gauge) // Style the indicator and knob lv_obj_set_style_arc_color(arc, lv_color_hex(0x666666), LV_PART_INDICATOR); lv_obj_set_style_bg_color(arc, lv_color_hex(0x333333), LV_PART_KNOB); lv_obj_align(arc, LV_ALIGN_CENTER, 0, 10); // Position on screen // Create a text label to display the temperature value lv_obj_t * text_label_temp_value = lv_label_create(lv_screen_active()); lv_label_set_text(text_label_temp_value, "--.-"); // Placeholder lv_obj_align(text_label_temp_value, LV_ALIGN_CENTER, 0, 10); // Center on screen // Apply a larger font style to the text label static lv_style_t style_temp; lv_style_init(&style_temp); lv_style_set_text_font(&style_temp, &lv_font_montserrat_32); // Use built-in 32px font lv_obj_add_style(text_label_temp_value, &style_temp, 0); // --- Create an Animation to Update Temperature Periodically --- lv_anim_t a_temp; lv_anim_init(&a_temp); lv_anim_set_exec_cb(&a_temp, set_temp); // Function to call lv_anim_set_duration(&a_temp, 2000); // Update every 2000ms (2 seconds) lv_anim_set_playback_duration(&a_temp, 2000); // For infinite repeat, same as duration lv_anim_set_var(&a_temp, text_label_temp_value); // Pass the label object to the function lv_anim_set_values(&a_temp, 0, 100); // Dummy values, not used by callback lv_anim_set_repeat_count(&a_temp, LV_ANIM_REPEAT_INFINITE); // Loop forever lv_anim_start(&a_temp); } // --- SETUP FUNCTION: Runs once at startup --- void setup() { // Initialize Serial Monitor for debugging Serial.begin(115200); Serial.println("ESP32 CYD DS18B20 Temperature Monitor Starting..."); // Initialize DS18B20 sensor sensors.begin(); // Initialize LVGL lv_init(); lv_log_register_print_cb(log_print); // Enable debug logs // Create the display object (using the TFT_eSPI driver configured for CYD) lv_display_t * disp; disp = lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf)); lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270); // Correct rotation for CYD // Build the user interface lv_create_main_gui(); Serial.println("Setup Complete. GUI Running."); } // --- LOOP FUNCTION: Runs continuously --- void loop() { // LVGL core tasks: Handle rendering and animation updates lv_task_handler(); lv_tick_inc(5); // Tell LVGL that 5ms have passed delay(5); // Small delay to prevent watchdog issues }
Understanding the code will help you customize it for your own projects.
Sensor Reading: The sensors.requestTemperatures() and sensors.getTempCByIndex(0) functions (from the DallasTemperature library) handle all the OneWire communication to get a clean temperature value.
Unit Selection: The #define TEMP_CELSIUS 1 line is a simple switch. Change it to 0 and re-upload to display Fahrenheit. The gauge range and degree symbol update automatically thanks to the #if TEMP_CELSIUS ... #else ... #endif preprocessor directives.
Dynamic Styling: Inside the set_temp() function, lv_obj_set_style_text_color() is used to change the label's color based on simple if statements comparing the temperature to thresholds. This creates an intuitive visual alert system.
The Arc Gauge: The lv_arc object is created and styled. Its value is set using lv_arc_set_value(). Note the map() function converts the temperature range (e.g., -20 to 40) to the arc's internal range (0 to 100).
Animation for Updates: Instead of using delay() in the loop(), which would freeze the GUI, we use an LVGL animation. lv_anim_set_exec_cb(&a_temp, set_temp) tells LVGL to call our set_temp() function every 2 seconds (lv_anim_set_duration(&a_temp, 2000)). This is the professional way to handle periodic tasks in a GUI.
Verify Your Files: Ensure you have the custom lv_conf.h and User_Setup.h files in the correct locations as per the setup guide.
Select Board and Port: In Arduino IDE, go to Tools > Board and select ESP32 Dev Module. Then select the correct COM Port.
Upload: Click the upload button. Open the Serial Monitor (set to 115200 baud) to see debug output.
See the Result: After uploading, your CYD screen should show a gray arc and a temperature reading in the center. The text color will be blue, green, or red based on the temperature. Touch the sensor to see the value and gauge move!
(Image: Your CYD displaying the temperature on the arc gauge)
Screen is Blank or White: This is 99% a library configuration issue. Revisit the CYD LVGL Setup Guide and ensure you've replaced the default lv_conf.h and User_Setup.h files with the ones provided.
Temperature Reads -127°C or 85°C: This is the sensor's "error" value.
Check your wiring: Is the 4.7k pull-up resistor connected correctly between DATA and 3.3V?
Check the GPIO pin: Is the code set to 27 and is your sensor connected to that pin?
Text or Gauge Not Updating: The animation might not be starting. Check the Serial Monitor for any LVGL error logs. Ensure you haven't added a long delay() somewhere in your code, as this will block LVGL.
Brownout Errors: If your ESP32 resets repeatedly, your power source may be weak. Use a good quality USB cable and a USB port that can supply sufficient current.
You've just built a core component of any environmental monitoring system. This same principle can be extended to:
Multi-Sensor Dashboard: Add a DHT22 for humidity and display both values.
Smart Thermostat Controller: Add touch buttons to set a target temperature and control a relay.
Data Logger: Use the CYD's microSD card slot to log temperature readings over time.
If you're ready to move from single sensors to complete, connected home automation systems, our eBook "Build a Home Automation System for Beginners" guides you through using the ESP32, LVGL, and Node-RED to create a professional, Wi-Fi-enabled control panel.
Congratulations! You've successfully built a smart, visually appealing temperature monitor. You've not only learned how to read a sensor but also mastered essential LVGL techniques like creating arcs, dynamic styling, and using animations—skills that form the foundation for any sophisticated embedded GUI project.
The ESP32 CYD is an unbeatable platform for learning and prototyping. Now go ahead and experiment—change the colors, add a second sensor, or design a new layout. The possibilities are endless.
======================================
Grove Infrared Emitter used to transmit infrared signals through an infrared LED
$8.50
E6 7.3-inch Color E-Paper Frame Solid Wood Design Ultra-Long Standby 800x480 E Ink Photo Frame
$86.70
Official Raspberry Pi 5 Case Red White ABS Shell with Fan Support Cluster Stacking for RPI 5 P
$15.90
Rocketek CSCR3 Smart CAC Card Reader Type-c Bank Tax Declaration SIM Card/IC Card ID Card Reader
$11.90
USB to Micro USB Connector USB-H Black for 5 inch HDMI-compatible Raspberry Pi Screen Display Monitor for Pi Screen 2B/3B/3B+/4B
$2.90 – $5.20Price range: $2.90 through $5.20
EMC testing is expensive, and failing it is worse than the test fee — it costs you a respin, a
We review a lot of boards — some designed in-house, some by other contractors, some by founders doing their own
When a battery-powered product dies too soon, the instinct is to blame the firmware. Surely there is a sleep mode
A wearable PCB is not just a small PCB. It is a board where every constraint that normally has some
The STM32 family is the workhorse of embedded hardware, and almost every project that uses one starts the same way:
The nRF52840 is one of the most popular BLE and multiprotocol chips in the world, and for good reason: it
No account yet?
Create an Account