Community project

Código Táctil Para Cerradura Segura

Arduino
Photo of Código Táctil Para Cerradura Segura
Generated with AI

alvearuno

Published September 20, 2026

This project implements a secure door lock controlled by a capacitive touch code entry system. The system uses an Arduino Uno to read a three-digit code from an isolated touch electrode, then commands twelve high-current actuators through dual MCP23017 I/O expanders and IBT-2 motor drivers to mechanically lock or unlock the door. A 12V battery with fused distribution powers the actuators, while a buck converter supplies clean 5V to the control electronics.

This guide provides a complete wiring diagram, detailed parts list, and step-by-step assembly instructions for integrating the touch sensor, LED indicators, power distribution, and motor control circuits. The included Arduino firmware handles capacitive touch detection, code validation with visual feedback, and sequential actuator sequencing. Safety testing procedures ensure proper operation before final installation.

Wiring diagram

Gather all the parts

QtyComponent
1

Electrodo táctil de tornillo

Tornillo metálico aislado

Un tornillo metálico aislado que detecta el toque del dedo para introducir la clave.

1

Resistencia de 1 MΩ, 1/4 W

1 MΩ

Resistencia que, junto al tornillo, permite detectar la capacitancia añadida por un dedo.

1

LED verde de 5 mm

Verde, 5 mm

La pequeña luz verde que indica que el cierre está preparado o que la clave fue correcta.

1

Resistencia de 220 ohmios

220 Ω, 1/4 W

La resistencia que limita la corriente del LED verde para que no se dañe.

1

LED rojo de 5 mm

Rojo, 5 mm

La pequeña luz roja que avisa de que la clave introducida no es correcta.

1

Resistencia de 220 ohmios

220 Ω, 1/4 W

La resistencia que limita la corriente del LED rojo para que no se dañe.

1

Módulo MCP23017 de 16 E/S, dirección 0x20

Dirección I2C 0x20

Placa expansora que añade salidas de control al Arduino mediante los dos cables I2C.

1

Módulo MCP23017 de 16 E/S, dirección 0x21

Dirección I2C 0x21

Placa expansora que añade salidas de control al Arduino mediante los dos cables I2C.

1

Batería de 12 V, 30 A continuos mínimo

12 V, 30 A continuos mínimo

Batería que entrega la energía de alta corriente a un solo actuador lineal cada vez.

1

Convertidor reductor de 12 V a 5 V, 3 A

5 V, 3 A mínimo

Módulo que convierte la batería de 12 V en los 5 V limpios que necesita el Arduino y la electrónica de mando.

1

Portafusible principal con fusible de 30 A

30 A

Protege el cable principal que sale de la batería de 12 V frente a un cortocircuito grave.

1

Bloque distribuidor de 12 fusibles para actuadores

12 × 25 A

Bloque que reparte la batería a los doce controladores, con un fusible individual por actuador.

1

IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver

43 A

IBT-2 high-current H-bridge motor driver module built around BTS7960 half-bridge devices. Common modules are sold for 6V-27V motor supplies and 5V logic, with 43A as a module headline rating; practical continuous current depends on board cooling and wiring. Direction and speed are controlled with RPWM/LPWM PWM inputs plus R_EN/L_EN enable lines. Logic-side VCC is separate from the high-power motor supply, and grounds must be common.

1

IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver

43 A

IBT-2 high-current H-bridge motor driver module built around BTS7960 half-bridge devices. Common modules are sold for 6V-27V motor supplies and 5V logic, with 43A as a module headline rating; practical continuous current depends on board cooling and wiring. Direction and speed are controlled with RPWM/LPWM PWM inputs plus R_EN/L_EN enable lines. Logic-side VCC is separate from the high-power motor supply, and grounds must be common.

1

IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver

43 A

IBT-2 high-current H-bridge motor driver module built around BTS7960 half-bridge devices. Common modules are sold for 6V-27V motor supplies and 5V logic, with 43A as a module headline rating; practical continuous current depends on board cooling and wiring. Direction and speed are controlled with RPWM/LPWM PWM inputs plus R_EN/L_EN enable lines. Logic-side VCC is separate from the high-power motor supply, and grounds must be common.

1

IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver

43 A

