Comprehensive Guide: Programming the ESP32 CYD (Cheap Yellow Display) with VS Code and PlatformIO

Introduction to ESP32 CYD Development

The ESP32 CYD (Cheap Yellow Display) represents a breakthrough in affordable embedded systems development, combining the powerful ESP32 microcontroller with an integrated 2.8-inch TFT touchscreen. This all-in-one solution eliminates the need for complex wiring between separate components, making it ideal for IoT dashboards, smart home controllers, wearable devices, and industrial HMIs. While many tutorials focus on the Arduino IDE for ESP32 CYD development, this comprehensive guide explores a more professional approach using Visual Studio Code with PlatformIO, offering superior code management, debugging capabilities, and library handling.

This tutorial not only covers basic setup but also dives deep into configuring the essential libraries—TFT_eSPI, XPT2046_Touchscreen, and LVGL—that transform this budget-friendly board into a capable interactive display platform. Whether you’re building a weather station interface, a retro gaming console, or a custom control panel, mastering VS Code with the ESP32 CYD will significantly accelerate your development workflow and project sophistication.

Prerequisites for ESP32 CYD Development

Before diving into the programming process, ensure you have the following components and knowledge:

Software Requirements:

  • Visual Studio Code (latest stable version)

  • PlatformIO IDE extension for VS Code

  • Basic familiarity with C/C++ programming

  • Git (for library management)

Hardware Requirements:

  • ESP32 CYD board (ESP32-2432S028R) or compatible variant

  • USB-C cable for programming and power

  • Computer with available USB port

Prior Experience:

  • Basic ESP32 programming concepts

  • Understanding of SPI communication protocol

  • Previous experience with Arduino IDE (helpful but not mandatory)

  • Familiarity with library management in embedded development

Note: This guide also applies if you’re using a standard ESP32 development board with a separate 2.8-inch ILI9341 240×320 TFT LCD touchscreen. The configuration steps remain largely identical, with only minor pin assignment differences.

Setting Up VS Code and PlatformIO

Installation Process

  1. Download and Install VS Code: Visit the official Visual Studio Code website and download the appropriate version for your operating system (Windows, macOS, or Linux). Follow the standard installation procedure.

  2. Install PlatformIO Extension:

    • Open VS Code and navigate to the Extensions view (Ctrl+Shift+X or Cmd+Shift+X on macOS)

    • Search for “PlatformIO IDE”

    • Click “Install” on the official PlatformIO extension by PlatformIO

    • Wait for the installation to complete (this may take several minutes as PlatformIO downloads necessary toolchains)

  3. Initial PlatformIO Configuration:

    • After installation, you’ll see the PlatformIO icon (an alien head) in the VS Code activity bar

    • Click this icon to open the PlatformIO Home screen

    • PlatformIO will automatically set up the ESP32 toolchain on first launch

Creating Your First ESP32 CYD Project

  1. From PlatformIO Home, select “New Project”

  2. Name your project (e.g., “ESP32_CYD_Test”)

  3. Select “Espressif ESP32” as the board

  4. Choose “ESP32 Dev Module” as the specific board (the CYD uses a standard ESP32)

  5. Select “Arduino” as the framework

  6. Choose your project location and click “Finish”

PlatformIO will create a project structure with a src folder (for your code) and a critical platformio.ini file (for project configuration). This initialization process demonstrates the professional workflow advantage of PlatformIO over Arduino IDE, with proper project separation and dependency management.

Installing Essential Libraries for ESP32 CYD

Understanding Library Dependencies

The ESP32 CYD requires three core libraries for full functionality:

  1. TFT_eSPI: Handles display graphics and text rendering

  2. XPT2046_Touchscreen: Manages touch input from the resistive touch layer

  3. LVGL (optional but recommended): Provides advanced graphical user interface elements

Installing XPT2046_Touchscreen Library

Unlike the Arduino IDE where libraries can be installed via the Library Manager, PlatformIO requires a different approach for the XPT2046_Touchscreen library due to known compatibility issues:

  1. Open your project’s platformio.ini file

  2. Add the following line under the [env:esp32dev] section (or your environment name):

