Sensor de nível de água com Arduino: calibração, alarme de transbordamento e bomba
Como usar um sensor de nível de água com Arduino: calibração vazio/metade/cheio, alimentação pelo pino contra corrosão, alarme de transbordamento com buzzer, controle de bomba, código para ESP32/Pico.
Um sensor de nível de água é o jeito mais barato e fácil de detectar com um Arduino a altura da água em um copo, um aquário, um pratinho de vaso ou um pequeno reservatório. À medida que as trilhas condutoras expostas da placa ficam embaixo d’água, a tensão na saída analógica sobe; o Arduino lê essa tensão com analogRead() e decide se a água está “vazio”, “metade” ou “cheio”. Ele se liga com três fios, funciona com poucas linhas de código e é o ponto de partida de muitos projetos, de alarmes de transbordamento a controle automático de bomba.
Neste guia você vai aprender o que há dentro do módulo, por que a leitura nunca chega a 1023, como fazer uma calibração vazio/metade/cheio e como evitar a corrosão que come o sensor em poucas semanas. Depois você vai montar um alarme de transbordamento com buzzer e um controle de bomba que enche um reservatório sozinho, comparar rapidamente o sensor com uma chave boia e com o XKC-Y25 sem contato e, por fim, ver como fazer o mesmo trabalho com o ESP32 e o Raspberry Pi Pico.

