Firmware for a daily timer switch powered by the QT Py ESP32 Pico
Find a file
2025-09-06 12:31:06 -07:00
.cargo initial commit 2025-09-06 02:35:57 -07:00
src refactor setup tasks 2025-09-06 12:31:06 -07:00
.gitignore initial commit 2025-09-06 02:35:57 -07:00
build.rs initial commit 2025-09-06 02:35:57 -07:00
Cargo.toml initial commit 2025-09-06 02:35:57 -07:00
README.md fix typo in readme tutorial 2025-09-06 12:25:26 -07:00
rust-toolchain.toml initial commit 2025-09-06 02:35:57 -07:00
sdkconfig.defaults initial commit 2025-09-06 02:35:57 -07:00

Flip-Flop

Firmware for a daily timer switch powered by the QT Py ESP32 Pico.

This application uses NTP to synchronize the microcontroller clock, allowing the system to recover automatically after losing power, so long as it remains within range of a known WiFi access point.

Configuration

Configuration values are hard-coded in src/config.rs. Previously, configuration was handled by toml-cfg, but hard-coding the values accomplishes the same thing with fewer moving parts.

Toolchain Installation and Usage

Refer to the Rust on ESP book for installation of the development toolchain.

Development was completed on a system running Fedora 42, which has some dependencies which diverge from the official documentation.

Detailed Instructions for Fedora 42

Installing espup

Espressif has documentation for setting up a development environment; however, these do not work out of the box with Fedora 42. In addition to installing Rust--

sudo dnf install rustup
rustup-init

--we must install several dependencies before espup will compile in the next step (note that the perl packages are case-sensitive):

sudo dnf install git wget flex bison gperf python3 python3-pip cmake ninja-build ccache libffi-devel openssl-devel dfu-util libusb1 perl-FindBin perl-IPC-Cmd perl-File-Compare
pip install virtualenv

Now, we can run:

cargo install espup --locked
cargo install espflash
cargo install ldproxy # Required for std development
espup install

This will install the relevant Espressif Rust, LLVM, and GCC tools, as well as generating an activation script in ~/export-esp.sh. If you want to use this toolchain by default, you may want to add source ~/export-esp.sh to your .profile.

Connecting and Flashing the MCU

Once the development board (or serial console) is connected to the computer via USB, the example project may be flashed with:

cargo run

This compiles the project and shells out automatically to espflash to flash and establish a serial console connection to the board. In my case, it identified the correct device automatically. However in some cases, the device exposed to the file system may have restrictive permissions applied, which will cause an error to the effect of:

[2025-09-06T05:46:02Z INFO ] Serial port: '/dev/<DEVICE NAME>'
[2025-09-06T05:46:02Z INFO ] Connecting...
Error:   × Failed to open serial port /dev/<DEVICE NAME>
  ╰─▶ Error while connecting to device

Granting read/write permissions to all users, should be sufficient to resolve the above issue (note that this is required each time the device is physically reconnected):

sudo chmod a+rw /dev/<DEVICE NAME>

The port will be saved to espflash_ports.toml. For further information, refer to the espflash documentation.

When successful, espflash will identify the connected MCU and its specifications.

[2025-09-06T05:47:07Z INFO ] Serial port: '/dev/ttyACM0'
[2025-09-06T05:47:07Z INFO ] Connecting...
[2025-09-06T05:47:08Z INFO ] Using flash stub
Chip type:         esp32 (revision v3.0)
Crystal frequency: 40 MHz
Flash size:        8MB
Features:          WiFi, BT, Dual Core, 240MHz, Embedded Flash, Embedded PSRAM, VRef calibration in efuse, Coding Scheme None

It will then spend several seconds flashing, booting, and finally executing the project on the ESP32 system.