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

Distance sensor connection schematic

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.