O que é um sensor de nível de água e como ele funciona?
A parte de baixo do módulo tem dez trilhas condutoras que não se tocam e se encaixam como os dentes de dois pentes. Cinco delas são trilhas de alimentação ligadas ao + da fonte; as outras cinco são trilhas de detecção que vão até a base do transistor NPN S8050 no topo da placa. Quando a placa está seca, só há ar entre as trilhas, o transistor fica cortado e o pino S fica perto de 0 V. Quando a placa entra na água, a água faz a ponte entre as trilhas de alimentação e as de detecção; uma pequena corrente entra na base do transistor, ele começa a conduzir e a tensão na saída S, tirada do emissor, sobe. Quanto mais alta a água, maior o comprimento molhado das trilhas, menor a resistência entre elas e maior a tensão de saída.
Esse jeito de funcionar tem três consequências importantes. Primeiro, o sensor na verdade não mede a água, e sim a condutividade da água: os minerais dissolvidos na água da torneira aumentam a leitura, enquanto a água pura (destilada) quase não dá nada. Segundo, como a saída vem de um transistor funcionando como seguidor de emissor, a tensão nunca chega à da alimentação; um sensor totalmente molhado alimentado com 5 V costuma ler em torno de 500–650 em um Arduino Uno e nunca chega perto de 1023. Terceiro, a relação não é linear: o valor sobe rápido nos primeiros milímetros e depois vai desacelerando cada vez mais. Por isso este sensor não é uma régua com precisão de milímetros, e sim um indicador prático que distingue com confiança alguns níveis.
| Característica | Valor |
|---|---|
| Tensão de operação | 3,3–5 V DC |
| Corrente de operação | Menos de 20 mA (máxima quando totalmente molhado) |
| Saída | Tensão analógica (pino S), sobe quando a água sobe |
| Área de detecção | Cerca de 40 × 16 mm, ou seja, no máximo uns 4 cm de altura de água |
| Tamanho da placa | Cerca de 62 × 20 mm |
| Temperatura de operação | 10–30 °C (valor do fabricante) |
| Pinos | S (sinal), + (VCC), − (GND) |
Ligação do sensor de nível de água: Arduino Uno, ESP32 e Pico
| Pino do sensor | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| S (sinal) | A0 | GPIO 34 (ADC1) | GP26 (ADC0) |
| + (VCC) | D7 (alimenta só durante a medição) | GPIO 25 | GP15 |
| − (GND) | GND | GND | GND |
O jeito mais fácil de evitar a corrosão é alimentar o sensor por um pino digital, como mostra a tabela: o código coloca o pino em HIGH logo antes da medição, espera 10 ms, lê o valor e coloca o pino em LOW de novo. Em um sistema que mede uma vez por segundo, as trilhas ficam energizadas só 1 por cento do tempo, o que desacelera o desgaste em cerca de cem vezes. Totalmente molhado, o módulo puxa no máximo uns 20 mA. O limite recomendado para um pino do Arduino Uno é 20 mA e o máximo absoluto é 40 mA, e o pino fica ligado só por alguns milissegundos, então essa ligação é segura; os pinos do ESP32 também fornecem essa corrente com folga. Já os pinos do Pico funcionam com uma configuração padrão de capacidade de corrente mais baixa, então, quando o sensor está totalmente molhado, a tensão do pino cai um pouco e as leituras ficam menores. Desde que você calibre com a mesma ligação, isso não é problema; se quiser valores mais estáveis, pode chavear o + do sensor com um pequeno transistor PNP como o BC557: o emissor vai no pino 3V3 da placa, o coletor no + do sensor e a base no pino GPIO por um resistor de 1 kΩ, e o sensor liga quando o pino está em LOW. Para escolher um transistor adequado, dê uma olhada na ferramenta de transistores.
Passo a passo: a sua primeira leitura com Arduino
- Ligue o pino S do sensor ao A0, o pino + ao D7 e o pino − ao GND. Segure a placa em pé, com as trilhas para baixo.
- Abra o código abaixo na Arduino IDE, selecione Arduino Uno como placa, escolha a porta certa e faça o upload.
- Abra o Monitor Serial e ajuste para 9600 baud. Confira se o valor fica perto de 0 com o sensor seco.
- Mergulhe o sensor devagar em um copo d’água: primeiro só a ponta, depois até a metade e depois até a linha onde as trilhas terminam. Em cada passo, espere alguns segundos e anote o valor.
1const int SENSOR_PIN = A0; // S → A0
2const int POWER_PIN = 7; // + → D7 (yalnızca ölçerken besle / power only while measuring)
3
4int readSensor() {
5 digitalWrite(POWER_PIN, HIGH); // sensörü aç / power the sensor
6 delay(10); // değerin oturmasını bekle / let the reading settle
7 long sum = 0;
8 for (int i = 0; i < 8; i++) { // 8 ölçümün ortalaması / average of 8 readings
9 sum += analogRead(SENSOR_PIN);
10 }
11 digitalWrite(POWER_PIN, LOW); // sensörü kapat / power off
12 return sum / 8;
13}
14
15void setup() {
16 pinMode(POWER_PIN, OUTPUT);
17 digitalWrite(POWER_PIN, LOW); // kapalı başla / start powered off
18 Serial.begin(9600);
19}
20
21void loop() {
22 int raw = readSensor();
23 Serial.print("Ham deger / Raw value: ");
24 Serial.println(raw);
25 delay(1000); // saniyede bir ölç / measure once a second
26}A função readSensor() mantém o sensor ligado só por cerca de 11 ms por medição. A espera de 10 ms deixa o transistor e a água entre as trilhas se estabilizarem em um valor estável; depois, a média de 8 leituras suaviza as pequenas oscilações de cada amostra. No Uno, cada analogRead() leva cerca de 0,1 ms, então 8 leituras levam menos de 1 ms. Quando você mexe a água ou balança o copo, os valores pulam no Monitor Serial; isso é normal, porque a superfície em movimento muda o tempo todo o comprimento molhado das trilhas.
Vazio, metade, cheio: como calibrar
Não use do jeito que estão os limites de códigos que você encontra na internet; cada sensor, cada tipo de água e cada tensão de alimentação dá valores diferentes. Calibre no recipiente em que o sensor vai ser usado de verdade e com a mesma água: água do aquário para um aquário, água com adubo para um reservatório de irrigação com adubo. Marque linhas em 0, 10, 20, 30 e 40 mm no sensor com uma caneta, mergulhe a placa até cada linha, espere 3–4 segundos para o valor se estabilizar e anote o número do Monitor Serial. A tabela abaixo mostra faixas típicas para água da torneira e alimentação de 5 V; anote os seus valores ao lado.
| Nível | Profundidade de imersão | Valor típico no Uno (5 V, água da torneira) |
|---|---|---|
| Vazio | 0 mm (seco) | 0–20 |
| Baixo | Cerca de 5–10 mm | 250–400 |
| Metade | Cerca de 20 mm | 400–480 |
| Cheio | Cerca de 40 mm (linha onde as trilhas terminam) | 480–650 |
O que chama atenção na tabela é como os valores sobem rápido no primeiro centímetro e depois se amontoam: pode haver uma diferença de várias centenas de unidades entre 0 e 10 mm, mas só algumas dezenas entre 20 e 40 mm. Por isso, em vez de traçar uma única reta com map(), a interpolação linear por partes, que usa uma razão separada entre cada par de pontos medidos, dá um resultado bem mais preciso. O código abaixo guarda em dois arrays os cinco pontos que você mediu, converte o valor bruto em milímetros e mostra o nome do nível. Você só precisa escrever as suas leituras no array RAW, em ordem crescente.
1const int SENSOR_PIN = A0;
2const int POWER_PIN = 7;
3
4// Kendi kalibrasyon ölçümlerin / your own calibration readings
5const int N = 5;
6const int RAW[N] = {0, 330, 440, 490, 520}; // ham değer, küçükten büyüğe / raw value, ascending
7const int MM[N] = {0, 10, 20, 30, 40}; // batma derinliği (mm) / immersion depth (mm)
8
9int readSensor() {
10 digitalWrite(POWER_PIN, HIGH);
11 delay(10);
12 long sum = 0;
13 for (int i = 0; i < 8; i++) sum += analogRead(SENSOR_PIN);
14 digitalWrite(POWER_PIN, LOW);
15 return sum / 8;
16}
17
18int rawToMm(int raw) {
19 if (raw <= RAW[0]) return MM[0];
20 for (int i = 1; i < N; i++) {
21 if (raw <= RAW[i]) { // iki nokta arasında oran kur / interpolate between two points
22 return map(raw, RAW[i - 1], RAW[i], MM[i - 1], MM[i]);
23 }
24 }
25 return MM[N - 1]; // en üst noktanın üstü / above the top point
26}
27
28const char* levelName(int mm) {
29 if (mm < 3) return "Bos / Empty";
30 if (mm < 15) return "Az / Low";
31 if (mm < 30) return "Yarim / Half";
32 return "Dolu / Full";
33}
34
35void setup() {
36 pinMode(POWER_PIN, OUTPUT);
37 digitalWrite(POWER_PIN, LOW);
38 Serial.begin(9600);
39}
40
41void loop() {
42 int raw = readSensor();
43 int mm = rawToMm(raw);
44 Serial.print(raw);
45 Serial.print(" -> ");
46 Serial.print(mm);
47 Serial.print(" mm, ");
48 Serial.println(levelName(mm));
49 delay(1000);
50}Alarme de transbordamento com buzzer
Um dos usos mais úteis de um sensor de nível de água é avisar de um transbordamento: colocado embaixo da máquina de lavar ou do aquecedor, em um pratinho de vaso, na bandeja de dreno do ar-condicionado ou na borda de um balde que está enchendo, o sensor dispara o alarme assim que a água toca a ponta dele. Até o nível “baixo” da tabela de calibração basta para isso. O código abaixo usa um buzzer ativo e o LED integrado do Uno; quando o valor passa de ALARM_ON, o buzzer apita a cada quarto de segundo e, quando o valor cai abaixo de ALARM_OFF, ele se cala. Como usa millis() em vez de delay() para a temporização, a medição e o buzzer não travam um ao outro. Para os tipos de buzzer, veja O que é um buzzer? e, para a ideia do millis(), veja millis() e delay().
1const int SENSOR_PIN = A0; // S → A0
2const int POWER_PIN = 7; // + → D7
3const int BUZZER_PIN = 8; // aktif buzzer + ucu / active buzzer +
4const int LED_PIN = 13; // Uno'nun dahili LED'i / Uno's built-in LED
5
6const int ALARM_ON = 200; // bu değer ve üstü taşma / at or above: overflow (kendin ölç / measure yours)
7const int ALARM_OFF = 100; // bunun altına inince alarm biter / alarm clears below this
8
9bool alarmActive = false;
10bool buzzerOn = false;
11unsigned long lastRead = 0;
12unsigned long lastBeep = 0;
13
14int readSensor() {
15 digitalWrite(POWER_PIN, HIGH);
16 delay(10);
17 long sum = 0;
18 for (int i = 0; i < 8; i++) sum += analogRead(SENSOR_PIN);
19 digitalWrite(POWER_PIN, LOW);
20 return sum / 8;
21}
22
23void setup() {
24 pinMode(POWER_PIN, OUTPUT);
25 pinMode(BUZZER_PIN, OUTPUT);
26 pinMode(LED_PIN, OUTPUT);
27 digitalWrite(POWER_PIN, LOW);
28 Serial.begin(9600);
29}
30
31void loop() {
32 unsigned long now = millis();
33
34 if (now - lastRead >= 1000) { // saniyede bir ölç / measure once a second
35 lastRead = now;
36 int level = readSensor();
37 if (!alarmActive && level >= ALARM_ON) alarmActive = true; // taşma başladı / overflow started
38 if (alarmActive && level < ALARM_OFF) alarmActive = false; // su çekildi / water receded
39 Serial.print("Seviye / Level: ");
40 Serial.println(level);
41 }
42
43 if (alarmActive) {
44 if (now - lastBeep >= 250) { // 250 ms öt, 250 ms sus / 250 ms on, 250 ms off
45 lastBeep = now;
46 buzzerOn = !buzzerOn;
47 digitalWrite(BUZZER_PIN, buzzerOn ? HIGH : LOW);
48 }
49 } else if (buzzerOn) {
50 buzzerOn = false;
51 digitalWrite(BUZZER_PIN, LOW);
52 }
53 digitalWrite(LED_PIN, alarmActive ? HIGH : LOW);
54}Controle de bomba: enchendo um reservatório sozinho
A segunda aplicação clássica é o reabastecimento automático que mantém o nível dentro de uma faixa. Você pode querer repor a água que evapora de um aquário a partir de um balde reserva, manter cheio o pote de água do seu pet ou abastecer o reservatório de uma estufa. A lógica é simples: quando o nível cai abaixo de START_BELOW, a bomba liga e, quando chega a STOP_ABOVE, ela para. A distância entre esses dois limites é a histerese que impede a bomba de ficar ligando e desligando sem parar. Lembre que o sensor tem uma área de detecção de só cerca de 4 cm; monte a placa em uma altura em que a faixa de água que você quer manter fique dentro desses 4 cm.

