ESP32 UNO - MQ3 Alcohol Sensor

Can a cheap gas module sense a breath of hand sanitizer? Hook an MQ3 alcohol sensor to the ESP32 Uno and it reports ethanol vapor within seconds. You get a yes/no alcohol detector from the DO pin, a 0–4095 level from the AO pin, and a small breathalyzer demo, all built on the ESP32 Uno form board with Arduino IDE code.

By the end, you can:

  1. Wire an MQ-3 module to a 3.3V board without frying its pins
  2. Detect alcohol vapor with digitalRead() on the DO output
  3. Measure ethanol concentration with analogRead() on the AO output
  4. Calibrate your own sensor and turn the numbers into a breath analyzer status
ESP32 Uno MQ3 alcohol sensor

Components You Need

1×ESP32 Uno-form Board
1×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)
1×MQ3 Alcohol Sensor
4×Resistors for two voltage dividers (2
1×Jumper Wires

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

Overview of MQ3 Alcohol Sensor

After this part, you know what the MQ3 senses, why it runs hot, and what each of its pins sends out.

The MQ3 belongs to the MOS (Metal Oxide Semiconductor) family of gas sensors. Its other name is Chemiresistor: the sensing layer changes its resistance when ethanol vapor reaches it. It is tuned for alcohol and picks up even a light trace of it.

The sensing element is a Tin Dioxide (SnO2) film on an Aluminum Oxide ceramic tube. A built-in heater keeps that film hot, because cold SnO2 does not react to alcohol. On top sits a stainless steel mesh, the anti-explosion network. It shields the hot parts and blocks dust, while gas still passes into the chamber.

Typical uses: breath analyzers, drunk driving detectors, alcohol alarms and air monitors that track ethanol levels.

Technical Specifications

Item Value
Supply voltage 5V DC
Load resistance 200 KΩ
Heater resistance 33Ω ± 5%
Heater power under 800mW
Sensing resistance 1 MΩ to 8 MΩ
Detection range 25 to 500 ppm
First preheat 24 to 48 hours

Good to know: ppm means parts per million. A reading of 500 ppm says that in every million gas molecules, 500 are ethanol and the remaining 999,500 are something else.

Pinout

Four pins sit on the module edge: two for power and two for the alcohol signal.

Module Pin Role
VCC Supply for the heater and the comparator. Needs 5V
GND Ground (0V)
DO Digital signal. Goes LOW when alcohol passes the set level, stays HIGH in clean air. The blue trimmer sets that level
AO Analog signal. Its voltage rises as the ethanol level rises
MQ3 alcohol sensor module pinout diagram

Two LEDs help with checks. PWR-LED glows whenever the module gets power. DO-LED copies the DO pin, so it glows while alcohol is present and goes dark in clean air.

How It Works

Here is the chain from alcohol vapor to a number on your screen.

Situation What Happens in the SnO2 Film Result
Clean air Hot SnO2 holds oxygen on its surface. The oxygen grabs free electrons and forms a barrier Very high resistance and almost no current
Alcohol present Ethanol reacts with that surface oxygen. The barrier drops and electrons flow into the tin dioxide again Resistance falls. More alcohol means lower resistance

The module turns this resistance change into two outputs:

Output Behavior Trimmer Effect
DO LOW and DO-LED on when the ethanol level is above the trimmer setting. HIGH and DO-LED off when it is below Sets the switching point
AO Voltage follows the ethanol level. More vapor gives a higher voltage, less vapor a lower one None

Warming Up and Calibrating the MQ3

After this part, your sensor is hot, stable and has limits that match your own room.

Step 1 — Warm it up

How long the heater needs depends on the sensor's history:

  1. Brand new, or unused for over a month: keep it powered for 24 to 48 hours before you trust the values.
  2. Used in the last days: 5 to 10 minutes is enough. Expect high numbers at the start that slowly fall and settle.

Warm-up only needs power, no code. Feed the module from any 5V source; the 5V and GND header pins of the ESP32 Uno are fine. Then just wait.

Step 2 — Find your threshold values

The heater ages and the readings drift over long storage. Measure your own numbers before you build a breathalyzer:

  1. Clean-air baseline. Run the AO sketch away from any alcohol and note the values. With the voltage divider on this page, many sensors sit near 350 to 550 on the ESP32 Uno.
  2. Vapor test. Hold isopropyl alcohol or hand sanitizer close and squeeze out some vapor. Never let liquid touch the sensor. Note the peak values. Expect something between 1500 and 3700, based on how much vapor reaches the mesh.
  3. Choose three levels from your notes, for example:
  • Sober: just above your clean-air number (e.g. under 480)
  • Within legal limits: from the baseline up to a medium level (e.g. 480 to 1600)
  • Above legal limits: over the medium level (e.g. 1600 and up)

※ NOTE THAT:

Every MQ3 sensor and every room gives different numbers. Use the values above only as a first guess, and replace them with what your own sensor shows.

Step 3 — Set the DO trigger point

The blue trimmer on the module decides when DO switches:

  1. Bring alcohol vapor close to the sensor.
  2. Turn the trimmer clockwise until DO-LED lights up.
  3. Turn it back counterclockwise until DO-LED just goes dark.
  4. The DO pin now switches at about this vapor level.

ESP32 Uno Pinout

Your code talks to GPIO numbers, while the board shows Uno labels like D2 and A0. Use this diagram to match the two before you plug in any jumper.

ESP32 Uno pinout diagram

How to Connect

After this part, the MQ3 is powered from 5V and both of its outputs reach the ESP32 Uno at a safe 3.3V level.

The wiring diagram between ESP32 Uno and MQ3 alcohol sensor

This image is created using Fritzing. Click to enlarge image

※ NOTE THAT:

The wiring diagram may not show the correct wiring for the ESP32 Uno. The sensor outputs can reach 5V, but ESP32 Uno pins are 3.3V only. The picture shows DO and AO wired straight to the board. On the ESP32 Uno, put a 10 kΩ and 20 kΩ voltage divider on each output, as this page shows. We will update the diagram soon. Until then, follow the wiring table and the text on this page, not the picture.

MQ3 Alcohol Sensor Pin ESP32 Uno Pin
VCC 5V
GND GND
DO D2 (GPIO26), through a 10 kΩ / 20 kΩ voltage divider
AO A0 (GPIO2), through a 10 kΩ / 20 kΩ voltage divider

You can use DO alone, AO alone, or both. With both wired, all three sketches below run without any change to the circuit.

WARNING

The MQ3 heater must run from 5V, so DO and AO can swing up to about 5V. A 5V signal can damage ESP32 Uno pins, because they are NOT 5V tolerant. Build one divider per signal: sensor pin to a 10 kΩ resistor, the far end of that resistor to the board pin (D2 or A0), and a 20 kΩ resistor from the board pin to GND. 5V then becomes about 3.3V at the pin. The wiring image does not show the resistors, so add them on a breadboard.

WARNING

A0 (GPIO2) is a boot strapping pin. The chip checks it at power-up, and it must not be pulled HIGH while you upload code. The 20 kΩ resistor to GND in the divider keeps it LOW, which is safe. If uploads fail, unplug the AO wire, upload, then plug it back in.

Good to know: A0 (GPIO2) is also an ADC2 pin. It reads fine in these sketches, but analogRead() on it stops working once you turn on WiFi.

ESP32 Uno Code - Alcohol Yes/No from the DO Pin

This sketch heats the sensor for 20 seconds and then prints a clear alcohol / no alcohol message from the DO pin, over and over.

/* * This ESP32 Uno code was developed by newbiely.com * * This ESP32 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-uno/esp32-uno-mq3-alcohol-sensor */ #define DO_PIN 26 // D2 (GPIO26) reads the MQ3 DO output (through a voltage divider) void setup() { // open the USB serial link to the PC Serial.begin(9600); // make the DO pin an input pinMode(DO_PIN, INPUT); Serial.println("Warming up the MQ3 sensor"); delay(20000); // give the MQ3 heater 20 seconds to heat up } void loop() { int alcoholState = digitalRead(DO_PIN); if (alcoholState == HIGH) Serial.println("Alcohol is NOT detected"); else Serial.println("Alcohol is detected"); }

Upload and Test

  1. First time with this board? Set it up with ESP32 Uno - Getting Started before you continue.
  2. Build the circuit by following the wiring table above, voltage dividers included.
  3. Plug in the USB Type-C cable between the ESP32 Uno and your computer.
  4. Select the board in Arduino IDE: pick ESP32 Dev Module and the COM port of the board (CH340).
  5. Paste the sketch into a new Arduino IDE window.
  6. Press Upload and wait for "Done uploading".
  7. Open the Serial Monitor at 9600 baud and wait for the warm-up line to pass.
  8. Bring vapor close: a cotton ball with rubbing alcohol or a drop of hand sanitizer on a tissue works well.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
Warming up the MQ3 sensor Alcohol is NOT detected Alcohol is NOT detected Alcohol is detected Alcohol is detected Alcohol is detected Alcohol is NOT detected Alcohol is NOT detected
Ln 11, Col 1
ESP32 Dev Module on COM15
2
  1. Pro tip: watch DO-LED on the module while you test. If the LED and the Serial Monitor disagree, a divider wire is loose.

※ NOTE THAT:

Wrong results, like "detected" in clean air or no reaction near alcohol, mean the trigger point is off. Turn the blue trimmer clockwise for more sensitivity or counterclockwise for less, until the messages match what is really in the air.

ESP32 Uno Code - Alcohol Level from the AO Pin

This sketch prints the raw AO reading two times per second, on a 0–4095 scale.

/* * This ESP32 Uno code was developed by newbiely.com * * This ESP32 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-uno/esp32-uno-mq3-alcohol-sensor */ #define AO_PIN 2 // A0 (GPIO2) reads the MQ3 AO output (through a voltage divider) void setup() { // open the USB serial link to the PC Serial.begin(9600); // set the ADC attenuation to 11 dB (up to ~3.3V input) analogSetAttenuation(ADC_11db); Serial.println("Warming up the MQ3 sensor"); delay(20000); // give the MQ3 heater 20 seconds to heat up } void loop() { int alcoholValue = analogRead(AO_PIN); Serial.print("MQ3 sensor AO value: "); Serial.println(alcoholValue); delay(500); }

Good to know: setup() calls analogSetAttenuation(ADC_11db). This lets the ESP32 Uno analog pin read the full span from 0V up to about 3.3V. With a narrow range, the numbers jump to 4095 far too early and the alcohol levels look wrong.

Upload and Test

  1. Paste the sketch into Arduino IDE, replacing the DO sketch.
  2. Press Upload.
  3. Open the Serial Monitor at 9600 baud and let the 20-second warm-up finish.
  4. Puff some vapor from hand sanitizer or rubbing alcohol toward the mesh.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
MQ3 sensor AO value: 412 MQ3 sensor AO value: 436 MQ3 sensor AO value: 451 MQ3 sensor AO value: 1523 MQ3 sensor AO value: 2287 MQ3 sensor AO value: 3104 MQ3 sensor AO value: 3561 MQ3 sensor AO value: 3392 MQ3 sensor AO value: 2408 MQ3 sensor AO value: 1288
Ln 11, Col 1
ESP32 Dev Module on COM15
2
  1. Pro tip: open Tools > Serial Plotter instead of the monitor. The rise and slow fall after each puff is much easier to read as a curve.

The DO and AO results give you everything you need to start an alarm, switch on a warning LED, or log readings for a breath analyzer.

ESP32 Uno Code - Three-Level Breathalyzer Demo

This sketch sorts each AO reading into one of three levels and prints the matching status every second.

/* * This ESP32 Uno code was developed by newbiely.com * * This ESP32 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-uno/esp32-uno-mq3-alcohol-sensor */ #define AO_PIN 2 // A0 (GPIO2) reads the MQ3 AO output (through a voltage divider) // Limits for the three levels - put YOUR OWN calibrated numbers here! // Run the AO sketch first to see what your sensor reads // The ESP32 Uno ADC is 12-bit, so a reading is between 0 and 4095 #define SOBER_THRESHOLD 480 // a reading under this counts as sober #define DRUNK_THRESHOLD 1600 // a reading at or over this counts as drunk; in between = within limits void setup() { // open the USB serial link to the PC Serial.begin(9600); // set the ADC attenuation to 11 dB (up to ~3.3V input) analogSetAttenuation(ADC_11db); // tell the user the heater is warming up Serial.println("MQ3 Alcohol Sensor - Breathalyzer"); Serial.println("Warming up sensor..."); delay(20000); // 20 s is enough for a sensor that was used recently Serial.println("Sensor ready!"); Serial.println(); } void loop() { int gasLevel = analogRead(AO_PIN); // take one raw ADC reading // show the raw number first Serial.print("Sensor Value: "); Serial.print(gasLevel); Serial.print(" | Status: "); // pick a status from the two limits if (gasLevel < SOBER_THRESHOLD) { Serial.println("Stone Cold Sober"); } else if (gasLevel >= SOBER_THRESHOLD && gasLevel < DRUNK_THRESHOLD) { Serial.println("Drinking but within limits"); } else { Serial.println("DRUNK"); } delay(1000); // one reading per second }

The limits in the code (480 and 1600) already fit the 12-bit ADC and the divider, but they are only examples. Your own calibration numbers will work better.

Upload and Test

  1. Calibrate. Run the AO sketch and note the clean-air value and the peak with vapor.
  2. Edit the limits. Put your numbers into SOBER_THRESHOLD and DRUNK_THRESHOLD.
  3. Upload the sketch to the ESP32 Uno.
  4. Try it by waving a sanitizer bottle or an alcohol swab near the mesh.
  5. Read the status in the Serial Monitor at 9600 baud.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
Sensor Value: 437 | Status: Stone Cold Sober Sensor Value: 452 | Status: Stone Cold Sober Sensor Value: 1205 | Status: Drinking but within limits Sensor Value: 1784 | Status: DRUNK Sensor Value: 2236 | Status: DRUNK Sensor Value: 980 | Status: Drinking but within limits Sensor Value: 461 | Status: Stone Cold Sober
Ln 11, Col 1
ESP32 Dev Module on COM15
2
  1. Pro tip: fan fresh air over the sensor between tests. It takes 30 seconds or more to drop back to its clean-air number.

WARNING

This build is a learning project. It is not a legal breathalyzer, and you must never use it to judge if a person can drive.

Video Tutorial

See the ESP32 Uno build in action in the video below.

Code Explanation

After this part, you know which lines matter in the three sketches and which ones to change.

Code Part What It Does
#define DO_PIN 26 / #define AO_PIN 2 Names the GPIOs for D2 and A0, so the rest of the code uses DO_PIN and AO_PIN
analogSetAttenuation(ADC_11db) Opens the ADC input range to about 3.3V (AO and breathalyzer sketches only)
delay(20000) in setup() Gives the heater 20 seconds before the first reading
digitalRead(DO_PIN) Returns HIGH for clean air and LOW for alcohol
analogRead(AO_PIN) Returns 0 to 4095. A higher number means more ethanol
SOBER_THRESHOLD / DRUNK_THRESHOLD The two limits that split readings into three status messages

The result: the DO sketch gives a simple yes/no, the AO sketch shows how much alcohol is there, and the breathalyzer sketch turns that number into words.

ESP32 Uno vs UNO R4 for This Project

This is what changes when you move the MQ3 project from the UNO R4 to the ESP32 Uno.

Item Arduino UNO R4 ESP32 Uno
Logic voltage 5V 3.3V
MQ3 signal wiring Direct to the pins Through 10 kΩ / 20 kΩ voltage dividers
DO pin in code 2 26 (D2)
AO pin in code A0 2 (A0)
Default ADC range 0 to 1023 (10-bit) 0 to 4095 (12-bit)
Extra setup line none analogSetAttenuation(ADC_11db)
Breathalyzer limits 120 and 400 480 and 1600

The header positions are the same, so the wiring image still fits. The big change is the two dividers, because the 5V module outputs would harm the 3.3V pins.

Go Wireless: Alcohol Level on Your Phone

After this part, you have a plan to see the MQ3 reading without a USB cable.

The ESP32 Uno has WiFi and Bluetooth built in. Send the AO number to a gauge or a live chart on your phone, and you can put the sensor at a party table or in a car and watch it from a distance. A DO-only build can also push a simple "alcohol detected" alert.

Good to know: A0 is an ADC2 pin, so analogRead() on it fails while WiFi is on. For a WiFi version, move the AO wire to A2 (GPIO35), A3 (GPIO34) or the extra hole GPIO32, and change AO_PIN in the code.

Troubleshooting

Problem Possible Cause Solution
Board has no COM port in Arduino IDE CH340 driver not installed, or a charge-only cable Install the CH340 driver and swap to a USB cable that carries data
Upload stops at "Failed to connect" or "Waiting for download" Board did not enter download mode Hold the BOOT button while the upload starts, then let go
Board does not boot or upload with the sensor plugged in A0 (GPIO2) is a boot strapping pin and the AO wire pulls it the wrong way Unplug the AO wire while uploading, and check that the 20 kΩ resistor goes to GND
Both module LEDs stay dark VCC or GND loose, or VCC on 3.3V Move VCC to the 5V pin and push every jumper in firmly
AO numbers are high in clean air Heater is still cold Wait 5 to 10 minutes, or 24 to 48 hours for a new sensor
AO always reads 4095 No divider on AO, or the attenuation line was removed Add the 10 kΩ / 20 kΩ divider and keep analogSetAttenuation(ADC_11db)
AO always reads 0 AO wire on the wrong header pin, or a divider resistor is open Check that AO goes to A0 and measure the voltage at the pin
DO message never changes Trimmer set fully one way Redo the trimmer steps with vapor near the sensor
Serial Monitor shows strange symbols Baud rate does not match Set the Serial Monitor to 9600 baud

FAQ

Can I run the MQ3 heater from the 3.3V header pin?

No. The heater is made for 5V. At 3.3V it never gets hot enough, so the readings stay low and jump around. Keep VCC on 5V and use the dividers to protect the signal pins.

What is the simplest way to drop the MQ3 AO voltage to 3.3V?

A two-resistor divider: 10 kΩ from the sensor pin to the board pin, and 20 kΩ from the board pin to GND. It scales 5V to about 3.3V. A logic level converter also works for DO, but a divider is the usual choice for AO.

Does the MQ3 sense only alcohol, or other gases too?

It is most sensitive to ethanol, but other vapors like benzine or some solvents can also raise the reading a little. That is why calibration in your own room matters.

Why are my ESP32 Uno numbers so much bigger than in older Arduino guides?

The ESP32 Uno ADC is 12-bit, so analogRead() goes up to 4095. The UNO R4 returns 0 to 1023 by default. The divider changes the scale a little more, so always use limits you measured on this board.

Why does the code call analogSetAttenuation(ADC_11db)?

The line widens the ESP32 Uno ADC window to roughly 0–3.3V, so the whole MQ3 swing lands somewhere in 0–4095. Leave it out and the window is narrow, so values pin at the top far too soon. The UNO R4 code has no such line, since only the ESP32 Uno core uses it. The divider keeps the pin at 3.3V or below, as it must be.

Is it a problem that A0 is a boot strapping pin?

Not with this circuit. GPIO2 must not be HIGH while you upload, and the 20 kΩ resistor to GND keeps it LOW. If uploads still fail, unplug the AO wire during the upload.

Can I use the AO reading together with WiFi on the ESP32 Uno?

Not on A0. A0 (GPIO2) and A1 (GPIO4) are ADC2 pins, and ADC2 cannot be read while WiFi is on. Move the AO wire to A2–A5 (GPIO35, 34, 36, 39) or GPIO32/33 and change AO_PIN in the code.

Can I use an Arduino Uno shield with an MQ3 on the ESP32 Uno?

The board has the Uno shape, so most shields fit. Check that the shield does not send 5V signals into the pins, because ESP32 Uno pins work at 3.3V.

How can I convert the AO reading into ppm or BAC?

You need the sensor's sensitivity curve from the datasheet, the load resistor value and a clean-air reference resistance. The math is possible, but cheap modules vary a lot, so the result is only a rough estimate. For learning, the three-level status is easier and more honest.

What if my project needs more pins than the Uno headers give?

The ESP32 Uno has a few extra holes near the power header: GPIO32 and GPIO33 (I/O, PWM, analog on ADC1, so they still read while WiFi is on) and GPIO15 (I/O, PWM, analog on ADC2). Add pin headers with a soldering iron, then put the plain GPIO number in your sketch. For a second MQ sensor's AO pin, or for a WiFi version of this project, GPIO32 or GPIO33 is the best pick. Two warnings: GPIO15 and GPIO0 (the IO0 pin at the unused Uno NC position) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code, so use GPIO32/33 first. Also, never use the six holes under the digital header (SD0–SD3, CMD, CLK = GPIO6–GPIO11). They are wired to the flash chip, and using them crashes the board.

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!