11. Networking and communication¶
Summary¶

Group Assignment¶
For this week’s group assignment, we had to send a message between two projects.
We already had several boards that we fabricated earlier, and we wanted to test communication between them. For this experiment, we used an Arduino Uno board together with our custom board. The goal was to send and receive signals between the two boards to verify that both UART communication and general I/O behavior were working correctly.
Uart¶

In the group assignment, we experimented with UART communication by directly connecting two boards using only two data lines (TX and RX) and a shared ground. This type of communication is very simple: the data is sent as a stream of bytes from one pin to another, without any addressing, routing, or device identification. UART is purely point-to-point — meaning that only two devices can communicate at a time, and the connection is physically fixed.
For my individual assignment, I expanded this idea and worked with real networking using the ESP32. Unlike UART, a network does not rely on direct pin-to-pin wires. Instead, devices communicate over Wi-Fi using protocols such as TCP/IP. This introduces several additional layers:
-
Device addressing: every device gets its own IP address, so multiple devices can exist on the same network at once.
-
Packet-based communication: data is split into packets, each containing addressing information, allowing messages to reach the correct device.
-
Routing rules: even in a small Wi-Fi network, communication follows standardized rules that determine how devices send, receive, and acknowledge data.
-
Scalability: unlike UART (which supports only two directly connected boards), a network allows many devices to communicate simultaneously.
So in summary:¶
UART:¶
-
Direct, two-wire connection (TX ↔ RX)
-
No addressing, no routing
-
Only two devices, short distance
-
Simple byte-level transfer
Network (Wi-Fi / TCP/IP):¶
-
Devices communicate wirelessly
-
Each device has an IP address
-
Data is sent in structured packets
-
Can support many devices at once
Understanding this difference helped me appreciate how communication scales from simple embedded device links (UART) to more advanced systems — such as my delivery robot, which uses Wi-Fi to host a web server and receive commands over a network instead of a direct wire.

We planned a simple test: when the button connected to the Arduino Uno is pressed, an LED on our custom board should turn on. To make this work, we used UART communication — the Arduino sends a specific serial command whenever the button is pressed, and our custom board listens for this command and activates the LED.
After defining this logic, we started writing the code for both boards. On the Arduino side, we programmed the microcontroller to detect the button press and send a short UART message. On our custom board, we wrote firmware that reads incoming UART data and toggles the LED accordingly.
This test allowed us to verify not only the button and LED functionality, but also that UART communication between both boards works reliably.
The first code is for the Arduino Uno.
#define button 3
char x = 'A';
char y = 'B';
void setup() {
Serial.begin(9600);
pinMode(button , INPUT_PULLUP);
}
void loop() {
int val = digitalRead(button);
if(val == 0){
Serial.print(x);
delay(300);
}
if(val == 1){
Serial.print(y);
delay(300);
}
}
The second code is for our board, meaning the receiving side.
#define led 2
void setup() {
pinMode(led , OUTPUT);
digitalWrite(led , 0);
Serial.begin(9600);
}
void loop() {
if(Serial.available()){
char val = Serial.read();
if(val == 'A'){
digitalWrite(led , 1);
}
if(val == 'B'){
digitalWrite(led , 0);
}
}
}
Result¶
Individual Assignment¶
ESP32 Wi-Fi access point¶
Since I already completed the Output Devices week and my robot platform is fully moving, this week I wanted to take the next step — connecting my custom board to a Raspberry Pi over a local Wi-Fi network. My goal was to control the robot wirelessly through the network and establish communication between the Raspberry Pi and my board as part of the final system integration.

In this photo, you can see my Raspberry Pi together with the custom ESP32 board that I made during the Output Devices week. My plan is to use the ESP32 as a Wi-Fi access point, creating a local wireless network. The Raspberry Pi connects to this ESP32 access point, so both devices are on the same local network.
Once the connection is established, I can send control signals from the Raspberry Pi to the ESP32 using simple HTTP requests. The Raspberry Pi runs a Python script that sends commands to the ESP32's IP address over Wi-Fi. The ESP32 receives these commands and then forwards them via UART to the hoverboard controller board. This way, the Raspberry Pi becomes the high-level controller, and the platform moves according to the commands received over the local network.