A bomba puxa muito mais corrente do que um pino do Arduino consegue fornecer, então acione-a com um módulo relé ou com um MOSFET de nível lógico e um diodo de roda livre, alimente a bomba com uma fonte separada e ligue juntos os GNDs das duas fontes. Para os detalhes, veja O que é um módulo relé?, como usar um MOSFET e a minibomba de água. A parte mais importante do código é uma medida de segurança: se a bomba funcionar durante todo o período MAX_RUN_MS e o nível ainda não tiver chegado ao alvo, o sistema bloqueia a bomba e avisa você com bipes curtos. A mangueira pode ter escapado, o balde reserva pode estar vazio ou o sensor pode ter saído do lugar; sem esse bloqueio, a bomba poderia funcionar a seco por horas ou alagar tudo.
1const int SENSOR_PIN = A0;
2const int POWER_PIN = 7;
3const int PUMP_PIN = 8; // röle IN / relay IN
4const int BUZZER_PIN = 9; // aktif buzzer / active buzzer
5const bool RELAY_ACTIVE_LOW = true; // çoğu röle modülü LOW ile çeker / most relay modules switch on LOW
6
7const int START_BELOW = 300; // bunun altında doldur / start filling below this (kendin ölç / measure yours)
8const int STOP_ABOVE = 480; // bu değerde dur / stop at this value
9const unsigned long MAX_RUN_MS = 30000; // en uzun çalışma 30 sn / max run time 30 s
10
11bool pumpOn = false;
12bool fault = false;
13unsigned long pumpStart = 0;
14
15int readSensor() {
16 digitalWrite(POWER_PIN, HIGH);
17 delay(10);
18 long sum = 0;
19 for (int i = 0; i < 8; i++) sum += analogRead(SENSOR_PIN);
20 digitalWrite(POWER_PIN, LOW);
21 return sum / 8;
22}
23
24void setPump(bool on) {
25 pumpOn = on;
26 bool pinHigh = RELAY_ACTIVE_LOW ? !on : on;
27 digitalWrite(PUMP_PIN, pinHigh ? HIGH : LOW);
28}
29
30void setup() {
31 setPump(false); // pin çıkış olmadan önce kapalı konuma al / set off before the pin becomes an output
32 pinMode(PUMP_PIN, OUTPUT);
33 pinMode(POWER_PIN, OUTPUT);
34 pinMode(BUZZER_PIN, OUTPUT);
35 digitalWrite(POWER_PIN, LOW);
36 Serial.begin(9600);
37}
38
39void loop() {
40 if (fault) { // arıza: pompa kilitli, kesik kesik öt / fault: pump locked out, beep
41 digitalWrite(BUZZER_PIN, HIGH);
42 delay(200);
43 digitalWrite(BUZZER_PIN, LOW);
44 delay(1800);
45 return; // yeniden başlatmak için reset / press reset to restart
46 }
47
48 int level = readSensor();
49
50 if (!pumpOn && level < START_BELOW) {
51 setPump(true); // seviye düştü, doldur / level low, start filling
52 pumpStart = millis();
53 } else if (pumpOn && level >= STOP_ABOVE) {
54 setPump(false); // istenen seviyeye ulaşıldı / target level reached
55 } else if (pumpOn && millis() - pumpStart > MAX_RUN_MS) {
56 setPump(false); // süre doldu, seviye yükselmedi / timed out, level did not rise
57 fault = true;
58 }
59
60 Serial.print("Seviye / Level: ");
61 Serial.print(level);
62 Serial.println(pumpOn ? " pompa / pump ON" : " pompa / pump OFF");
63 delay(500);
64}Sensor de nível de água vs. chave boia vs. XKC-Y25
| Característica | Sensor de nível de água (trilhas condutoras) | Chave boia | XKC-Y25 (sem contato) |
|---|---|---|---|
| Método de detecção | Condutividade da água | Ímã flutuante e contato reed | Variação de capacitância atrás da parede do recipiente |
| Saída | Analógica (alguns níveis) | Contato aberto ou fechado | Digital (há líquido ou não) |
| Faixa de medição | Cerca de 0–4 cm | Um ponto (altura de montagem) | Um ponto (altura de montagem) |
| Contato com a água | Sim, trilhas na água | Sim, corpo na água | Não, fica colado do lado de fora do recipiente |
| Corrosão | Sim; alimentar pelo pino é obrigatório | Praticamente nenhuma | Nenhuma |
| Alimentação | 3,3–5 V | Não precisa (contato passivo) | 5–24 V, cerca de 5 mA |
| Melhor para | Experimentos, alarmes de transbordamento, recipientes pequenos | Reservatórios permanentes, proteção de bomba | Reservatórios fechados de plástico ou vidro, líquidos corrosivos |
| Preço | O mais barato | Barato | Mais caro que os outros |
Uma chave boia é formada por uma haste com um contato reed dentro e uma boia com ímã que desliza ao longo dela. Quando a água sobe, a boia sobe, o ímã se alinha com o contato reed e o contato fecha ou abre. Montando a boia de cabeça para baixo na haste, você alterna entre o comportamento normalmente aberto (NA) e normalmente fechado (NF). Para ligar ao Arduino, ligue um fio em um pino digital e o outro no GND e configure o pino como INPUT_PULLUP; como não há desgaste por eletrólise, ela dura muito mais em instalações permanentes. Os contatos dos modelos pequenos costumam ser limitados a cerca de 0,5 A e 10 W, então acione a bomba por um relé, e não diretamente. Para entender como funciona um contato reed, veja o artigo Chave reed.

