title: Measuring Distance with an ESP8266 and an Ultrasonic Sensor, Streamed to KiwisIoT
published: false
description: Build a Wi-Fi distance monitor with an ESP8266 NodeMCU, an HC-SR04 ultrasonic sensor, and a live KiwisIoT dashboard.
tags: esp8266, iot, arduino, embedded
cover_image: REPLACE_WITH_COVER_IMAGE_URL
Ever wanted a live distance reading on a dashboard you can check from any browser? In this project, an ESP8266 NodeMCU reads an HC-SR04 ultrasonic sensor every two seconds, calculates the distance in centimeters, and sends the value over Wi-Fi to a KiwisIoT panel, where it updates in near real time.
The full project, including the sketch, README, and images, is on GitHub: https://github.com/Kiwistron/KiwisIoT-Projects/tree/main/esp8266/003-ultrasonic-kiwisiot
What You Need
- ESP8266 NodeMCU (CP2102 or CH340 board)
- HC-SR04 ultrasonic sensor
- A micro USB cable
- Four jumper wires
- Arduino IDE 1.8.19 or later
- A KiwisIoT account
Wiring
| HC-SR04 Pin | NodeMCU Pin | Notes |
|---|---|---|
| VCC | VIN (5V) | The HC-SR04 needs 5V |
| GND | GND | Common ground |
| TRIG | D1 (GPIO5) | Trigger output |
| ECHO | D2 (GPIO4) | Echo input |
Circuit diagram
Watch out for the ECHO pin. The HC-SR04 outputs 5V on ECHO, but the ESP8266's GPIO pins only tolerate 3.3V. A simple voltage divider (for example, 1 kΩ in series with ECHO and 2 kΩ from ECHO to GND) protects the board. A logic level shifter works too.
code
#include <ESP8266WiFi.h>
#include <KiwisIoT.h>
const char* ssid = "YOUR_WIFI_NAME";
const char* pass = "YOUR_WIFI_PASSWORD";
const char* topic = "YOUR_DASHBOARD_TOPIC_ID";
#define TRIG_PIN D1
#define ECHO_PIN D2
KiwisIoT kiwisiot(ssid, pass, topic);
void sendDistance() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH, 30000);
if (duration == 0) {
Serial.println();
Serial.println("Ultrasonic: No echo received");
return;
}
float distance = duration * 0.0343 / 2;
Serial.println();
Serial.println("---------- ULTRASONIC MONITORING ----------");
Serial.print("Distance: ");
Serial.print(distance, 2);
Serial.println(" cm");
String distanceData = String(distance, 2);
kiwisiot.send("0", distanceData);
Serial.print("Sent to KiwisIoT Channel 0: ");
Serial.print(distanceData);
Serial.println(" cm");
}
void setup() {
Serial.begin(115200);
Serial.println(" ULTRASONIC DISTANCE MONITOR ");
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
digitalWrite(TRIG_PIN, LOW);
Serial.println("Ultrasonic sensor initialized");
Serial.println("Connecting to KiwisIoT...");
kiwisiot.begin();
Serial.println("KiwisIoT initialized");
Serial.println("Starting distance monitoring...");
}
void loop() {
kiwisiot.run();
static unsigned long lastSend = 0;
if (millis() - lastSend >= 2000) {
lastSend = millis();
sendDistance();
}
delay(100);
}
How the Measurement Works
The ultrasonic sensor measures distance by timing an echo. The firmware sends a 10 µs pulse on TRIG, then uses pulseIn() to measure how long ECHO stays HIGH. Sound travels about 0.0343 cm per microsecond, and the signal travels to the object and back, so the distance is:
distance (cm) = duration × 0.0343 / 2
Here is the core function from the sketch:
void sendDistance() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH, 30000);
if (duration == 0) {
Serial.println("Ultrasonic: No echo received");
return;
}
float distance = duration * 0.0343 / 2;
String distanceData = String(distance, 2);
kiwisiot.send("0", distanceData);
}
The 30000 argument sets a 30 ms timeout, so if nothing reflects the signal, pulseIn() returns 0 instead of blocking the loop. The sketch checks for that and skips the send.
Sending Data to KiwisIoT
The loop() function calls kiwisiot.run() on every pass to keep the connection alive, and sends a reading every 2 seconds using a millis() timer. This avoids delay() blocking the connection work.
void loop() {
kiwisiot.run();
static unsigned long lastSend = 0;
if (millis() - lastSend >= 2000) {
lastSend = millis();
sendDistance();
}
delay(100);
}
Setting Up the Dashboard
- Log in to KiwisIoT and create a new panel.
- Add a Label widget to show the reading.
- Copy the panel's Topic ID and paste it into the sketch.
The label updates with each reading, and the panel shows Online while the board is connected.
Serial Monitor Output
Open the Serial Monitor at 115200 baud to check the readings locally:
---------- ULTRASONIC MONITORING ----------
Distance: 5.35 cm
[TX] {"0":"5.35"}
Sent to KiwisIoT Channel 0: 5.35 cm
Ultrasonic: No echo received
code output
Troubleshooting
- "Access is denied" on upload: Close the Serial Monitor before uploading.
- "No echo received" every time: Check the TRIG and ECHO wiring and the 5V supply. Point the sensor at a flat, hard surface.
- Unstable readings: Secure the jumper wires and keep the sensor away from walls.
- Dashboard not updating: Confirm the Topic ID and that the board is connected to a 2.4 GHz network.
Where to Go Next
- Trigger an alert when the distance drops below a threshold
- Log readings over time for KiwisIoT's chart widgets
- Add more sensors on separate channels
The complete code and setup instructions are in the GitHub repository. Feedback and improvements are welcome.



Top comments (0)