#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const int pinServo = 9;
const int pinBotonSi = 4;
const int pinBotonNo = 5;
const int pinLEDVerde = 6;
const int pinLEDRojo = 7;
const int pinBuzzer = 8;
const int pinBotonReinicio = 3;
Servo miServo;
LiquidCrystal_I2C lcd(0x27, 16, 2);
int angulo = 90;
bool esperandoRespuesta = false;
// Preguntas
String preguntas[] = {
"Es un angulo RECTO?",
"Es un angulo LLANO?",
"Es un angulo AGUDO?",
"Es un angulo OBTUSO?"
};
String tipoAnguloCorrecto = "";
// ===============================
// 🔧 Función de calibración + inversión
// ===============================
int mapearAngulo(int angulo) {
int offset = 0; // Ajustá este valor si queda corrido (ej: -10, +15, etc.)
float factor = 1.0; // Ajustá si 180° no coincide con tu impresión
// Invertir ángulo → 0 pasa a 180 y viceversa
int corregido = (180 - angulo) * factor + offset;
if (corregido < 0) corregido = 0;
if (corregido > 180) corregido = 180;
return corregido;
}
// ===============================
// 🔧 Setup
// ===============================
void setup() {
Serial.begin(115200);
miServo.attach(pinServo);
pinMode(pinBotonSi, INPUT_PULLUP);
pinMode(pinBotonNo, INPUT_PULLUP);
pinMode(pinLEDVerde, OUTPUT);
pinMode(pinLEDRojo, OUTPUT);
pinMode(pinBuzzer, OUTPUT);
pinMode(pinBotonReinicio, INPUT_PULLUP);
lcd.init();
lcd.backlight();
// 🔎 Secuencia de calibración inicial
lcd.clear();
lcd.setCursor(0,0); lcd.print("Calibrando...");
miServo.write(mapearAngulo(0));
delay(1500);
miServo.write(mapearAngulo(90));
delay(1500);
miServo.write(mapearAngulo(180));
delay(1500);
reiniciarJuego();
}
// ===============================
// 🔁 Loop principal
// ===============================
void loop() {
if (digitalRead(pinBotonReinicio) == LOW) {
reiniciarJuego();
delay(1000);
}
if (esperandoRespuesta) {
if (digitalRead(pinBotonSi) == LOW) {
validarRespuesta(true);
delay(500);
}
if (digitalRead(pinBotonNo) == LOW) {
validarRespuesta(false);
delay(500);
}
}
}
// ===============================
// 📺 Mostrar ángulo y pregunta
// ===============================
void actualizarLCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Angulo: ");
lcd.print(angulo);
int indicePregunta = random(0, 4);
tipoAnguloCorrecto = preguntas[indicePregunta];
lcd.setCursor(0, 1);
lcd.print(tipoAnguloCorrecto);
esperandoRespuesta = true;
}
// ===============================
// ✅ Validar respuesta
// ===============================
void validarRespuesta(bool respuestaSi) {
bool esCorrecto = false;
if ((tipoAnguloCorrecto == "Es un angulo RECTO?" && angulo == 90) ||
(tipoAnguloCorrecto == "Es un angulo AGUDO?" && angulo > 0 && angulo < 90) ||
(tipoAnguloCorrecto == "Es un angulo OBTUSO?" && angulo > 90 && angulo < 180) ||
(tipoAnguloCorrecto == "Es un angulo LLANO?" && angulo == 180)) {
esCorrecto = respuestaSi;
} else {
esCorrecto = !respuestaSi;
}
if (esCorrecto) {
digitalWrite(pinLEDVerde, HIGH);
digitalWrite(pinLEDRojo, LOW);
digitalWrite(pinBuzzer, LOW);
} else {
digitalWrite(pinLEDVerde, LOW);
digitalWrite(pinLEDRojo, HIGH);
tone(pinBuzzer, 1000);
delay(1000);
noTone(pinBuzzer);
}
delay(1000);
digitalWrite(pinLEDVerde, LOW);
digitalWrite(pinLEDRojo, LOW);
esperandoRespuesta = false;
actualizarLCD();
}
// ===============================
// 🔄 Reiniciar juego
// ===============================
void reiniciarJuego() {
angulo = random(0, 181);
miServo.write(mapearAngulo(angulo)); // 🎯 Servo calibrado e invertido
esperandoRespuesta = false;
actualizarLCD();
}