Ambient Light + Air Quality + More — a reliable, low-cost sensor network for home, lab, and in-vehicle prototypes, built around CAN with OTA updates and multi-node management.
Last updated: January 25, 2026
Why CAN for sensors?
CAN was designed for noisy, distributed environments and it shines when you want dependable, multi-drop communication over long cables. That makes it a strong backbone not only for vehicles, but also for home automation and lab setups where Wi-Fi can be unreliable or too power-hungry.
This project builds a CAN-based sensor node and a companion display client that together provide:
- Ambient light, temperature, humidity, pressure, IAQ, CO₂eq, VOC
- Multi-node addressing (up to 16 nodes on the same bus)
- OTA firmware updates over CAN (~3.3 KB/s)
- Device management and automated sanity testing with a CLI tool
System overview
The system has three pieces:
- Sensor nodes — ESP32-C3 + ALS + BME680/BME688 + CAN transceiver
- Monitor/display node — ESP32-C3 + OLED + CAN transceiver
- Host tool —
can-sensor-toolfor monitoring, management, and OTA (Linux / SocketCAN)
All nodes communicate at 500 kbps over a standard CAN bus.
Hardware design
Core components
- ESP32-C3 SuperMini (~$2 board)
- SN65HVD230 CAN transceiver (3.3 V native — no level-shifting needed)
- ALS sensor: VEML7700 or OPT3001 (board footprint supports either; mount only one)
- BME680/BME688 for temperature, humidity, pressure, and IAQ data
- On-board buck converter: 6–30 V input (12 V typical), generates stable 5 V / 3.3 V locally
Power-over-CAN using 6P4C (RJ-11)
The system uses a two-pair telephone cable: one pair for CAN-H / CAN-L, one pair for power. Simple, low-cost, and practical. Tested reliably to 15 m with standard RJ-11 cables.
RJ-11 junction board — low-cost two-pair power + CAN distribution. This is a ready-made off-the-shelf board available from common electronics marketplaces.
Sensor board
Sensor board: ESP32-C3, ALS footprint, BME680, SN65HVD230 transceiver, buck converter, and RJ-11 connector.
Sensor board sub-modules: base PCB with ESP32-C3 SuperMini, SN65HVD230 CAN transceiver, BME680 environmental sensor, VEML7700/OPT3001 ALS, buck converter, and RJ-11 connector.
Monitor board
Monitor board with OLED display showing live values: 22 lux, 25.9 °C, 32 % RH, 989 hPa, IAQ 51 (Good).
Monitor board sub-modules: base PCB with ESP32-C3 SuperMini, SN65HVD230 CAN transceiver, SSD1306 OLED display, buck converter, and RJ-11 connector.
Sensor auto-detection (one firmware, many boards)
The sensor firmware auto-detects what's connected at boot:
- ALS: VEML7700 (0–120 K lux) or OPT3001 (0–83 K lux)
- Environmental: BME680 or BME688
A single firmware image works across all hardware variants — no build-time configuration needed.
CAN architecture (high-level)
Each node gets 32 CAN message IDs (0x20 spacing):
- 0x100–0x10F: sensor data for Node 0 (ALS at +0x00, ENV at +0x01, AIQ at +0x02, …)
- 0x110–0x11F: control/management for Node 0 (stop, start, reboot, OTA, discovery, …)
The same layout repeats at +0x20 per node, supporting up to 16 nodes on a single bus. Reserved offsets are available for future sensor types (gas selectivity, mm-wave presence, etc.).
Full frame layouts and byte-level formats are documented in the repo README.
Real measurements (sample log)
Below is a snippet captured with can-sensor-tool monitor:
[Node 0] ALS (OPT3001): 79 lux, seq=13, config=201, status=OK [Node 0] ENV: 24.83°C, 38% RH, 991.2 hPa, status=OK [Node 0] AIQ: IAQ=50 (Good), accuracy=0, CO2=500 ppm, VOC=0 ppm, status=OK ... [Node 0] ALS (OPT3001): 192 lux, seq=20, config=203, status=OK [Node 0] ENV: 25.09°C, 36% RH, 991.2 hPa, status=OK [Node 0] AIQ: IAQ=50 (Good), accuracy=0, CO2=500 ppm, VOC=0 ppm, status=OK ... [Node 0] ALS (OPT3001): 0 lux, seq=24, config=200, status=OK [Node 0] ENV: 25.15°C, 35% RH, 991.2 hPa, status=OK
Over this run, light levels ranged from 0 (near-dark) to ~192 lux while temperature stayed around 25 °C. IAQ reported "Good" with CO₂eq at 500 ppm throughout.
Automated sanity testing
The can-sensor-tool includes a sanity-test command that exercises the full node lifecycle in one shot — discovery, start/stop, interval accuracy, reboot, node-ID change, factory reset, OTA update, and final re-discovery:
$ can-sensor-tool sanity-test ./build/esp32-can-sensor.bin [1/9] Discovery... PASS: Node 0 responds to PING [2/9] Device Info... PASS: FW v1.0.1, sensors=0x13, ALS=OPT3001, partition=ota_1 (valid) [3/9] Start/Stop... PASS: Received 3 ALS msgs in 3s, 0 after STOP [4/9] Monitor Interval... PASS: Average interval: 977 ms (target: 1000 ms) [5/9] Reboot... PASS: Node rebooted and recovered in 2005 ms [6/9] Set Node ID... PASS: Successfully changed 0->1->0 [7/9] Factory Reset... PASS: Factory reset completed in 2204 ms [8/9] OTA Update... PASS: OTA OK, node booted v1.0.1 on ota_0 (3.2 KB/s, 106369 ms) [9/9] Final Discovery... PASS: Node 0 still responds after all tests Results: 9/9 passed, 0 failed
This makes it practical to validate firmware changes end-to-end before deploying to multiple nodes.
Device management + OTA over CAN
The can-sensor-tool handles discovery, monitoring, and A/B OTA firmware updates over the CAN bus.
The ESP32 uses an A/B partition scheme: each OTA update writes to the inactive slot, reboots into it, and keeps the previous slot as a rollback target. If the new firmware fails to validate on first boot, the bootloader automatically reverts.
In testing, OTA reached ~3.2–3.3 KB/s, and a ~345 KB firmware image completed in ~106 seconds. This makes it feasible to update multiple nodes on a live bus without physical access.
Use cases
Home & Lab
- Multi-room light + environment monitoring
- Low-cost wiring with RJ-11 and a junction board
- Central monitoring on OLED or a PC via SocketCAN
In-vehicle prototype (POC)
- Rugged wiring and noise-tolerant communication
- Deterministic update rates across multiple nodes
- OTA updates without pulling nodes from the vehicle
In-vehicle smart ambient sensing
- Monitor cabin temperature, humidity, IAQ, CO₂eq, VOC, and BME688-based gas signals for passenger comfort and safety
- Feed IVI/ADAS systems with real-time ambient conditions for alerts or policy decisions
- Use ambient light data to adjust in-vehicle displays — HDR10+ Adaptive and Dolby Vision perform real-time dynamic tone-mapping that requires a continuous ambient light input to optimize frame rendering on the display (the HDR10+ Automotive spec mandates this ambient light feed)
- Add human presence detection (planned) to enable occupancy-aware safety and convenience features
Enterprise / larger infrastructure
- CAN as a reliable wired sensor backbone
- Up to 16 nodes per bus today; extendable with multiple bus segments
Current limitations and roadmap
Current
- No formal environmental or long-term reliability testing yet
- Human presence detection (mmWave) not implemented
Planned
- Add mmWave human presence sensor
- Expand other sensor types using reserved CAN offsets
BSEC licensing note
BME680/BME688 air-quality outputs use Bosch Sensortec's BSEC 2.x library, which is proprietary and not included in this repo. To enable it, download the BSEC zip from Bosch, accept their license, and pass it to build.sh (see BME680_SETUP.md in the repo).
Build and flash (sensor board)
- Install ESP-IDF and download the Bosch BSEC library (e.g.
bsec2-6-1-0_generic_release_22102024.zip). - Connect the ESP32-C3 board to your PC via USB.
- Clone the sensor firmware repo and build:
git clone https://github.com/hackboxguy/Esp32-CAN-ALS.git
cd Esp32-CAN-ALS
./build.sh --target=esp32c3 --idfpath=$HOME/esp/esp-idf/ \
--version=1.0.1 \
--bsecpath=/path/to/bsec2-6-1-0_generic_release_22102024.zip
./build.sh --flash
Build and flash (monitor board)
- Install ESP-IDF.
- Connect the ESP32-C3 board to your PC via USB.
- Clone the display client repo and build:
git clone https://github.com/hackboxguy/Esp32-CAN-Disp-Client.git cd Esp32-CAN-Disp-Client idf.py set-target esp32c3 idf.py build flash
SOURCE CODE
github.com/hackboxguy/Esp32-CAN-ALS — sensor node firmware + can-sensor-tool
github.com/hackboxguy/Esp32-CAN-Disp-Client — OLED monitor client firmware
KICAD PCB FILES
CAN-Sensor-Board.zip — sensor board KiCad project + gerbers
CAN-Monitor-Board.zip — monitor board KiCad project + gerbers
No comments:
Post a Comment