O que é
Open drain (dreno aberto) é um tipo de saída digital em que o pino só consegue puxar o sinal para o GND. Ele nunca empurra o sinal para o VCC. Em microcontroladores, é um modo alternativo ao push-pull.
Push-pull vs open-drain
| Estado | Push-pull (OUTPUT) | Open-drain (OUTPUT_OPEN_DRAIN) |
|---|---|---|
| LOW | Liga o pino ao GND | Liga o pino ao GND |
| HIGH | Liga o pino ao VCC (ex.: 3,3 V) | Solta o pino (alta impedância, sem tensão própria) |
No push-pull o pino tem dois transistores, um para o VCC e um para o GND. No open-drain só existe o transistor para o GND.
Analogia: o push-pull puxa a porta para fechar e empurra para abrir. O open-drain só sabe puxar a porta para baixo, e para abrir ele só solta.
Por que usar
- Conversão de nível: o pino nunca aplica 3,3 V no circuito externo. O nível “alto” é definido pelo resistor de pull-up ou pelo VCC do outro lado, que pode ser 5 V.
- Barramento compartilhado: vários dispositivos ligados na mesma linha não brigam entre si, porque ninguém força nível alto. É por isso que o I2C usa open-drain com pull-up.
- Módulos ativos em LOW com optoacoplador: ver o exemplo abaixo.
Exemplo: módulo de relé ativo em LOW alimentado com 5 V
Em muitos módulos de relé, o LED do optoacoplador fica entre o VCC (5 V) e o pino IN:
5V (VCC) ──► resistor ──► LED do optoacoplador ──► IN
- IN em ~0 V: passa corrente pelo LED, e o relé aciona.
- IN em ~5 V: não passa corrente, e o relé desliga.
Um ESP32 entrega só 3,3 V no HIGH. Sobram cerca de 1,7 V sobre o LED, e isso pode ser suficiente para passar uma corrente pequena. O relé então fica ligado ou instável, e o HIGH não desliga de verdade.
Com open-drain, o HIGH solta o pino. O IN fica só com o 5 V do módulo, sem diferença de tensão no LED, e o relé desliga por completo.
Uso no Arduino (ESP32)
const int RELAY_PIN = 5;
void setup() {
pinMode(RELAY_PIN, OUTPUT_OPEN_DRAIN);
digitalWrite(RELAY_PIN, HIGH); // desligado (pino solto)
}
void loop() {
digitalWrite(RELAY_PIN, LOW); // puxa para o GND, aciona
delay(3000);
digitalWrite(RELAY_PIN, HIGH); // solta, desliga
delay(3000);
}- Antes de configurar o pino como saída, defina o nível com
digitalWrite(..., HIGH). Assim o relé não aciona por um instante na inicialização. - Para sinais lentos (relé, LED), o pull-up interno ou o do módulo é suficiente. Em barramentos rápidos, o valor do pull-up importa.
Alternativas se o open-drain não bastar
- Transistor NPN (2N2222, BC548) com resistor de ~1 kΩ na base.
- Level shifter 3,3 V → 5 V.
- Resistor de pull-up de ~10 kΩ entre o IN e o VCC (5 V), caso o módulo ligue sozinho com o IN solto.