Opening system of a showcase with arduino

Description

The purpose of the project is to create a system of selective opening of shop windows.

The requirements are:

  • There are a total of 8 windows.
  • They must be able to open each of the 8 windows independently.
  • They must be able to open all the windows at once.
  • The time during which the locks must be opened is 1 minute.
  • There are 3 bolts for window.
Descripcion_01
Shop Window

Instructions

Components used

The components used have been:

Componente_01
Bolt

Assembly of the circuit

The Fritzing scheme is as follows:

Esquema_01
Scheme using Fritzing

As can be seen in the following images, the system has been mounted on a pcb board 9x15. The power supply has been chosen of 30A because each of the bolts uses 900 mA and there are 24 of these. The LM2596S module has been used to reduce the input voltage to the Arduino from 12V to 6V.

Images of the system mounted inside the laboratory:

Galeria_01
Upper detail of the assembled PCB
Galeria_02
Bottom detail of the assembled PCB
Galeria_03
Keyboard and relay block
Galeria_04
Connection of the relay block
Galeria_05
Complete system

Software

To verify the address I2C of the relay block has been used the program called Arduino I2c Scanner.

The libraries used have been:

  • I2C_RL8xxM: library used to access the relay block.
  • Wire: library used to I2C connections and is a dependenciy of the I2C_RL8xxM library.
  • keypad: library used to manage the membrane keypad 4x3.

The code of the Arduino is the following:

#include <Wire.h>
#include <I2C_RL8xxM.h>
#include <Keypad.h>

/**
Filas y columnas del teclado
*/
const byte ROWS = 4;
const byte COLS = 3;

/**
@brief Asignación de pins de las patas
*/
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3};

/**
@brief Define los simbolos de los botones del teclado
*/
char Keys[ROWS][COLS] =
{
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

/**
@brief Inicializa el teclado
*/
Keypad keypad = Keypad(makeKeymap(Keys), rowPins, colPins, ROWS, COLS);

char key;

//Tiempo restante de botones
int botones[8] = { 0, 0, 0, 0, 0, 0, 0, 0};

int estadoBotones[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // 0 es desactivado y 1 es activado.

int segundosEspera = 60;

//Se declara una variable que almacenará el tiempo actual (real) transcurrido
//desde que se enciende la placa.
unsigned long tiempo = 0;

//Se declara una variable que almacenará el último valor de tiempo en el que se
//ejecutó la instrucción (delay).
unsigned long t_actualizado = 0;

//Se declara una variable que almacenará el tiempo que se desea que dure el delay.
unsigned long t_delay = 1000; // Por ser milisegundos, nos esperamos un segundo.


int DirReles = 32;

I2C_RL8xxM rb (DirReles);

int pinLed = 13;

void setup()
{
  Serial.begin(9600); //Para debug
  Serial.println("Inicio");

  Wire.begin(); //Inicializa el I2C como master
  keypad.addEventListener(keypadEvent); // Añade un gestor de eventos para el teclado

  pinMode(13, OUTPUT);
}

void activaRele(int numRele)
{
  Serial.print("Rele activado: ");
  Serial.println(numRele);

  if (estadoBotones[numRele - 1] == 0)
  {
    estadoBotones[numRele - 1] = 1;
    botones[numRele - 1] = segundosEspera + 2;

    rb.Switch (numRele, true);
  }
  Serial.println("Rele activado: FIN");
}

void apagaRele(int numRele)
{
  Serial.print("Rele desactivado: ");
  Serial.println(numRele);

  if (estadoBotones[numRele - 1] == 1)
  {
    estadoBotones[numRele - 1] = 0;

    rb.Switch (numRele, false);
  }
  Serial.println("Rele desactivado: FIN");
}

/**
Gestión de la tecla pulsada
*/
void keypadEvent(KeypadEvent key)
{
  Serial.print("Tecla pulsada: ");
  Serial.println(key);

  switch (keypad.getState()) {
    case PRESSED: //pulsado + soltado
      Serial.println("PRESSED");
      digitalWrite(13, HIGH);
      if (key == '0')
      {
        activaRele(1);
        activaRele(2);
        activaRele(3);
        activaRele(4);
        activaRele(5);
        activaRele(6);
        activaRele(7);
        activaRele(8);
      } else if (key == '1')
      {
        activaRele(1);
      } else if (key == '2')
      {
        activaRele(2);
      } else if (key == '3')
      {
        activaRele(3);
      } else if (key == '4')
      {
        activaRele(4);
      } else if (key == '5')
      {
        activaRele(5);
      } else if (key == '6')
      {
        activaRele(6);
      } else if (key == '7')
      {
        activaRele(7);
      } else if (key == '8')
      {
        activaRele(8);
      } else if (key == '9')
      {

      } else if (key == '#')
      {

      } else if (key == '*')
      {
      }
      break;

    case RELEASED: //Soltado
      Serial.println("RELEASED");
      digitalWrite(13, LOW);
      break;

    case HOLD: //Mantenido el botón pulsado
      Serial.println("HOLD");
      break;
  }
}


void testReles()
{
  for (int i = 0; i < 8; i++)
  {
    if (botones[i] == 1)
    {
      apagaRele(i + 1);
    }
    if (botones[i] > 0)
    {
      botones[i]--;
    }
  }
  //Serial.println("Comprobación estado relés");
}

//Se quita, si no el SoftTimer no funciona. Este lo tiene definido dentro.
void  loop()
{
  key = keypad.getKey();
  /*
    if (key) {
      Serial.print("Tecla pulsada: ");
      Serial.println(key);
    }*/

  //Se almacena el tiempo que ha transcurrido desde que se encendió el Arduino.
  tiempo = millis();

  //Si ese tiempo es mayor que el intervalo de deseado (equivalente al tiempo
  //de delay) se actualiza el intervalo y se ejecutan las instruciones relacionadas.
  //La idea detrás de este algoritmo consiste en pensar que si han transcurrido
  //20ms y se desea un delay de 30ms cada vez, cuando se superen esos 30ms la
  //variable con la que se compara pasa a ser 60ms. Una vez se alcanzan los 60ms
  //pasa a ser 90ms y así sucesivamente.
  if ( tiempo > t_actualizado + t_delay)
  {
    //Se actualiza el tiempo que ha de transcurrir para el próximo delay.
    t_actualizado = tiempo;

    testReles();
  }

}

Complementary and additional places in which the article has been published:

results matching ""

    No results matching ""