DIY Dry box — Part 7

The infrastructure is ready, waiting for data. The last part is to program a microcontroller with humidity sensors to report the humidity levels to the MQTT server.

I have never done any of that before, so I decided to go with something mostly plug and play on the hardware part (thanks to Adafruit):

The sensors being the same model, they share the same bus address, that’s why the multiplexer is required, it will provide each sensor with a different address.

I chose that microcontroller because it has a RISC-V processor (which is an architecture that I hope will take over, it’s one more step in the open hardware direction). Also, the main languages used to write software for this microcontroller are C/C++, MicroPython and CircuitPython, but it seems there’s decent Rust support for it.

I have never developed software for a microcontroller before (well… not since school) and I have never written anything in Rust either.

Development environment

I’m using JetBrains IntelliJ IDEA with the Rust plugin. I already installed Rustup which installs rust and cargo.

And now the necessary to develop for the ESP32-C3 (on debian):

sudo apt-get install -y git curl gcc clang ninja-build cmake libudev-dev unzip xz-utils python3 python3-pip python3-venv libusb-1.0-0 libssl-dev pkg-config libtinfo5 libpython2.7
rustup install nightly
rustup component add rust-src --toolchain nightly
rustup target add riscv32imc-unknown-none-elf
cargo install cargo-generate
cargo install ldproxy
cargo install espflash
cargo install espmonitor

Then create a new project using the ESP IDF template:

$ cargo generate --vcs none --git https://github.com/esp-rs/esp-idf-template cargo
🤷   Project Name : drybox
🔧   Destination: /home/user/drybox ...
🔧   Generating template ...
✔ 🤷   MCU · esp32c3
✔ 🤷   STD support · true
✔ 🤷   Configure project to use Dev Containers (VS Code, GitHub Codespaces and Gitpod)? (beware: Dev Containers not available for esp-idf v4.3.2) · false
✔ 🤷   ESP-IDF native build version (v4.3.2 = previous stable, v4.4 = stable, mainline = UNSTABLE) · v4.4
[ 1/10]   Done: .cargo/config.toml
[ 2/10]   Done: .cargo
[ 3/10]   Done: .gitignore
[ 4/10]   Done: .vscode
[ 5/10]   Done: Cargo.toml
[ 6/10]   Done: build.rs
[ 7/10]   Done: rust-toolchain.toml
[ 8/10]   Done: sdkconfig.defaults
[ 9/10]   Done: src/main.rs
[10/10]   Done: src
🔧   Moving generated files into: `/home/user/drybox`...
✨   Done! New project created /home/user/drybox

This creates an “hello world” project. Let’s compile it and flash it to the microcontroller:

$ cd drybox/
$ cargo build
$ espflash --monitor /dev/ttyACM0 target/riscv32imc-esp-espidf/debug/drybox
Serial port: /dev/ttyACM0
Connecting...

Chip type:         ESP32-C3 (revision 3)
Crystal frequency: 40MHz
Flash size:        4MB
Features:          WiFi
MAC address:       10:91:00:00:00:00
App/part. size:    409712/4128768 bytes, 9.92%
[00:00:00] ########################################      12/12      segment 0x0                                                                                                                                    [00:00:00] ########################################       1/1       segment 0x8000                                                                                                                                 [00:00:04] ########################################     210/210     segment 0x10000                                                                                                                                
Flashing has completed!
Commands:
CTRL+R    Reset chip
CTRL+C    Exit

ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x15 (USB_UART_CHIP_RESET),boot:0xd (SPI_FAST_FLASH_BOOT)
Saved PC:0x4004c622
0x4004c622 - chip726_phyrom_version_num
at ??:??
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd6100,len:0x172c
load:0x403ce000,len:0x928
0x403ce000 - _coredump_iram_start
at ??:??
load:0x403d0000,len:0x2ce0
0x403d0000 - _coredump_iram_start
at ??:??
entry 0x403ce000
0x403ce000 - _coredump_iram_start
at ??:??
I (24) boot: ESP-IDF v4.4-dev-2825-gb63ec47238 2nd stage bootloader
I (24) boot: compile time 12:10:40
I (25) boot: chip revision: 3
I (28) boot_comm: chip revision: 3, min. bootloader chip revision: 0
I (35) boot.esp32c3: SPI Speed      : 80MHz
I (40) boot.esp32c3: SPI Mode       : DIO
I (44) boot.esp32c3: SPI Flash Size : 4MB
I (49) boot: Enabling RNG early entropy source...
I (54) boot: Partition Table:
I (58) boot: ## Label            Usage          Type ST Offset   Length
I (65) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (73) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (80) boot:  2 factory          factory app      00 00 00010000 003f0000
I (88) boot: End of partition table
I (92) boot_comm: chip revision: 3, min. application chip revision: 0
I (99) esp_image: segment 0: paddr=00010020 vaddr=3c050020 size=17648h ( 95816) map
I (122) esp_image: segment 1: paddr=00027670 vaddr=3fc89c00 size=0146ch (  5228) load
I (123) esp_image: segment 2: paddr=00028ae4 vaddr=40380000 size=07534h ( 30004) load
I (133) esp_image: segment 3: paddr=00030020 vaddr=42000020 size=419b4h (268724) map
I (176) esp_image: segment 4: paddr=000719dc vaddr=40387534 size=0264ch (  9804) load
I (178) esp_image: segment 5: paddr=00074030 vaddr=50000010 size=00010h (    16) load
I (185) boot: Loaded app from partition at offset 0x10000
I (188) boot: Disabling RNG early entropy source...
I (205) cpu_start: Pro cpu up.
I (213) cpu_start: Pro cpu start user code
I (213) cpu_start: cpu freq: 160000000
I (213) cpu_start: Application information:
I (216) cpu_start: Project name:     libespidf
I (221) cpu_start: App version:      1
I (226) cpu_start: Compile time:     Sep 27 2022 22:28:32
I (232) cpu_start: ELF file SHA256:  0000000000000000...
I (238) cpu_start: ESP-IDF:          08fa67f
I (243) heap_init: Initializing. RAM available for dynamic allocation:
I (250) heap_init: At 3FC8BF90 len 00050780 (321 KiB): DRAM
I (256) heap_init: At 3FCDC710 len 00002950 (10 KiB): STACK/DRAM
I (263) heap_init: At 50000020 len 00001FE0 (7 KiB): RTCRAM
I (270) spi_flash: detected chip: generic
I (274) spi_flash: flash io: dio
I (278) sleep: Configure to isolate all GPIO pins in sleep state
I (284) sleep: Enable automatic switching of GPIO sleep configuration
I (292) cpu_start: Starting scheduler.
Hello, world!

Good news, it works!

But that’s about it. When I tried to write the software to talk to the sensor over I²C (at the end of 2022, most of the libs were in an alpha state), I did manage to get a response but the content only partially matched what I expected, but I could not get meaningful data. I read several times the HTU31D datasheet to no avail.

Comments Add one by sending me an email.