#include <ESP32Servo.h> // biblioteca específica para o controle de servos no ESP32
#include <Wire.h> // Biblioteca para comunicação I2C
#include <Adafruit_GFX.h> // Biblioteca para gráficos
#include <Adafruit_SSD1306.h> // Biblioteca para controle do display OLED
// Definicao do pino dos botoes
#define bot1_pin 16
#define bot2_pin 17
#define bot3_pin 5
// Definicao pino leitura adc
#define ADC_pin 32
// Parametros do display oled
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
// variavel display oled
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Servo servoMotor; // É criado um objeto da classe Servo chamado servoMotor, o qual será usado para controlar o servo motor.
float angle = 0; // angulo atual do servo
int increment = 15; // Incremento para o movimento do servo
int tempo = 0; // Tempo de delay do modo 1
int mode = 0; // Modo selecionado por cada botao
int analog = 0; // Variavel para salvar leitura analogica
bool intervalo = false; // Variavel para direcionar o servo motor no modo 1
// Funcao de interrupcao botao 1
void IRAM_ATTR bot1_function(){
angle = 0; // Reinicia angulo
intervalo = false; // Reinicia intervalo
mode = 1; // Seleciona modo
}
// Funcao de interrupcao botao 2
void IRAM_ATTR bot2_function(){
mode = 2; // Seleciona modo
}
// Funcao de interrupcao botao 3
void IRAM_ATTR bot3_function(){
if(mode == 1){
mode = 0; // Seleciona modo
}
}
// Funcao para caso modo 1 ativo
void func_mode1(){
// Coloca angulo no servo
servoMotor.write(angle);
// Atualiza o ângulo do servo
if(intervalo){
tempo = 200; // Tempo de volta de 200 ms
angle -= increment; // Decrementa para voltar no sentido anti-horario
// Caso angulo chegue a 0 graus, o servo motor volta no sentido horario e espera um segundo
if(angle == 0){
delay(tempo);
servoMotor.write(angle);
intervalo = false;
delay(1000-tempo);
}
}
else{
tempo = 100; // Tempo de volta de 100 ms
angle += increment; // Decrementa para voltar no sentido horario
// Caso angulo chegue a 180 graus, o servo motor volta no sentido horario e espera um segundo
if(angle >= 180){
delay(tempo);
servoMotor.write(angle);
intervalo = true;
delay(1000-tempo);
}
}
// Aguarda um delay antes de atualizar o ângulo
delay(tempo);
}
// Funcao para caso modo 2 ativo
void func_mode2(){
analog = analogRead(ADC_pin); // Leitura analogica no pino 32
angle = (analog/4095.0)*180; // Converte leitura analogica em angulo (leitura da esp32 vai de 0 a 4095)
servoMotor.write(angle); // Atualiza angulo servo motor
Serial.print("\t");
Serial.print("Leitura ADC: ");
Serial.print(analog); // Printa valor leitura analogica
}
void setup() {
Serial.begin(115200);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Inicia display
display.clearDisplay(); // Limpa display
display.display();
servoMotor.setPeriodHertz(50); // Define a frequência do servo para 50Hz
servoMotor.attach(4, 500, 2500); // Conecta o servo ao pino 4 com pulsos de 500us a 2500us
//o servo espera receber um sinal PWM com uma frequência de 50Hz.
pinMode(bot1_pin,INPUT_PULLUP); // Seleciona entrada botao 1
attachInterrupt(bot1_pin, bot1_function, FALLING); // Ativa interrupcao botao 1
pinMode(bot2_pin,INPUT_PULLUP); // Seleciona entrada botao 2
attachInterrupt(bot2_pin, bot2_function, FALLING); // Ativa interrupcao botao 2
pinMode(bot3_pin,INPUT_PULLUP); // Seleciona entrada botao 3
attachInterrupt(bot3_pin, bot3_function, FALLING); // Ativa interrupcao botao 3
}
// controlar o servo em loop
void loop () {
// o ângulo do servo é definido usando servoMotor.write(angle),
//o que move o servo para a posição correspondente ao ângulo atual.
// Printa modo
Serial.print("Modo: ");
Serial.print(mode);
// Caso modo 1 esta ativo
if(mode == 1){
func_mode1();
}
else if(mode == 2){ // Caso modo 2 ativo
func_mode2();
}
Serial.print("\t");
Serial.print("Angulo: ");
Serial.println(angle); // Printa angulo do servo motor
display.clearDisplay(); // Limpa o display
display.setTextSize(1); // Define o tamanho do texto como 1 (pequeno)
display.setTextColor(SSD1306_WHITE); // Define a cor do texto como branco
display.setCursor(0, 0); // Define a posição do cursor para (0, 0)
display.print("Sentido: "); // Imprime uma mensagem e muda o cursor de linha (println)
if(mode == 1){ // Condicao para printar sentido no servo caso estiver no modo 1
if(intervalo)
display.println("Anti-horario");
else display.println("Horario");
}
else {
display.println("Modo incompativel");
}
display.print("Angulo: "); // Imprime uma mensagem e irá imprimir a próxima da mesma linha(print)
display.println(angle); // Imprime o valor de uma variável
display.display();
}