commit a892593ea5248ec9a474b999f98ce1fe545149e7
parent 671c2a382cc4b2a53803c1fe7509c3e96e84e50a
Author: Daniel Barlow <dan@telent.net>
Date: Wed, 4 Feb 2026 18:59:46 +0000
sense-check docs and comments
Diffstat:
4 files changed, 58 insertions(+), 34 deletions(-)
diff --git a/README.md b/README.md
@@ -7,7 +7,7 @@ Comprises:
* some code for an ESP32-C3 wich can be connected (via level
shifters and other electronics, don't plug it straight in) to the
-bike's ECU,
+bike's ECU,
* a very PoC implementation of an android client, using Termux
@@ -30,20 +30,22 @@ The ESP32 is connected to the diagnostic port of the ECU and can
interrogate it to dump its "tables". This is based on "K-line", a 1
wire 10400 baud serial connection operating with 12V logic.
-It connects to a wifi network (wifi credentials are presently
-hardcoded) and listens on a UDP socket for incoming subscription
-requests. When it receives a subscription request, it starts to
-periodically query the ECU for the requested tables and sends the
-value using UDP back to the subscriber.
+On first boot, or if it can't connect to a Wifi network, it will
+function as a Bluetooth LE peripheral: you can connect to it,
+choose a wifi network and provide the password.
+
+In normal operation it will connect to the configured Wifi network and
+open TCP and UDP sockets, The client connects first to TCP and
+provides a digitally signed session key, then (provided the signature
+is valid) to the UDP socket to send a subscription requests. When the
+device receives a subscription request, it starts to periodically
+query the ECU for the requested tables and sends the value using UDP
+back to the subscriber.
To avoid using hardcoded IP addresses, it uses multicast DNS/DNS
service discovery to advertise itself as providing the
`_keihin._udp.local" service, so a client can use
zeroconf/bonjour/avahi to find where it is.
-For the moment, there is no security on the UDP service. Until and
-unless that canges, you probably shouldn't tell it to connect to
-untrusted wifi networks.
-
-There is a prototype/example client in android-termux-client/. Consult
+There is a prototype/example client in client/. Consult
the README in that directory for details.
diff --git a/client/README.md b/client/README.md
@@ -1,12 +1,39 @@
# Client
-In the absence of an actual proper Android app, this is a Python
-script that runs in Termux.
+## Wifi configuration
-## Setup
+To choose a wifi network and send the password, run
-* You will need to (manually, because this
-is Android) install Termux and Termux:Gui from the F-Droid repository,
+```sh
+$ PASSWORD="my wifi passphrase" python client/ble.py my_network_name
+```
+
+The device will reboot once the wifi details have been saved
+
+
+## Data logging
+
+Once the wifi is operational, you can run
+
+```sh
+$ python client/eculocate.py Bike 120
+```
+
+to collect data for 120 seconds.
+
+## Android
+
+If you want to log data while actually, y'know, *riding the bike*, you
+might wish to do that without balancing a laptop on the pillion.
+There isn't an actual proper Android app (yet, anyway) but we do have
+a Python script that runs in Termux.
+
+### Setup
+
+* You will need to (manually, because this is Android) install Termux
+and Termux:Gui from the F-Droid repository,
+
+* You also need to copy `privkey.bin` from wherever you built the Rust app onto the phone
* in a Termux shell, run
@@ -16,6 +43,3 @@ $ termux-setup-storage
$ pkg install binutils make libsodium
$ SODIUM_INSTALL=system pip install pynacl zeroconf
```
-
-* you also need to copy `privkey.bin` from wherever you built the
-Rust app onto the phone
diff --git a/ecu-esp32/src/main.rs b/ecu-esp32/src/main.rs
@@ -47,6 +47,11 @@ extern crate alloc;
esp_bootloader_esp_idf::esp_app_desc!();
const BUILD_ID: &str = env!("BUILD_ID");
+
+// If the device has valid wifi credentials but you need to change them,
+// build with FORCE_WIFI_CHOOSER.
+// We should figure out some way to let the end-user do this (add a button?)
+
const FORCE_WIFI_CHOOSER : bool = option_env!("FORCE_WIFI_CHOOSER").is_some();
diff --git a/ecu-esp32/src/wifi.rs b/ecu-esp32/src/wifi.rs
@@ -1,8 +1,5 @@
-//! Set SSID and PASSWORD env variable before running this example.
-//!
//! This gets an ip address via DHCP and advertises it with mdns
-// use alloc::vec;
use alloc::vec::Vec;
use alloc::string::String;
use alloc::format;
@@ -27,17 +24,14 @@ use esp_hal::{
rng::Rng,
};
use esp_println::println;
-use esp_radio::{
-// Controller,
- wifi::{
- ScanConfig,
- WifiController,
- WifiDevice,
- WifiEvent,
- WifiStaState,
- WifiError,
- AccessPointInfo
- },
+use esp_radio::wifi::{
+ ScanConfig,
+ WifiController,
+ WifiDevice,
+ WifiEvent,
+ WifiStaState,
+ WifiError,
+ AccessPointInfo
};
use embassy_net::Stack;
@@ -254,7 +248,6 @@ async fn net_task(mut runner: Runner<'static, WifiDevice<'static>>) {
runner.run().await
}
-
async fn run_tcp_handler(stack : Stack<'_>,
sessions : &SessionStore,
mut flasher : crate::ota::Flasher<'_>) {