Week 9
Wireless Communication
This week’s topic was to use wireless connection (Wi-Fi, bluetooth) in any way. I had some ideas on how to incorporate this into my other projects, but in the end I didn’t see much sense in that given I dont’ have a separate power supply to actually control something from a distance.
So I’ve decided to just draw some data from a sensor to my browser, using ESP32 as a wi-fi access point. The sensor I’ve used is an ultrasonic distance sensor HC-SR04.
Setting up the sensor and wifi
Schematic of the connection
Here you connect:
- (Vcc) -> (5V)
- (GND) -> (GND)
- Trig -> GPIO 5
- Echo -> GPIO 18
And here’s the code for ESP32 to create a wifi network and process html fetch requests.
#include <WiFi.h>
#include <WebServer.h>
const char* ssid = "ESP32-Access-Point";
const char* password = "12345678";
#define TRIG_PIN 5
#define ECHO_PIN 18
WebServer server(80);
long getDistance() {
long duration, distance;
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
duration = pulseIn(ECHO_PIN, HIGH);
distance = (duration / 2) / 29.1;
return distance;
}
void handleRoot() {
long distance = getDistance();
String response = "Distance: " + String(distance) + " cm";
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", response);
}
void setup() {
Serial.begin(115200);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
// Set up the Wi-Fi access point
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
server.on("/", handleRoot);
server.begin();
}
void loop() {
server.handleClient();
}
Web Client
Here’s the code for an hmtl page that you can open, and it will display the data read from the sensor.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Distance Sensor Data Visualization</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns"></script>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
margin: 20px;
}
#chart-container {
max-width: 900px;
margin: 0 auto;
}
#distanceChart {
width: 100%;
height: 500px;
}
</style>
</head>
<body>
<h1>Distance Sensor Data</h1>
<div id="chart-container">
<canvas id="distanceChart"></canvas>
</div>
<div id="error-message" style="color: red;"></div>
<script>
const ctx = document.getElementById('distanceChart').getContext('2d');
const distanceChart = new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [{
label: 'Distance (cm)',
data: [],
backgroundColor: 'rgba(75, 192, 192, 0.2)',
borderColor: 'rgba(75, 192, 192, 1)',
borderWidth: 1
}]
},
options: {
scales: {
x: {
type: 'time',
time: {
unit: 'second',
stepSize: 1
}
},
y: {
beginAtZero: true
}
}
}
});
async function fetchData() {
try {
const response = await fetch('http://192.168.4.1/');
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
const data = await response.text();
const distance = parseFloat(data.split(" ")[1]);
const now = new Date();
if (distanceChart.data.labels.length >= 30) { // Keep the last 30 values
distanceChart.data.labels.shift();
distanceChart.data.datasets[0].data.shift();
}
distanceChart.data.labels.push(now);
distanceChart.data.datasets[0].data.push(distance);
distanceChart.update();
} catch (error) {
document.getElementById('error-message').innerText = 'Error: ' + error.message;
console.error('Error fetching data:', error);
}
}
setInterval(fetchData, 200); // Fetch data every 200 milliseconds
window.onload = fetchData; // Fetch data on page load
</script>
</body>
</html>
Result
For this project I practically didn’t have any experience. So it was a big Chat-GPT struggle to get it to work. Otherwise, the part that I thought would be the hardest, connecting esp32, turned out to be the easier plug and play thing ever.
Here’s the video of the visualization in the web client.