atomspectra-waterfall-esp32

Installing the AtomSpectra ESP32 Gateway

πŸ‡·πŸ‡Ί Русская вСрсия Β· πŸ‡¬πŸ‡§ English

Step-by-step guide: from a bare board to a working spectrum in your browser.

1. What you need

Hardware

Component Why
ESP32-S3-DevKitC-1 N16R8 The gateway board. It must be the S3 β€” you need USB OTG Host (GPIO19/20). A regular ESP32 / C3 will not work β€” they have no USB Host. 16 MB Flash + 8 MB PSRAM. Buy on Ozon
USB-C OTG cable Connects the ESP32-S3 USB port (host) to the spectrometer USB port (device). The ESP32-S3-DevKitC-1 has two USB-C connectors β€” use the one labeled β€œUSB” (not β€œUART”).
USB cable for flashing Connects the ESP32-S3 UART port (labeled β€œUART”) to the PC for the first flash.
KB Radar β€œAtom Spectra” A gamma spectrometer with a USB port. Inside β€” FTDI FT232R (VID 0403, PID 6001), 600000 baud.
5V USB power supply For continuous operation (after flashing, the USB-UART cable can be removed).

ESP32-S3 board pinout

Software

Option A β€” local ESP-IDF (recommended for development):

Option B β€” Docker (simpler, nothing to install):

2. Physical connection

Assembly β€” spectrometer, ESP32-S3, USB meter

                    USB-C "UART"              USB-C "USB" (OTG)
                    (for flashing)            (for the spectrometer)
                         β”‚                         β”‚
 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 β”‚   PC    │◄──────►│         ESP32-S3-DevKitC-1        │◄──────►│ Atom Spectra β”‚
 β”‚ (COM14) β”‚  USB   β”‚            N16R8                  β”‚  USB   β”‚ (FTDI FT232R β”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  OTG   β”‚  600 kBd)    β”‚
                                    β”‚                            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚ WiFi 2.4 GHz
                                    β–Ό
                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                              β”‚  Browser  β”‚
                              β”‚  BecqMoni β”‚
                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Important: the ESP32-S3-DevKitC-1 has two USB-C connectors. Use the UART port for flashing. Use the USB (OTG) port to connect the spectrometer. Do not mix them up!

Board jumpers β€” close the USB-OTG jumper

3. Building the firmware

Option A: local ESP-IDF

# Clone the repository
git clone https://github.com/VibeEngineering-LLC/atomspectra-waterfall-esp32.git
cd atomspectra-waterfall-esp32

# Set the target chip
idf.py set-target esp32s3

# Build
idf.py build

Dependencies (usb_host_cdc_acm, littlefs) are downloaded automatically on the first build via the ESP-IDF Component Manager (main/idf_component.yml).

Option B: Docker (no ESP-IDF install)

git clone https://github.com/VibeEngineering-LLC/atomspectra-waterfall-esp32.git
cd atomspectra-waterfall-esp32

# Build inside a Docker container
docker run --rm -v "$(pwd):/project" -w /project espressif/idf:v5.4 \
  bash -c ". /opt/esp/idf/export.sh && idf.py build"

On Windows (PowerShell):

