Close
0%
0%

MNIST on ESP32-C3 — No TensorFlow, Pure C

Handwritten digit recognition on a $3 MCU. Neural network exported as a standalone C header by Hasaki. No runtime, framework or dependencies

Similar projects worth following
Most approaches to running neural networks on microcontrollers rely on TensorFlow Lite — runtime, dependencies, overhead. This project takes a different path. Train a 784-128-10 network on desktop using Hasaki, a C++ CLI tool. Export it as a standalone C header with a predict() function. Drop it into the ESP32-C3 firmware. No runtime. No framework. No dependencies. The ESP32 hosts a web server with an HTML5 canvas. Draw a digit on any browser on the same network — the chip classifies it locally in under a millisecond. Memory footprint: 12.2% RAM, 78.9% Flash (INT8, 784-128-10, 390 KB header). GitHub: https://github.com/AlexRosito67/hasaki-mnist-esp32 Hasaki: https://github.com/AlexRosito67/hasaki

Most approaches to running neural networks on microcontrollers rely on TensorFlow Lite — runtime, dependencies, overhead. This project takes a different path.


The pipeline 
Train a 784-128-10 network on desktop using Hasaki — a C++ CLI tool that trains feedforward networks and exports standalone C headers. No Python, no framework, no runtime. The exported header contains the weights and a predict() function that compiles on any C99 toolchain.


The hardware

ESP32-C3 Super Mini. $3. No additional components required for the core demo. Optional: LED matrix display for visual output.


How it works

The ESP32 hosts a web server with an HTML5 canvas. Any device on the same network opens the page, draws a digit, and the chip runs inference locally in under a millisecond — no cloud, no external API.
Memory footprint (INT8, 784-128-10)
RAM: 40,108 B / 327,680 B — 12.2%
Flash: 1,034,610 B / 1,310,720 B — 78.9%
Flash includes the full sketch plus the 390 KB INT8 model header.


Training

Trained with Hasaki Pro — Adam optimizer, dropout 0.3, L2 0.0001, early stopping. Converged at epoch 1981. Final Val Loss: 0.058. Validation accuracy: ~98.2%.
INT8 quantization passes the mean error threshold — less than 5% degradation vs float.

The exported header

#include "mnist_int8.h"

float input[784];
float output[10];

predict(input, output);
// output[i] = confidence for digit i

No heap allocation. No dependencies. If it compiles for your target, it runs.

  • 1 × ESP32-C3 SUPER MINI

  • 1
    Clone the repository
    git clone https://github.com/AlexRosito67/hasaki-mnist-esp32
  • 2
    Open in Arduino IDE or PlatformIO

    Open `src/main.cpp` (PlatformIO) or `mnist_esp32.ino` (Arduino IDE).

  • 3
    Set your WiFi credentials
    #define WIFI_SSID     "YOUR_SSID"
    #define WIFI_PASSWORD "YOUR_PASSWORD"
    #define DISPLAY_IP    "192.168.1.XXX"  // optional LED matrix

View all 8 instructions

Enjoy this project?

Share

Discussions

Does this project spark your interest?

Become a member to follow this project and never miss any updates