This firmware runs on a Seeed XIAO ESP32-S3 and acts as:
- LoRa receiver — reads hex payloads from a LoRa module on
Serial1with pinsRX_PIN/TX_PIN(seesrc/tsesp/main.cpp). - Relay driver — maps a 16-bit command word to six GPIOs (solenoids/valves), active low (LOW = energized).
- I2C slave at
0x09— accepts 2-byte writes and exposes the last valid state on read (for a Teensy or other master).
It uses the ESP-specific driver in lib/ESPLoRaModule and lora_config_esp.h (not the Teensy lib/LoRaModule + lora_config.h).
setRelays(uint16_t state)uses bits 14 down to 9 for relays 1–6 (see comments in source).- Commands are accepted only if
RELAY_MSB_BIT(0x8000) is set — same convention aslora_config.h/ ESP config headers. - OPEN = bit 1 → GPIO driven LOW; closed → HIGH.
See Relay bitmap.
LoRaModule::receiveData(hexData)parses+RCV=...lines and returns the hex payload string.parseHexToUint16()converts touint16_tand updateslastI2CValue.- If valid (
MSBset),setRelays()runs.
Wire.begin(I2C_SLAVE_ADDR)withonReceive/onRequest.- Write: expects exactly 2 bytes; other lengths are drained and ignored.
- Request: returns high then low byte of
lastI2CValue.
This aligns with SolenoidReceive on the Teensy (lib/SolenoidReceive), which performs a 2-byte requestFrom to the same address when the mux selects that downstream bus.
lora_config_esp.h defines:
LORA_BAND928000000 (vs Teensylora_config.h915000000 in-repo)LORA_RECEIVER_ADDRESS2 (vs TeensyLORA_RECEIVER_ADDRESS4 inlora_config.h)
For a working over-the-air link, band, network ID, spreading-factor parameters, and module addresses must be made consistent across sender and receiver in hardware configuration. Treat the headers as the single source of truth once you standardize them.