ini
lib_deps = 
    https://github.com/PaulStoffregen/XPT2046_Touchscreen.git
  1. Save the file. PlatformIO will automatically download and install this library from GitHub on the next build.

Expert Tip: Adding libraries via GitHub URLs ensures you get the latest version directly from the source, which is particularly important for frequently updated libraries like XPT2046_Touchscreen. This method also provides better version control than the PlatformIO library registry for this specific library.

Installing TFT_eSPI Library

The TFT_eSPI library can be installed through PlatformIO’s Library Manager:

  1. Click the PlatformIO icon in the activity bar

  2. Select “Libraries” from the PlatformIO menu

  3. Search for “TFT_eSPI” in the search bar

  4. Find the library by Bodmer (the official version)

  5. Click “Add to Project” and select your current ESP32 CYD project

Alternatively, you can add it directly to your platformio.ini file:

ini
lib_deps = 
    https://github.com/PaulStoffregen/XPT2046_Touchscreen.git
    bodmer/TFT_eSPI@^2.5.43

The version specification (@^2.5.43) ensures compatibility while allowing minor updates. After adding, your platformio.ini should also include these essential settings for proper serial monitoring:

ini
monitor_speed = 115200
upload_speed = 921600
board_build.flash_mode = dio

Configuring the TFT_eSPI Library for ESP32 CYD

The Critical User_Setup.h File

The TFT_eSPI library requires specific configuration for each display type through a User_Setup.h file. Generic configurations available online often won’t work correctly with the ESP32 CYD, leading to display issues, incorrect colors, or touch calibration problems.

Step-by-Step Configuration Process

  1. Locate the TFT_eSPI library in your project:

    • In VS Code’s Explorer panel, navigate to: .pio/libdeps/esp32dev/TFT_eSPI

    • The esp32dev portion may vary based on your board selection during project creation

  2. Find and open User_Setup.h:

    • Within the TFT_eSPI folder, locate User_Setup.h

    • This file contains numerous configuration options for different displays

  3. Replace with ESP32 CYD specific configuration:

    • Download the pre-configured User_Setup.h file specifically tested for ESP32 CYD

    • Completely replace the contents of the existing User_Setup.h with the downloaded version

    • Save the file

  4. Key Configuration Details:
    The correct User_Setup.h for ESP32 CYD should include these essential definitions:

cpp
#define ILI9341_DRIVER
#define TFT_WIDTH  240
#define TFT_HEIGHT 320
#define TFT_MISO 39
#define TFT_MOSI 32
#define TFT_SCLK 25
#define TFT_CS   33
#define TFT_DC   15
#define TFT_RST  32
#define TOUCH_CS 33
#define LOAD_GLCD
#define LOAD_FONT2
#define SPI_FREQUENCY  40000000
#define SPI_TOUCH_FREQUENCY  2500000

Critical Note: Using an incorrect User_Setup.h file is the most common source of problems when working with TFT displays on ESP32. The configuration must match exactly the pin assignments and display driver of your specific hardware. Random Nerd Tutorials provides a tested configuration that accounts for the ESP32 CYD’s unique pin mapping and ILI9341 display controller characteristics.

Testing Display and Touchscreen Functionality

Complete Test Sketch

After installing and configuring the libraries, verify everything works correctly with this comprehensive test code:

cpp
#include <SPI.h>
#include <TFT_eSPI.h>
#include <XPT2046_Touchscreen.h>

TFT_eSPI tft = TFT_eSPI();

// ESP32 CYD touchscreen pin definitions
#define XPT2046_IRQ 36   // T_IRQ
#define XPT2046_MOSI 32  // T_DIN
#define XPT2046_MISO 39  // T_OUT
#define XPT2046_CLK 25   // T_CLK
#define XPT2046_CS 33    // T_CS

SPIClass touchscreenSPI = SPIClass(VSPI);
XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);

#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
#define FONT_SIZE 2

