#include <Arduino.h>
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
// Timer 2 para PWM por hardware (válido en NUCLEO-C031C6)
HardwareTimer timer2(TIM2);
// Pantalla OLED por I2C
SSD1306AsciiWire oled;
// Parámetros iniciales
int freq = 1000; // Frecuencia en Hz
int duty = 0; // Duty cycle en %
void flushSerialIn() {
while (Serial.available()) Serial.read();
}
void updatePWM() {
timer2.setPWM(1, D10, freq, 0); // Canal 1, pin D10, frecuencia, duty=0%
delay(2); // Espera para que se actualice
uint32_t arr = timer2.getOverflow();
uint32_t pulse = (arr * duty) / 100;
timer2.setCaptureCompare(1, pulse);
}
void updateDisplay() {
oled.clear();
oled.setCursor(0, 0);
oled.print("Freq: ");
oled.print(freq);
oled.println(" Hz");
oled.print("Duty: ");
oled.print(duty);
oled.println(" %");
// Barra gráfica proporcional al duty
int barWidth = map(duty, 0, 100, 0, 128);
for (int i = 0; i < barWidth; i++) {
oled.setCursor(i, 5);
oled.write(0xFF); // Bloque lleno
}
}
void setup() {
Serial.begin(115200);
delay(300);
// Configura I2C para usar D14 (PB9) como SDA y D15 (PB8) como SCL
Wire.setSDA(PB9); // D14
Wire.setSCL(PB8); // D15
Wire.begin();
oled.begin(&Adafruit128x64, 0x3C); // Dirección I2C del SSD1306
oled.setFont(System5x7);
oled.clear();
Serial.println("\n=== CONTROL PWM NUCLEO-C031C6 ===");
Serial.println("Salida PWM: D10 (TIM2_CH1)");
Serial.println("Frecuencia: 1000 Hz");
Serial.println("Ciclo inicial: 0% (DESACTIVADO)");
Serial.println("\nIngrese el ciclo de trabajo (0 - 100)% y presione ENTER.\n");
updatePWM(); // Inicia PWM en 0%
updateDisplay(); // Muestra estado inicial
}
void loop() {
if (!Serial.available()) return;
duty = Serial.parseInt(); // Leer número ingresado
flushSerialIn(); // Limpiar buffer
duty = constrain(duty, 0, 100);
updatePWM(); // Aplicar nuevo PWM
updateDisplay(); // Actualizar OLED
Serial.print("Ciclo de trabajo actualizado a: ");
Serial.print(duty);
Serial.println("% \n");
}