ESP32 S3 UNO - Rain Sensor
This ESP32 S3 Uno rain sensor tutorial shows you how to detect rain or snow and read how wet the sensing pad is. You will wire a rainfall sensor module to the ESP32 S3 Uno form board and write Arduino code for both of its outputs. The digital output tells you "rain" or "no rain", and the analog output gives you a number that changes with the amount of water.
In this tutorial, you will:
- Wire a rain sensor module to the ESP32 S3 Uno
- Power the sensor from a GPIO pin to slow down corrosion
- Detect rain or snow with the digital DO pin and digitalRead()
- Measure rain intensity with the analog AO pin and analogRead()

Once it works, you can change the code to start a motor, close a window, or sound an alarm when rain or snow falls.
Hardware Preparation
| 1 | × | ESP32 S3 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 | × | Rain Sensor | |
| 1 | × | Jumper Wires |
Or you can buy the following kits:
| 1 | × | DIYables Sensor Kit (18 sensors/displays) |
Additionally, some of these links are for products from our own brand, DIYables .
Overview of Rain Sensor
A rain sensor tells your project when water lands on it. It can sense both rain and melting snow, and it gives you two kinds of output: a digital signal (HIGH or LOW) and an analog signal that changes with the amount of water.
The module comes in two parts, which you connect with two wires:
- The sensing pad
- The electronic module

The sensing pad
The sensing pad is the part that goes outside, for example on a roof or a window sill, where rain or snow can reach it. It has many thin copper tracks. Half of them are power tracks and half are sense tracks. The two groups do not touch, so no current flows between them while the pad is dry.
When water or wet snow covers the pad, it bridges the tracks and current can flow. The more water there is, the better the connection. The two groups of tracks work the same way, so it does not matter which wire of the pad goes where.
The electronic module
The electronic module turns the signal from the pad into values that the ESP32 S3 Uno can read. It has four pins.
| Pin | Description |
|---|---|
| VCC | Power input, 3.3V to 5V |
| GND | Ground (0V) |
| DO | Digital output. HIGH when there is no rain, LOW when rain is detected. Set the threshold with the potentiometer |
| AO | Analog output. The value goes down when there is more water and goes up when there is less water |
The module also has two small LEDs. The PWR-LED shows that the module has power. The DO-LED follows the DO pin and turns on when rain is detected.
How It Works
The two outputs give you two different views of the same pad. Pick the one that fits your project, or use both.
The DO pin
A small potentiometer on the module sets the sensitivity. When the water level on the pad goes above this threshold, the DO pin goes LOW and the DO-LED turns on. When the level is below the threshold, the DO pin stays HIGH and the DO-LED stays off.
The AO pin
The AO pin gives a voltage that falls as more water covers the pad, and rises as the pad dries. The potentiometer has no effect on this pin, so the analog value always shows the raw water level.
ESP32 S3 Uno Pinout
The image below shows the pinout diagram of the ESP32 S3 Uno form board. Use it to find the Uno header pins (D3, D4, A0…) and their GPIO numbers when you wire the circuit.

Wiring Diagram
You could connect the sensor's VCC pin straight to the 3.3V pin. But when power is always on, the copper tracks on the pad wear out fast because of electrochemical corrosion. A better way is to power the sensor from a digital output pin and turn it on only for the short moment of each reading. This tutorial uses D3 (GPIO17) for that.
The module has two outputs. You can wire one of them or both, depending on what your project needs.