IBT-2 high-current H-bridge motor driver module built around BTS7960 half-bridge devices. Common modules are sold for 6V-27V motor supplies and 5V logic, with 43A as a module headline rating; practical continuous current depends on board cooling and wiring. Direction and speed are controlled with RPWM/LPWM PWM inputs plus R_EN/L_EN enable lines. Logic-side VCC is separate from the high-power motor supply, and grounds must be common.

1

IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver

43 A

IBT-2 high-current H-bridge motor driver module built around BTS7960 half-bridge devices. Common modules are sold for 6V-27V motor supplies and 5V logic, with 43A as a module headline rating; practical continuous current depends on board cooling and wiring. Direction and speed are controlled with RPWM/LPWM PWM inputs plus R_EN/L_EN enable lines. Logic-side VCC is separate from the high-power motor supply, and grounds must be common.

1

IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver

43 A

IBT-2 high-current H-bridge motor driver module built around BTS7960 half-bridge devices. Common modules are sold for 6V-27V motor supplies and 5V logic, with 43A as a module headline rating; practical continuous current depends on board cooling and wiring. Direction and speed are controlled with RPWM/LPWM PWM inputs plus R_EN/L_EN enable lines. Logic-side VCC is separate from the high-power motor supply, and grounds must be common.

1

IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver

43 A

IBT-2 high-current H-bridge motor driver module built around BTS7960 half-bridge devices. Common modules are sold for 6V-27V motor supplies and 5V logic, with 43A as a module headline rating; practical continuous current depends on board cooling and wiring. Direction and speed are controlled with RPWM/LPWM PWM inputs plus R_EN/L_EN enable lines. Logic-side VCC is separate from the high-power motor supply, and grounds must be common.

1

IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver

43 A

IBT-2 high-current H-bridge motor driver module built around BTS7960 half-bridge devices. Common modules are sold for 6V-27V motor supplies and 5V logic, with 43A as a module headline rating; practical continuous current depends on board cooling and wiring. Direction and speed are controlled with RPWM/LPWM PWM inputs plus R_EN/L_EN enable lines. Logic-side VCC is separate from the high-power motor supply, and grounds must be common.

1

IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver

43 A

IBT-2 high-current H-bridge motor driver module built around BTS7960 half-bridge devices. Common modules are sold for 6V-27V motor supplies and 5V logic, with 43A as a module headline rating; practical continuous current depends on board cooling and wiring. Direction and speed are controlled with RPWM/LPWM PWM inputs plus R_EN/L_EN enable lines. Logic-side VCC is separate from the high-power motor supply, and grounds must be common.

1

IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver

43 A

IBT-2 high-current H-bridge motor driver module built around BTS7960 half-bridge devices. Common modules are sold for 6V-27V motor supplies and 5V logic, with 43A as a module headline rating; practical continuous current depends on board cooling and wiring. Direction and speed are controlled with RPWM/LPWM PWM inputs plus R_EN/L_EN enable lines. Logic-side VCC is separate from the high-power motor supply, and grounds must be common.

1

IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver

43 A

IBT-2 high-current H-bridge motor driver module built around BTS7960 half-bridge devices. Common modules are sold for 6V-27V motor supplies and 5V logic, with 43A as a module headline rating; practical continuous current depends on board cooling and wiring. Direction and speed are controlled with RPWM/LPWM PWM inputs plus R_EN/L_EN enable lines. Logic-side VCC is separate from the high-power motor supply, and grounds must be common.

1

IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver

43 A

IBT-2 high-current H-bridge motor driver module built around BTS7960 half-bridge devices. Common modules are sold for 6V-27V motor supplies and 5V logic, with 43A as a module headline rating; practical continuous current depends on board cooling and wiring. Direction and speed are controlled with RPWM/LPWM PWM inputs plus R_EN/L_EN enable lines. Logic-side VCC is separate from the high-power motor supply, and grounds must be common.

1

Actuador lineal 1 de 12 V

12 V, 10 A con carga / 20 A de bloqueo

El primer cierre motorizado; se mueve durante un máximo de 15 segundos, de uno en uno con los demás.

1

Actuador lineal 2 de 12 V

12 V, 10 A con carga / 20 A de bloqueo

El segundo cierre motorizado; se mueve durante un máximo de 15 segundos, de uno en uno con los demás.

1

Actuador lineal 3 de 12 V

