Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Cerradura por Gestos Sin Contacto: Acceso Seguro con APDS-9960 y Arduino

Componentes y materiales

Sensor SparkFun APDS-9960 (gestos, proximidad, RGB) 1
Arduino UNO 1
LED RGB difuso (cátodo común) 1
Pantalla LCD 16x2 (blanco sobre azul, Adafruit) 1
Resistencia 4,75 kΩ 2
Cables jumper 1 set
Resistencia 1 kΩ 1

Software

Sobre el proyecto

Nota: El APDS-9960 no funciona con Arduino Nano ni Mega 2560 (según pruebas del autor).

Base para una cerradura controlada por gestos. Usa un sensor APDS-9960 para detectar movimientos (arriba, abajo, izquierda, derecha) y compara con una contraseña gestual predefinida. Si coincide, acciona un servomotor que abre el cerrojo. Incluye LCD para retroalimentación visual y LEDs RGB para estado.

Montaje

Conexiones clave

Caja

Caja de cartón con orificios para componentes. Opcional: soldar en placa perforada para mayor robustez.

Código principal

#include <Wire.h>
#include <SparkFun_APDS9960.h>
#include <LiquidCrystal.h>
#include <Servo.h>

#define PINSIZE 6
#define SERVOPIN 9
#define APDS9960_INT 2

LiquidCrystal lcd(12, 11, 6, 5, 4, 3);
Servo servo;

SparkFun_APDS9960 apds = SparkFun_APDS9960();
uint8_t proximity_data = 0;
int red_led = A1, green_led = A2;
int pageNum = 0;
String secret[PINSIZE] = {"UP","DOWN","UP","UP","RIGHT","LEFT"}; // Contraseña (mayúsculas)
String currentGesture = "";
int numRight = 0;
volatile int isr_flag = 0;

void setup() {
  pinMode(APDS9960_INT, INPUT);
  lcd.begin(16, 2);
  servo.attach(SERVOPIN); servo.write(0); servo.detach();
  Serial.begin(9600);
  Serial.print("Password length: "); Serial.println(PINSIZE);

  attachInterrupt(0, interruptRoutine, FALLING);

  if (apds.init()) Serial.println("APDS-9960 init OK");
  else Serial.println("APDS-9960 init FAIL");

  if (!apds.setProximityGain(PGAIN_1X)) Serial.println("PGAIN fail");
  if (apds.enableProximitySensor(false)) Serial.println("Proximity ON");
  else Serial.println("Proximity FAIL");

  if (apds.enableGestureSensor(true)) Serial.println("Gesture ON");
  else Serial.println("Gesture FAIL");
}

void loop() {
  // Página 0: espera proximidad (~3 pulgadas)
  if (pageNum == 0) {
    if (apds.readProximity(proximity_data)) {
      if (proximity_data >= 40) { pageNum = 1; delay(2000); }
    }
  }

  switch (pageNum) {
    case 0:
      LCDClear(); lcd.print("Locked- get"); lcd.setCursor(0,1); lcd.print("3 inches away."); blinkRed(); break;

    case 1: // Introducir código
      numRight = 0;
      lcd.print("Enter code...");
      for (int x = 0; x < PINSIZE; x++) {
        while (!apds.isGestureAvailable()) {}
        if (isr_flag == 1) {
          detachInterrupt(0);
          handleGesture();
          isr_flag = 0;
          attachInterrupt(0, interruptRoutine, FALLING);

          if (currentGesture != "NONE") {
            if (currentGesture == secret[x]) {
              LCDClear(); lcd.print("Next"); numRight++;
              analogWrite(green_led, 255); delay(1000); allOff();
            } else {
              LCDClear(); lcd.print("Wrong, return to"); lcd.setCursor(0,1); lcd.print("main page.");
              analogWrite(red_led, 255); delay(1000); allOff();
              pageNum = 0; break;
            }
            if (numRight == PINSIZE) { pageNum = 2; break; }
          } else { LCDClear(); lcd.print("Not recognized:"); lcd.setCursor(0,1); lcd.print("Try again."); x--; }
        }
      }
      break;

    case 2: // Acceso concedido
      LCDClear(); lcd.print("Enter now."); pageNum = 0;
      servo.attach(SERVOPIN); servo.write(90); enter(); delay(1000); servo.write(0);
      break;
  }
}

void interruptRoutine() { isr_flag = 1; }

void handleGesture() {
  if (apds.isGestureAvailable()) {
    switch (apds.readGesture()) {
      case DIR_UP:    currentGesture = "UP";    break;
      case DIR_DOWN:  currentGesture = "DOWN";  break;
      case DIR_LEFT:  currentGesture = "LEFT";  break;
      case DIR_RIGHT: currentGesture = "RIGHT"; break;
      case DIR_NEAR:  currentGesture = "NEAR";  break;
      case DIR_FAR:   currentGesture = "FAR";   break;
      default:        currentGesture = "NONE";
    }
    Serial.println(currentGesture);
    LCDClear(); lcd.print(currentGesture);
  }
}

void allOff() { analogWrite(red_led, 0); analogWrite(green_led, 0); }
void blinkRed() { analogWrite(red_led, 255); delay(250); allOff(); delay(250); }
void LCDClear() { lcd.clear(); lcd.setCursor(0, 0); }

void enter() {
  for (int x = 0; x < 30; x++) { analogWrite(green_led, 255); delay(100); allOff(); delay(100); }
  for (int x = 9; x > 0; x--) {
    LCDClear(); lcd.print("Closing in: "); lcd.setCursor(0,1); lcd.print(x); lcd.print(" seconds..."); delay(1000);
  }
  LCDClear(); lcd.print("Closing");
}

Esquemático

Ver diagrama en sección "Schematics" del proyecto original (conexiones I2C con pull-ups 4,7k a 3,3V, LCD, servo, LEDs).

Personalización

Proceso de manufactura

  1. La evolución y fabricación de cerraduras modernas de cilindro de pines
  2. Cerradura de combinación: Diseño, fabricación y evolución histórica
  3. Alerta de Sed Inteligente para Plantas: Sensor DIY para Riego Óptimo
  4. Reloj de Palabras en Italiano con Arduino Nano, NeoPixel, LCD y RTC
  5. Ahorra Pines en Arduino: Conecta Teclado 4x3 con Solo 3 Conexiones Analógicas
  6. Medidor kWh Sigfox Fiable con Arduino MKR Fox 1200
  7. Monitor de temperatura con Bluetooth usando Arduino Nano
  8. Kit Compañero Arduino Nano: Componentes y Herramientas Esenciales para Electrónica DIY
  9. Kit Adaptador USB MIDI para Arduino Micro / Leonardo: Lista Completa de Componentes
  10. Circuito de entrada analógica aislada para Arduino
  11. Test de Precisión de Tiempo de Reacción con Arduino UNO