docker run --rm -v "${PWD}:/project" -w /project espressif/idf:v5.4 `
  bash -c ". /opt/esp/idf/export.sh && idf.py build"

Build output: build/atomspectra.bin (+ bootloader + partition table).

4. Flashing

Via ESP-IDF (if installed)

# Connect the ESP32-S3 to the PC via the UART port
# Find the COM port (Device Manager β†’ CH340/CH343/CP2102/FTDI)
idf.py -p COM14 flash

Via esptool directly (after a Docker build)

pip install esptool

# Flash all three images
esptool.py -p COM14 -b 460800 \
  --before default_reset --after hard_reset \
  write_flash --flash_mode dio --flash_size 16MB \
  0x0 build/bootloader/bootloader.bin \
  0x8000 build/partition_table/partition-table.bin \
  0x10000 build/atomspectra.bin

First boot β€” WiFi setup

  1. After flashing, the board reboots and raises an access point β€œAtomSpectra-Setup” (open, no password)
  2. Connect to it with a phone or laptop
  3. A captive portal opens (or go to http://192.168.4.1/)
  4. Pick your WiFi network from the list
  5. Enter the password and press Connect
  6. The board reboots and connects to your network
  7. The board IP is in the router’s DHCP table or in the UART monitor: idf.py -p COM14 monitor

Captive portal β€” WiFi setup

5. Usage

  1. Open http://<board-IP>/ in a browser
  2. Connect the spectrometer with a USB-C OTG cable to the USB port of the ESP32-S3 (not UART!)
  3. The spectrum appears automatically (refreshed once per second)

Controls

Button What it does
β–Ά Start Start spectrum acquisition on the instrument (command -sta)
β–  Stop Stop acquisition (command -sto)
↻ Reset Reset the accumulated spectrum (command -rst)
Log / Lin Toggle logarithmic / linear Y scale
CPS / Counts Toggle Y units: count rate / accumulated pulses
Ch / keV Toggle X scale: channels / energy in keV
Save Save the current spectrum to the ESP flash
Load Load a saved spectrum (overlaid on the live one)
XML Download a BecqMoni-compatible file
CSV Download an InterSpec-compatible file

Cursor

Hover over the chart β€” info appears below it:

Energy calibration

Calibration is read from the instrument automatically on connection (command -inf). If calibration is received β€” the keV button enables the energy scale. Polynomial: E(ch) = cβ‚€ + c₁·ch + cβ‚‚Β·chΒ² + c₃·chΒ³ + cβ‚„Β·ch⁴.

6. Changing WiFi

Two ways:

  1. Via the Web UI: the WiFi Reset button β†’ the board reboots into access-point mode
  2. Via UART: idf.py -p COM14 erase-otadata + reflash

7. TCP bridge for BecqMoni / AtomSpectra on a PC

If you want to use the desktop BecqMoni or AtomSpectra software over WiFi:

  1. In the program, choose β€œTCP/IP” instead of a COM port
  2. Enter the address: <board-IP> port 8234
  3. The program works as if directly connected over USB

The TCP bridge and the Web UI work simultaneously β€” data is duplicated.

8. Partition table

nvs,      data, nvs,      0x9000,   0x6000      (24 KB β€” WiFi settings)
phy_init, data, phy,      0xf000,   0x1000      (4 KB)
factory,  app,  factory,  0x10000,  3M          (3 MB β€” firmware)
storage,  data, littlefs, ,         12944K      (12.9 MB β€” saved spectra)

9. Security

WiFi password in flash

Your WiFi password is stored in the nvs partition in plaintext. Anyone with physical access to the board can read the flash contents with a standard tool and extract the password:

esptool.py -p COM14 read_flash 0x9000 0x6000 nvs.bin
strings nvs.bin        # the SSID and password will be among the strings

The Web UI (basic auth) and OTA passwords are stored the same way (unencrypted). This is a deliberate trade-off for the typical scenario β€” the board sits on a trusted home LAN and only the owner has physical access to it.

When it matters

Enable encryption if:

How to enable it (NVS encryption + flash encryption)

The only correct way to protect the password in NVS is flash encryption (NVS encryption works on top of it). The template in sdkconfig.defaults is commented out:

#CONFIG_SECURE_FLASH_ENC_ENABLED=y
#CONFIG_NVS_ENCRYPTION=y

⚠ IRREVERSIBLE. Flash encryption burns eFuses on the ESP32-S3 chip. The process cannot be rolled back, the chip cannot be returned to its original state, and in Release mode reflashing over UART is blocked forever. A configuration mistake can brick the board.

Steps (only deliberately, after reading the Espressif documentation):

  1. Study the official docs: Flash Encryption and NVS Encryption.
  2. Uncomment the two lines in sdkconfig.defaults.
  3. Rebuild from scratch: idf.py fullclean && idf.py build.
  4. Flash. On first boot the chip generates a key and encrypts the flash.

The firmware ships with encryption disabled by default β€” the decision is left to you precisely because it is irreversible.

Troubleshooting

The spectrometer is not detected over USB

No spectrum (Web UI shows an empty chart)

WiFi will not connect

The build fails