Here is the Wi-Fi access point I created, named “HoverESP32”. I connected my Raspberry Pi to this network so both devices are on the same local Wi-Fi system, allowing me to send control commands wirelessly to the ESP32.

Here, I sent data to the ESP32 using a Python script from the terminal. The script sends an HTTP request to the ESP32’s IP address, and the ESP32 receives the command and forwards it to the hoverboard controller via UART.
Here is the Python script that I ran on the Raspberry Pi.¶
import requests
import time
ESP_IP = "192.168.4.1"
def send(c: str):
url = f"http://{ESP_IP}/cmd"
try:
r = requests.get(url, params={"c": c}, timeout=2)
print(f"-> {c} | {r.status_code} {r.text.strip()}")
except requests.RequestException as e:
print(f"ERR sending '{c}': {e}")
def main():
print("Controls: F=Forward, B=Backward, L=Left, R=Right, S=Stop, Q=Quit")
while True:
val = input("cmd [F/B/L/R/S/Q]: ").strip().upper()
if not val:
continue
if val == "Q":
print("Bye.")
break
if val not in {"F","B","L","R","S"}:
print("Unknown command. Use F/B/L/R/S or Q to quit.")
continue
send(val)
time.sleep(0.05)
if __name__ == "main":
main()
Here is the code for the ESP32, which receives data from the Raspberry Pi over Wi-Fi and then sends that data to the hoverboard controller board via UART.¶
You can find the firmware and step-by-step flashing instructions here
#include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>
#define HOVER_BAUD 115200
#define START_FRAME 0xABCD
#define HoverSerial Serial
typedef struct attribute((packed)) {
uint16_t start;
int16_t steer;
int16_t speed;
uint16_t checksum;
} SerialCommand;
static inline void sendCmd(int16_t steer, int16_t speed) {
SerialCommand cmd;
cmd.start = START_FRAME;
cmd.steer = steer;
cmd.speed = speed;
cmd.checksum = (uint16_t)(cmd.start ^ cmd.steer ^ cmd.speed);
HoverSerial.write((uint8_t*)&cmd, sizeof(cmd));
}
#define SPEED_MAX_HW 300
#define STEER_MAX_HW 300
#define SPEED_CMD 250
#define STEER_CMD 200
#define COMMAND_TIMEOUT_MS 1000
unsigned long lastCmdTS = 0;
int16_t lastSteer = 0;
int16_t lastSpeed = 0;
const char* AP_SSID = "HoverESP32";
const char* AP_PASS = "12345678";
WebServer server(80);
const char HTML_PAGE[] PROGMEM = R"HTML(
<!doctype html><meta name=viewport content="width=device-width,initial-scale=1">
<style>button{font-size:22px;padding:14px 20px;margin:8px;width:46%} .row{display:flex;gap:8px;flex-wrap:wrap}</style>
<h2>Hover Control</h2>
<div class=row>
<button onclick="send('F')">Forward</button><button onclick="send('B')">Backward</button>
<button onclick="send('L')">Left</button><button onclick="send('R')">Right</button>
<button onclick="send('S')">Stop</button>
</div>
<script>
async function send(c){
try{ await fetch('/cmd?c='+c); }catch(e){ console.log(e); }
}
</script>
)HTML";
void handleRoot() {
server.send(200, "text/html", HTML_PAGE);
}
void applyCommand(char c) {
int16_t steer = 0;
int16_t speed = 0;
switch (c) {
case 'F': speed = SPEED_CMD; break;
case 'B': speed = -SPEED_CMD; break;
case 'L': steer = -STEER_CMD; break;
case 'R': steer = STEER_CMD; break;
case 'S': default: steer = 0; speed = 0; break;
}
if (speed > SPEED_MAX_HW) speed = SPEED_MAX_HW;
if (speed < -SPEED_MAX_HW) speed = -SPEED_MAX_HW;
if (steer > STEER_MAX_HW) steer = STEER_MAX_HW;
if (steer < -STEER_MAX_HW) steer = -STEER_MAX_HW;
lastSteer = steer;
lastSpeed = speed;
lastCmdTS = millis();
sendCmd(lastSteer, lastSpeed);
}
void handleCmd() {
if (!server.hasArg("c")) {
server.send(400, "text/plain", "Usage: /cmd?c=F|B|L|R|S");
return;
}
char c = server.arg("c")[0];
applyCommand(c);
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", String("OK: ") + c);
}
#define LED_PIN 2
void setup() {
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
HoverSerial.begin(HOVER_BAUD);
WiFi.mode(WIFI_AP);
WiFi.softAP(AP_SSID, AP_PASS);
IPAddress ip = WiFi.softAPIP();
server.on("/", handleRoot);
server.on("/cmd", handleCmd);
server.begin();
Serial.begin(115200);
Serial.print("AP IP: "); Serial.println(ip);
}
void loop() {
server.handleClient();
if (millis() - lastCmdTS > COMMAND_TIMEOUT_MS) {
if (lastSpeed != 0 || lastSteer != 0) {
lastSpeed = 0; lastSteer = 0;
sendCmd(0, 0);
}
lastCmdTS = millis();
}
digitalWrite(LED_PIN, (millis() % 1000) < 500);
}
Networking Explanation¶
In the group assignment, we communicated between two boards directly using UART. This type of communication is very simple: two wires (TX and RX) exchange bytes without using addresses or any network protocol. It is point-to-point communication — only one device talks to one other device, and no routing or addressing is required.
However, in my individual assignment I used a completely different communication model — networking over Wi-Fi using an HTTP web server running on the ESP32. This introduces actual networking protocols (IP, TCP, HTTP), which allow communicating with multiple devices, not just one.
What I did in this week¶
In my project, I configured the ESP32 to work in Wi-Fi Access Point mode, creating its own wireless network. Then I started a web server using the ESP32 WebServer library. This server listens on port 80 and waits for incoming HTTP requests.
I created a small HTML interface with buttons (Forward, Backward, Left, Right, Stop). When a button is pressed, the browser sends a request like:
/cmd?c=F
The ESP32 receives this request, extracts the command letter (F, B, L, R, S), and converts it into a structured binary command for the hoverboard driver.
This means that instead of sending raw bytes from pin to pin, I am now using:
-
IP addressing
-
TCP connections
-
HTTP requests (GET)
-
Parsing parameters (c=F)
-
Multiple clients can connect at the same time (smartphone, laptop, etc.)
So this week I demonstrated how to use network-based communication, not just UART.
Why this is different from UART¶
| UART (group assignment) | Wi-Fi + HTTP (this week) |
|---|---|
| Two wires only (TX/RX) | Wireless, no wires |
| No addressing | Every device gets an IP address |
| No protocol, just bytes | HTTP protocol + TCP + IP |
| Only 1-to-1 communication | Many-to-one (multiple clients) |
| No ability to control from a browser | Full web interface with UI |
This shows a clear difference between point-to-point serial communication and network communication, which relies on protocols, addressing, requests, and structured messages.
Why I needed a web server¶
The web server allows me to:
-
Create a universal control interface that works on any device
-
Use Wi-Fi to control the robot from a distance
-
Replace physical serial cables with wireless commands
-
Handle multiple commands reliably through HTTP
The ESP32 receives the HTTP request, converts it into a binary command, and sends it to the hoverboard driver through UART. So this week combines both networking and embedded communication.

Here is my final version of both codes. I flashed the ESP32 with the firmware, mounted the board back onto the robot platform, and then ran the Python control script on the Raspberry Pi.
Conclusion¶
This week I successfully integrated wireless communication into my robot platform. I created a Wi-Fi access point on the ESP32, connected the Raspberry Pi to this local network, and established a full control pipeline using HTTP commands over Wi-Fi. The ESP32 received these commands and translated them into UART packets for the hoverboard controller, allowing me to move the robot platform wirelessly for the first time.
I also finalized and tested the ESP32 firmware, verified UART communication, and implemented a safe command timeout. On the Raspberry Pi side, I wrote a Python script that sends directional commands to the ESP32, making it possible to control the robot in real time from the terminal.
Overall, this week helped me understand network communication, embedded wireless control, and system integration between multiple boards. I now have a stable communication bridge between the Raspberry Pi, the ESP32, and the hoverboard controller — an important milestone for my final project.