#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int amplitude = 30;
int targetAmplitude = amplitude;
int incrementAmplitude = 5;
float frequency = 0.1;
float targetFrequency = frequency;
float incrementFrequency = 0.01;
int buttonPinIncreaseAmp = 2;
int buttonPinDecreaseAmp = 15; // Pin D3 para disminuir la amplitud
int buttonPinIncreaseFreq = 14; // Pin D4 para aumentar la frecuencia
int buttonPinDecreaseFreq = 4; // Pin D5 para disminuir la frecuencia
int buttonPinSelectSine = 27; // Pin D27 para seleccionar la señal senoidal
int buttonPinSelectSquare = 26; // Pin D26 para seleccionar la señal cuadrada
int buttonPinSelectTriangular = 12; // Pin D12 para seleccionar la señal triangular
int x0 = 1;
int y0_value = 32;
int x1 = 10;
int y1_value = 20;
bool isSine = true;
bool isSquare = false;
bool isTriangular = false;
void IRAM_ATTR increaseAmplitude()
{
targetAmplitude = min(amplitude + incrementAmplitude, 100);
}
void IRAM_ATTR decreaseAmplitude()
{
targetAmplitude = max(amplitude - incrementAmplitude, 0);
}
void IRAM_ATTR increaseFrequency()
{
if (frequency + incrementFrequency <= 5.0)
{
targetFrequency = frequency + incrementFrequency;
}
}
void IRAM_ATTR decreaseFrequency()
{
if (frequency - incrementFrequency >= 0.01)
{
targetFrequency = frequency - incrementFrequency;
}
}
void drawLine(int x0, int y0, int x1, int y1)
{
display.drawLine(x0, y0, x1, y1, SSD1306_WHITE);
}
void drawSignalSine()
{
for (int i = 0; i < SCREEN_WIDTH; i++)
{
int y = round(amplitude * sin(frequency * i) + SCREEN_HEIGHT / 2);
display.drawPixel(i, y, SSD1306_WHITE);
}
}
void drawSignalSquare()
{
for (int i = 0; i < SCREEN_WIDTH; i++)
{
int y;
if (sin(frequency * i) > 0)
{
y = amplitude + SCREEN_HEIGHT / 2;
}
else
{
y = -amplitude + SCREEN_HEIGHT / 2;
}
display.drawPixel(i, y, SSD1306_WHITE);
}
}
void drawSignalTriangular()
{
int x2 = x1 * 2;
int y2_value = y0_value;
int x3 = x1 * 3;
int y3_value = (32 - y1_value) + 32;
int x4 = x1 * 4;
int y4_value = y0_value;
display.clearDisplay();
drawLine(x0, y0_value, x1, y1_value);
drawLine(x1, y1_value, x2, y2_value);
drawLine(x2, y2_value, x3, y3_value);
drawLine(x3, y3_value, x4, y4_value);
int xc = 4;
int i = 0;
for (i = 4; i < 35; i++) {
drawLine(x1 * xc, y4_value, x1 * (xc + 1), y1_value);
drawLine(x1 * (xc + 1), y1_value, x1 * (xc + 2), y0_value);
drawLine(x1 * (xc + 2), y0_value, x1 * (xc + 3), y3_value);
drawLine(x1 * (xc + 3), y3_value, x1 * (xc + 4), y0_value);
xc = xc + 4;
}
}
void setup()
{
Serial.begin(115200);
pinMode(buttonPinIncreaseAmp, INPUT_PULLUP);
pinMode(buttonPinDecreaseAmp, INPUT_PULLUP);
pinMode(buttonPinIncreaseFreq, INPUT_PULLUP);
pinMode(buttonPinDecreaseFreq, INPUT_PULLUP);
pinMode(buttonPinSelectSine, INPUT_PULLUP);
pinMode(buttonPinSelectSquare, INPUT_PULLUP);
pinMode(buttonPinSelectTriangular, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(buttonPinIncreaseAmp), increaseAmplitude, FALLING);
attachInterrupt(digitalPinToInterrupt(buttonPinDecreaseAmp), decreaseAmplitude, FALLING);
attachInterrupt(digitalPinToInterrupt(buttonPinIncreaseFreq), increaseFrequency, FALLING);
attachInterrupt(digitalPinToInterrupt(buttonPinDecreaseFreq), decreaseFrequency, FALLING);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
{
Serial.println(F("Error al inicializar la pantalla SSD1306"));
for (;;)
;
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
}
void loop()
{
display.clearDisplay();
if (amplitude < targetAmplitude)
{
amplitude++;
y1_value++;
}
else if (amplitude > targetAmplitude)
{
amplitude--;
y1_value--;
}
if (frequency < targetFrequency)
{
frequency += 0.01;
x1--;
}
else if (frequency > targetFrequency)
{
frequency -= 0.01;
x1++;
}
bool selectSine = digitalRead(buttonPinSelectSine) == LOW;
bool selectSquare = digitalRead(buttonPinSelectSquare) == LOW;
bool selectTriangular = digitalRead(buttonPinSelectTriangular) == LOW;
if (selectSine)
{
isSine = true;
isSquare = false;
isTriangular = false;
}
if (selectSquare)
{
isSine = false;
isSquare = true;
isTriangular = false;
}
if (selectTriangular)
{
isSine = false;
isSquare = false;
isTriangular = true;
}
if (isSine)
{
drawSignalSine();
}
else if (isSquare)
{
drawSignalSquare();
}
else if (isTriangular)
{
drawSignalTriangular();
}
display.display();
delay(10); // Pequeña pausa para suavizar el cambio
}