Sistema de controle automático de um braço em L invertido utilizando Arduino, sensor MPU6050 (acelerômetro + giroscópio) e motor brushless controlado por ESC.
Este projeto implementa diferentes estratégias de controle para manter um braço em uma posição angular desejada:
| Script | Estratégia | Uso |
|---|---|---|
| start_braço.ino | PID com AUTOSTART | ⭐ PRINCIPAL - Uso autônomo |
| controle_autonomo.ino | Perturba & Observa (P&O) | Alternativo - Otimização |
| angulo_braco.ino | Leitura de sensor | Debug/Calibração |
Bateria conectada
↓
Arduino liga e calibra
↓
Motor incrementa throttle gradualmente
↓
Detecta movimento do braço (3° confirmado)
↓
Salva automaticamente o throttleBase
↓
Passa para Fase 2
Com throttleBase já descoberto
↓
Aplica algoritmo PID
↓
Mantém braço no setpoint (ex: 0° = horizontal)
↓
Rejeita perturbações
↓
Sistema estável!
| Componente | Modelo | Função |
|---|---|---|
| Arduino | Uno/Nano | Controlador |
| Sensor | MPU6050 | Acelerômetro + Giroscópio |
| ESC | 30A+ brushless | Controla motor |
| Motor | Brushless 1000-4000KV | Fornece torque |
| Bateria | 3S LiPo (11.1V) | Alimentação |
| Braço Mecânico | ~20cm, 50-300g | Carga |
Arduino ↔ MPU6050 (I2C)
A4 (SDA) → SDA
A5 (SCL) → SCL
GND → GND
5V → VCC
Arduino ↔ ESC
D9 (PWM) → Signal
GND → GND
Bateria → ESC
+ → +
- → -
Script: start_braço.ino
Passos:
- Upload do código para Arduino
- Conecte bateria ao circuito
- Sistema inicia automaticamente:
- Calibra sensor
- Faz partida automática
- Descobre throttleBase
- Estabiliza no setpoint
Saída esperada:
- Braço sai do repouso sozinho
- Vai para posição desejada (padrão 0° = horizontal)
- Fica estável e rejeita perturbações
Script: angulo_braco.ino
Passos:
- Upload do código
- Abra Serial Monitor (115200 baud)
- Mexa o braço e veja o ângulo em tempo real
Output:
Iniciando MPU6050...
Calibrando giroscópio (não mexa!)...
Calibração pronta!
---
Lendo ângulo do braço (em graus)
---
Ângulo: -5.50°
Ângulo: -5.48°
Ângulo: 0.00°
Ângulo: 3.20°
Script: controle_autonomo.ino
Implementa algoritmo de otimização P&O com máquina de estados:
- ARM → Armamento do ESC
- AUTOSTART → Partida com impulsos automáticos
- CAPTURE_PO → Aproximação ao setpoint com P&O agressivo
- HOLD_PO → Manutenção com P&O suave + deadband
Setpoint (ângulo desejado):
float setpointDeg = 0.0; // 0° = horizontal
// float setpointDeg = 45.0; // 45° inclinado
// float setpointDeg = -10.0; // -10° para baixoGanhos PID (afeta resposta do sistema):
float Kp = 18.0; // Proporcional (força proporcional ao erro)
float Ki = 0.8; // Integral (elimina erro residual)
float Kd = 1.2; // Derivativo (amortecimento)AUTOSTART:
const int AUTOSTART_STEP_US = 2; // Incremento por ciclo
const int AUTOSTART_INTERVAL_MS = 20; // Frequência
const float AUTOSTART_DETECTION_DEG = 3.0; // Movimento mínimo detectado
const unsigned long AUTOSTART_TIMEOUT_MS = 10000; // Timeout 10s✅ OBRIGATÓRIO:
- Proteção mecânica (limite de curso)
- Hélice protegida em caixa
- Área de testes livre
- Óculos de proteção
- Supervisor presente
❌ NUNCA:
- Teste sem proteções
- Deixe bateria conectada sem supervisão
- Remova limitadores mecânicos
- Comece com throttle alto
BATERIA CONECTADA
↓
[SETUP]
├─ Liga sensor MPU6050
├─ Calibra giroscópio (1000 amostras)
├─ Arma ESC
└─ Begin AUTOSTART
↓
[AUTOSTART - Fase 1]
├─ Incrementa throttle 2µs a cada 20ms
├─ Aguarda movimento do braço
├─ Detecta quando se move (3° confirmado)
├─ Salva throttleBase automaticamente
└─ Passa para PID
↓
[PID CONTROL - Fase 2]
├─ Lê ângulo sensor (a cada 5ms)
├─ Calcula erro = setpoint - ângulo
├─ Aplica PID: u = Kp*e + Ki*∫e + Kd*de/dt
├─ Envia PWM ao motor
├─ Rampa suave (1µs por vez)
└─ Mantém braço no setpoint
↓
[REPETIR] → Loop infinito 200 Hz
| Métrica | Valores |
|---|---|
| Tempo de acomodação | 3-5s |
| Overshoot | <10° |
| Erro estacionário | <0.5° |
| Rejeição de perturbação | <500ms |
| Frequência de controle | 200 Hz (5ms) |
| Taxa de bateria 3S LiPo | ~30-60 min |
Causa: Throttle base descoberto mas muito baixo, ou peso muito alto
Solução:
- Ajuste
AUTOSTART_STEP_USpara 3 ou 4 (mais agressivo) - Ou
AUTOSTART_DETECTION_DEGpara 2.0 (menos rigoroso)
Causa: Ganhos PID muito altos
Solução:
float Kp = 12.0; // Diminua de 18.0
float Kd = 2.0; // Aumente de 1.2Causa: AUTOSTART lento demais
Solução:
const int AUTOSTART_STEP_US = 4; // Era 2
const int AUTOSTART_INTERVAL_MS = 10; // Era 20Causa: Braço muito pesado ou motor fraco
Solução:
- Reduza peso do braço
- Use motor mais potente
- Aumente timeout:
const unsigned long AUTOSTART_TIMEOUT_MS = 15000;
I2C → MPU6050 → 14 bytes
├─ Acelerômetro (6 bytes): ax, ay, az
├─ Temperatura (2 bytes) - ignorado
└─ Giroscópio (6 bytes): gx, gy, gz
1. Acelerômetro → atan2(ax, √(ay²+az²)) → anguloAcel
2. Giroscópio → (gy - offset) / 131 LSB → velocidadAngular
3. Filtro Complementar:
angleDeg = 0.98 * (angleDeg + gyroRate*dt)
+ 0.02 * accelAngle
erro = setpoint - angleDeg
Proporcional: Kp * erro
Integral: Ki * ∫erro·dt (com anti-windup)
Derivativo: Kd * d(erro)/dt
Comando final: u = Kp*e + Ki*∫e + Kd*de/dt
Throttle: base + u
"Sistema autônomo de controle de atitude usando PID. Ao ligar, faz AUTOSTART automático: aumenta gradualmente o motor até detectar movimento, salva o ponto de equilíbrio, e depois usa controle PID para manter o braço no ângulo desejado com rejeição de perturbações."
- AUTOSTART: Descobrir throttleBase automaticamente
- PID: Manter braço no setpoint
- Filtro Complementar: Mesclar acelerômetro + giroscópio
- Segurança: Timeout, limites, rampa suave
| Versão | Script | Estratégia | Status |
|---|---|---|---|
| 1.0 | start_braço.ino | PID + AUTOSTART | ✅ Funcional |
| 1.0 | controle_autonomo.ino | Perturba & Observa | ✅ Funcional |
| 1.0 | angulo_braco.ino | Leitura sensor | ✅ Debug |
- Adicionar segundo eixo (2 DOF)
- Controle via rádio remoto
- Datalogger para análise
- Otimização automática de ganhos PID
- Interface gráfica em Processing