void setup() {
  Serial.begin(115200);
  
  // Initialize touchscreen SPI
  touchscreenSPI.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
  touchscreen.begin(touchscreenSPI);
  touchscreen.setRotation(1); // Landscape mode
  
  // Initialize display
  tft.init();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  
  // Display welcome message
  tft.drawCentreString("ESP32 CYD Ready", SCREEN_WIDTH/2, 50, FONT_SIZE);
  tft.drawCentreString("Touch to Test", SCREEN_WIDTH/2, 100, FONT_SIZE);
  tft.drawCentreString("Check Serial Monitor", SCREEN_WIDTH/2, 150, FONT_SIZE);
  
  Serial.println("ESP32 CYD Test Initialized");
}

void loop() {
  if (touchscreen.tirqTouched() && touchscreen.touched()) {
    TS_Point p = touchscreen.getPoint();
    
    // Calibrate raw touch coordinates to screen dimensions
    int x = map(p.x, 200, 3700, 1, SCREEN_WIDTH);
    int y = map(p.y, 240, 3800, 1, SCREEN_HEIGHT);
    int z = p.z;
    
    // Display touch coordinates
    tft.fillRect(0, 180, SCREEN_WIDTH, 60, TFT_BLACK);
    tft.drawCentreString("X: " + String(x), SCREEN_WIDTH/2, 180, FONT_SIZE);
    tft.drawCentreString("Y: " + String(y), SCREEN_WIDTH/2, 200, FONT_SIZE);
    tft.drawCentreString("Pressure: " + String(z), SCREEN_WIDTH/2, 220, FONT_SIZE);
    
    // Print to serial monitor
    Serial.printf("Touch - X: %d, Y: %d, Pressure: %d\n", x, y, z);
    
    delay(200); // Debounce delay
  }
}

Upload and Verification Process

  1. Build the Project: Click the checkmark icon in the blue bottom status bar (or press Ctrl+Alt+B) to compile the code

  2. Upload to ESP32 CYD: Click the right-arrow icon (or press Ctrl+Alt+U) to upload the compiled code

  3. Open Serial Monitor: Click the plug icon (or press Ctrl+Alt+S) to open the serial monitor at 115200 baud

  4. Expected Results:

    • The display should show a welcome message

    • Touching the screen should display coordinates on both the display and serial monitor

    • The touch pressure value should increase when pressing harder

Troubleshooting Common Issues

Problem Possible Cause Solution
Blank or white screen Incorrect User_Setup.h Verify User_Setup.h matches ESP32 CYD exactly
Touch coordinates incorrect Calibration values off Adjust map() function parameters in test code
Display colors distorted Wrong color mode setting Ensure TFT_RGB_ORDER is correctly set in User_Setup.h
SPI conflicts Multiple SPI devices Ensure proper CS pin selection and SPI bus separation

Installing and Configuring LVGL for Advanced GUIs

Why LVGL for ESP32 CYD?

LVGL (Light and Versatile Graphics Library) is a professional open-source embedded graphics library that enables sophisticated user interfaces on microcontrollers. While the TFT_eSPI library handles basic drawing functions, LVGL provides:

  • Advanced widgets (buttons, sliders, charts, lists)

  • Animations and transitions

  • Multi-language support

  • Memory-efficient rendering

  • Touch gesture recognition

For projects requiring more than basic text and shapes, LVGL transforms the ESP32 CYD into a capable platform for modern GUI applications.

Installation Process

  1. Add LVGL to PlatformIO Project:

    • Open PlatformIO Libraries (PIO Home → Libraries)

    • Search for “lvgl”

    • Select version 9.x (latest stable)

    • Click “Add to Project” and select your ESP32 CYD project

  2. Create lv_conf.h Configuration File:

    • In your project’s root directory, create a new file named lv_conf.h

    • Copy the LVGL configuration template specifically designed for ESP32 CYD:

cpp
#ifndef LV_CONF_H
#define LV_CONF_H

#define LV_MEM_SIZE (32 * 1024)  // Increased memory for ESP32
#define LV_HOR_RES_MAX 320
#define LV_VER_RES_MAX 240
#define LV_COLOR_DEPTH 16
#define LV_USE_GPU_STM32_DMA2D 0
#define LV_USE_LOG 1
#define LV_LOG_PRINTF 1
#define LV_USE_ASSERT_NULL 1
#define LV_USE_ASSERT_MEM 1
#define LV_USE_ASSERT_OBJ 1
#define LV_USE_USER_DATA 1

