Disciplina: SEL0433 - Aplicação de Microprocessadores Plataforma: ESP32 DevKit Simulador: Wokwi
Integrantes:
- Felipe Bressanin Maitan - 13748652
- Eduardo Gondim Rezende - 15448693
- Matheus Herberts Rios de Lima - 15653174
- Objetivos
- Estrutura do repositório
- Parte 1 — LED RGB com PWM (LEDC)
- Parte 2 — Exercício 1: Servo com potenciômetro
- Parte 2 — Exercício 2: Servo com MCPWM, OLED e múltiplos modos
- Conceitos envolvidos
- Como simular no Wokwi
- Discussão dos resultados
- Reflexão final
O projeto explora dois pilares da programação de microcontroladores de 32 bits na ESP32: geração de sinais PWM (via periféricos LEDC e MCPWM) e comunicação serial/protocolos de interface (UART e I2C). Na Parte 1, um LED RGB tem sua cor variada continuamente por três canais PWM independentes. Na Parte 2, um servomotor é controlado primeiro de forma simples (potenciômetro + biblioteca ESP32Servo) e depois de forma mais completa, com múltiplos modos de operação, interface visual em display OLED e interação via botão e Serial.
.
└── Parte 1/
└── diagram.json
└── sketch.ino
└── wokwi-project.txt
└── Parte 2 Exercício 1/
└── diagram.json
└── libraries.txt
└── sketch.ino
└── wokwi-project.txt
└── Parte 2 Exercício 2/
└── diagram.json
└── sketch.ino
└── wokwi-project.txt
└── Ex1.png
└── Ex2pt1.png
└── Ex2pt2.png
└── README.md
Biblioteca principal: LEDC (nativa do core ESP32, acessada por ledcSetup/ledcAttachPin/ledcWrite.
Hardware: LED RGB catodo comum, 3x resistores de 220 Ω, conectado às GPIOs 25 (R), 26 (G) e 27 (B).
Configuração do PWM:
- Frequência: 5 kHz
- Resolução: 8 bits (0–255)
- 3 canais independentes (um por cor)
Incrementos independentes por cor:
| Cor | Incremento por ciclo |
|---|---|
| Verde | 5 |
| Azul | 10 (2x o verde) |
| Vermelho | 15 (3x o verde) |
Cada cor incrementa seu duty cycle de 0 a 255 e reinicia ao atingir o máximo, criando um ciclo contínuo de mistura de cores. A cada iteração, o duty cycle e o incremento de cada canal são reportados via Serial (115200 baud).
Print da simulação (Wokwi):
Biblioteca principal: ESP32Servo, conforme solicitado no enunciado.
Hardware: Potenciômetro no ADC1 (GPIO 34), servomotor na GPIO 18.
Funcionamento:
int leituraADC = analogRead(POT_PIN);
int angulo = map(leituraADC, 0, 4095, 0, 180);
servo.write(angulo);A leitura do ADC (0–4095, resolução de 12 bits) é mapeada linearmente para o intervalo de ângulo do servo (0–180°). A biblioteca ESP32Servo abstrai a geração do pulso PWM de 50 Hz (período de 20 ms) necessário para servomotores padrão, com pulso mínimo de 500 µs e máximo de 2400 µs, configurados em servo.attach(SERVO_PIN, 500, 2400).
Print da simulação (Wokwi):
Este exercício foi a aplicação própria do grupo, com ênfase na biblioteca nativa MCPWM da ESP32 (driver/mcpwm.h), além de recursos adicionais de hardware/software exigidos pelo enunciado: ADC, botão com interrupção externa, display OLED via I2C e comunicação serial bidirecional.
- Três modos de operação, alternados por botão (interrupção
FALLING) ou por comando serial:POT: ângulo do servo controlado diretamente pelo potenciômetro.AUTO: varredura automática de 0° a 180°, com velocidade da varredura também controlada pelo potenciômetro.SERIAL: ângulo definido digitando um valor (0–180) ou comandoS=90no Serial Monitor.
- Display OLED (I2C, SSD1306 128x64) mostrando modo atual, leitura do ADC, ângulo, largura de pulso em µs, duty cycle em % e uma barra de progresso visual.
- Cálculo explícito de PWM: período de 20 ms (50 Hz), pulso mínimo de 500 µs e máximo de 2500 µs, com duty cycle calculado a partir da largura de pulso:
pulseUs = map(angleDeg, 0, 180, SERVO_MIN_US, SERVO_MAX_US); dutyPercent = 100.0f * ((float)pulseUs / (float)SERVO_PERIOD_US);
- Interrupção externa no botão de troca de modo, com debounce por software (250 ms).
- Teste de inicialização automático: ao ligar, o servo varre 0° → 90° → 180° → 90°, confirmando que a resposta de PWM está correta antes de entrar em operação normal.
O código foi estruturado para permitir duas saídas de PWM, selecionáveis pela flag USE_MCPWM_DIRECT:
USE_MCPWM_DIRECT = 1: usa a API nativamcpwm_gpio_init/mcpwm_init/mcpwm_set_duty_in_us.USE_MCPWM_DIRECT = 0(padrão): gera o pulso de 50 Hz manualmente por GPIO.
Print da simulação (Wokwi):
- PWM (Pulse Width Modulation): técnica de controle analógico por meio da variação da largura do pulso dentro de um período fixo, expressa como duty cycle (%).
- LEDC: periférico da ESP32 dedicado à geração de PWM para controle de LEDs/atuadores simples, com canais e temporizadores configuráveis.
- MCPWM (Motor Control PWM): periférico mais avançado da ESP32, voltado a controle de motores, com suporte a geração de sinais complementares, detecção de falhas e captura, permitindo maior precisão de temporização.
- ADC (Analog-to-Digital Converter): conversão da tensão analógica do potenciômetro em valor digital de 12 bits (0–4095) para uso no cálculo do ângulo/duty cycle.
- Interrupção externa (GPIO Interrupt): captura assíncrona do acionamento do botão sem necessidade de polling constante, com debounce implementado em software.
- Comunicação serial UART: interface usada tanto para depuração (relatório de estado) quanto para controle interativo do sistema (troca de modo, definição de ângulo).
- I2C e display OLED (SSD1306): barramento de comunicação usado para exibir, em tempo real, o estado do sistema (modo, ADC, ângulo, duty cycle).
- Acesse wokwi.com e crie um novo projeto ESP32.
- Cole o código do exercício desejado (
.ino) no editor. - Monte o circuito correspondente:
- Parte 1: LED RGB catodo comum + 3 resistores de 220 Ω nas GPIOs 25, 26 e 27.
- Parte 2 (Ex. 1 e 2): potenciômetro na GPIO 34, servomotor na GPIO 18; no Exercício 2, adicionar botão na GPIO 25 (com pull-up interno) e display OLED SSD1306 (I2C) nas GPIOs 21 (SDA) e 22 (SCL).
- Nas bibliotecas do projeto (
diagram.json/ gerenciador de bibliotecas do Wokwi), adicione:ESP32Servo(Exercício 1 da Parte 2)Adafruit GFX LibraryeAdafruit SSD1306(Exercício 2 da Parte 2)
- Rode a simulação e abra o Serial Monitor a 115200 baud para acompanhar os logs.
- Capture prints/gravações da simulação em funcionamento e salve em
docs/.
Na Parte 1, o comportamento do LED RGB confirmou o funcionamento independente dos três canais PWM configurados via LEDC: cada cor incrementou seu duty cycle em taxas diferentes (verde +5, azul +10, vermelho +15 por ciclo), o que fez com que as cores se misturassem em padrões distintos a cada repetição do laço, já que os três canais reiniciam em momentos diferentes ao atingir 255. A frequência de 5 kHz manteve o LED sem cintilação perceptível, e as mensagens enviadas pela UART a 115200 baud permitiram conferir, em tempo real, que os valores de duty cycle reportados no Serial Monitor correspondiam à intensidade visual observada na simulação.
Na Parte 2 – Exercício 1, o servo respondeu de forma linear e estável à variação do potenciômetro: girar o potenciômetro de um extremo a outro moveu o servo suavemente de 0° a 180°, sem saltos bruscos, o que já era esperado dado o mapeamento direto entre a leitura de 12 bits do ADC e o intervalo de ângulo. O uso da biblioteca ESP32Servo simplificou bastante a geração do sinal PWM de 50 Hz, evitando a necessidade de calcular manualmente a largura de pulso nesse exercício introdutório.
Na Parte 2 – Exercício 2, os três modos de operação (POT, AUTO, SERIAL) funcionaram conforme esperado e a troca entre eles pelo botão respondeu de forma confiável após a implementação do debounce por software, sem leituras espúrias causadas pelo ruído mecânico do contato. O display OLED se mostrou útil para acompanhar o estado do sistema sem depender exclusivamente do Serial Monitor, especialmente para visualizar a largura de pulso (µs) e o duty cycle (%) calculados a cada atualização. A principal dificuldade encontrada foi que a saída MCPWM direta (mcpwm_set_duty_in_us) não animava o servo corretamente no Wokwi. A solução adotada foi gerar o pulso de 50 Hz manualmente via GPIO temporizado por micros(), mantendo intactos os cálculos de período, duty cycle e largura de pulso que seriam usados com o MCPWM real, o que preserva o objetivo pedagógico do exercício mesmo diante da limitação do simulador.
O desenvolvimento deste projeto evidenciou cenários em que o uso de um microcontrolador de 32 bits como a ESP32 se justifica claramente, e outros em que seria um exagero de engenharia. Para o controle de um único LED RGB por PWM (Parte 1), por exemplo, um microcontrolador de 8 bits, como um ATmega328P (Arduino Uno), já seria suficiente: a tarefa não exige alto poder de processamento, múltiplos periféricos simultâneos ou conectividade sem fio, e o consumo energético de um chip mais simples tende a ser menor, o que é relevante para aplicações embarcadas alimentadas por bateria.
Por outro lado, a segunda parte do projeto (especialmente o Exercício 2, com múltiplos modos de controle, display OLED via I2C, leitura de ADC, tratamento de interrupção externa e comunicação serial simultânea) já se beneficia da maior capacidade de processamento e da disponibilidade de periféricos integrados da ESP32. Rodar essas tarefas de forma responsiva e concorrente seria mais difícil em um microcontrolador de 8 bits, que teria menos memória RAM e menos periféricos de hardware dedicados.
Também é preciso considerar os recursos não utilizados neste projeto, mas disponíveis na ESP32, como Wi-Fi e Bluetooth: se o objetivo fosse apenas o controle local do servo e do LED, esses recursos representariam consumo energético desperdiçado. Isso reforça a necessidade de escolher os componentes de forma cuidadosa para garantir a maior eficiência possível do projeto.