12 V, 10 A con carga / 20 A de bloqueo

El tercer cierre motorizado; se mueve durante un máximo de 15 segundos, de uno en uno con los demás.

1

Actuador lineal 4 de 12 V

12 V, 10 A con carga / 20 A de bloqueo

El cuarto cierre motorizado; se mueve durante un máximo de 15 segundos, de uno en uno con los demás.

1

Actuador lineal 5 de 12 V

12 V, 10 A con carga / 20 A de bloqueo

El quinto cierre motorizado; se mueve durante un máximo de 15 segundos, de uno en uno con los demás.

1

Actuador lineal 6 de 12 V

12 V, 10 A con carga / 20 A de bloqueo

El sexto cierre motorizado; se mueve durante un máximo de 15 segundos, de uno en uno con los demás.

1

Actuador lineal 7 de 12 V

12 V, 10 A con carga / 20 A de bloqueo

El séptimo cierre motorizado; se mueve durante un máximo de 15 segundos, de uno en uno con los demás.

1

Actuador lineal 8 de 12 V

12 V, 10 A con carga / 20 A de bloqueo

El octavo cierre motorizado; se mueve durante un máximo de 15 segundos, de uno en uno con los demás.

1

Actuador lineal 9 de 12 V

12 V, 10 A con carga / 20 A de bloqueo

El noveno cierre motorizado; se mueve durante un máximo de 15 segundos, de uno en uno con los demás.

1

Actuador lineal 10 de 12 V

12 V, 10 A con carga / 20 A de bloqueo

El décimo cierre motorizado; se mueve durante un máximo de 15 segundos, de uno en uno con los demás.

1

Actuador lineal 11 de 12 V

12 V, 10 A con carga / 20 A de bloqueo

El undécimo cierre motorizado; se mueve durante un máximo de 15 segundos, de uno en uno con los demás.

1

Actuador lineal 12 de 12 V

12 V, 10 A con carga / 20 A de bloqueo

El duodécimo cierre motorizado; se mueve durante un máximo de 15 segundos, de uno en uno con los demás.

Assemble it in 8 steps

1. Fija los actuadores con la puerta abierta

Monta los doce actuadores lineales y sus herrajes con la puerta completamente abierta. Cada actuador debe poder llegar a sus propios finales de carrera sin forzar el cierre ni doblar la varilla.

  • Etiqueta cada par de cables como A1 a A12 antes de llevarlos al cuadro de control.
  • No pruebes un actuador instalado en una puerta cerrada hasta comprobar que su mecanismo no puede atrapar dedos ni bloquear una salida de emergencia.

2. Monta la batería y los fusibles

Con la batería desconectada, lleva el positivo de la batería de 12 V al portafusible principal de 30 A y de ahí a la entrada del bloque de doce fusibles. Lleva el negativo de la batería a una barra común de GND. Pon un fusible de 25 A en cada una de las doce salidas del bloque.

  • Usa cable y terminales dimensionados para 25 A en cada ramal de actuador, y mantén el cable principal lo más corto posible.
  • Un fusible de 30 A no protege doce actuadores contra una suma de corrientes: el programa mueve uno por vez, pero cada ramal debe conservar su fusible de 25 A.

3. Conecta los doce controladores de potencia

Conecta OUT1 a B+ de driver_1, OUT2 a B+ de driver_2, y continúa en el mismo orden hasta OUT12 y driver_12. Conecta B- y GND de todos los controladores a la barra común de GND. Conecta M+ y M- de cada driver al par de cables de su actuador con el mismo número.

  • Si un actuador se mueve al revés en la prueba, desconecta la batería y cambia sólo sus dos cables M+ y M-.
  • Nunca cambies cables M+ o M- con la batería conectada: un cortocircuito en esta zona puede quemar cableado o el controlador.

4. Alimenta la parte de 5 V

Conecta la entrada IN+ del convertidor a la salida protegida de 12 V después del fusible principal y su IN- a GND. Ajusta y verifica primero que OUT+ entrega exactamente 5 V. Después conecta OUT+ al rail de 5 V y OUT- a GND; ese rail alimenta el Arduino, los dos MCP23017 y VCC, R_EN y L_EN de cada BTS7960.

  • Todas las masas GND —batería, convertidor, Arduino, expansores y controladores— deben quedar unidas para que las órdenes tengan referencia común.
  • No lleves 12 V al Arduino, a los expansores MCP23017 ni a los pines VCC de los BTS7960: sólo deben recibir 5 V.