1const int FLOAT_PIN = 2; // bir kablo D2'ye, diğeri GND'ye / one wire to D2, the other to GND
2
3void setup() {
4 pinMode(FLOAT_PIN, INPUT_PULLUP); // dahili pull-up direnci / internal pull-up resistor
5 Serial.begin(9600);
6}
7
8void loop() {
9 // Kontak kapalıyken pin LOW okunur / the pin reads LOW when the contact is closed
10 if (digitalRead(FLOAT_PIN) == LOW) {
11 Serial.println("Kontak kapali / Contact closed");
12 } else {
13 Serial.println("Kontak acik / Contact open");
14 }
15 delay(500);
16}Já o XKC-Y25 é um sensor capacitivo que nunca toca na água: você o cola do lado de fora de um reservatório de plástico ou vidro e ele detecta se há líquido atrás da parede. Segundo o fabricante, funciona com 5–24 V, puxa cerca de 5 mA, detecta através de paredes não metálicas de até 13 mm de espessura e responde em cerca de 500 ms. O nível alto da saída é igual à tensão de alimentação, então, ao ligar um XKC-Y25 alimentado com 5 V a um ESP32 ou a um Pico, use um divisor de tensão (a ferramenta de divisor de tensão calcula os resistores certos). O ajuste de sensibilidade e os modelos com saídas diferentes estão explicados em detalhe no artigo sensor de nível sem contato XKC-Y25.