// Enable required widgets
#define LV_USE_LABEL 1
#define LV_USE_BUTTON 1
#define LV_USE_BUTTONMATRIX 1
#define LV_USE_CHECKBOX 1
#define LV_USE_SLIDER 1
#define LV_USE_DROPDOWN 1
// Add other widgets as needed

#endif /*LV_CONF_H*/
  1. Update platformio.ini: Ensure your configuration includes sufficient memory allocation:

ini
board_build.partitions = huge_app.csv
build_flags = 
    -DBOARD_HAS_PSRAM
    -mfix-esp32-psram-cache-issue
lib_ldf_mode = deep+

LVGL Initialization Code

Integrate LVGL with your existing TFT_eSPI and touchscreen setup:

cpp
#include <lvgl.h>
#include <TFT_eSPI.h>
#include <XPT2046_Touchscreen.h>

TFT_eSPI tft = TFT_eSPI();
XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);

static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[SCREEN_WIDTH * SCREEN_HEIGHT / 10];

void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  uint32_t w = (area->x2 - area->x1 + 1);
  uint32_t h = (area->y2 - area->y1 + 1);
  
  tft.startWrite();
  tft.setAddrWindow(area->x1, area->y1, w, h);
  tft.pushColors((uint16_t *)&color_p->full, w * h, true);
  tft.endWrite();
  
  lv_disp_flush_ready(disp);
}

void touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) {
  if (touchscreen.touched()) {
    TS_Point p = touchscreen.getPoint();
    data->point.x = map(p.x, 200, 3700, 0, SCREEN_WIDTH);
    data->point.y = map(p.y, 240, 3800, 0, SCREEN_HEIGHT);
    data->state = LV_INDEV_STATE_PR;
  } else {
    data->state = LV_INDEV_STATE_REL;
  }
}

void setup() {
  Serial.begin(115200);
  
  // Initialize display
  tft.init();
  tft.setRotation(1);
  
  // Initialize touchscreen
  touchscreen.begin();
  
  // Initialize LVGL
  lv_init();
  lv_disp_draw_buf_init(&draw_buf, buf, NULL, SCREEN_WIDTH * SCREEN_HEIGHT / 10);
  
  // Initialize display driver
  static lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv);
  disp_drv.hor_res = SCREEN_WIDTH;
  disp_drv.ver_res = SCREEN_HEIGHT;
  disp_drv.flush_cb = my_disp_flush;
  disp_drv.draw_buf = &draw_buf;
  lv_disp_drv_register(&disp_drv);
  
  // Initialize input device driver
  static lv_indev_drv_t indev_drv;
  lv_indev_drv_init(&indev_drv);
  indev_drv.type = LV_INDEV_TYPE_POINTER;
  indev_drv.read_cb = touchpad_read;
  lv_indev_drv_register(&indev_drv);
  
  // Create a simple button as test
  lv_obj_t *btn = lv_btn_create(lv_scr_act());
  lv_obj_set_size(btn, 100, 50);
  lv_obj_center(btn);
  
  lv_obj_t *label = lv_label_create(btn);
  lv_label_set_text(label, "Click Me!");
  lv_obj_center(label);
  
  Serial.println("LVGL Initialized with ESP32 CYD");
}

void loop() {
  lv_timer_handler();
  delay(5);
}

Building a Complete ESP32 CYD Project

Sample Application: IoT Dashboard

Combine all learned elements into a practical IoT dashboard example:

cpp
// ESP32 CYD IoT Dashboard
// Displays sensor data with LVGL widgets

#include <lvgl.h>
#include <TFT_eSPI.h>
#include <XPT2046_Touchscreen.h>
#include <WiFi.h>
#include <HTTPClient.h>

// Display and touch objects
TFT_eSPI tft;
XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);

// LVGL objects
lv_obj_t *temperatureLabel;
lv_obj_t *humidityLabel;
lv_obj_t *pressureLabel;
lv_obj_t *chart;
lv_chart_series_t *tempSeries;