5. Conecta el Arduino, los expansores y los LED

Conecta SDA de ambos MCP23017 a A4 del Arduino y SCL de ambos a A5. Conecta VDD a 5 V y VSS a GND. Conecta D3 a la resistencia de 220 Ω del LED verde y la resistencia al ánodo; conecta el cátodo a GND. Conecta D4 a la resistencia de 220 Ω del LED rojo y la resistencia al ánodo; conecta el cátodo a GND.

  • A4 → SDA (datos), A5 → SCL (reloj), D3 → resistencia → LED verde (aviso), D4 → resistencia → LED rojo (error).
  • No conectes un LED directamente a D3 o D4: la resistencia de 220 Ω evita que el LED y el Arduino se dañen.

6. Conecta las 24 órdenes de los controladores

En expansor_salidas_1 conecta P0/P1 a RPWM/LPWM de driver_1, P2/P3 a driver_2, y continúa por parejas hasta P14/P15 para driver_8. En expansor_salidas_2 conecta P0/P1 a driver_9, P2/P3 a driver_10, P4/P5 a driver_11 y P6/P7 a driver_12.

  • RPWM y LPWM son las dos órdenes de sentido; el programa deja una a cero antes de encender la otra, y sólo activa un driver cada vez.
  • No unas RPWM y LPWM del mismo controlador entre sí: recibir órdenes contrarias puede dañar el controlador o causar un frenado brusco.

7. Monta el tornillo táctil aislado

Sujeta el tornillo donde se vaya a tocar, aislándolo eléctricamente del marco metálico. Conecta D7 a un extremo de la resistencia de 1 MΩ; conecta el otro extremo de la resistencia al tornillo. Conecta también el tornillo directamente a D8.

  • D7 → resistencia de 1 MΩ → tornillo (medida segura); tornillo → D8 (lectura del toque).
  • Si el tornillo toca una parte metálica conectada a tierra, la detección puede fallar; mantén aislada la zona que se toca.

8. Prueba con seguridad antes de cerrar la puerta

Enciende primero sin conectar los cables M+ y M- de los actuadores y confirma los LED. Después conecta un solo actuador, prueba abrir y cerrar con la puerta abierta y confirma el sentido. Por último conecta los demás, manteniendo libre la zona de movimiento.

  • La clave de apertura inicial es 1-2-3 y la de cierre inicial es 3-2-1; ambas se pueden cambiar al comienzo del código.
  • Antes de usarlo como cierre real, comprueba que la puerta siempre se pueda abrir desde el interior y que el fallo de alimentación no cree un riesgo para personas.

Review all connections

1. Connections between "placa_tactil" and "Arduino"

Functionplaca_tactilArduino
digitalTOUCHGPIO 8

2. Connections between "resistor_tacto" and "Arduino"

Functionresistor_tactoArduino
digitalEND_AGPIO 7
digitalEND_BElectrodo táctil de tornillo TOUCHEXT

3. Connections between "resistor_led_verde" and "Arduino"

Functionresistor_led_verdeArduino
digitalEND_AGPIO 3
digitalEND_BLED verde de 5 mm ANODOEXT

4. Connections between "led_verde_estado" and "Arduino"

Functionled_verde_estadoArduino
groundCATODOGND

5. Connections between "resistor_led_rojo" and "Arduino"

Functionresistor_led_rojoArduino
digitalEND_AGPIO 4
digitalEND_BLED rojo de 5 mm ANODOEXT

6. Connections between "led_rojo_error" and "Arduino"

Functionled_rojo_errorArduino
groundCATODOGND

7. Connections between "expansor_salidas_1" and "Arduino"

Functionexpansor_salidas_1Arduino
powerVDD5V
groundVSSGND
i2cSDAGPIO 18
i2cSCLGPIO 19
digitalP0IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver RPWMEXT
digitalP1IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver LPWMEXT
digitalP2IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver RPWMEXT
digitalP3IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver LPWMEXT
digitalP4IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver RPWMEXT
digitalP5IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver LPWMEXT
digitalP6IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver RPWMEXT
digitalP7IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver LPWMEXT
digitalP8IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver RPWMEXT
digitalP9IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver LPWMEXT
digitalP10IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver RPWMEXT
digitalP11IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver LPWMEXT
digitalP12IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver RPWMEXT
digitalP13IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver LPWMEXT

