#include <Arduino.h>
#include <AiEsp32RotaryEncoder.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
// Definición de pines para el encoder rotativo y el botón
#define ROTARY_ENCODER_A_PIN 14
#define ROTARY_ENCODER_B_PIN 13
#define ROTARY_ENCODER_BUTTON_PIN 12
#define ROTARY_ENCODER_VCC_PIN -1
// Definición de pines para la pantalla OLED
#define SCL 22
#define SDA 21
#define SCREEN_WIDTH 128 // Ancho de la pantalla OLED en píxeles
#define SCREEN_HEIGHT 64 // Alto de la pantalla OLED en píxeles
#define OLED_RESET -1 // Pin de reset de la pantalla OLED (no se usa)
// Definición de pines para el sensor DHT22
#define DHT_PIN 15
#define DHT_TYPE DHT22
// Definición de pines para la comunicación serial
#define RX_PIN 16 // Pin para la recepción serial
#define TX_PIN 17 // Pin para la transmisión serial
// Definición de pin para el potenciómetro
#define POT_PIN 34 // Pin analógico donde está conectado el potenciómetro
// Variables para el menú
int selectedOption = 0;
const int numOptions = 4; // Actualizado al número total de opciones del menú
String menuOptions[] = {"Leer Datos DHT", "Leer Datos POT", "Enviar a Serial2", "Enviar POT a Serial2"};
// Inicialización del objeto de la pantalla OLED
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Inicialización del encoder rotativo
AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN,
ROTARY_ENCODER_B_PIN,
ROTARY_ENCODER_BUTTON_PIN,
ROTARY_ENCODER_VCC_PIN,
4);
// Inicialización del sensor DHT22
DHT dht(DHT_PIN, DHT_TYPE);
// Variables para el control del mensaje "Leyendo"
bool isReading = false;
// Lista para almacenar las mediciones de humedad y temperatura
#define NUM_READINGS 50
float humidityReadings[NUM_READINGS];
float temperatureReadings[NUM_READINGS];
int readingsIndex = 0;
// Lista para almacenar las mediciones del potenciómetro
int potReadings[NUM_READINGS];
// Variables para controlar el estado de las mediciones del sensor DHT y el potenciómetro
bool hasReadingsDHT = false;
bool hasReadingsPot = false;
void setup() {
// Inicialización de la comunicación serie
Serial.begin(9600);
Serial2.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN);
// Inicialización de la pantalla OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
// Mostrar "Bienvenido" centrado y con letra grande en la pantalla OLED una sola vez
display.clearDisplay();
display.setTextSize(2); // Tamaño de letra grande
display.setTextColor(WHITE);
// Calcular las coordenadas del cursor para centrar el texto en la pantalla
int16_t textWidth = 11 * strlen("Bienvenido"); // Aproximación del ancho del texto
int16_t x = (SCREEN_WIDTH - textWidth) / 2;
int16_t y = (SCREEN_HEIGHT - 16) / 2; // Altura de la fuente
Serial2.println("Y");
display.setCursor(x, y);
display.println("Bienvenido");
display.display();
Serial.println("Iniciando Sistema");
// Esperar unos segundos antes de continuar con la inicialización
delay(2000);
// Inicialización del encoder rotativo
rotaryEncoder.begin();
rotaryEncoder.setup([] { rotaryEncoder.readEncoder_ISR(); });
rotaryEncoder.setBoundaries(0, numOptions - 1, false);
// Inicialización del sensor DHT22
dht.begin();
Serial2.println("Z");
}
void loop() {
// Funciones principales del bucle
rotary_loop();
handle_rotary_button();
}
// Función para manejar el botón del encoder rotativo
void handle_rotary_button() {
static bool wasButtonDown = false;
bool isEncoderButtonDown = rotaryEncoder.isEncoderButtonDown();
if (isEncoderButtonDown && !wasButtonDown) {
wasButtonDown = true;
switch (selectedOption) {
case 0: // Leer Datos DHT
if (!isReading) {
isReading = true;
performDHTReadings();
isReading = false;
}
break;
case 1: // Leer Datos POT
if (!isReading) {
isReading = true;
performPotReadings();
isReading = false;
}
break;
case 2: // Enviar a Serial2
if (hasReadingsDHT) {
sendDHTReadingsToSerial2();
} else {
display.clearDisplay();
display.setCursor(0, 0);
display.println("Sin mediciones DHT");
display.display();
delay(2000); // Mostrar el mensaje por 2 segundos
}
break;
case 3: // Enviar POT a Serial2
if (hasReadingsPot) {
sendPotReadingsToSerial2();
} else {
display.clearDisplay();
display.setCursor(0, 0);
display.println("Sin mediciones POT");
display.display();
delay(2000); // Mostrar el mensaje por 2 segundos
}
break;
}
} else if (!isEncoderButtonDown && wasButtonDown) {
wasButtonDown = false;
}
}
// Función para enviar las mediciones del sensor DHT22 al puerto serial2
void sendDHTReadingsToSerial2() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("Enviando Mediciones DHT...");
display.display();
Serial2.println("F");
delay(100);
for (int i = 0; i < NUM_READINGS; ++i) {
Serial2.print("H: ");
Serial2.print(humidityReadings[i]);
Serial2.print(", T: ");
Serial2.println(temperatureReadings[i]);
delay(10); // Breve retardo para evitar saturar el puerto serial
}
Serial2.println("C");
delay(100);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("Mediciones DHT Enviadas...");
display.display();
delay(1500);
}
// Función para enviar las mediciones del potenciómetro al puerto serial2
void sendPotReadingsToSerial2() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("Enviando Mediciones POT...");
display.display();
Serial2.println("G");
delay(100);
for (int i = 0; i < NUM_READINGS; ++i) {
Serial2.print("P: ");
Serial2.println(potReadings[i]);
delay(10); // Breve retardo para evitar saturar el puerto serial
}
Serial2.println("K");
delay(100);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("Mediciones POT Enviadas...");
display.display();
delay(1500);
}
// Función para realizar 50 mediciones de DHT
void performDHTReadings() {
hasReadingsDHT = false; // Reiniciar el estado de las mediciones de DHT
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("Realizando mediciones DHT...");
display.display();
Serial.println("Realizando mediciones DHT...");
// Realizar 50 mediciones de DHT y almacenarlas en la lista
for (int i = 0; i < NUM_READINGS; ++i) {
humidityReadings[i] = dht.readHumidity();
temperatureReadings[i] = dht.readTemperature();
// Imprimir las mediciones en el puerto serial
Serial.print("Humedad: ");
Serial.print(humidityReadings[i]);
Serial.print("%\t");
Serial.print("Temperatura: ");
Serial.print(temperatureReadings[i]);
Serial.println("°C");
// Breve retardo entre cada medición
delay(100);
}
hasReadingsDHT = true; // Indicar que hay mediciones de DHT disponibles
// Mostrar mensaje de completado en la pantalla OLED
display.clearDisplay();
display.setCursor(0, 0);
display.println("Mediciones DHT completadas");
display.display();
}
// Función para realizar 50 mediciones del potenciómetro
void performPotReadings() {
hasReadingsPot = false; // Reiniciar el estado de las mediciones del potenciómetro
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("Realizando mediciones POT...");
display.display();
Serial.println("Realizando mediciones POT...");
// Realizar 50 mediciones del potenciómetro y almacenarlas en la lista
for (int i = 0; i < NUM_READINGS; ++i) {
potReadings[i] = analogRead(POT_PIN);
// Imprimir las mediciones en el puerto serial
Serial.print("Potenciometro: ");
Serial.println(potReadings[i]);
// Breve retardo entre cada medición
delay(100);
}
hasReadingsPot = true; // Indicar que hay mediciones del potenciómetro disponibles
// Mostrar mensaje de completado en la pantalla OLED
display.clearDisplay();
display.setCursor(0, 0);
display.println("Mediciones POT completadas");
display.display();
}
// Función para manejar el loop del encoder rotativo
void rotary_loop() {
int encoderDelta = rotaryEncoder.encoderChanged();
if (encoderDelta != 0) {
selectedOption = (selectedOption + encoderDelta + numOptions) % numOptions;
}
// Mostrar el título y el menú en la pantalla OLED
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
int16_t titleWidth = 11 * strlen("Opciones");
int16_t titleX = (SCREEN_WIDTH - titleWidth) / 2;
int16_t titleY = 5;
display.setCursor(titleX, titleY);
display.println("Opciones");
for (int i = 0; i < numOptions; ++i) {
if (i == selectedOption) {
display.setTextColor(BLACK, WHITE);
} else {
display.setTextColor(WHITE);
}
int16_t optionY = titleY + 20 + (i * 10);
display.setCursor(0, optionY);
display.println(menuOptions[i]);
}
display.display();
}