Web Bluetooth & Dashboard Recommendations
Building a wireless dashboard is completely optional. During practice and testing, you can use the USB Serial Monitor, a generic phone BLE terminal app, or build your own custom web page.
If you want to build a quick web interface, the Web Bluetooth API (supported in Google Chrome and Microsoft Edge on desktop, laptops, and Android) is convenient because it runs directly in the browser with no native app installs.
Here are some recommendations and example patterns for how you can structure wireless communication.
1. Protocol Ideas & Recommendations
You don't need to follow any rigid format. Design whatever feels easiest for your team to write and debug:
Approach A: Plain Text or CSV (Simplest)
Just send comma-separated values or human-readable strings from the ESP32:
1.42, -0.4, 12.15
Or:
dist: 1.42m, heading: -0.4 deg, batt: 12.1V
This is effortless to view in the Arduino Serial Monitor and quick to split in JavaScript using string.split(",").
Approach B: Tagged Key-Value Tokens (Flexible)
If you want to stream multiple telemetry points at once, prefixing each value with a short key makes parsing easy:
D:1.420 H:-0.4 B:12.15
In your frontend, you can split by spaces and extract each value by its prefix:
D:= Current distance in metersH:= Current heading angle in degreesB:= Battery voltage
Approach C: Single-Letter or Prefix Commands
For sending data from the computer/phone to the car:
- Single-letter actions:
Sfor Start,Xfor Stop,Rfor Reset,Afor Arm motors. - Simple value updates:
DIST:1.50orTIME:8.0.
2. Example Web Bluetooth Workflow
Below is a minimal JavaScript template showing how to connect to a BLE peripheral, receive incoming notifications, and send a command string. You can adapt this into your own custom UI.
Connecting to the Device
const SERVICE_UUID = "19b10000-e8f2-537e-4f6c-d104768a1214";
const STATUS_CHAR = "19b10001-e8f2-537e-4f6c-d104768a1214";
const CMD_CHAR = "19b10002-e8f2-537e-4f6c-d104768a1214";
let bleDevice = null;
let cmdChar = null;
async function connectToCar() {
try {
// 1. Prompt user to choose the Bluetooth device
bleDevice = await navigator.bluetooth.requestDevice({
filters: [{ namePrefix: "Scioly" }],
optionalServices: [SERVICE_UUID],
});
bleDevice.addEventListener("gattserverdisconnected", () => {
cmdChar = null;
console.log("Car disconnected");
});
// 2. Connect to the GATT server
const server = await bleDevice.gatt.connect();
const service = await server.getPrimaryService(SERVICE_UUID);
// 3. Listen for notifications from the car
const statusChar = await service.getCharacteristic(STATUS_CHAR);
await statusChar.startNotifications();
statusChar.addEventListener("characteristicvaluechanged", handleIncomingData);
// 4. Get the characteristic used for sending commands
cmdChar = await service.getCharacteristic(CMD_CHAR);
console.log("Connected to car!");
} catch (err) {
console.error("Connection failed:", err);
}
}
Reading Incoming Telemetry
function handleIncomingData(event) {
// Decode raw bytes to text
const message = new TextDecoder().decode(event.target.value).trim();
console.log("Received from car:", message);
// Example: Split space-separated tokens
const tokens = message.split(" ");
tokens.forEach((token) => {
const [key, value] = token.split(":");
if (key === "D") {
console.log("Distance:", parseFloat(value), "meters");
} else if (key === "H") {
console.log("Heading:", parseFloat(value), "degrees");
} else if (key === "B") {
console.log("Battery:", parseFloat(value), "V");
}
});
}
Sending Commands to the Car
async function sendCommand(commandText) {
if (!cmdChar) {
console.warn("Not connected to car");
return;
}
// Encode string into bytes and write to the command characteristic
const data = new TextEncoder().encode(commandText.trim());
await cmdChar.writeValue(data);
console.log("Sent command:", commandText);
}
// Example usage:
// sendCommand("START");
// sendCommand("DIST:2.00");
3. General Tips
- Use what works best for your team: You don't need fancy graphs or full web apps. Even a basic HTML page with a "Connect" button, two input boxes for distance/time, and a "Send" button is enough to save hours of pit tuning.
- Serial Monitor Fallback: Always make sure your car can still be operated via the physical start button and USB Serial cable in case you have Bluetooth issues or forget your laptop.
- Competition Rule Reminder: Wireless communication is strictly banned during competition runs and impound. Always turn the physical wireless switch OFF (and verify the wireless LED
D1is dark) before turning your car in for inspection!