Build an e-nose
that sniffs OpenSmell.
An electronic nose from off-the-shelf parts — no PCB milling, no electronics degree. Wire sensors, flash with a click, and record into the open CSV stream the whole stack shares.
The support model: the fully automated path today is the MQ sensor family (1–6 sensors). Digital sensors wire in and stream the same way but need DIY firmware. Everything else is on the catalog so you know it exists and what it needs — the builder never promises a plan it can't back up.
Plays the complete OpenSmell pipeline today: one-click Osmograph firmware flash, standard wiring, channel mapping into the 6-channel encoder.
Wireable and the data format is compatible, but Osmograph's one-click flash currently covers MQ-only configurations. Use the PlatformIO firmware pattern to bring your own driver.
Feasible on the bench but not plug-and-play — a conditioning circuit (or an on-board-conditioned module) is required, and there is no OpenSmell software support yet. The serial CSV contract is documented so you can build the driver.
Orders of magnitude more sensitive (ppb) and correspondingly more expensive and calibration-sensitive. Not part of the current kit.
Every sensor family, on one stack
The OpenSmell pipeline doesn't care how the numbers arrived — only that they respond to the chemicals you want to detect. Different families trade accuracy, cost, and complexity.
Metal-oxide · analog
The MQ family: heated elements whose resistance changes with gas contact. Broad, cheap, proven — and the only family with full one-click software support today.
Metal-oxide · digital
MEMS sensors like BME688, SGP40/41, and ENS160 that handle the heater and conditioning on-chip and talk over I²C. Relative indices, not calibrated ppb.
Electrochemical
Real gas concentration for specific toxic gases (CO, NO₂, SO₂…). Needs conditioning or an on-board-conditioned module like the Winsen ZE03. No software support yet.
Research-grade
Photoionisation detectors reach ppb levels — orders of magnitude beyond MOX, and correspondingly more expensive and calibration-sensitive. Outside the current kit.
Sensor catalog
What's on the market, what each one detects, how it connects, and exactly how much OpenSmell supports it today. Support level is the first thing to read — the per-sensor detail is one click away below.
What N sensors give you
More sensors, more independent chemical dimensions — and finer discrimination between similar smells. There is no universal best count; it depends on what you want to detect.
Detect presence vs. absence of a known substance. Gas leak alarms. Smoke detection. Basic alcohol sensing.
Distinguish chemically different foods (garlic vs. coffee, citrus vs. herbs). Track spoilage over days. Detect anomalies against a clean-air baseline.
Distinguish chemically similar foods (garlic vs. ginger, onion vs. shallot). Higher accuracy on all classification tasks.
Maximum chemical resolution with current MOX technology. Complex mixture analysis. Research-grade applications.
The 6-sensor kit feeds the same 6-channel layout the encoder and session-invariance models consume — the exact shape the reference proof was validated on (OpenSmell/session-invariance, using SmellNet's processed base_data subset: NO₂, ethanol, VOC, CO, alcohol, LPG). Start with three if unsure — you can add sensors later and the firmware handles any count automatically.
Build yours, live
Pick what you want to do, adjust the sensors, and watch the rig update. Only technically valid configurations produce a build plan — then download it as a PDF.
What do you want to do?
Pick your sensors
3/6 MQ · 0/1 digital3 MQ sensors · Food identification & spoilage
Prices aren't listed here — they vary by region. Two 10 kΩ resistors per MQ sensor go into the voltage divider; the USB cable must be data-capable, not charge-only.
MQ-only configs flash with Osmograph in one click (Detect Board → select sensor config → Flash). No manual code editing. PlatformIO firmware source also lives in electronic-nose/firmware.
Stream contract: comma-separated values over serial at 115200 baud. The Osmograph firmware emits OSM-prefixed lines every 500 ms over USB Serial and a WiFi AP (TCP :8080, mDNS osmograph) at the same time; a BLE variant lives in electronic-nose/firmware/variants.
Pick a controller
ESP32 is the recommended board. If you already own one of these, it works too.
| Board | ADC inputs | Logic | Wireless | Fit |
|---|---|---|---|---|
ESP32 (ESP-WROOM-32, 38-pin) The reference board. ADC1 is WiFi-safe — the firmware maps sensors only to ADC1 so WiFi and BLE stay usable while recording. | 6× ADC1, 12-bit (GPIO34/35/32/33/36/39) | 3.3 V | WiFi AP + BLE | Recommended |
ESP32-S3 / C3 Same ESP32 SDK, same CSV contract — but the ADC1 channels live on different GPIOs. Re-map the pin table in the firmware before flashing. | Different ADC1 pin numbering (S3: GPIO1–10) | 3.3 V | WiFi + BLE | Works — pin remap |
ESP8266 (NodeMCU) A single ADC input. One MQ sensor works; for more, add an I²C ADC (e.g. ADS1115) and keep the sensors on the 5 V rail with dividers into the ADC inputs. | 1× 10-bit (A0) | 3.3 V | WiFi (no BLE) | Works — limited channels |
Arduino Uno / Nano Common shelf board. Streams the same CSV over USB Serial, but there is no onboard WiFi or BLE — the host (Osmograph) has to stay connected via USB. | 6× 10-bit (A0–A5) | 5 V | None on board (shield required) | Works — serial only |
Raspberry Pi Pico / Pico W Twelve-bit ADC but only four usable inputs. Pico W adds WiFi; a plain Pico is serial-only. Keep divider outputs at or below 3.3 V. | 4× 12-bit (GP26–29) | 3.3 V | Pico W only: WiFi (no BLE) | Works — limited channels |
One-click Osmograph flashing is ESP32-only today. The other boards share the same CSV stream contract, so they work with the platform — but you bring the Arduino or PlatformIO toolchain.
From parts to instrument
Wire it
Rails, power, and one voltage divider per MQ sensor onto unique ADC1 pins.
Flash firmware
Osmograph one-click for MQ-only rigs; PlatformIO pattern for mixed/digital.
Burn in
24 cumulative hours powered on — a one-time requirement.
First test
Crush a garlic clove near the array; watch the traces move.
Record & train
30+ seconds per substance in Osmograph; train a classifier with a click.
Calibrate
The calibration wizard is in active development — within-session use works now.
Contribute
Upload labelled recordings to the Data Commons (HuggingFace opensmell/community).
Stuck at any step? Builders share rig photos and catch mistakes early on the Discord — mention your sensor list and goal. Day-to-day progress lands on opensmell.xyz.
Four pins. One ADC1 GPIO each.
Every MQ module exposes VCC, GND, DO (ignore it), and AO. The AO line needs a voltage divider of two equal 10 kΩ resistors to sit safely in the ESP32's 0–3.3 V range. All ADC1 pins work while WiFi is active — avoid ADC2 pins like GPIO25/26 when recording over WiFi.
| Sensor slot | GPIO | ADC channel |
|---|---|---|
| Sensor 1 | GPIO34 | ADC1_CH0 |
| Sensor 2 | GPIO35 | ADC1_CH1 |
| Sensor 3 | GPIO32 | ADC1_CH2 |
| Sensor 4 | GPIO33 | ADC1_CH4 |
| Sensor 5 | GPIO36 | ADC1_CH5 |
| Sensor 6 | GPIO39 | ADC1_CH6 |
Sensor AO ─── R ───┬─── ESP32 ADC pin
│
R
│
GND- ESP32 VIN (5 V) → red power rail
- ESP32 GND → blue ground rail
- Each sensor VCC → red rail
- Each sensor GND → blue rail
- Each sensor AO → voltage divider (two equal resistors) → a unique GPIO
- No bare metal touching between the red and blue rails
Osmograph firmware streams OSM,<adc0>,<adc1>,… over serial (115200 baud) every 500 ms — and over the WiFi AP on TCP :8080.
The reference firmware prints plain comma-separated values at 10 Hz. Anything that emits comma-separated numbers on that contract is compatible downstream.
Fewer than six channels? Map them into the encoder with expand_channels — Osmograph does this automatically during training and prediction.
Calibration research maps a new device's voltages into a shared representation anchored to reference prototypes — but it is still research, not a shipped feature. Within-session experiments work today; cross-device alignment is under active development. The working protocol (a 2D-Procrustes alignment against reference prototypes) is in the electronic-nose EXPERIMENT.md; the latest results live in interoperability/alignment_experiments and encoder/research/calibration-experiments.
Safety & common mistakes
Cross-check your wiring before applying power. These are the failure modes people actually hit.
Before you power up
- Check polarity twice before powering: ESP32 VIN → 5 V, GND → GND. Reversed power is the fastest way to kill a board.
- Never feed 5 V into a 3.3 V GPIO or ADC pin. The two-resistor divider is there for a reason.
- MQ heater elements run at roughly 80 °C and are always on when powered. Keep plastic, wires, and fingers clear.
- MQ heaters draw ~150 mA each. Four to six sensors can exceed a laptop USB port's 500 mA budget — use a powered hub or an external 5 V supply.
- Bare electrochemical cells are not direct ADC inputs — they need a load/amplifier circuit. Wire a cell straight to GPIO and you risk the cell and the ADC.
- The ESP32 is ESD-sensitive. Touch a grounded surface before handling the board.
- If the board powers but never shows up on your computer, the cable is almost certainly charge-only.
Mistakes people make
- Wiring DO instead of AO. MQ modules expose a digital DO pin (threshold output) and an analog AO pin. AO is the gas value — DO is not.
- Two sensors sharing one ADC pin. Each MQ sensor needs a unique ADC1 pin. Sharing corrupts both readings.
- Skipping the voltage divider. MQ AO can swing above 3.3 V. Without the divider the ADC clips at 3.3 V and reads wrong, and can be damaged.
- Under-sizing the breadboard. The 38-pin ESP32 spans ~11 rows and blocks the columns it sits on. A 170-point mini board only fits 1–2 sensors.
- Two identical I²C breakouts. Two SGP40s (or two of any same-address breakout) collide on the bus. Pick one digital add-on, or change an address if the breakout allows it.
- Flashing over a charge-only cable. The board powers up but the port never enumerates. Swap the cable.
- Sensors sealed in an enclosure. MQ sensors need airflow. A sealed box fills with heater heat and stale air — readings become meaningless.
After flashing — tips
- After flashing, you don't need the laptop plugged in: power the rig from a USB wall adapter or power bank and stream over the WiFi AP (or BLE). Your machine stays untethered.
- Let the heaters warm up 5 minutes before every session — readings drift hard while they settle.
- Log a clean-air baseline at the start of each session; drift happens and the baseline is your reference.
- Use a cup, jar, or bag to hold samples at a consistent distance from the array.
- Keep the rig near fresh air between samples, not next to the thing you're sniffing.
- Re-flash to switch streaming mode — the variants cover USB-only, WiFi, and BLE.
Keep the sensors in air, not in a box.
A basic enclosure is 3D-printed or laser-cut from 3 mm acrylic. The critical part is airflow — MQ sensors need ambient air, and the heater runs hot, so never seal the chamber.
- 120 × 80 mm base plate with mounting holes for the ESP32 and sensor breakouts.
- Space MQ sensors at least 20 mm apart for airflow.
- Vented lid with 5 mm holes in a grid pattern above the sensors.
- Optional 30 mm 5 V fan for active air exchange.
- The heater runs hot (~80 °C) — keep at least 10 mm clearance above each sensor.
- For food testing, add a small door or slot to insert samples without opening the main chamber.
Printable model files (STL) are being finalised — a Fusion 360 template is pending. When they land they'll be published under an open license. Join the Discord to follow along.
MIRIS
A custom sensor we're building in the lab. When it ships, it slots straight into this stack — same data contract, same apps. No details to share yet.
Build, measure, contribute.
Your recordings — labelled and uploaded to the Data Commons — train the next encoder and raise the standard for everyone. Calibration makes every rig count as a data source.
