Connect each MQ sensor's
AOUT pin to Arduino analog pins A0–A5. All sensors share VCC→5V and GND→GND. Copy the sketch below into Arduino IDE, select your board (Tools → Board → Arduino Uno) and port, then click Upload. Once uploaded, click Connect Arduino above — your browser will ask which USB port to use. MQ sensors need a warm-up time of about 2–3 minutes after powering on for stable readings.
Arduino Sketch
STEP 01Upload this sketch. Uno is silent by default. The app sends commands — Uno responds with exactly the requested number of readings.
Live Sensor Readings
A class is a category your AI will learn to recognise. Good starting classes:
clean air, coffee, ethanol. Add at least 2 — more classes means more training data needed. The readings number tells the Arduino how many sensor snapshots to take per collection session. 20 readings per session × 3 sessions = 60 samples per class — a good target. You can edit the count later by clicking the number on each chip.
Smell Classes
STEP 02Define each smell and how many readings to collect per session. The Uno will take exactly that many readings with a 150 ms settle delay between each when you hit collect.
Sensor Labels
Hold your ENose close to the smell source and wait 5 seconds for the sensors to respond. Select the class, then click Collect Readings. The app sends a burst command like
S20\n to the Arduino — it takes exactly 20 readings with 150 ms between each, then goes silent. Watch the progress bar fill up. Repeat for every class. Tips: vary the distance and intensity between sessions so the model learns robustly. The CSV file is written live to disk — safe even if the browser crashes. Badge colours: 🔴 not enough · 🟡 getting there · 🟢 ready to train.
Data Collection
STEP 03Select a class and expose your ENose to that smell. Click Collect Readings — the app sends the count to the Uno, which takes exactly that many readings with a 150 ms settle delay between each, then goes silent. All readings are saved to CSV instantly.
Live CSV File
File System AccessA CSV file is opened automatically when you collect your first sample. Every reading is saved to disk instantly — safe against browser crashes. You can also open a file manually below. Requires Chrome or Edge.
| # | class | A0 | A1 | A2 | A3 | A4 | A5 | |
|---|---|---|---|---|---|---|---|---|
| no samples yet | ||||||||
Normalization rescales your raw ADC values (0–1023) to a 0–1 range. This is critical — without it, sensor channels with higher raw values dominate training unfairly. Min-Max is best for MQ sensors since they have a fixed hardware range.
AutoConfig runs
new ParameterSuggester().analyze(data) — it counts your samples, classes, and input dimensions, then recommends: how many neurons per layer, which optimizer (usually Adam), how many epochs, what batch size, and which loss function (Categorical Cross-Entropy for multi-class smell classification). You can override any value before training.
Normalization
STEP 04aRescale inputs before training. Min-Max recommended for MQ sensors (0-1023 ADC range).
AutoConfig — ParameterSuggester
STEP 04bRuns new ParameterSuggester().analyze(data) to auto-suggest architecture, optimizer, epochs, batch size, and loss function based on your dataset.
Training runs in a Web Worker (a background thread) so the page stays responsive. The loss number measures how wrong the model is — you want it to go down. If K-Fold is on, the dataset is split into k groups and k separate models are trained — each model is tested on the group it never trained on. The final accuracy shown is the average across all k folds, which is much more reliable than a single test. The green line on the chart is training loss; the blue line is validation loss. If they diverge (training keeps falling but validation rises), the model is overfitting — collect more data.
Training Progress
STEP 05The Confusion Matrix shows exactly which smells the model confuses. Rows are actual classes, columns are what the model predicted. The diagonal (green) is correct. Off-diagonal (red) is wrong — if "coffee" is often predicted as "ethanol", those two smells look similar to your sensors.
Predict Once sends
S1\n to the Arduino for a single fresh reading, then classifies it instantly. Start Live sends L\n — the Arduino streams at 4 Hz and predictions update continuously. The confidence % shows how certain the model is — below 60% usually means the smell is between two classes or the sensors haven't warmed up.
Results
STEP 06Fill fields manually or use live sensor readings to run predictions.
Download the trained model as JSON (weights + normalization + class labels). Load it later to predict without retraining.
Generates a self-contained enose_uno.ino + mashtishkInference.h — flash once and the Uno classifies smells on its own with no computer attached. Weights, normalization, and class labels are compiled directly into the sketch.
PROGMEM float arrays — keeps SRAM freeenose_uno/enose_uno.ino + enose_uno/mashtishkInference.h
Load samples — retrain: bring in a previously saved samples.json (or CSV) and jump straight to AutoConfig + Train. Useful when you already have enough sessions collected and just want to rebuild the model.
Load model — predict: bring in a saved model.json and go directly to live prediction — no collecting or retraining required.
Load samples — retrain
STEP 07cLoad samples and jump directly to AutoConfig + Train. Use when you have enough sessions and want to retrain with updated data.
Load model — predict without retraining
STEP 07dLoad a saved model.json to go directly to live prediction. No collecting or retraining needed.