Tutorial · Iniciante · 30 min
Por que seu robô reinicia quando os motores entram em operação
Entenda por que a queda de tensão reinicia um robô: calcule o orçamento de corrente, considere a resistência interna da bateria e meça a queda sob carga.
Introdução
O robô funciona na bancada. Você o coloca no chão, os motores giram e tudo para — o monitor serial reinicia do início, a sequência do LED começa novamente e o que o robô estava fazendo é esquecido.
O primeiro impulso de quase todo mundo é procurar o problema no código. Não há nada no código.
O que aconteceu é que a partida dos motores exigiu mais corrente do que a bateria conseguia fornecer, fazendo sua tensão cair; a tensão de alimentação ficou abaixo do necessário para o microcontrolador e a placa reiniciou. Isso é uma queda de tensão (brownout) e é a falha mais comum em um primeiro robô — este site afirma isso no caminho de controle dos motores, em quase todas as páginas de componentes e na lista de solução de problemas de metade dos projetos. Esta é a página que explica o assunto.
Primeiro, confirme se é uma reinicialização, não uma falha
Essas situações exigem correções diferentes, mas parecem idênticas de longe.
Coloque uma linha distinta no início de setup():
void setup() {
Serial.begin(115200);
Serial.println(F("---- BOOT ----"));
}
Agora execute o robô até ele se comportar mal e observe o monitor:
---- BOOT ----aparece novamente → a placa reiniciou. É um problema de alimentação. Continue lendo.- A saída para ou repete a mesma linha indefinidamente → a placa ficou presa em um laço ou falhou. Esse é um problema de código, e esta não é a página certa.
- A saída vira caracteres sem sentido → a tensão de alimentação está caindo, mas não o bastante para reiniciar. Também é um problema de alimentação, e as mesmas correções se aplicam.
Em placas AVR, você pode ir além e perguntar ao chip por que ele reiniciou. MCUSR armazena o motivo, mas main() é executado muito depois do momento em que ele precisa ser lido, portanto capture-o em uma função .init3 executada primeiro:
uint8_t resetFlags __attribute__((section(".noinit")));
void captureReset(void) __attribute__((naked, used, section(".init3")));
void captureReset(void) {
resetFlags = MCUSR;
MCUSR = 0;
}
void setup() {
Serial.begin(115200);
if (resetFlags & _BV(BORF)) Serial.println(F("cause: BROWN-OUT"));
if (resetFlags & _BV(EXTRF)) Serial.println(F("cause: reset pin"));
if (resetFlags & _BV(PORF)) Serial.println(F("cause: power-on"));
if (resetFlags & _BV(WDRF)) Serial.println(F("cause: watchdog"));
}
Uma ressalva honesta: um Uno com Optiboot tem o bootloader lendo MCUSR e limpando-o antes que seu código o veja, guardando o valor no registrador r2. Se todos os indicadores estiverem zerados na sua placa, esse é o motivo — use o teste ---- BOOT ----, que não depende de nada e nunca mente.
Por que a tensão desaba
Uma bateria não é uma fonte de tensão. É uma fonte de tensão em série com uma resistência, e essa resistência determina se o robô funciona:
V_terminal = V_open_circuit − I × R_internal
R_internal é uma propriedade da química e do tamanho da célula, e varia imensamente entre os conjuntos que estão na mesma gaveta.
| Conjunto | Circuito aberto | R_internal | Com surto de 2 A |
|---|---|---|---|
| 2×18650 Li-ion | 7,4 V | ≈ 0,10 Ω | 7,20 V |
| 4×AA NiMH | 4,8 V | ≈ 0,12 Ω | 4,56 V |
| 4×AA alcalina | 6,0 V | ≈ 0,80 Ω | 4,40 V |
| Bloco de 9 V PP3 | 9,0 V | ≈ 2,0 Ω | 5,00 V, e caindo |
Três conclusões importam mais do que os números:
O bloco de nove volts é a pior opção de bateria que você pode colocar em um robô. Ele tem a maior tensão impressa, cerca de 500 mAh de capacidade e dois ohms de resistência interna. É uma bateria para detector de fumaça.
Células alcalinas não sustentam a tensão sob carga. Sua resistência interna é cerca de seis vezes a de uma célula NiMH e aumenta conforme se descarga — então o robô funciona por vinte minutos e depois começa a reiniciar, o que parece uma falha intermitente, mas é apenas uma bateria descarregada se comportando exatamente como deveria.
Baterias recarregáveis vencem no que realmente importa. NiMH e Li-ion são as químicas padrão para robôs não por serem recarregáveis, mas porque mantêm a tensão sob carga.
Calcule o orçamento de corrente antes de escolher o conjunto
Some o consumo do robô duas vezes — uma vez para o funcionamento normal e outra para o pior instante.
| Componente | Em funcionamento | Pior caso |
|---|---|---|
| Placa Arduino Uno | 45 mA | 45 mA |
| Motorredutor TT ×2 | 400 mA | 2000 mA (ambos em travamento) |
| Matriz de sensores de refletância infravermelha | 100 mA | 100 mA |
| HC-SR04 | 15 mA | 15 mA |
| Servo SG90 | 150 mA | 700 mA (em travamento) |
| Bluetooth HC-05 | 30 mA | 40 mA |
| ESP32 (Wi-Fi) | 80 mA | 250 mA (rajada de transmissão) |
Um seguidor de linha básico — Uno, dois motores e uma matriz IR — consome cerca de 545 mA em funcionamento e 2,15 A no pior instante. O pior instante normalmente é breve; a exceção é um robô aplicando força no limite de tração, que permanece na corrente de travamento enquanto a força é aplicada. Use o primeiro número para dimensionar a capacidade da bateria e o segundo para verificar a queda de tensão, porque eles respondem a perguntas diferentes:
runtime ≈ capacity / running current 2000 mAh / 545 mA ≈ 3.7 h ideal
sag = worst-case current × R_internal
Espere uma autonomia real em torno de dois terços desse valor. Você não descarregará um conjunto até zero, os surtos custam mais do que sua média e as capacidades são medidas em baixas taxas de descarga.
A faixa que o detector de queda de tensão não detecta
Todo AVR tem um detector de queda de tensão que mantém o chip reiniciado abaixo de uma tensão definida. Em um Arduino Uno, esse fusível vem de fábrica em 2,7 V.
Um ATmega328P a 16 MHz não é especificado para funcionar a 2,7 V. A classe de velocidade de seu datasheet vai de 4 MHz a 1,8 V até 20 MHz a 4,5 V e, ao interpolar para 16 MHz, resulta em um mínimo de aproximadamente 3,8 V.
Isso explica o sintoma que as pessoas têm mais dificuldade para acreditar: um robô que não reinicia de forma limpa, mas simplesmente se comporta de maneira estranha quando os motores entram em operação. Variáveis corrompidas, um servo que dá um salto, um sensor I²C retornando dados sem sentido, uma máquina de estados em um estado para o qual não há transição. Nessa faixa, o chip executa instruções fora das condições de operação especificadas, e “garantido” é precisamente o termo que dá peso a essa afirmação.
Portanto, não considere “não reiniciou” como prova de que a alimentação está correta.
Um conjunto, dois trilhos
A solução não são duas baterias. É um conjunto alimentando dois caminhos.
- A corrente dos motores vai do conjunto diretamente para o terminal de alimentação do motor no driver — o
+12Vde um L298N ou oVMde um TB6612FNG. Ela nunca passa pelo microcontrolador. - A corrente lógica vem de uma saída regulada de 5 V — o regulador da placa do driver, um módulo buck separado ou USB durante o desenvolvimento.
- As massas devem ser conectadas juntas. Todo sinal entre a placa e o driver é uma tensão medida em relação à massa; sem uma referência compartilhada, os pinos de direção não têm efeito. Essa é a segunda falha de ligação mais comum depois da anterior.
Nunca opere motores pelo pino de 5 V de um Arduino nem pelo regulador do conector cilíndrico. O regulador do Uno é um pequeno componente linear que converte em calor a diferença entre entrada e saída: com entrada de 7,4 V, saída de 5 V e 500 mA, isso resulta em (7.4 − 5) × 0.5 = 1.2 W em um encapsulamento sem dissipador. Ele ficará quente, depois entrará em proteção térmica, e o robô reiniciará por um motivo que não tem relação com a bateria.
O que um capacitor realmente corrige
O conselho usual é colocar um capacitor eletrolítico de grande capacidade em paralelo com a alimentação dos motores. O conselho está certo, mas o motivo normalmente dado está errado, e a aritmética esclarece:
ΔV = I × Δt / C
Um capacitor de 1000 µF solicitado para conduzir um surto de partida de 2 A durante 10 ms sofreria uma queda de 2 × 0.010 / 0.001 = 20 V. Ele não pode fazer esse trabalho. Um capacitor não conduz o surto de partida do motor — somente uma bateria com menor resistência interna faz isso.
O que ele conduz são as variações rápidas. A uma frequência de comutação PWM de 8 kHz, o período é 125 µs, então o mesmo capacitor sofre 2 × 0.000125 / 0.001 = 0.25 V de ondulação — um trabalho que realiza com folga. Ele também absorve os picos de comutação que os motores com escovas devolvem à fonte.
Portanto, instale um capacitor eletrolítico de 470 a 1000 µF em paralelo com a alimentação dos motores, mais um cerâmico de 0,1 µF próximo ao driver, e espere que ele reduza o ruído e corrija o comportamento irregular dos sensores. Não espere que ele corrija uma reinicialização. Se um capacitor resolveu sua reinicialização, o conjunto estava no limite e você comprou uma margem muito pequena.
Meça em vez de adivinhar
Dez minutos com um multímetro são melhores do que uma tarde de especulação.
- Ajuste o medidor para volts CC e coloque-o nos terminais da bateria, não no Arduino.
- Anote a tensão de repouso.
- Inicie os motores, de preferência sob carga real, com o robô no chão.
- Observe o valor.
Uma queda de mais de alguns décimos de volt já é sua resposta. Para obter R_internal a partir dela, faça a divisão: um conjunto de 6,0 V que cai para 4,4 V enquanto consome cerca de 2 A resulta em (6.0 − 4.4) / 2 = 0.8 Ω.
Depois, repita a medição no trilho de 5 V durante a partida dos motores. Esse é o valor que o microcontrolador realmente enfrenta e, se ele cair na direção de 3,8 V, você encontrou a falha sem precisar de um osciloscópio.
Multímetros baratos fazem médias com lentidão demais para capturar o ponto mais baixo de uma queda de um milissegundo, portanto considere a leitura otimista. A queda real é pelo menos tão grande quanto isso.
Correções, das mais baratas às mais caras
- Pare de alimentar motores pela placa. É gratuito e resolve diretamente uma grande parte dos casos.
- Troque o conjunto. Alcalinas ou 9 V → NiMH ou 18650. Normalmente, é toda a solução.
- Conecte as massas. É gratuito, e sua ausência causa falhas mais estranhas do que uma queda de tensão.
- Adicione o capacitor eletrolítico de grande capacidade. Para ruído e falhas transitórias dos sensores, não para reinicializações.
- Aumente a velocidade dos motores gradualmente em vez de dar um comando brusco. Um perfil de movimento espalha a corrente de partida ao longo do tempo, em vez de exigir toda ela em um único instante — é o mesmo código que impede as rodas de patinar.
- Dimensione os motores corretamente. Se um motor receber um comando de torque acima do necessário, consumirá mais corrente do que deveria; o cálculo de dimensionamento de motorredutor vem antes de todo esse problema.
- Separe o regulador. Um pequeno conversor buck para o trilho lógico desacopla esse trilho por completo da queda causada pelos motores.
Depois de organizar o trilho, medi-lo em software é o próximo passo — e medir uma tensão de forma confiável é mais difícil do que parece, porque a referência padrão do ADC é o próprio trilho.
Quando algo dá errado
| Sintoma | Causa usual |
|---|---|
| A saída serial reinicia do topo quando os motores entram em operação | Queda de tensão; verifique o conjunto antes do código |
| Funciona com USB, mas falha com bateria | O conjunto não fornece o surto; o USB fornece |
| Funciona por vinte minutos e depois reinicia repetidamente | A resistência interna das alcalinas aumenta durante a descarga |
| Comportamento estranho, sem reinicialização limpa | A alimentação está na faixa de 2,7–3,8 V; fora da especificação, mas acima do limiar de queda de tensão |
| Os sensores retornam dados sem sentido apenas durante a movimentação | Ruído na alimentação; use capacitor eletrolítico de grande capacidade e trilhos separados |
| Os pinos de direção parecem não fazer nada | Não há massa comum entre a placa e o driver |
| Regulador quente demais para tocar | A lógica é alimentada por um regulador linear com tensão de entrada alta demais |
| Um capacitor resolveu, mas o problema voltou | O conjunto estava no limite; o capacitor comprou milissegundos, não ampères |
A alimentação é a camada sob todas as outras camadas de um robô, e por isso uma falha aqui imita uma falha em qualquer outro lugar. Quando algo inexplicável começa a acontecer no instante em que os motores entram em operação, meça a bateria primeiro — isso leva dez minutos e fica certo mais vezes do que qualquer outra suposição.
Explore o grafo
Faz parte destas montagens
Projetos e caminhos de aprendizagem que incluem este tutorial.
- ProjetoConstrua um plotter de caneta cartesiano de dois eixos
- ProjetoConstrua um robô de cobertura que percorre todo o ambiente
- ProjetoConstrua um robô de coleta e colocação que sabe quando falhou
- ProjetoConstrua um robô Mecanum que se desloca lateralmente
- ProjetoConstrua um robô mini sumo: preensão, cunha e detecção de borda
- ProjetoConstrua um rover GPS de pontos de passagem que dirige sozinho
- Caminho de aprendizagemAcionamento holonômico: mover-se de lado sem girar
- Caminho de aprendizagemFundamentos de eletrônica de robôs: roteiro de aprendizagem
- Caminho de aprendizagemMovimento preciso com motores de passo: roteiro de aprendizagem
Leitura complementar