8. Connections between "expansor_salidas_2" and "Arduino"

Functionexpansor_salidas_2Arduino
powerVDD5V
groundVSSGND
i2cSDAGPIO 18
i2cSCLGPIO 19
digitalP0IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver RPWMEXT
digitalP1IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver LPWMEXT
digitalP2IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver RPWMEXT
digitalP3IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver LPWMEXT
digitalP4IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver RPWMEXT
digitalP5IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver LPWMEXT
digitalP6IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver RPWMEXT
digitalP7IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver LPWMEXT
digitalP8IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver RPWMEXT
digitalP9IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver LPWMEXT

9. Connections between "bateria_12v" and "Arduino"

Functionbateria_12vArduino
power+12VPortafusible principal con fusible de 30 A INEXT
groundGNDGND

10. Connections between "fusible_principal_30a" and "Arduino"

Functionfusible_principal_30aArduino
powerOUTBloque distribuidor de 12 fusibles para actuadores INEXT

11. Connections between "convertidor_12a5v" and "Arduino"

Functionconvertidor_12a5vArduino
powerIN+Portafusible principal con fusible de 30 A OUTEXT
groundIN-GND
powerOUT+5V
groundOUT-GND

12. Connections between "bloque_fusibles_12v" and "Arduino"

Functionbloque_fusibles_12vArduino
powerOUT1IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver B+EXT
powerOUT2IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver B+EXT
powerOUT3IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver B+EXT
powerOUT4IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver B+EXT
powerOUT5IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver B+EXT
powerOUT6IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver B+EXT
powerOUT7IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver B+EXT
powerOUT8IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver B+EXT
powerOUT9IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver B+EXT
powerOUT10IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver B+EXT
powerOUT11IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver B+EXT
powerOUT12IBT-2 BTS7960 43A High-Current H-Bridge Motor Driver B+EXT

13. Connections between "driver_1" and "Arduino"

Functiondriver_1Arduino
powerVCC5V
groundGNDGND
powerR_EN5V
powerL_EN5V
groundB-GND
dataM+Actuador lineal 1 de 12 V M+EXT
dataM-Actuador lineal 1 de 12 V M-EXT

14. Connections between "driver_2" and "Arduino"

Functiondriver_2Arduino
powerVCC5V
groundGNDGND
powerR_EN5V
powerL_EN5V
groundB-GND
dataM+Actuador lineal 2 de 12 V M+EXT
dataM-Actuador lineal 2 de 12 V M-EXT

15. Connections between "driver_3" and "Arduino"

Functiondriver_3Arduino
powerVCC5V
groundGNDGND
powerR_EN5V
powerL_EN5V
groundB-GND
dataM+Actuador lineal 3 de 12 V M+EXT
dataM-Actuador lineal 3 de 12 V M-EXT

16. Connections between "driver_4" and "Arduino"

Functiondriver_4Arduino
powerVCC5V
groundGNDGND
powerR_EN5V
powerL_EN5V
groundB-GND
dataM+Actuador lineal 4 de 12 V M+EXT
dataM-Actuador lineal 4 de 12 V M-EXT

17. Connections between "driver_5" and "Arduino"

Functiondriver_5Arduino
powerVCC5V
groundGNDGND
powerR_EN5V
powerL_EN5V
groundB-GND
dataM+Actuador lineal 5 de 12 V M+EXT
dataM-Actuador lineal 5 de 12 V M-EXT

18. Connections between "driver_6" and "Arduino"

Functiondriver_6Arduino
powerVCC5V
groundGNDGND
powerR_EN5V
powerL_EN5V
groundB-GND
dataM+Actuador lineal 6 de 12 V M+EXT
dataM-Actuador lineal 6 de 12 V M-EXT

19. Connections between "driver_7" and "Arduino"

Functiondriver_7Arduino
powerVCC5V
groundGNDGND
powerR_EN5V
powerL_EN5V
groundB-GND
dataM+Actuador lineal 7 de 12 V M+EXT
dataM-Actuador lineal 7 de 12 V M-EXT

