DAX ESP32 Nodes are various custom hardware devices that run on a common firmware platform with the ESP32 microcontroller. These devices were created to work with DAX Home Automation and to control my custom lights.
On startup, the device checks its internal configuration memory to see what type of device it has been configured as (defaulting as a DAX Lamp). Based on this device type, the firmware will configure the drivers to talk to the various hardware peripherals.
Below is a block diagram of a universal ESP32 Node - items with a dashed border are optional depending on the type of device
The DAX ESP32 nodes can use both WiFi and Bluetooth Low Energy connectivity simultaneously. The “radios” command used to enable or disable WiFi and/or BLE. Stand-alone DAX lamps that do not interface with DAX will have both radios disabled. For most devices, WiFi is used to connect to DAX for remote commands over MQTT, and to download firmware updates over HTTPS. When BLE is enabled, the serial command interface is available over the BLE UART characteristic. This is to allow apps to locally control devices. By default, WiFi is enabled and BLE is disabled.
In order to uniquely identify itself, the DAX ESP32 node will generate a device ID based on it's MAC address. An example device ID might be “daxLight-00112233”.
To establish an MQTT connection to DAX, the device does the following:
One thing I have learned during my career (and with my previous sensor network) is that remote firmware updates are essential to maintain progress with IoT devices. The ability to perform a DFU (device firmware update) OTA (over the air) was one reason for selecting the ESP32 microcontroller. The OTA process uses a combination of MQTT (or a local serial command) and HTTPS for downloading firmware updates.
The HTTPS host name used for firmware updates is configured on my local DNS server to point to the IP address of the DAX Home Automation server. The firmware has the root CA (certificate authority) manually inserted in the source code.
Device type is configured with the “setpcb” command over serial or MQTT. All of the devices below run the same firmware.
DAX Lamps are the first and simplest devices that I made. Typically only a USB power input and 3 pins for the LED strip are required. Onboard they only have an ESP32 module, a 3.3V LDO, a micro USB connector, and a few passives. I have made several variations of these PCB's in order to fit different types of physical lamp configurations.
The 3 LED output pins are 5V, data out (@3.3V), and ground. Although the WS2812B requires 5V logic, I have found that the ESP32's 3.3V logic is able to drive LED strips just fine without any kind of logic level converter.
These boards also contain 4 pins that can be configured as capacitive touch buttons and can either locally control the lights on the node, or they can send commands back to DAX to control the lights in the entire room.
The Switchpanel is a board I made to control other DAX devices in different rooms. It has 4x capacitive touch buttons, 4x single color status LEDs above the touch buttons, 4x WS2812B RGB LEDs at the top, and a piezo buzzer on the back.
Pressing a button on the switchpanel will make the board beep and the status LED above the button will light up. The Switchpanel the sends a message over MQTT to the topic “dax/device_id/btn” with the value “BTN1”, “BTN2”, etc.
The built-in behavior of these buttons is to operate all devices in the same zone. So if I press the “light on” button, all of the LED lights in the same zone will turn on. If I press the “sound on” button, white noise will begin playing on any daxAudio device in the same zone. No configuration is required. I can add these devices to another room by simply assigning them to a different zone.
I like to play particular white noise audio files sometimes in my bedroom or workshop, and I also like alerts and chimes to play when various events occur. I have been using serialMP3 modules for this purpose, but those boards have a lot of parts (including a $20 codec that is difficult to find now) and require a nalig radio module to operate. With the I2S capabilities of the ESP32, I have been able to make a much simpler and cheaper alternative.
The ESP32 is a powerful 240 MHz dual-core microcontroller. This is fast enough to read wav file samples directly from a microSD card and output the data as I2S. It's also fast enough to do software MP3 decoding into I2S. The I2S data is outputted to either a MAX98357A 2W amplifier or a PCM5102A DAC connected to a 3.5 mm socket, depending on the board version.
The amp version of the board (shown below) can be connected directly to a speaker.
MQTT commands are used to play, stop, and loop audio files. Additionally, there is a download command so the ESP32 can download a new sound file over HTTPS and write it directly to the microSD card.
I'll be upfront - the ESP32 runs too hot to have a temperature sensor on the same PCB. Particularly when the device stays awake and connected to WiFi, any onboard sensor will easily climb up to 90 degrees when the room is at a comfortable 75 degrees.
This ESP32 board that I like to affectionately call “tank temp” has an HTU21D temperature sensor at the end of a long, narrow section of the PCB. It was my attempt to keep the sensor far enough away as to more accurately measure the room temperature. Unfortunately, this technique is not effective and the sensor still reads way too hot.
Instead, I use DS18B20 1-wire temperature sensors connected to one of the headers. These sensors have enough physical distance that they can be used to more accurately measure ambient room temperature.
Writeup: Sep 2023