#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
#include <MPU6050.h>
#include <RTClib.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Pines en el ESP32
const int buttonPin = 17; // Pin del botón
const int sensorPin = 34; // Pin del sensor analógico
const int dhtPin = 4; // Pin del DHT22
#define DHTTYPE DHT22 // Tipo de sensor DHT
DHT dht(dhtPin, DHTTYPE); // Inicialización del sensor DHT
MPU6050 mpu;
RTC_DS1307 rtc;
int buttonState = 0; // Estado del botón
int lastButtonState = 0; // Último estado del botón
int counter = 0; // Contador
// Sensibilidad del MPU6050
const float accelSensitivity = 16384.0; // Para ±2g (32768/2)
const float gyroSensitivity = 131.0; // Para ±250°/s (32768/250)
// Variables for GUI
int gear = 4; // Example gear value
float speed = 228; // Example speed value in KPH
int distance = 52210; // Example odometer value in KM
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
dht.begin(); // Inicialización del sensor DHT
Wire.begin();
mpu.initialize();
if (!mpu.testConnection()) {
Serial.println("MPU6050 connection failed");
while (1);
}
if (!rtc.begin()) {
Serial.println("No se pudo encontrar el RTC");
while (1);
}
if (!rtc.isrunning()) {
Serial.println("El RTC no está funcionando, ajustando la hora.");
// Ajustar la fecha y hora: (Año, Mes, Día, Hora, Minuto, Segundo)
rtc.adjust(DateTime(2024, 8, 11, 13, 44, 30));
// O ajusta a la fecha y hora de compilación:
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
buttonState = digitalRead(buttonPin);
lastButtonState = buttonState;
}
void time(int x, int y) {
display.setCursor(x, y);
DateTime now = rtc.now();
display.print(now.year(), DEC);
display.print('/');
display.print(now.month(), DEC);
display.print('/');
display.print(now.day(), DEC);
display.print(" ");
display.print(now.hour(), DEC);
display.print(':');
display.print(now.minute(), DEC);
display.print(':');
display.print(now.second(), DEC);
delay(1000);
}
void displayACELEROMETRO(int x, int y) {
int16_t ax, ay, az;
int16_t gx, gy, gz;
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
float ax_g = ax / accelSensitivity;
float ay_g = -ay / accelSensitivity;
float az_g = az / accelSensitivity;
float gx_dps = gx / gyroSensitivity;
float gy_dps = gy / gyroSensitivity;
float gz_dps = gz / gyroSensitivity;
float sqrt_g = sqrt(pow(ax_g, 2) + pow(ay_g, 2)); // Módulo de la aceleración
display.setCursor(x, y);
display.print(sqrt_g);
display.print(" G");
display.drawCircle(x + 14, y - 18, 12, WHITE);
display.fillCircle(4 * ax_g + x + 14, 4 * ay_g + y - 18, 3, SSD1306_WHITE);
}
void displayDHT22Data(int x, int y) {
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
if (isnan(temperature) || isnan(humidity)) {
display.setCursor(x, y);
display.println("Error reading DHT22!");
} else {
display.setCursor(x, y);
//display.print("Temp: ");
display.print(temperature);
display.println(" C");
display.setCursor(x, y + 8);
//display.print("Humidity: ");
display.print(humidity);
display.println(" %");
}
}
void drawArc(int x0, int y0, int r, int start_angle, int end_angle, uint16_t color) {
// Recorrer cada ángulo desde start_angle hasta end_angle
for (int16_t angle = start_angle; angle <= end_angle; angle++) {
int16_t x = r * cos(radians(angle)) + x0;
int16_t y = r * sin(radians(angle)) + y0;
display.drawPixel(x, y, color);
}
}
void drawSpeedometer(float speed, int gear, int distance) {
float sensorValue = analogRead(sensorPin);
// Centros de las circurferencias
int Cy = 32;
int Cx = 64;
// Radio circunferencia
int Rc = 25;
// Coordenadas de las marcas del velocimetro
int In = Rc -5; //Inicio
int Fn = Rc; //Final
// valores de inicio y final del arco
int In_A = 145; //Inicio
int Fn_A = 145 + (sensorValue/16.31); //Final
// Dibujar círculo principal
display.drawCircle(Cx, Cy, Rc, SSD1306_WHITE);
display.drawCircle(Cx, Cy, Rc +1, SSD1306_WHITE);
// Dibijar un arco
drawArc(Cx, Cy, Rc +6, In_A, Fn_A, SSD1306_WHITE);
drawArc(Cx, Cy, Rc +7, In_A, Fn_A, SSD1306_WHITE);
// Dibujar marcas del velocímetro
for (int i = 5; i < 15; i++) {
float angle = i * 28.5; // 360° dividido en 10 partes (30° cada una)
int x1 = Cx + In * cos(radians(angle));//segundo numero es el largo
int y1 = Cy + In * sin(radians(angle));
int x2 = Cx + Fn * cos(radians(angle));
int y2 = Cy + Fn * sin(radians(angle));
display.drawLine(x1, y1, x2, y2, SSD1306_WHITE);
}
// Dibujar la aguja
/*
float needleAngle = map(speed, 0, 240, 0, 360); // Mapear la velocidad al ángulo de la aguja
int needleX = 64 + 20 * cos(radians(needleAngle));
int needleY = 32 + 20 * sin(radians(needleAngle));
display.drawLine(64, 32, needleX, needleY, SSD1306_WHITE);
*/
// Dibujar la velocidad
display.setTextSize(2);
display.setCursor(Cx -17, Cy -7);
display.print((int)speed);
// Dibujar la marcha (gear)
display.setTextSize(1);
display.setCursor(Cx -3, Cy -18);
display.print(gear);
// Dibujar el odómetro
display.setCursor(86, 57);
display.print(distance);
display.print("KM");
//displayACELEROMETRO(100, 30);
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH && lastButtonState == LOW) {
// El botón ha sido pulsado
counter++;
if (counter > 3) {
counter = 0; // Reseteamos a 0 si supera el 3
}
delay(300); // Anti-rebote
}
lastButtonState = buttonState;
display.clearDisplay();
display.setCursor(0, 0);
float sensorValue = analogRead(sensorPin);
switch (counter) {
case 0:
drawSpeedometer(speed, gear, distance);
/*
display.setCursor(0, 0);
display.print(sensorValue / 292.4);
display.print("V");
display.setCursor(0, 8);
display.print(sensorValue / 292.4);
display.print("V");
displayACELEROMETRO(100, 56); // Parte inferior derecha
displayDHT22Data(0, 46); // Parte inferior izquierda
*/
break;
case 1:
display.print("Sensor Value 1: ");
display.print(sensorValue / 341.2);
display.print("V");
time(0,10);
break;
case 2:
displayDHT22Data(0, 0);
break;
case 3:
displayACELEROMETRO(64, 32);
break;
}
display.display();
delay(100);
}