20. Connections between "driver_8" and "Arduino"

Functiondriver_8Arduino
powerVCC5V
groundGNDGND
powerR_EN5V
powerL_EN5V
groundB-GND
dataM+Actuador lineal 8 de 12 V M+EXT
dataM-Actuador lineal 8 de 12 V M-EXT

21. Connections between "driver_9" and "Arduino"

Functiondriver_9Arduino
powerVCC5V
groundGNDGND
powerR_EN5V
powerL_EN5V
groundB-GND
dataM+Actuador lineal 9 de 12 V M+EXT
dataM-Actuador lineal 9 de 12 V M-EXT

22. Connections between "driver_10" and "Arduino"

Functiondriver_10Arduino
powerVCC5V
groundGNDGND
powerR_EN5V
powerL_EN5V
groundB-GND
dataM+Actuador lineal 10 de 12 V M+EXT
dataM-Actuador lineal 10 de 12 V M-EXT

23. Connections between "driver_11" and "Arduino"

Functiondriver_11Arduino
powerVCC5V
groundGNDGND
powerR_EN5V
powerL_EN5V
groundB-GND
dataM+Actuador lineal 11 de 12 V M+EXT
dataM-Actuador lineal 11 de 12 V M-EXT

24. Connections between "driver_12" and "Arduino"

Functiondriver_12Arduino
powerVCC5V
groundGNDGND
powerR_EN5V
powerL_EN5V
groundB-GND
dataM+Actuador lineal 12 de 12 V M+EXT
dataM-Actuador lineal 12 de 12 V M-EXT

Deploy the firmware

#include <Arduino.h>
#include <Wire.h>
#include <CapacitiveSensor.h>
#include <Adafruit_MCP23X17.h>

enum SystemState { IDLE, READY_PATTERN, ENTERING_CODE, DIGIT_FLASH, SUCCESS_PATTERN, ERROR_PATTERN, MOVING_ACTUATORS };
enum RequestedAction { NO_ACTION, OPEN_DOOR, CLOSE_DOOR };


// Forward declarations
void setGreenBrightness(byte brightness);
void lightsOff();
void resetEntry();
void writeExpanderPin(byte actuator, bool reverse, bool value);
void stopAllActuators();
void startOneActuator(byte actuator, bool useRPWM);
bool codeMatches(const byte expected[3]);
void startReadyPattern();
void beginCodeEntry();
void finishDigit();
void registerTap();
void startSequentialMovement();
void updateMotion();
void updateIndicatorsAndState();

const byte GREEN_LED_PIN = 3;
const byte RED_LED_PIN = 4;
const byte TOUCH_SEND_PIN = 7;
const byte TOUCH_RECEIVE_PIN = 8;

// ===== AJUSTES DE TOQUES Y TIEMPOS: MODIFÍCALOS AQUÍ =====
// Tiempo mínimo entre dos toques que cuentan como toques distintos de una cifra.
const unsigned long MIN_TIME_BETWEEN_TAPS_MS = 350;
// Tiempo máximo sin tocar que termina una cifra y permite pasar a la siguiente.
const unsigned long MAX_TIME_BETWEEN_TAPS_MS = 1800;
// Tiempo máximo total para introducir las tres cifras una vez activado el teclado.
const unsigned long CODE_ENTRY_TIMEOUT_MS = 10000;

// Primer aviso verde: encendido 500 ms, apagado 500 ms, encendido 500 ms.
const unsigned long READY_PATTERN_MS = 1500;
const unsigned long DIGIT_FLASH_MS = 250;
const unsigned long ERROR_PATTERN_MS = 2000;
const unsigned long SUCCESS_PATTERN_MS = 3000;

// ===== CLAVES DE ACCESO: MODIFÍCALAS AQUÍ =====
// Cada número es el número de toques de una cifra. Ejemplo {1,2,3} = toque, pausa;
// dos toques, pausa; tres toques. Cada cifra debe estar entre 1 y 9.
const byte openCode[3] = {1, 2, 3};   // Clave que ABRE los 12 cierres.
const byte closeCode[3] = {3, 2, 1};  // Clave que CIERRA los 12 cierres.