Acompanhando o nível da água pelo celular com o ESP32
Com o ESP32 você leva a medição para o celular pelo Wi-Fi. Ligue sempre o pino S do sensor a um pino do ADC1 (GPIO 32–39); os pinos do ADC2 não podem ser lidos com o Wi-Fi ligado. O ADC do ESP32 é de 12 bits, então os valores vão de 0 a 4095 e, como o sensor é alimentado com 3,3 V, os números não podem ser comparados com os do Uno; você vai precisar calibrar de novo. O ADC do ESP32 não é totalmente linear perto de 0 V e perto do topo da faixa, mas, como aqui importa a diferença entre os níveis e não a tensão absoluta, isso não é problema. O código abaixo faz uma leitura a cada dois segundos e serve uma pequena página web que se atualiza sozinha a cada cinco segundos, que você pode abrir no celular conectado à mesma rede.
1#include <WiFi.h>
2#include <WebServer.h>
3
4const char* WIFI_SSID = "WIFI_ADIN"; // ağ adın / your network name
5const char* WIFI_PASS = "WIFI_SIFREN"; // ağ şifren / your network password
6
7const int SENSOR_PIN = 34; // S → GPIO 34 (ADC1, Wi-Fi ile çalışır / works with Wi-Fi)
8const int POWER_PIN = 25; // + → GPIO 25
9const int HALF = 1500; // yarım eşiği / half threshold (kendin ölç / measure yours)
10const int FULL = 2000; // dolu eşiği / full threshold (kendin ölç / measure yours)
11
12WebServer server(80);
13int lastRaw = 0;
14unsigned long lastRead = 0;
15
16int readSensor() {
17 digitalWrite(POWER_PIN, HIGH);
18 delay(10);
19 long sum = 0;
20 for (int i = 0; i < 16; i++) sum += analogRead(SENSOR_PIN); // 0–4095
21 digitalWrite(POWER_PIN, LOW);
22 return sum / 16;
23}
24
25const char* levelName(int raw) {
26 if (raw < 100) return "Bos / Empty";
27 if (raw < HALF) return "Az / Low";
28 if (raw < FULL) return "Yarim / Half";
29 return "Dolu / Full";
30}
31
32void handleRoot() {
33 String html = "<!DOCTYPE html><html><head><meta charset='utf-8'>"
34 "<meta name='viewport' content='width=device-width'>"
35 "<meta http-equiv='refresh' content='5'></head><body>"
36 "<h1>Su seviyesi / Water level</h1><h2>";
37 html += levelName(lastRaw);
38 html += "</h2><p>Ham deger / Raw: ";
39 html += lastRaw;
40 html += "</p></body></html>";
41 server.send(200, "text/html", html);
42}
43
44void setup() {
45 Serial.begin(115200);
46 pinMode(POWER_PIN, OUTPUT);
47 digitalWrite(POWER_PIN, LOW);
48 WiFi.begin(WIFI_SSID, WIFI_PASS);
49 while (WiFi.status() != WL_CONNECTED) { // bağlanana kadar bekle / wait until connected
50 delay(500);
51 Serial.print(".");
52 }
53 Serial.println();
54 Serial.print("Adres / Address: http://");
55 Serial.println(WiFi.localIP());
56 server.on("/", handleRoot);
57 server.begin();
58}
59
60void loop() {
61 server.handleClient();
62 if (millis() - lastRead >= 2000) { // 2 sn'de bir ölç / measure every 2 s
63 lastRead = millis();
64 lastRaw = readSensor();
65 }
66}Antes do upload, troque WIFI_SSID e WIFI_PASS pelos dados da sua rede; o ESP32 só se conecta a redes de 2,4 GHz. Quando abrir o Monitor Serial a 115200 baud, basta digitar no navegador do celular o endereço que aparece. Se quiser receber uma notificação no celular quando o nível estiver “cheio”, você pode transformar a mesma leitura em mensagem com o método do artigo bot do Telegram com ESP32.
Alarme de transbordamento com Raspberry Pi Pico e MicroPython
No Raspberry Pi Pico, os pinos GP26, GP27 e GP28 são usados para leituras analógicas. A função read_u16() do MicroPython converte a medição de 12 bits do Pico para a faixa de 0–65535, então os seus limites vão ser números bem maiores que no Uno. O código abaixo alimenta o sensor pelo GP15, lê a saída S no GP26 e dá um aviso de transbordamento com três bipes curtos de um buzzer ativo no GP14. Como no primeiro sketch, defina os limites a partir das suas próprias medições.
1from machine import ADC, Pin
2import time
3
4sensor = ADC(26) # GP26 (ADC0) → S
5power = Pin(15, Pin.OUT, value=0) # GP15 → sensör + / sensor +
6buzzer = Pin(14, Pin.OUT, value=0) # GP14 → aktif buzzer / active buzzer
7
8ALARM_ON = 20000 # bu değer ve üstü taşma / at or above: overflow (kendin ölç / measure yours)
9ALARM_OFF = 10000 # bunun altında alarm biter / alarm clears below this
10
11def read_level(samples=8):
12 power.value(1)
13 time.sleep_ms(10) # değerin oturmasını bekle / let the reading settle
14 total = 0
15 for _ in range(samples):
16 total += sensor.read_u16() # 0–65535
17 power.value(0)
18 return total // samples
19
20alarm = False
21while True:
22 level = read_level()
23 if not alarm and level >= ALARM_ON:
24 alarm = True
25 elif alarm and level < ALARM_OFF:
26 alarm = False
27 print("Seviye / Level:", level, "ALARM" if alarm else "")
28 if alarm:
29 for _ in range(3): # üç kısa bip / three short beeps
30 buzzer.value(1)
31 time.sleep_ms(150)
32 buzzer.value(0)
33 time.sleep_ms(150)
34 else:
35 time.sleep(1)Ideias de projetos com sensor de nível de água
- Aviso de transbordamento do pratinho do vaso: um buzzer que toca quando a água se acumula no pratinho depois da rega; junte com um sensor de umidade do solo e você tem um sistema de irrigação completo.
- Reposição automática do aquário: um sistema de reabastecimento com limite de tempo que repõe a água evaporada a partir de um balde reserva com uma minibomba.
- Pote de água do pet: um lembrete que acende um LED ou manda uma notificação para o celular pelo ESP32 quando o pote fica baixo.
- Detector de vazamento de água: um alarme de vazamento com o sensor deitado no chão embaixo da máquina de lavar ou do aquecedor, ou no porão.
- Reservatório de estufa inteligente: uma proteção que vigia o nível do reservatório de irrigação e bloqueia a bomba quando ele seca; ela se encaixa fácil no projeto de estufa inteligente.
- Medidor de cisterna de chuva: um painel que mostra o nível como vazio, metade ou cheio em um display LCD I2C; você também pode acrescentar um sensor de chuva para registrar o momento em que a chuva começa.
Erros comuns e como corrigi-los
| Sintoma | Causa provável | Solução |
|---|---|---|
| O valor é sempre 0, mesmo na água | O pino + não está sendo alimentado (POWER_PIN nunca vai para HIGH) ou o S está no pino errado | Confira as linhas de pinMode e digitalWrite e se o S está ligado a um pino analógico |
| O valor pula aleatoriamente mesmo seco | O pino S está flutuando ou o GND não está ligado | Confira os três fios; o GND tem de ser comum |
| Nunca chega a 1023, mesmo totalmente submerso | Isso é normal; a saída vem de um seguidor de emissor | Defina os limites a partir do maior valor que você mesmo mediu |
| Nenhuma leitura em água pura | Água destilada ou purificada tem condutividade muito baixa | Use um XKC-Y25 ou uma chave boia com esse tipo de água |
| Os valores caem ou variam ao longo de algumas semanas | Eletrólise e depósitos nas trilhas | Alimente o sensor por um pino, limpe as trilhas com uma escova macia e troque o sensor se for preciso |
| A bomba ou o buzzer fica ligando e desligando no limite | É usado um único limite; a superfície em movimento faz o valor oscilar | Use dois limites separados para ligar e desligar (histerese) e tire a média das leituras |
| No ESP32, o valor não pode ser lido depois que o Wi-Fi conecta | O sensor está em um pino do ADC2 | Passe o S para um pino do ADC1, entre GPIO 32 e 39 |
O sensor de nível de água ensina leitura analógica, calibração, histerese e problemas do mundo real, como a corrosão, com um único módulo barato. Se você precisa medir centímetro por centímetro o nível de um reservatório grande, pode partir para uma solução ultrassônica como o sensor de distância HC-SR04. No app BlueGrays você encontra a estação de irrigação inteligente e projetos de alarme com buzzer, com esquemas de circuito e código passo a passo, e pode acrescentar facilmente o sensor de nível de água a eles.
Perguntas frequentes
Como funciona um sensor de nível de água?
Quando as trilhas condutoras intercaladas da placa entram na água, a água faz a ponte entre elas e uma corrente entra na base do transistor S8050 da placa. Quanto mais o transistor conduz, maior a tensão no pino S; o Arduino lê essa tensão com analogRead() para saber a altura da água.
Por que o meu sensor de nível de água sofre corrosão?
Quando uma corrente contínua passa o tempo todo pelas trilhas molhadas, começa a eletrólise e o revestimento das trilhas ligadas ao + se dissolve. Se você alimentar o sensor por um pino digital em vez do 5V e ligá-lo só por alguns milissegundos a cada leitura, o desgaste desacelera muito e o sensor dura meses.
O sensor de nível de água funciona em água destilada?
Na prática, não. Como o sensor mede a condutividade da água, água destilada ou purificada, sem minerais dissolvidos, dá leituras muito baixas. Para esse tipo de água, sensores que não dependem da condutividade, como o XKC-Y25 sem contato ou uma chave boia, são a melhor escolha.
Por que a leitura do sensor de nível de água não chega a 1023?
A saída S é tirada do emissor do transistor, então a tensão fica abaixo da alimentação, e a corrente de base é limitada pela resistência da água. Em um Arduino Uno com 5 V, um sensor totalmente molhado costuma ler em torno de 500–650, então defina os seus limites a partir desse máximo.
Um sensor de nível de água pode ficar totalmente submerso?
Não. Só a parte de baixo, com as trilhas condutoras, deve ir na água; se a parte de cima, com o transistor, o LED e os pinos, molhar, ela entra em curto e o sensor lê errado ou queima. Proteger a eletrônica com cola quente ou verniz faz ele durar mais.
Como medir o nível de um reservatório de água grande?
Este sensor só cobre uma faixa de cerca de 4 cm, então não serve para reservatórios grandes. Para medir o nível de forma contínua, usam-se sensores ultrassônicos à prova d’água, como o JSN-SR04T, montados na tampa do reservatório; para vigiar só alguns pontos críticos, colocam-se chaves boia em alturas diferentes.
Projetos para montar depois desta leitura
Ver todos os projetos
Uso do buzzer
Já se perguntou como uma campainha ou um alarme produz som? O Arduino faz um pequeno buzzer emitir bipes em intervalos curtos: bipe, pausa, bipe, pausa. Você vê como a eletricidade produz som e dá o p

