Arduino UV-C Sterilization Control

1:35

Aquí tienes una versión modificada del código donde se reemplaza el interruptor de mercurio por un sensor magnético para puertas. He realizado los siguientes cambios:
  • Renombré la variable mercurySwitchPin a doorSensorPin.
  • Renombré las variables relacionadas (mercurySwitchState y lastMercurySwitchState) a doorSensorState y lastDoorSensorState.
  • Se actualizan los comentarios para reflejar que se usa un sensor magnético de puerta.
Puedes revisar el siguiente código:

Cpp


#include 
#include 
#include 

// Definiciones de pines
const int buttonPin = 2;        // Pin para el botón del temporizador
const int screenButtonPin = 4;  // Pin para el botón de control de pantalla
const int LED_POWER = 13;       // Pin para el LED de encendido
const int RELE = 3;             // Pin para el relé, controla la UV-C
const int BUZZER = 5;           // Pin para el zumbador
const int doorSensorPin = 6;    // Pin para el sensor magnético de puerta
const int LED_RED = 7;          // Pin para el LED rojo

// Bitmaps iniciales (sustituir por datos reales si es necesario)
const unsigned char initialImageBitmap[] PROGMEM = { /* Datos de bitmap... */ };
const unsigned char uvImageBitmap[] PROGMEM = { /* Datos de bitmap... */ };

// Configuración del temporizador
const unsigned long totalDuration = 60000; // 60 segundos
const unsigned long autoOffDelay = 25000;  // 25 segundos

bool timerRunning = false;
bool displayOn = true;

unsigned long lastInteractionTime;
unsigned long endTime;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50;

int lastButtonState = HIGH;
int lastScreenButtonState = HIGH;
int lastDoorSensorState = HIGH;  // Renombrado para el sensor magnético

// Variables para manejar mejor el antirrebote
int currentScreenButtonState = HIGH;
unsigned long screenButtonPressTime = 0;
bool screenButtonPressed = false;

// Configuración OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void showInitialImage() {
  display.clearDisplay();
  display.drawBitmap(0, 0, initialImageBitmap, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_WHITE);
  display.display();
}

void displayQuestionWithImage() {
  display.clearDisplay();
  display.setCursor(0, 0);
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.print(F("  Deseas Esterilizar?"));
  display.drawBitmap(0, 16, uvImageBitmap, SCREEN_WIDTH, 48, SSD1306_WHITE);
  display.display();
}

void toggleDisplay() {
  displayOn = !displayOn;
  if (displayOn) {
    Serial.println("Pantalla encendida.");
    showInitialImage();
    delay(2000);
    displayQuestionWithImage();
  } else {
    Serial.println("Pantalla apagada.");
    if (timerRunning) {
      timerRunning = false;
      digitalWrite(RELE, LOW);
    }
    display.clearDisplay();
    display.display();
  }
  lastInteractionTime = millis();
}

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(screenButtonPin, INPUT_PULLUP);
  pinMode(LED_POWER, OUTPUT);
  pinMode(RELE, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  pinMode(doorSensorPin, INPUT_PULLUP);  // Configuración para sensor magnético
  pinMode(LED_RED, OUTPUT);
  digitalWrite(LED_POWER, HIGH);
  Serial.begin(9600);

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }

  toggleDisplay();
}