// ===== MOVIMIENTO DE LOS ACTUADORES: MODIFÍCALO SÓLO TRAS UNA PRUEBA MECÁNICA =====
// El máximo por actuador es 15 s. Los actuadores con final de carrera interno se detienen antes.
const unsigned long ACTUATOR_MAX_RUN_MS = 15000;
// Pausa sin corriente entre un actuador y el siguiente.
const unsigned long BETWEEN_ACTUATORS_MS = 300;
// Cambia false por true si la dirección RPWM resulta ser la de abrir al probar el actuador 1.
const bool OPEN_USES_RPWM = false;

const unsigned long TOUCH_THRESHOLD = 800;
const byte EXPANDER_1_ADDRESS = 0x20;
const byte EXPANDER_2_ADDRESS = 0x21;
const byte ACTUATOR_COUNT = 12;

CapacitiveSensor touchSensor(TOUCH_SEND_PIN, TOUCH_RECEIVE_PIN);
Adafruit_MCP23X17 expander1;
Adafruit_MCP23X17 expander2;

SystemState state = IDLE;
RequestedAction pendingAction = NO_ACTION;
byte enteredDigits[3];
byte digitCount = 0;
byte tapsForDigit = 0;
byte currentActuator = 0;
bool actuatorEnergized = false;
bool touchWasDetected = false;
unsigned long lastTouchMs = 0;
unsigned long lastTapMs = 0;
unsigned long stateStartedMs = 0;
unsigned long entryStartedMs = 0;
unsigned long motionStartedMs = 0;

void setGreenBrightness(byte brightness) { analogWrite(GREEN_LED_PIN, brightness); }
void lightsOff() { setGreenBrightness(0); digitalWrite(RED_LED_PIN, LOW); }

void resetEntry() {
  digitCount = 0;
  tapsForDigit = 0;
  lastTapMs = 0;
}

void writeExpanderPin(byte actuator, bool reverse, bool value) {
  // Actuadores 1..7: MCP23017 #1, P0..P13. Actuadores 8..12: MCP23017 #2, P0..P9.
  Adafruit_MCP23X17 *expander = (actuator < 7) ? &expander1 : &expander2;
  byte localActuator = (actuator < 7) ? actuator : actuator - 7;
  byte pin = localActuator * 2 + (reverse ? 1 : 0);
  expander->digitalWrite(pin, value ? HIGH : LOW);
}

void stopAllActuators() {
  for (byte i = 0; i < ACTUATOR_COUNT; i++) {
    writeExpanderPin(i, false, false);
    writeExpanderPin(i, true, false);
  }
}

void startOneActuator(byte actuator, bool useRPWM) {
  // Primero se apagan todas las salidas: nunca se permiten dos actuadores a la vez.
  stopAllActuators();
  writeExpanderPin(actuator, !useRPWM, false);
  writeExpanderPin(actuator, useRPWM, true);
}

bool codeMatches(const byte expected[3]) {
  for (byte i = 0; i < 3; i++) {
    if (enteredDigits[i] != expected[i]) return false;
  }
  return true;
}

void startReadyPattern() {
  resetEntry();
  lightsOff();
  state = READY_PATTERN;
  stateStartedMs = millis();
}

void beginCodeEntry() {
  lightsOff();
  resetEntry();
  state = ENTERING_CODE;
  entryStartedMs = millis();
}

void finishDigit() {
  if (tapsForDigit == 0) return;
  if (tapsForDigit > 9 || digitCount >= 3) {
    state = ERROR_PATTERN;
    stateStartedMs = millis();
    resetEntry();
    return;
  }

  enteredDigits[digitCount++] = tapsForDigit;
  tapsForDigit = 0;
  if (digitCount < 3) {
    state = DIGIT_FLASH;
    stateStartedMs = millis();
  } else if (codeMatches(openCode)) {
    pendingAction = OPEN_DOOR;
    state = SUCCESS_PATTERN;
    stateStartedMs = millis();
  } else if (codeMatches(closeCode)) {
    pendingAction = CLOSE_DOOR;
    state = SUCCESS_PATTERN;
    stateStartedMs = millis();
  } else {
    pendingAction = NO_ACTION;
    state = ERROR_PATTERN;
    stateStartedMs = millis();
  }
}