Medição da intensidade da luz com LDR
Quer ver a luminosidade do seu quarto em números? O LDR, um pequeno componente sensível à luz, mede a luz ambiente, e o Arduino exibe o valor na tela do computador a cada meio segundo. Cubra o sensor

Leitura da intensidade da luz com módulo LDR e ESP32
Acompanhe em tempo real no Monitor Serial o valor bruto do ADC do módulo LDR e a porcentagem relativa de luz calculada a partir de referências de escuridão e claridade. Essa porcentagem não é uma medida em lux. O projeto ensina a lógica de calibração do módulo. É ideal fazê-lo antes do projeto 10, pois ajuda a determinar o valor do limiar.

Estação de irrigação inteligente
Um jardineiro que rega suas plantas sozinho para que elas não sequem enquanto você está de férias. Um sensor de umidade do solo mede o quanto a terra está úmida; quando ela seca, o Arduino aciona a bo

Leitura de uma chave reed
Você já teve curiosidade sobre a chave magnética dos alarmes de portas e janelas? Quando um ímã se aproxima do módulo de relé reed, a pequena chave interna fecha; o Arduino faz a leitura uma vez por s

Servidor web assíncrono com ESP32 (IP no LCD)
Neste projeto, transformamos o ESP32 em um servidor web assíncrono que você pode controlar pelo celular ou computador na mesma rede Wi-Fi. Com a biblioteca ESPAsyncWebServer, o servidor processa várias requisições ao mesmo tempo (ao contrário do WebServer.h tradicional, que bloqueia a execução ao processar uma requisição). Você poderá abrir o endereço IP do ESP32 no navegador e clicar nos botões ON/OFF (as rotas /on e /off) para ligar e desligar o LED conectado ao GPIO 5.

Alarme de movimento com ESP32 (PIR + buzzer + LED + Telegram)
Um sistema de alarme de segurança inteligente que aciona o buzzer e o LED quando o sensor PIR detecta movimento e, ao mesmo tempo, envia uma notificação instantânea ao proprietário pelo Telegram. Inclui um intervalo de espera de 30 segundos para limitar a frequência dos alarmes repetidos; esse mecanismo não valida as detecções do PIR nem elimina disparos falsos. Pode ser usado na segurança de casas, no monitoramento de garagens, depósitos ou salas de trabalho.
Mais artigos
App BlueGrays
Monte este circuito passo a passo pelo celular
Esquema do circuito, código e lista de componentes em uma só tela. Mais de 200 projetos com Arduino, ESP32 e Pico prontos para montar.
Escaneie com seu celular
Aponte a câmera para o código para abrir a loja de aplicativos do seu celular.
ou abrir a loja

