Category: Arduino Projects

  • A $20 ESP32-S3 Scanner Turns Small Objects Into 3D Meshes—Here’s the Trick

    A $20 ESP32-S3 Scanner Turns Small Objects Into 3D Meshes—Here’s the Trick

    A maker has turned a tiny ESP32-S3 board into a handheld 3D-scanning proof of concept—using a camera, a tracking target and geometry algorithms rather than a conventional depth camera. The striking idea is not that a microcontroller has become a professional scanner; it is how carefully the project narrows the problem.

    CircuitDigest’s October 2026 coverage of the creator’s project describes a Seeed Studio XIAO ESP32-S3 paired with a round-screen expansion. The report says the hardware cost is roughly $20, but that figure is the project coverage’s estimate, not a verified shopping total for every region or bill of materials.

    How can a small MCU reconstruct a shape?

    The scanner uses fiducial markers on a tracking target to estimate the camera’s position as the operator moves around an object. Software then combines multiple views using space carving: a 3D voxel grid is tested against what each camera image could see, and inconsistent regions are removed. A marching-cubes lookup table converts the remaining voxel surface into a triangle mesh.

    That pipeline trades generality for a constrained setup. The camera must observe the markers reliably, the object needs enough views, and the reconstruction code has to fit the board’s memory and processing budget. The project reportedly uses a low-resolution live preview for the display while capturing higher-resolution frames for the heavier processing stage.

    What the project report says—and what it doesn’t prove

    The coverage reports approximately 1mm structural resolution and says the creator targets small objects such as trinkets or field specimens. Treat those as project-reported results: we have not independently tested the scanner, reproduced the build or verified that resolution across different objects.

    A small demo is also not a substitute for calibrated metrology. Shiny, transparent, featureless or moving surfaces can be difficult for camera-based reconstruction. Lighting, tracking accuracy, camera calibration, surface texture and the number of viewpoints all affect the result. A mesh that looks convincing on screen may still be unsuitable for dimension-critical parts.

    Why it is still a useful embedded-computing story

    The project illustrates a broader design lesson: embedded vision improves when the problem is divided into manageable stages. A low-cost board does not need to run a giant neural model to do useful computer vision. In this case, pose estimation and classical geometry do much of the work, while a display offers immediate feedback.

    For a student or maker who wants to reproduce the idea, start by studying the creator’s original post, bill of materials and source code before buying parts. Validate camera capture, marker tracking and memory use separately. Then test a simple object under controlled light, and record the measured dimensions against a known reference. Do not infer that every XIAO ESP32-S3 kit includes the same display, camera or software.

    Bottom line: The reported scanner is a clever low-cost proof of concept, not a ready-made replacement for photogrammetry apps or industrial scanners. Its real hook is the engineering: constrained capture, tracking markers and efficient 3D reconstruction on a very small computer.

    Sources: Original ESP32 object-scanner project shared by its creator; CircuitDigest project coverage; Seeed Studio XIAO ESP32-S3 documentation.

    Featured photo: Illustrative photo of a separate handheld 3D mapping scanner by CSIRO; it is not the ESP32-S3 DIY project pictured in the source. Photo via Wikimedia Commons, licensed under CC BY 3.0. The image was cropped and resized for this article.

  • Master DHT11 to Firebase ESP8266 and ESP32 | Beginner’s Guide to Send Data & Display on Website (2026)

    Learn how to connect Wi-Fi, read Master DHT11 to Firebase ESP8266 and ESP32 Beginner’s Guide to Send Data & Display on Website (2025), and display temperature & humidity data live on your custom HTML/CSS/JS website. Learn how to read temperature & humidity from a DHT11 using ESP8266/ESP32, send it to Firebase Realtime Database over Wi-Fi, and display live readings on a custom HTML/CSS/JS website. Full code, wiring diagram, and SEO tips included.

    Master DHT11 to Firebase ESP8266 and ESP32

    Quick overview (What you’ll build for DHT11 to Firebase ESP8266 and ESP32 )

    1. ESP8266/ESP32 reads temperature & humidity from a DHT11 sensor.
    2. Device connects to your Wi-Fi and posts JSON data to Firebase Realtime Database.
    3. A simple web app (HTML/CSS/JS) reads the Firebase data and displays it live.
      This is a common workflow for hobby IoT dashboards. (Random Nerd Tutorials)

    Prerequisites of DHT11 to Firebase ESP8266 and ESP32

    • Hardware: ESP8266 NodeMCU (or ESP32), DHT11 sensor, jumper wires, breadboard, micro USB cable.
    • Software: Arduino IDE (or PlatformIO), DHT library (by Adafruit or other), WiFi and HTTP client libraries (built into ESP cores), Firebase Realtime Database (a Firebase project).
    • Basic familiarity with Arduino IDE and creating a Firebase project in the Firebase console. Helpful tutorials use these exact stacks. (Random Nerd Tutorials, Instructables)

    Hardware wiring (simple)

    • DHT11 VCC → 3.3V (or 5V depending on module; NodeMCU uses 3.3V recommended)
    • DHT11 GND → GND
    • DHT11 DATA → D2 (GPIO4) on NodeMCU (or any digital pin on ESP32)
    • If module has a pull-up resistor, fine; if not, add a 4.7k–10k pull-up between DATA and VCC.
      This wiring pattern is standard for NodeMCU+DHT setups. (Instructables, iotbyhvm.ooo)

    Step 1 : Create Firebase project & Realtime Database

    1. Go to [Firebase console] and create a new project.
    2. In “Build → Realtime Database” create a database and start in test mode for development (this allows reads/writes from the device). Important: test mode is insecure — switch to proper rules and auth before production.
    3. Note your database URL, it looks like https://your-project-id-default-rtdb.firebaseio.com/. You’ll use this as the base URL to POST JSON.
      (Using Realtime Database + direct REST writes or Firebase libraries is the common approach for IoT devices). (Random Nerd Tutorials)

    Security note: For production, secure your database with rules or use authenticated tokens. Tutorials often use test mode for beginners to simplify setup. (Random Nerd Tutorials)

    Step 2 : ESP code (NodeMCU / ESP8266 example using Arduino IDE)

    This example uses the DHT library + ESP8266HTTPClient to POST via Firebase REST API. Replace placeholders (SSID, PASSWORD, FIREBASE_URL) with your info.

    /* DHT11 -> Firebase (ESP8266) example
       Requires libraries:
       - DHT sensor library (by Adafruit) or similar
       - ESP8266WiFi (built-in)
       - ESP8266HTTPClient (built-in)
    */
    
    #include <ESP8266WiFi.h>
    #include <ESP8266HTTPClient.h>
    #include <ArduinoJson.h>    // optional but convenient
    #include <DHT.h>
    
    #define DHTPIN D2           // data pin (change if needed)
    #define DHTTYPE DHT11       // DHT 11
    DHT dht(DHTPIN, DHTTYPE);
    
    const char* ssid = "YOUR_WIFI_SSID";
    const char* password = "YOUR_WIFI_PASS";
    const char* firebaseUrl = "https://your-project-id-default-rtdb.firebaseio.com/"; // trailing slash
    
    unsigned long lastSend = 0;
    const unsigned long sendInterval = 15000; // 15s
    
    void setup() {
      Serial.begin(115200);
      delay(100);
      dht.begin();
      WiFi.begin(ssid, password);
      Serial.print("Connecting WiFi");
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      Serial.println("\nWiFi connected, IP: ");
      Serial.println(WiFi.localIP());
    }
    
    void loop() {
      if (millis() - lastSend < sendInterval) return;
      lastSend = millis();
    
      float h = dht.readHumidity();
      float t = dht.readTemperature();
    
      if (isnan(h) || isnan(t)) {
        Serial.println("Failed reading DHT sensor!");
        return;
      }
    
      // Build JSON
      String payload = "{";
      payload += "\"temperature\":" + String(t, 2) + ",";
      payload += "\"humidity\":" + String(h, 2) + ",";
      payload += "\"ts\":" + String(millis());
      payload += "}";
    
      // Firebase REST: POST to /readings.json to push a new node
      String url = String(firebaseUrl) + "readings.json"; // test mode (no auth)
      Serial.println("POST to: " + url);
      Serial.println(payload);
    
      if (WiFi.status() == WL_CONNECTED) {
        HTTPClient http;
        http.begin(url);
        http.addHeader("Content-Type", "application/json");
        int httpCode = http.POST(payload);
        if (httpCode > 0) {
          String resp = http.getString();
          Serial.printf("HTTP %d: %s\n", httpCode, resp.c_str());
        } else {
          Serial.printf("Failed, error: %s\n", http.errorToString(httpCode).c_str());
        }
        http.end();
      } else {
        Serial.println("WiFi not connected");
      }
    }
    

    Notes:

    • This uses the Realtime Database REST API (push to readings.json) — many community tutorials use the same method for simplicity. (How2Electronics, Instructables)
    • For ESP32, replace include/wifi classes accordingly and D2 pin selection may differ. See RandomNerdTutorials for ESP32 variants. (Random Nerd Tutorials)

    Step 3 : Verify data in Firebase console

    Open your Firebase Realtime Database in the console; you should see a /readings node with auto-generated keys and JSON objects containing temperature, humidity, and ts. This confirms successful writes. Many tutorials use this verify step. (Random Nerd Tutorials)

    Step 4 : Simple web app to display readings (HTML/CSS/JS)

    You can either:

    • Use Firebase Web SDK (recommended) to read Realtime Database easily and show live updates; or
    • Use REST calls from JS to pull latest data periodically.

    Below is a minimal Firebase Web SDK example (place in index.html). Replace the firebaseConfig object with your project config (found in Firebase console → Project settings → SDK setup):

    <!doctype html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="description" content="Live DHT11 dashboard using Firebase Realtime Database">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      <title>DHT11 Firebase Dashboard</title>
      <style>
        body{font-family:Arial,Helvetica,sans-serif;display:flex;flex-direction:column;align-items:center;padding:2rem;}
        .card{border-radius:8px;padding:1rem;box-shadow:0 6px 18px rgba(0,0,0,0.08);width:320px;text-align:center;}
        .big{font-size:2.4rem;font-weight:600;}
        .small{color:#666}
      </style>
    </head>
    <body>
      <div class="card">
        <div class="big" id="temp">-- °C</div>
        <div class="small">Temperature</div>
      </div>
      <div style="height:12px"></div>
      <div class="card">
        <div class="big" id="hum">-- %</div>
        <div class="small">Humidity</div>
      </div>
    
      <!-- Firebase SDK -->
      <script src="https://www.gstatic.com/firebasejs/9.22.0/firebase-app-compat.js"></script>
      <script src="https://www.gstatic.com/firebasejs/9.22.0/firebase-database-compat.js"></script>
      <script>
        // Replace with your Firebase config
        const firebaseConfig = {
          apiKey: "YOUR_API_KEY",
          authDomain: "YOUR_PROJECT.firebaseapp.com",
          databaseURL: "https://your-project-id-default-rtdb.firebaseio.com",
          projectId: "YOUR_PROJECT",
          storageBucket: "YOUR_PROJECT.appspot.com",
          messagingSenderId: "SENDER_ID",
          appId: "APP_ID"
        };
        firebase.initializeApp(firebaseConfig);
        const db = firebase.database();
    
        // Listen for last reading (assumes readings/child push used in the device)
        const readingsRef = db.ref('readings'); 
        // We'll query the last item:
        readingsRef.limitToLast(1).on('child_added', snapshot => {
          const data = snapshot.val();
          if (data) {
            document.getElementById('temp').textContent = (data.temperature || '--') + " °C";
            document.getElementById('hum').textContent = (data.humidity || '--') + " %";
          }
        });
      </script>
    </body>
    </html>
    

    Why this works: The Firebase Web SDK keeps a realtime socket to the DB and updates the DOM when new readings arrive. This is the same approach used in many Firebase IoT dashboards. (Random Nerd Tutorials)

    Common errors & troubleshooting ESP8266 and ESP32

    • Wi-Fi won’t connect: check SSID/password, check 3.3V vs 5V for modules.
    • DHT readings nan: ensure correct wiring and a short delay after dht.begin(). DHT11 is slow (max ~1Hz).
    • Firebase write errors (403): database rules might block unauthenticated writes — either open test mode (dev only) or implement auth. Tutorials warn about test mode. (Instructables, Arduino Forum)

    FAQ of DHT11 to Firebase

    Q: Do I need a Firebase paid plan?

    A: No — Firebase Realtime Database has a free tier sufficient for small hobby projects. For production and heavy write/read operations, consider billing & quotas. (Random Nerd Tutorials)


    Q: Can I use DHT22 instead of DHT11?

    A: Yes — DHT22 gives better accuracy and range; switch DHTTYPE and wiring as needed. Many guides use either sensor. (Random Nerd Tutorials)

    Q: Is it safe to keep DB in test mode?

    A: No — test mode is insecure. Use Firebase rules and authentication for production. (Random Nerd Tutorials)

    Sources & references (most useful tutorials / examples I consulted)