Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Taykl12/Classify/llms.txt

Use this file to discover all available pages before exploring further.

The ESP32-C3 SuperMini serves as Classify’s physical attendance trigger. Once flashed, it connects to your local network, sends periodic heartbeats to the Classify API, and fires an attendance event whenever the BOOT button is pressed. This page walks you through setting up your credentials, choosing an IDE, and uploading the firmware.

Hardware required

  • ESP32-C3 SuperMini board
  • USB-C cable (data-capable, not charge-only)
  • Your Classify server running and reachable on the local network (see Environment Setup)

Step 1 — Create your credentials file

The firmware reads WiFi and API credentials from esp32/include/secrets.h. This file is excluded from version control, so you must create it yourself by copying the provided example.
1

Copy the example file

Navigate to the esp32/include/ directory and duplicate secrets.h.example:
cp esp32/include/secrets.h.example esp32/include/secrets.h
2

Fill in your credentials

Open esp32/include/secrets.h and replace the placeholder values:
#pragma once

/*
 * Copy this file as secrets.h (same folder) and fill in your values.
 * secrets.h is in .gitignore and will not be committed to the repository.
 *
 * DEVICE_TOKEN must match ESP32_DEVICE_TOKEN in server/.env
 */

constexpr const char* WIFI_SSID     = "your-wifi-network";
constexpr const char* WIFI_PASSWORD = "your-wifi-password";
// IPv4 of your server + :3001 on LAN, or your Render/production URL (no trailing slash)
constexpr const char* API_BASE_URL  = "http://192.168.x.x:3001";
constexpr const char* DEVICE_TOKEN  = "dev-esp32-token";
FieldDescription
WIFI_SSIDYour 2.4 GHz network name
WIFI_PASSWORDWiFi password
API_BASE_URLLAN IP of the machine running the Classify server, including port 3001
DEVICE_TOKENShared secret — must match ESP32_DEVICE_TOKEN in server/.env
DEVICE_TOKEN must match the value of ESP32_DEVICE_TOKEN in your server’s .env file exactly. A mismatch will cause the device to receive 401 Unauthorized responses and no attendance events will be recorded.

Step 2 — Flash the firmware

Choose the IDE that fits your workflow. Both use the same source code.
; PlatformIO — ESP32-C3 SuperMini (compatible with esp32-c3-devkitm-1)

[platformio]
default_envs = esp32-c3-supermini

[env:common]
platform  = espressif32 @ ^6.9.0
framework = arduino
monitor_speed = 115200
monitor_rts = 0
monitor_dtr = 0
monitor_filters = time, esp32_exception_decoder
upload_speed = 460800
build_flags =
    -D ARDUINO_USB_MODE=1
    -D ARDUINO_USB_CDC_ON_BOOT=1
    -D CORE_DEBUG_LEVEL=0

[env:esp32-c3-supermini]
extends = env:common
board   = esp32-c3-devkitm-1
board_build.flash_mode = dio
board_build.f_flash     = 80000000L
board_build.f_cpu       = 160000000L
board_upload.flash_size = 4MB
; Uncomment and set your port if PlatformIO doesn't detect it automatically:
; upload_port = COM3
; monitor_port = COM3

Arduino IDE instructions

1

Install the ESP32 board package

In Arduino IDE, go to File → Preferences and add the following URL to Additional boards manager URLs:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
Then open Tools → Board → Boards Manager, search for esp32, and install the ESP32 by Espressif Systems package.
2

Select the correct board and settings

Go to Tools and configure:
  • Board: ESP32C3 Dev Module
  • USB CDC On Boot: Enabled
  • Upload Speed: 460800
  • Port: select the COM/tty port for your device
The ESP32-C3 SuperMini uses native USB via CDC. You must set USB CDC On Boot: Enabled — without it the serial monitor will not receive output and uploads may fail on some systems.
3

Open and upload the sketch

Open firmware/esp32-c3-supermini/esp32-c3-supermini.ino in Arduino IDE. Ensure secrets.h exists in esp32/include/ (or copy it next to the .ino file if using Arduino IDE outside the PlatformIO project structure), then click Upload.

Step 3 — Verify the device is running

Once the firmware boots, the device will immediately attempt to join WiFi and start its heartbeat loop.
Open the serial monitor at 115200 baud to watch live output. You’ll see WiFi connection status, assigned IP address, signal strength, and each GET /api/device/esp32/heartbeat response code. This is the fastest way to confirm the device is reaching your server and the token is accepted.
Expected serial output on a successful start:
ESP32-C3 Classify starting...
Connecting to "your-wifi-network"...
WiFi: IP assigned
Connected. IP: 192.168.1.42
Signal: -58 dBm
GET /api/device/esp32/heartbeat -> 200
GET /api/device/esp32/heartbeat -> 200

GPIO reference

GPIOFunctionNotes
9BOOT button (input, pull-up)Active LOW; 200 ms debounce
8Blue onboard LED (output)Active LOW — LOW = on

Button and LED behavior

  • Button press + release schedules a POST /api/device/esp32/button with an X-Device-Token header.
  • On a successful POST, the blue LED blinks twice to confirm the event was received.
  • A 12-second HTTP quiet period follows each button POST to prevent duplicate triggers.
  • A 4-second minimum interval is enforced between successive button posts.

API endpoints used by the device

MethodPathPurpose
GET/api/device/esp32/heartbeatKeepalive ping every 8 seconds
POST/api/device/esp32/buttonAttendance trigger on button press
The POST /api/device/esp32/button endpoint returns:
{
  "ok": true,
  "connected": true,
  "pressCount": 7,
  "lastSeenAt": "2024-01-15T10:30:00.000Z"
}

Admin monitoring

These endpoints require an admin JWT and are not called by the device itself:
MethodPathPurpose
GET/api/admin/esp32/statusView device status and last heartbeat
POST/api/admin/esp32/resetReset the press counter to zero

Troubleshooting

SymptomLikely causeFix
No serial outputUSB CDC On Boot disabledRe-flash with CDC On Boot: Enabled
WL_NO_SSID_AVAILWrong SSID or 5 GHz networkCheck WIFI_SSID; use a 2.4 GHz network
401 UnauthorizedToken mismatchEnsure DEVICE_TOKEN matches ESP32_DEVICE_TOKEN in server/.env
Heartbeat backoff increasingServer unreachableVerify API_BASE_URL IP and that the server is running on port 3001

Build docs developers (and LLMs) love