#include <Arduino.h>
#include <driver/ledc.h>
#include <math.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
const int adc = 36; // Pino ADC para leitura de sinal analógico
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
#define PWM_RESOLUTION LEDC_TIMER_10_BIT // Resolução de 10 bits (0-1023)
#define PWM_PIN_1 25
#define PWM_PIN_2 26
#define PWM_PIN_3 27
#define POT_PIN 32 // Pino do potenciômetro
// Definição dos canais PWM como ledc_channel_t
ledc_channel_t PWM_CHANNEL_1 = LEDC_CHANNEL_0;
ledc_channel_t PWM_CHANNEL_2 = LEDC_CHANNEL_1;
ledc_channel_t PWM_CHANNEL_3 = LEDC_CHANNEL_2;
// Variáveis para controle da barra de progresso
int barWidth = 0; // Largura atual da barra
int lastBarWidth = -1; // Última largura da barra desenhada
// Inicialização do LCD I2C (endereço 0x27, 20 colunas, 4 linhas)
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Protótipo da função para exibir o texto "IFSP"
void displayIFSP();
void setup() {
Serial.begin(115200);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Endereço 0x3C para 128x64
Serial.println(F("Falha na alocação SSD1306"));
for (;;);
}
delay(2000);
display.clearDisplay();
// Exibe "IFSP" por 5 segundos ao iniciar
displayIFSP();
// Inicializa o LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Freq1: 0 Hz");
lcd.setCursor(0, 1);
lcd.print("Freq2: 0 Hz");
lcd.setCursor(0, 2);
lcd.print("Freq3: 0 Hz");
lcd.setCursor(0, 3);
lcd.print("Pot: 0");
// Configura o timer PWM para os três canais
ledc_timer_config_t ledc_timer;
ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE;
ledc_timer.timer_num = LEDC_TIMER_0;
ledc_timer.duty_resolution = PWM_RESOLUTION;
ledc_timer.freq_hz = 5000; // Frequência inicial
ledc_timer.clk_cfg = LEDC_AUTO_CLK;
ledc_timer_config(&ledc_timer);
// Configura os canais PWM
ledc_channel_config_t ledc_channel;
ledc_channel.speed_mode = LEDC_HIGH_SPEED_MODE;
ledc_channel.timer_sel = LEDC_TIMER_0;
ledc_channel.duty = 512; // 50% de duty cycle (resolução de 10 bits)
ledc_channel.hpoint = 0;
// Canal 1
ledc_channel.channel = PWM_CHANNEL_1;
ledc_channel.gpio_num = PWM_PIN_1;
ledc_channel_config(&ledc_channel);
// Canal 2
ledc_channel.channel = PWM_CHANNEL_2;
ledc_channel.gpio_num = PWM_PIN_2;
ledc_channel_config(&ledc_channel);
// Canal 3
ledc_channel.channel = PWM_CHANNEL_3;
ledc_channel.gpio_num = PWM_PIN_3;
ledc_channel_config(&ledc_channel);
// Ajuste inicial dos sinais PWM defasados em 120 graus
setPWMPhase(PWM_CHANNEL_1, 0); // fpr yhe first motor
setPWMPhase(PWM_CHANNEL_2, 120); // for tye second Motor
setPWMPhase(PWM_CHANNEL_3, 240); // For yhe last motor
}
void loop() {
// Leitura do valor do ADC
int adcValue = analogRead(adc);
// Converte o valor do ADC para um valor percentual de 0 a 100
int percent = map(adcValue, 0, 4095, 0, 100);
// Atualiza a largura da barra de progresso de forma suave
updateBarWidth(percent);
// Atualiza o texto no display SSD1306
updateDisplay(percent);
// Leitura do valor do potenciômetro
int potValue = analogRead(POT_PIN);
// Converte o valor do potenciômetro para a frequência desejada
float frequency = map(potValue, 0, 4095, 0, 5000);
setPWMSpeed(frequency);
// Atualiza o LCD com as novas frequências e valor do potenciômetro
lcd.setCursor(0, 0);
lcd.print("Freq1: ");
lcd.print(frequency);
lcd.print(" Hz ");
lcd.setCursor(0, 1);
lcd.print("Freq2: ");
lcd.print(frequency);
lcd.print(" Hz ");
lcd.setCursor(0, 2);
lcd.print("Freq3: ");
lcd.print(frequency);
lcd.print(" Hz ");
lcd.setCursor(0, 3);
lcd.print("Pot: ");
lcd.print(potValue);
lcd.print(" ");
delay(100); // Aguarda um pouco antes de alterar a velocidade novamente
}
void setPWMSpeed(float frequency) {
if (frequency > 0) {
// Define a frequência para cada canal PWM
ledc_set_freq(LEDC_HIGH_SPEED_MODE, LEDC_TIMER_0, frequency);
} else {
// Para o PWM se a frequência for 0
ledc_set_freq(LEDC_HIGH_SPEED_MODE, LEDC_TIMER_0, 1);
}
}
void setPWMPhase(ledc_channel_t channel, float phase) {
// Calcula o duty cycle com base na fase desejada
uint32_t duty = 512 + 512 * sin(phase * PI / 180);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, channel, duty);
ledc_update_duty(LEDC_HIGH_SPEED_MODE, channel);
}
void updateBarWidth(int percent) {
// Calcula a nova largura da barra proporcionalmente ao percentual
int newBarWidth = map(percent, 0, 100, 0, SCREEN_WIDTH);
// Atualiza a barra apenas se houver uma mudança significativa na largura
if (newBarWidth != lastBarWidth) {
lastBarWidth = newBarWidth;
// Limpa a área onde a barra será desenhada
display.fillRect(0, 0, SCREEN_WIDTH, 10, BLACK);
// Desenha a barra de progresso horizontal no display SSD1306
display.fillRect(0, 0, newBarWidth, 10, WHITE);
display.display(); // Mostra a barra de progresso
}
}
void updateDisplay(int percent) {
// Atualiza o texto no display SSD1306
display.clearDisplay();
display.setTextSize(2); // Tamanho grande para o texto
display.setTextColor(WHITE); // Cor do texto
// Centraliza o texto verticalmente
int textHeight = 16; // Altura do texto
int centerY = (SCREEN_HEIGHT - textHeight) / 2; // Posição central vertical
// Imprime o valor percentual
display.setCursor(0, centerY);
display.print(percent);
display.print("%"); // Símbolo de percentagem
// Texto "Fator de aceleracao" abaixo do valor percentual
display.setTextSize(1); // Tamanho normal para o texto
display.setCursor(0, centerY + textHeight + 4); // Posição do texto abaixo do percentual
display.println("Fator de");
display.println("aceleracao");
display.display(); // Mostra tudo na tela
}
void displayIFSP() {
// Exibe o texto "IFSP" de forma grande no display
display.clearDisplay();
display.setTextSize(3); // Tamanho grande para o texto
display.setTextColor(WHITE); // Cor do texto
// Centraliza o texto horizontal e verticalmente
int textWidth = 3 * 6 * 4; // Largura aproximada do texto "IFSP" em pixels
int textHeight = 3 * 8; // Altura aproximada do texto "IFSP" em pixels
int centerX = (SCREEN_WIDTH - textWidth) / 2; // Centraliza horizontalmente
int centerY = (SCREEN_HEIGHT - textHeight) / 2; // Centraliza verticalmente
// Exibe o texto "IFSP"
display.setCursor(centerX, centerY);
display.println("IFSP");
display.display(); // Mostra o texto no display
delay(5000); // Mantém o texto visível por 5 segundos
display.clearDisplay(); // Limpa o display após 5 segundos
}