Custom Firmware Development¶
This guide covers setting up a development environment and building custom firmware for HALSER.
Development Environment¶
HALSER firmware is developed using PlatformIO with the Arduino framework. PlatformIO integrates with VS Code and provides dependency management, build automation, and device upload.
Platform Configuration¶
Use the following platformio.ini configuration as a starting point:
[env:esp32-c3]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/54.03.20/platform-espressif32.zip
board = esp32-c3-devkitm-1
framework = arduino
lib_ldf_mode = deep
upload_speed = 2000000
monitor_speed = 115200
build_flags =
-DARDUINO_USB_CDC_ON_BOOT=1
-DARDUINO_USB_MODE=1
USB CDC
The ARDUINO_USB_CDC_ON_BOOT=1 flag is required for USB serial communication on the ESP32-C3. Without it, Serial output will not appear over USB.
Pin Assignments¶
Always use the HALSER pin definitions rather than hard-coded GPIO numbers. See the GPIO Reference for the complete mapping.
Key pins for serial communication:
| Function | GPIO | Constant (default firmware) |
|---|---|---|
| UART1 TX | 2 | kUART1TxPin |
| UART1 RX | 3 | kUART1RxPin |
| CAN TX | 4 | kCANTxPin |
| CAN RX | 5 | kCANRxPin |
| I2C SDA | 6 | kI2CSDA |
| I2C SCL | 7 | kI2CSCL |
| RGB LED | 8 | kRGBLEDPin |
| Button | 9 | kButtonPin |
| 1-Wire | 10 | kOneWirePin |
Key Libraries¶
| Library | Version | Purpose |
|---|---|---|
| SensESP | 3.2.0 | IoT framework (WiFi, web UI, Signal K) |
| SensESP/NMEA0183 | — | NMEA 0183 sentence parsing |
| NMEA2000-library | 4.17.2 | NMEA 2000 message handling |
| NMEA2000_twai | — | ESP32 TWAI (CAN) driver for NMEA2000 |
| Adafruit NeoPixel | — | RGB LED control |
Starting Points¶
From the Default Firmware¶
The HALSER default firmware provides a complete working example of:
- SensESP application setup
- NMEA 0183 sentence parsing (GGA, RMC, VTG, HDG, VHW, DPT, MWV)
- NMEA 2000 message transmission
- RGB LED status indication
- Configurable bit rate via web UI
Clone and modify it to suit your needs.
From a SensESP Template¶
For a fresh start, use the SensESP project template and add HALSER-specific pin definitions.
Bare Arduino¶
For minimal projects that don't need WiFi or web UI:
#include <Arduino.h>
// HALSER pin definitions
constexpr int kUART1TxPin = 2;
constexpr int kUART1RxPin = 3;
constexpr int kCANTxPin = 4;
constexpr int kCANRxPin = 5;
constexpr int kRGBLEDPin = 8;
constexpr int kButtonPin = 9;
constexpr int kOneWirePin = 10;
void setup() {
Serial.begin(115200); // USB CDC serial
Serial1.begin(4800, SERIAL_8N1, kUART1RxPin, kUART1TxPin);
}
void loop() {
// Read from NMEA 0183 input
while (Serial1.available()) {
char c = Serial1.read();
Serial.print(c); // Echo to USB for debugging
}
}
Example Use Cases¶
AIS Receiver Bridge¶
The default firmware does not handle AIS sentences (VDM/VDO). To bridge AIS data, you need custom firmware that:
- Receives NMEA 0183 on RS-485 RX at 38400 bit/s
- Parses or forwards VDM/VDO sentences
- Sends data via WiFi (Signal K, TCP, or UDP)
1-Wire Temperature Sensor to NMEA 2000¶
Connect a DS18B20 temperature sensor to the 1-Wire header and transmit PGN 130312 (Temperature) on the NMEA 2000 bus. The SensESP framework has built-in support for both 1-Wire sensors and NMEA 2000 temperature messages.
Victron VE.Direct Integration¶
Victron VE.Direct uses raw UART at 19200 bit/s. Connect the VE.Direct cable to the UART terminal block (3.3 V jumper setting) and parse the VE.Direct text protocol in firmware.
Programming¶
USB-C Upload¶
Connect HALSER to your computer via USB-C. PlatformIO will detect the ESP32-C3 USB CDC serial port automatically.
OTA Updates¶
If using SensESP, over-the-air (OTA) firmware updates are supported via the web UI once WiFi is configured.