void registerTap() {
  unsigned long now = millis();
  if (now - lastTouchMs < MIN_TIME_BETWEEN_TAPS_MS) return;
  lastTouchMs = now;
  if (state == IDLE) startReadyPattern();
  else if (state == ENTERING_CODE) {
    tapsForDigit++;
    lastTapMs = now;
  }
}

void startSequentialMovement() {
  currentActuator = 0;
  actuatorEnergized = true;
  bool useRPWM = (pendingAction == OPEN_DOOR) ? OPEN_USES_RPWM : !OPEN_USES_RPWM;
  startOneActuator(currentActuator, useRPWM);
  motionStartedMs = millis();
  state = MOVING_ACTUATORS;
}

void updateMotion() {
  unsigned long now = millis();
  if (actuatorEnergized && now - motionStartedMs >= ACTUATOR_MAX_RUN_MS) {
    stopAllActuators();
    actuatorEnergized = false;
    motionStartedMs = now;
  } else if (!actuatorEnergized && now - motionStartedMs >= BETWEEN_ACTUATORS_MS) {
    currentActuator++;
    if (currentActuator >= ACTUATOR_COUNT) {
      pendingAction = NO_ACTION;
      startReadyPattern();
    } else {
      bool useRPWM = (pendingAction == OPEN_DOOR) ? OPEN_USES_RPWM : !OPEN_USES_RPWM;
      startOneActuator(currentActuator, useRPWM);
      actuatorEnergized = true;
      motionStartedMs = now;
    }
  }
}

void updateIndicatorsAndState() {
  unsigned long elapsed = millis() - stateStartedMs;
  if (state == READY_PATTERN) {
    setGreenBrightness((elapsed < 500 || (elapsed >= 1000 && elapsed < 1500)) ? 255 : 0);
    if (elapsed >= READY_PATTERN_MS) beginCodeEntry();
  } else if (state == DIGIT_FLASH) {
    setGreenBrightness(255);
    if (elapsed >= DIGIT_FLASH_MS) {
      lightsOff();
      state = ENTERING_CODE;
    }
  } else if (state == SUCCESS_PATTERN) {
    unsigned long phase = elapsed % 1000;
    byte brightness = (phase < 500) ? map(phase, 0, 499, 0, 255) : map(phase, 500, 999, 255, 0);
    setGreenBrightness(brightness);
    if (elapsed >= SUCCESS_PATTERN_MS) {
      lightsOff();
      startSequentialMovement();
    }
  } else if (state == ERROR_PATTERN) {
    // Cuatro destellos completos en 2 s: 250 ms encendido y 250 ms apagado cada vez.
    digitalWrite(RED_LED_PIN, (elapsed % 500) < 250 ? HIGH : LOW);
    if (elapsed >= ERROR_PATTERN_MS) {
      lightsOff();
      startReadyPattern();
    }
  } else if (state == MOVING_ACTUATORS) updateMotion();
}

void setup() {
  pinMode(GREEN_LED_PIN, OUTPUT);
  pinMode(RED_LED_PIN, OUTPUT);
  lightsOff();
  touchSensor.set_CS_AutocaL_Millis(0xFFFFFFFF);

  Wire.begin();
  expander1.begin_I2C(EXPANDER_1_ADDRESS);
  expander2.begin_I2C(EXPANDER_2_ADDRESS);
  // El primer expansor usa P0..P13 (actuadores 1 a 7); P14 y P15 quedan libres.
  for (byte pin = 0; pin < 14; pin++) expander1.pinMode(pin, OUTPUT);
  // El segundo usa P0..P9 (actuadores 8 a 12).
  for (byte pin = 0; pin < 10; pin++) expander2.pinMode(pin, OUTPUT);
  stopAllActuators();
}

void loop() {
  long sensorValue = touchSensor.capacitiveSensor(20);
  bool touching = sensorValue > TOUCH_THRESHOLD;
  if (touching && !touchWasDetected) registerTap();
  touchWasDetected = touching;

  if (state == ENTERING_CODE) {
    if (tapsForDigit > 0 && millis() - lastTapMs >= MAX_TIME_BETWEEN_TAPS_MS) finishDigit();
    if (millis() - entryStartedMs >= CODE_ENTRY_TIMEOUT_MS) {
      lightsOff();
      resetEntry();
      state = IDLE;
    }
  }
  updateIndicatorsAndState();
}

Remix this project

Make it yours in one click

Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.

Open in Schematik