// WiFi credentials
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";

// Weather API
const String apiKey = "YOUR_API_KEY";
const String city = "London";

void updateWeatherData() {
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    String url = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "&appid=" + apiKey + "&units=metric";
    
    http.begin(url);
    int httpCode = http.GET();
    
    if (httpCode == 200) {
      String payload = http.getString();
      // Parse JSON response (simplified)
      float temperature = 22.5; // Extract from JSON
      float humidity = 65;      // Extract from JSON
      float pressure = 1013;    // Extract from JSON
      
      // Update LVGL labels
      lv_label_set_text_fmt(temperatureLabel, "Temp: %.1f°C", temperature);
      lv_label_set_text_fmt(humidityLabel, "Humidity: %.0f%%", humidity);
      lv_label_set_text_fmt(pressureLabel, "Pressure: %.0fhPa", pressure);
      
      // Update chart
      lv_chart_set_next_value(chart, tempSeries, temperature);
    }
    http.end();
  }
}

void setup() {
  Serial.begin(115200);
  
  // Initialize display
  tft.init();
  tft.setRotation(1);
  
  // Initialize touchscreen
  touchscreen.begin();
  
  // Initialize LVGL
  lv_init();
  // ... LVGL initialization code from previous section
  
  // Connect to WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("WiFi connected");
  
  // Create UI
  lv_obj_t *scr = lv_scr_act();
  
  // Title
  lv_obj_t *title = lv_label_create(scr);
  lv_label_set_text(title, "ESP32 CYD Weather Dashboard");
  lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 10);
  
  // Data labels
  temperatureLabel = lv_label_create(scr);
  lv_label_set_text(temperatureLabel, "Temp: -- °C");
  lv_obj_align(temperatureLabel, LV_ALIGN_LEFT_MID, 20, -40);
  
  humidityLabel = lv_label_create(scr);
  lv_label_set_text(humidityLabel, "Humidity: --%");
  lv_obj_align(humidityLabel, LV_ALIGN_LEFT_MID, 20, -10);
  
  pressureLabel = lv_label_create(scr);
  lv_label_set_text(pressureLabel, "Pressure: -- hPa");
  lv_obj_align(pressureLabel, LV_ALIGN_LEFT_MID, 20, 20);
  
  // Chart
  chart = lv_chart_create(scr);
  lv_obj_set_size(chart, 150, 100);
  lv_obj_align(chart, LV_ALIGN_RIGHT_MID, -20, 0);
  lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 40);
  lv_chart_set_point_count(chart, 20);
  tempSeries = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
  
  // Update button
  lv_obj_t *btn = lv_btn_create(scr);
  lv_obj_set_size(btn, 100, 40);
  lv_obj_align(btn, LV_ALIGN_BOTTOM_MID, 0, -20);
  lv_obj_t *btnLabel = lv_label_create(btn);
  lv_label_set_text(btnLabel, "Update");
  lv_obj_center(btnLabel);
  
  // Button event
  lv_obj_add_event_cb(btn, [](lv_event_t *e) {
    updateWeatherData();
  }, LV_EVENT_CLICKED, NULL);
  
  // Initial data update
  updateWeatherData();
}

void loop() {
  lv_timer_handler();
  
  // Auto-update every 30 seconds
  static unsigned long lastUpdate = 0;
  if (millis() - lastUpdate > 30000) {
    updateWeatherData();
    lastUpdate = millis();
  }
  
  delay(5);
}

Advanced Tips and Best Practices

Optimizing Performance

  1. Use PSRAM Effectively: The ESP32 CYD includes 8MB of PSRAM. Enable it in platformio.ini:

    ini
    board_build.partitions = huge_app.csv
    build_flags = 
        -DBOARD_HAS_PSRAM
        -mfix-esp32-psram-cache-issue
  2. LVGL Memory Optimization:

    • Adjust LV_MEM_SIZE in lv_conf.h based on your widget complexity

    • Use lv_disp_set_draw_buffers() for double buffering

    • Enable compression for images: #define LV_USE_IMG_COMPRESSED 1

  3. Display Refresh Optimization:

    • Set appropriate SPI frequency (40MHz works well for ESP32 CYD)

    • Use tft.setSwapBytes(true) for correct color order

    • Implement partial updates where possible instead of full screen refreshes