This image is created using Fritzing. Click to enlarge image
| Rain Sensor Pin | ESP32 S3 Uno Pin |
|---|---|
| VCC | D3 (GPIO17) |
| GND | GND |
| DO | D4 (GPIO19) |
| AO | A0 (GPIO2) |
※ NOTE THAT:
Because the sensor gets its power from D3 (GPIO17), it runs at 3.3V. Its DO and AO outputs therefore stay at 3.3V or less, which is safe for the ESP32 S3 Uno pins. Do not power the module from 5V, because the ESP32 S3 Uno pins are not 5V tolerant.
ESP32 S3 Uno Code - Read value from DO pin
This sketch turns on the sensor through D3 (GPIO17), waits 10 ms, and reads the DO pin on D4 (GPIO19). Then it turns the sensor off again and prints "The rain is detected" or "The rain is NOT detected" once per second.
Detailed Instructions
Follow these steps one by one:
- New to the ESP32 S3 Uno? Follow ESP32 S3 Uno - Getting Started first.
- Wire it up as shown in the diagram.
- Connect the board to your computer with a USB Type-C cable.
- Open Arduino IDE, choose the ESP32S3 Dev Module board and the correct COM port.
- Copy the code above and paste it into Arduino IDE.
- Upload the code by clicking the Upload button.
- Open the Serial Monitor and set it to 9600 baud.
- Drop a little water on the sensing pad, then wipe it dry.
- Check the result on the Serial Monitor:
- Tip: If the DO-LED stays on all the time, or never turns on even when the pad is wet, turn the potentiometer on the module slowly to change the sensitivity.
ESP32 S3 Uno Code - Read value from AO pin
This sketch powers the sensor for a short moment, reads the analog value on A0 (GPIO2), and prints it to the Serial Monitor every second. The ESP32 S3 Uno has a 12-bit ADC, so the value goes from 0 to 4095. A high number means a dry pad, and a low number means a wet pad.
In setup(), the code calls analogSetAttenuation(ADC_11db). By default, the ESP32 S3 Uno ADC can only measure a small voltage. With 11 dB attenuation, the analog pin reads the full range, from 0V up to about 3.3V. Without this line, the reading hits 4095 too early and you cannot see the difference between a dry pad and a slightly wet one.
Detailed Instructions
- Copy the code above and paste it into Arduino IDE.
- Upload the code by clicking the Upload button.
- Open the Serial Monitor and set it to 9600 baud.
- Put some water on the sensing pad, a few drops at a time.
- Check the result on the Serial Monitor. The value falls as you add water and rises again as the pad dries:
- Tip: Write down the value for a dry pad and for a wet pad. You can then pick your own threshold in code, for example "rain" when the value drops below 2500.
Video Tutorial
Watch the video below to see this ESP32 S3 Uno project step by step.
Function References
These are the main Arduino functions used in this tutorial. Click a name to read more about it.
FAQ
Can I power the rain sensor from the 5V pin of the ESP32 S3 Uno?
The module works at 5V, but then its DO and AO outputs can reach 5V. The ESP32 S3 Uno pins are not 5V tolerant, so this can damage the board. Power the sensor from 3.3V, or from a GPIO pin like D3 (GPIO17) as this tutorial does.
Why is the rain sensor powered from a GPIO pin instead of 3.3V?
When current flows through the wet copper tracks all the time, they corrode and the pad stops working after a while. By turning the sensor on only for 10 ms per reading, the code cuts this wear a lot. One small module draws only a few mA, which a GPIO pin can supply.
What range of values does the AO pin give on the ESP32 S3 Uno?
The ESP32 S3 Uno has a 12-bit ADC, so analogRead() returns 0 to 4095, not 0 to 1023 as on the UNO R4. A dry pad gives a value near the top of the range, and a very wet pad gives a low value. The exact numbers depend on your module and the water, so measure them yourself.
Why does the code call analogSetAttenuation(ADC_11db)?
It sets the ESP32 S3 Uno ADC input range to about 0 to 3.3V, so the full sensor signal maps to 0 to 4095. Without it the range is smaller and the readings reach 4095 too early. The UNO R4 does not need this line, because it is ESP32-only. Keep the sensor output at 3.3V or less.
Can the rain sensor tell rain from snow?
No. It only senses water on the pad. Snow is detected when it melts on the pad and bridges the copper tracks. Dry, cold snow may not be detected until it starts to melt.
What if my project needs more pins than the Uno headers give?
The ESP32 S3 Uno has two extra rows of holes with more GPIOs: GPIO15 and GPIO16 (I/O, PWM, analog), GPIO45 and GPIO35 to GPIO42 (I/O, PWM), and GPIO47/GPIO48 (output only, PWM). Solder pin headers to use them and write the GPIO number in code. For a second rain sensor, GPIO15 or GPIO16 fits the AO pin, and GPIO35 to GPIO42 fit the DO pin. Do not use GPIO47/GPIO48 for inputs. Be careful with two things. First, GPIO47/GPIO48 may run at 1.8V instead of 3.3V on some modules (especially ones with "V" in the name, like R8V or R16V), so 3.3V devices can be damaged or act strangely. Second, GPIO0, GPIO3 (D6), GPIO45 and GPIO46 (D9) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code. Use the other extra pins first.
Troubleshooting
| Problem | Possible Cause | Solution |
|---|---|---|
| No COM port appears in Arduino IDE | USB driver missing or board not in upload mode | Install the CP210x or CH340 driver, use a data USB cable, or hold BOOT while you press RESET |
| Serial Monitor shows nothing or strange characters | Wrong baud rate | Set the Serial Monitor to 9600 baud |
| Always "The rain is NOT detected" even when wet | VCC not on D3 or DO not on D4, or sensitivity too low | Check the wiring table and turn the potentiometer until the DO-LED turns on with water |
| Always "The rain is detected" even when dry | Pad still wet or sensitivity too high | Dry the pad fully and turn the potentiometer the other way |
| AO value stays at 4095 | Missing analogSetAttenuation line or AO wire loose | Keep analogSetAttenuation(ADC_11db) in setup() and check the wire on A0 (GPIO2) |
| AO value stays near 0 or changes randomly | Sensor not powered or GND not connected | Check that VCC goes to D3 (GPIO17) and GND goes to GND |
| Readings get weaker over weeks | Corrosion on the copper tracks | Keep the GPIO power method, clean the pad, or replace it |
| Board resets or gets damaged | Sensor powered from 5V | Power the module from 3.3V or a GPIO pin only |