void loop() {
  int buttonState = digitalRead(buttonPin);
  int doorSensorState = digitalRead(doorSensorPin);  // Leer sensor magnético

  unsigned long currentMillis = millis();

  // Apagar pantalla si no hay interacción durante 25 segundos y el temporizador no está en marcha
  if (displayOn && !timerRunning && (currentMillis - lastInteractionTime > autoOffDelay)) {
    toggleDisplay();
  }

  // Comprobar si el sensor magnético detecta que la puerta se abrió
  if (doorSensorState == LOW && lastDoorSensorState == HIGH) {
    timerRunning = false;
    digitalWrite(RELE, LOW);
    digitalWrite(LED_RED, HIGH);

    if (displayOn) {
      display.clearDisplay();
      display.setCursor(0, 0);
      display.setTextSize(1);
      display.print(F("    Puerta abierta"));
      display.setCursor(0, 16);
      display.print(F("     ¡PELIGRO!"));
      display.display();
    }
    lastInteractionTime = currentMillis;
  }

  if (doorSensorState == HIGH && lastDoorSensorState == LOW) {
    digitalWrite(LED_RED, LOW);
    if (displayOn && !timerRunning) {
      displayQuestionWithImage();
    }
  }

  lastDoorSensorState = doorSensorState;

  // Manejo de antirrebote para el botón del temporizador
  if (buttonState != lastButtonState) {
    lastDebounceTime = currentMillis;
  }

  if ((currentMillis - lastDebounceTime) > debounceDelay) {
    if (buttonState == LOW && !timerRunning && displayOn && doorSensorState == HIGH) {
      endTime = currentMillis + totalDuration;
      timerRunning = true;
      Serial.println("Timer iniciado");
      digitalWrite(RELE, HIGH);

      if (displayOn) {
        display.clearDisplay();
        display.setCursor(0, 0);
        display.setTextSize(1);
        display.print(F("Running..."));
        display.display();
      }
      lastInteractionTime = currentMillis;
    }
  }

  lastButtonState = buttonState;

  // Manejo de antirrebote mejorado para el botón de control de la pantalla
  currentScreenButtonState = digitalRead(screenButtonPin);
  if (currentScreenButtonState == LOW && lastScreenButtonState == HIGH && !screenButtonPressed) {
    screenButtonPressTime = currentMillis;
    screenButtonPressed = true;
  }

  if (screenButtonPressed && (currentMillis - screenButtonPressTime > debounceDelay)) {
    if (currentScreenButtonState == LOW) {
      toggleDisplay();
    }
    screenButtonPressed = false;
  }

  lastScreenButtonState = currentScreenButtonState;

  // Comprobar si se debe detener el temporizador
  if (timerRunning && doorSensorState == HIGH) {
    unsigned long currentTime = millis();
    if (currentTime >= endTime) {
      timerRunning = false;
      digitalWrite(RELE, LOW);
      Serial.println("Tiempo alcanzado");

      if (displayOn) {
        display.clearDisplay();
        display.setCursor(0, 0);
        display.setTextSize(1);
        display.print(F("     Esterilizacion        completa                                                                            QUIROFANO                                 LISTO"));
        display.display();

        digitalWrite(BUZZER, HIGH);
        delay(15000);
        digitalWrite(BUZZER, LOW);

        delay(3000);
        displayQuestionWithImage();
        lastInteractionTime = millis();
      }
    } else {
      unsigned long remainingTime = endTime - currentTime;
      int seconds = (remainingTime / 1000) % 60;
      int minutes = (remainingTime / 1000) / 60;

      if (displayOn) {
        display.clearDisplay();
        display.setCursor(0, 0);
        display.setTextSize(1);
        display.print(F("   Tiempo restante:"));

        display.setCursor(35, 30);
        display.setTextSize(2);
        display.print(minutes);
        display.print(F(":"));
        if (seconds < 10) {
          display.print(F("0"));
        }
        display.print(seconds);
        display.display();
      }
    }
  }
}
Si necesitas más ajustes o tienes alguna duda sobre la implementación, ¡déjame saber!
Confirmar lógica sensor
Ajuste sensibilidad
Añadir manejo errores
Incluir salida serial
Conectar sensor al prototipo
368 days

Ready.


To get started, talk to Flux or create a New Document.

Documents

    Documents are markdown text files which describe project goals, capture details, or even simulation outputs.

    Assets

    No assets added.

    Sound Pink Massive Robot Spider

    Sound Pink Massive Robot Spider thumbnail
    Welcome to your new project. Imagine what you can build here.

    Properties

    Properties describe core aspects of the project.

    Pricing & Availability

    Distributor

    Qty 1

    Controls