Troubleshooting Advanced Issues

Advanced Issue Diagnosis Method Solution
LVGL lag or slow response Monitor frame rate with lv_refr_get_fps_avg() Reduce widget count, optimize drawing callbacks, increase LVGL tick rate
Memory fragmentation Monitor heap with ESP.getFreeHeap() Use PSRAM for buffers, implement memory pooling for frequently created/destroyed objects
SPI conflicts with other peripherals Check SPI bus usage conflicts Use different SPI buses (HSPI/VSPI) for display vs other sensors
Touch calibration drift Log raw touch values over time Implement dynamic calibration, store calibration data in NVS

Version Management Best Practices

  1. Library Version Pinning: Always specify library versions in platformio.ini to ensure consistent builds:

    ini
    lib_deps = 
        bodmer/TFT_eSPI@2.5.43
        https://github.com/PaulStoffregen/XPT2046_Touchscreen.git#v1.4.0
        lvgl/lvgl@9.2.0
  2. Configuration File Management: Store your User_Setup.h and lv_conf.h files in a version control system separate from the library installations.

  3. Project Templates: Create a baseline ESP32 CYD project with all configurations pre-set, then duplicate it for new projects rather than reconfiguring each time.

Conclusion and Further Resources

The ESP32 CYD, when combined with VS Code and PlatformIO, becomes a powerful development platform for interactive display applications. By following this comprehensive guide, you’ve established a professional development environment, configured all necessary libraries, and learned to create both basic and advanced applications with LVGL.

Key Takeaways:

  • VS Code with PlatformIO offers superior project management compared to Arduino IDE

  • Proper library configuration is critical—especially the User_Setup.h file for TFT_eSPI

  • LVGL enables professional-grade user interfaces on the ESP32 CYD

  • Regular testing at each configuration step prevents compound issues

Next Steps to Expand Your ESP32 CYD Skills:

  1. Explore LVGL Widgets: Experiment with advanced widgets like charts, meters, rollers, and text areas

  2. Add External Sensors: Connect I2C or SPI sensors to create complete monitoring systems

  3. Implement Power Saving: Use ESP32 deep sleep modes with display power management for battery-powered projects

  4. Create Custom Themes: Design unique visual styles with LVGL’s theme system

  5. Add Wireless Connectivity: Implement MQTT for IoT dashboards or Bluetooth for peripheral control

Additional Resources:

With this foundation, you’re equipped to tackle increasingly complex projects with the ESP32 CYD. The combination of low-cost hardware and professional development tools democratizes advanced embedded display applications, enabling everything from home automation interfaces to portable diagnostic tools. As you continue developing, remember to share your projects with the community—each project contributes to the collective knowledge base that makes platforms like the ESP32 CYD so valuable to makers and engineers worldwide.

======================================

About ESP32S.com

Since 2016, ESP32S.com has grown to become a complete ecosystem partner for your IoT journey. Based in Shenzhen, a global hub for electronics innovation, we have helped hundreds of developers and businesses bring their ESP32-based ideas to life. Our team is dedicated to providing exceptional support and innovative solutions to help you achieve your IoT goals.
At ESP32S.com, we master the intricacies of developing an ESP32-based product, which involves multiple stages, from concept to market launch. That’s why we now offer comprehensive solutions covering the entire product lifecycle for ESP32-based devices. Whether you need help with PCB design, prototyping, production, or even marketing and fulfillment, we have you covered.

Contact Us

Ready to take your IoT project to the next level? Contact ESP32S.com today to learn more about our comprehensive solutions for ESP32-based devices. Let us be your trusted partner in bringing your innovative ideas to life. Contact us now to get started.

Table of Contents

Related Posts
Start typing to see products you are looking for.
Shopping cart
Sign in

No account yet?

Shop
Wishlist
0 items Cart
My account
/** * salesmartly 聊天插件 */