Proyecto del Grupo 6. «Venduino»

1. Introducción.

1.1. Grupo e Integrantes:

El proyecto «Venduino» ha sido realizado por Rubén Reina Hernández, Alejandro Cano González y Mario Águdo Ávila, que son integrantes del Grupo 6 del Campus de Móstoles.

1.2. Presentación del Proyecto:

“Venduino” es una máquina
expendedora, o de «vending», hecha con arduino. Más adelante detallaremos el
funcionamiento de la máquina.
A la hora de elegir el proyecto
para la asignatura fueron planteadas varias opciones, empezando por la
realización de una impresora 3D, sin embargo, llegamos a la conclusión de que
este proyecto iba a tener un coste muy alto y lo descartamos. Otra opción fue
construir un dispensador de comida para animales, en el que pudieras introducir
valores y horas a las que esa comida iba a ser expendida, de forma automática,
sin embargo consideramos que la máquina “Venduino” era un proyecto más
interesante.
En primer lugar, “Venduino” iba a
ser una máquina de vending que utiliza monedas, como las que nos podemos
encontrar en la universidad o en el metro, sin embargo se nos ocurrió la
posibilidad de hacer pagos con sistemas de prepago. Esto lo hacemos mediante un
sistema de NFC, que funciona mediante unas tarjetas o llaveros que almacenan
dinero para pagar los artículos deseados de las máquinas, de tal forma que no
haga falta llevar dinero encima para pagar, simplemente habría que usar la
tarjeta, que es similar a la del transporte público, por ejemplo.
El resto del funcionamiento, que
se verá más adelante, es similar al de una máquina expendedora normal.

1.3. Cómo utilizar «Venduino»:

«Venduino» funciona como una máquina expendedora normal. Simplemente hay que tener en cuenta que funciona mediante tarjetas prepago.
Primero se selecciona el articulo deseado y la pantalla indicará su precio, posteriormente posas la tarjeta de prepago en la celda blanca, que es donde esta situado el NFC, y se descontará el precio del producto al saldo de la tarjeta de prepago. Por último la máquina expenderá el producto y el usuario introducirá la mano en la máquina para recoger el artículo deseado.

1.4. Materiales y presupuesto necesarios:

**Arduino MEGA incluye el kit entero, con varios componentes.
El coste de este proyecto es de aproximadamente 80 euros.

2. Desarrollo del proyecto.

2.1. Construcción de la máquina:

La construcción de una maquina expendedora tiene muchas posibilidades, nosotros hemos elegido hacerla de 4 celdas, por lo que hemos elegido las siguientes medidas para la madera.
En cuanto a la construcción es simplemente tener en cuenta que hay que construir una caja, que se pueda abrir por delante y por detrás, siendo la primera abertura para introducir los distintos artículos que se van a vender, y la segunda para tener visible el circuito por si hubiera algún fallo o modificación. Todo se ha atornillado y va con bisagras. El cableado y el metacrilato estan pegados con silicona.
Para los muelles de la máquina se han usado perchas de alambre con un grosor suficiente para que no se doblen.

2.2 Circuito:

El circuito que hace que la maquina funcione es el siguiente:

Como se puede ver ha sido necesario la utilización de dos arduinos, esto se explicará más adelante.

2.3. Código:

/*
  LiquidCrystal Library – Hello World
 Demonstrates the use a 16×2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are
compatible with the
 Hitachi HD44780 driver. There are many of them
out there, and you
 can usually tell them by the 16-pin interface.
 This sketch prints «Hello World!» to
the LCD
 and shows the time.
  The circuit:
 * LCD RS pin to digital pin 41
 * LCD Enable pin to digital pin 43
 * LCD D4 pin to digital pin 37
 * LCD D5 pin to digital pin 35
 * LCD D6 pin to digital pin 33
 * LCD D7 pin to digital pin 31
 * LCD R/W pin to ground
 * LCD VSS pin to ground
 * LCD VCC pin to 5V
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 22 Nov 2010
 by Tom Igoe
 modified 7 Nov 2016
 by Arturo Guadalupi
 This example code is in the public domain.
 http://www.arduino.cc/en/Tutorial/LiquidCrystalHelloWorld
*/
//
include the library code:
#include
<LiquidCrystal.h>
//
initialize the library by associating any needed LCD interface pin
// with
the arduino pin number it is connected t
const
int rs = 41, en = 43, d4 = 37, d5 = 35, d6 = 33, d7 = 31;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
/**
 *
—————————————————————————-
 * This is a MFRC522 library example; see
https://github.com/miguelbalboa/rfid
 * for further details and other examples.
 *
 * NOTE: The library file MFRC522.h has a lot of
useful info. Please read it.
 *
 * Released into the public domain.
 *
—————————————————————————-
 * This sample shows how to read and write data
blocks on a MIFARE Classic PICC
 * (= card/tag).
 *
 * BEWARE: Data will be written to the PICC, in
sector #1 (blocks #4 to #7).
 *
 *
 *
 */
#include
<SPI.h>
#include
<MFRC522.h>
constexpr
uint8_t RST_PIN = 5;     // Configurable,
see typical pin layout above
constexpr
uint8_t SS_PIN = 53;     // Configurable,
see typical pin layout above
MFRC522
mfrc522(SS_PIN, RST_PIN);   // Create
MFRC522 instance.
MFRC522::MIFARE_Key
key;
long
tiempo = 0;
int
motor1 = 22;
int
motor2 = 23;
int
motor3 = 24;
int
motor4 = 25;
void
setup() {
  pinMode(A15,INPUT);
  pinMode(A14,INPUT);
  pinMode(A13,INPUT);
  pinMode(A12,INPUT);
 
  pinMode(motor1,OUTPUT);
  pinMode(motor2,OUTPUT);
  pinMode(motor3,OUTPUT);
  pinMode(motor4,OUTPUT);
  digitalWrite(motor1, LOW);
  digitalWrite(motor2, LOW);
  digitalWrite(motor3, LOW);
  digitalWrite(motor4, LOW);
 
  // set up the LCD’s number of columns and
rows:
  lcd.begin(16, 2);
  lcd.setCursor(0,
0);
  mostrarSeleccion();
 // print the number of seconds since reset:
    Serial.begin(9600); // Initialize serial
communications with the PC
    while (!Serial);    // Do nothing if no serial port is opened
(added for Arduinos based on ATMEGA32U4)
    SPI.begin();        // Init SPI bus
    mfrc522.PCD_Init(); // Init MFRC522 card
    // Prepare the key (used both as key A and
as key B)
    // using FFFFFFFFFFFFh which is the default
at chip delivery from the factory
    for (byte i = 0; i < 6; i++) {
        key.keyByte[i] = 0xFF;
    }
   
    Serial.println(F(«BEWARE: Data will be
written to the PICC, in sector #1»));
}
void mostrarSeleccion(){
      lcd.clear();
     
lcd.print(«Seleccione un»);
     
lcd.setCursor(0,1);
     
lcd.print(«Producto»);
  }
int
usoNFC(int precioEntero, int precioDecimal) {
  // Look for new cards
    if ( ! mfrc522.PICC_IsNewCardPresent())
        return 0;
    // Select one of the cards
    if ( ! mfrc522.PICC_ReadCardSerial())
        return 0;
    // Show some details of the PICC (that is:
the tag/card)
    Serial.print(F(«Card UID:»));
    dump_byte_array(mfrc522.uid.uidByte,
mfrc522.uid.size);
    Serial.println();
    MFRC522::PICC_Type piccType =
mfrc522.PICC_GetType(mfrc522.uid.sak);
    // Check for compatibility
    if (   
piccType != MFRC522::PICC_TYPE_MIFARE_MINI
        &&  piccType != MFRC522::PICC_TYPE_MIFARE_1K
        &&  piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
        Serial.println(F(«This code only
works with MIFARE Classic cards.»));
        return 0;
    }
    // that is: sector #1, covering block #4 up
to and including block #7
    byte sector         = 1;
    byte blockAddr      = 4;
    byte dataBlock[]    = {
        0, 0, 0, 0, //  parte entera, parte decimal, 0, 0
        0, 0, 0, 0,
//  0, 0, 0, 0
        0, 0, 0, 0,
//  0, 0, 0, 0
        0, 0, 0,
0  // 
0, 0, 0, 0
    };
    byte
trailerBlock   = 7;
    MFRC522::StatusCode status;
    byte buffer[18];
    byte size = sizeof(buffer);
    // Authenticate using key A
    Serial.println(F(«Authenticating using
key A…»));
    status = (MFRC522::StatusCode)
mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock,
&key, &(mfrc522.uid));
    if (status != MFRC522::STATUS_OK) {
        Serial.print(F(«PCD_Authenticate()
failed: «));
       
Serial.println(mfrc522.GetStatusCodeName(status));
        return 0;
    }
    // Read data from the block
    Serial.print(F(«Reading data from
block «)); Serial.print(blockAddr);
    Serial.println(F(» …»));
    status = (MFRC522::StatusCode)
mfrc522.MIFARE_Read(blockAddr, buffer, &size);
    if (status != MFRC522::STATUS_OK) {
        Serial.print(F(«MIFARE_Read()
failed: «));
       
Serial.println(mfrc522.GetStatusCodeName(status));
        return 0;
    }
    Serial.print(F(«Data in block
«)); Serial.print(blockAddr); Serial.println(F(«:»));
    dump_byte_array(buffer, 16);
Serial.println();
    Serial.println();
    int aux = pagar(dataBlock, buffer[0],
buffer[1], precioEntero, precioDecimal);
    if ( aux == 1) {
   
        // Write data to the block
        Serial.print(F(«Writing data into
block «)); Serial.print(blockAddr);
        Serial.println(F(» …»));
        dump_byte_array(dataBlock, 16);
Serial.println();
        status = (MFRC522::StatusCode)
mfrc522.MIFARE_Write(blockAddr, dataBlock, 16);
        if (status != MFRC522::STATUS_OK) {
            Serial.print(F(«MIFARE_Write()
failed: «));
           
Serial.println(mfrc522.GetStatusCodeName(status));
            return 0;
        }
        Serial.println();
   
        // Read data from the block (again,
should now be what we have written)
        Serial.print(F(«Reading data from
block «)); Serial.print(blockAddr);
        Serial.println(F(» …»));
        status = (MFRC522::StatusCode)
mfrc522.MIFARE_Read(blockAddr, buffer, &size);
        while (status != MFRC522::STATUS_OK) {
            Serial.print(F(«MIFARE_Read()
failed: «));
           
Serial.println(mfrc522.GetStatusCodeName(status));
            return 0;
        }
        Serial.print(F(«Data in block
«)); Serial.print(blockAddr); Serial.println(F(«:»));
        dump_byte_array(buffer, 16);
Serial.println();
   
        // Check that data in block is what we
have written
        // by counting the number of bytes that
are equal
        Serial.println(F(«Checking
result…»));
        byte count = 0;
        for (byte i = 0; i < 16; i++) {
            // Compare buffer (= what we’ve
read) with dataBlock (= what we’ve written)
            if (buffer[i] == dataBlock[i])
                count++;
        }
        Serial.print(F(«Number of bytes
that match = «)); Serial.println(count);
        if (count == 16) {
            Serial.println(F(«Success
:-)»));
        } else {
            Serial.println(F(«Failure, no
match :-(«));
            Serial.println(F(«  perhaps the write didn’t work
properly…»));
            return 0;
        }
        Serial.println();
    }
    // Halt PICC
    mfrc522.PICC_HaltA();
    // Stop encryption on PCD
    mfrc522.PCD_StopCrypto1();
    String entero = String(buffer[0]);
    String decimal = String(buffer[1]);
    String cadena = «Saldo:
«+entero+»,»+decimal+» eur»;
    lcd.clear();
    lcd.print(cadena);
    delay(1500);
    if ( aux == 1) {
        return 1;
    } else {
        return 0;
    }
}
int
pagar(byte *dataBlock, byte entero, byte decimal, byte precioEntero, byte
precioDecimal) {
    if (entero >= precioEntero) {
        if (entero == precioEntero) {
            if (decimal >= precioDecimal) {
              dataBlock[0] = 0;
              dataBlock[1] = decimal –
precioDecimal;
              return 1;
            } else {
                lcd.clear();
                lcd.print(«Dinero»);
                lcd.setCursor(0,1);
               
lcd.print(«insuficiente»);
                delay(1500);
                return 0;
            }
        }
        if (decimal >= precioDecimal) {
            dataBlock[0] = entero –
precioEntero;
           
dataBlock[1] = decimal – precioDecimal;
            return 1;
        } else {
            dataBlock[0] = entero –
precioEntero – 1;
            dataBlock[1] = decimal + 100 –
precioDecimal;
            return 1;
        }
    } else {
        lcd.clear();
        lcd.print(«Dinero»);
        lcd.setCursor(0,1);
       
lcd.print(«insuficiente»);
        delay(1500);
        return 0;
    }
}
void
dump_byte_array(byte *buffer, byte bufferSize) {
    for (byte i = 0; i < bufferSize; i++) {
        Serial.print(buffer[i], DEC);
        Serial.print(» «);
    }
}
void
soltarProducto(int motor) {
    digitalWrite(motor,HIGH);
    delay(100);
    digitalWrite(motor,LOW);
    delay(3000);
}
void
loop() {
      if (digitalRead(A15)==HIGH){
            lcd.clear();
            lcd.print(«Precio:
1,50 eur»);
           
delay(1500);
           
lcd.clear();
           
lcd.print(«Acerque la «);
           
lcd.setCursor(0,1);
           
lcd.print(«tarjeta»);
            tiempo
= millis();
            int aux
= 0;
            aux =
usoNFC(1,50);
           
while((aux != 1)&&(tiempo + 5000 > millis())) {
                aux
= usoNFC(1,50);
            }
            if (aux
== 1) {
               
lcd.clear();
               
lcd.print(«Que lo disfrute»);
               
soltarProducto(motor4);
            }
           
mostrarSeleccion();
      }
      if
(digitalRead(A14)==HIGH){
           
lcd.clear();
           
lcd.print(«Precio: 1,00 eur»);
           
delay(1500);
           
lcd.clear();
           
lcd.print(«Acerque la «);
           
lcd.setCursor(0,1);
           
lcd.print(«tarjeta»);
            tiempo
= millis();
            int aux
= usoNFC(1,00);
           
while((aux != 1)&&(tiempo + 5000 > millis())) {
                aux
= usoNFC(1,00);
            }
            if (aux
== 1) {
               
lcd.clear();
               
lcd.print(«Que lo disfrute»);
               
soltarProducto(motor3);
            }
           
mostrarSeleccion();
      }
      if
(digitalRead(A13)==HIGH){
           
lcd.clear();
           
lcd.print(«Precio: 2,30 eur»);
           
delay(1500);
           
lcd.clear();
           
lcd.print(«Acerque la «);
           
lcd.setCursor(0,1);
           
lcd.print(«tarjeta»);
            tiempo
= millis();
            int aux
= usoNFC(2,30);
           
while((aux != 1)&&(tiempo + 5000 > millis())) {
                aux
= usoNFC(2,30);
            }
            if (aux
== 1) {
               
lcd.clear();
               
lcd.print(«Que lo disfrute»);
               
soltarProducto(motor2);
            }
           
mostrarSeleccion();
      }
      if
(digitalRead(A12)==HIGH){
           
lcd.clear();
           
lcd.print(«Precio: 0,85 eur»);
           
delay(1500);
           
lcd.clear();
           
lcd.print(«Acerque la «);
            lcd.setCursor(0,1);
           
lcd.print(«tarjeta»);
            tiempo
= millis();
            int aux
= usoNFC(0,85);
           
while((aux != 1)&&(tiempo + 5000 > millis())) {
                aux
= usoNFC(0,85);
            }
            if (aux
== 1) {
               
lcd.clear();
               
lcd.print(«Que lo disfrute»);
               
soltarProducto(motor1);
            }
           
mostrarSeleccion();
      }
  
}

3. Problemas y soluciones a estos.

En esta sección contaremos
algunos de los problemas que hemos tenido en la realización del proyecto.
·        Elección de motores: la elección de los
motores adecuados requirió tiempo, ya que no sabíamos exactamente cuales
escoger, algunas páginas de internet recomendaban algunos servomotores que tenían
un coste muy alto, así que decidimos probar a usar unos motores DC que no
tuvieran una gran velocidad de rotación, de tal modo que, añadiendo el factor
de que podemos controlar el tiempo de giro, elegimos unos motores bastante
económicos y que finalmente funcionaban tal y como queríamos.
·        Uso de pantalla LCD: nos dimos cuenta que
si usábamos una pantalla LCD, no íbamos a poder usar el “arduino UNO”, ya que
se quedaba “pequeño”, por lo que finalmente decimos comprar un “elegoo MEGA”,
ya que tiene más entradas y salidas, que el primero.
·        Problema con NFC + motores y uso de segundo
arduino:
cuando unimos todos los componentes del circuito (nfc, motores y pantalla),
una vez que se seleccionaba un producto y se pagaba, el arduino se bloqueaba y
ya no leía más las tarjetas para realizar el pago o la pantalla LCD recibía y
escribía símbolos extraños. Esto se producía por el funcionamiento del motor,
la posible causa sería que el motor producía un ruido electromagnético que
hacía recibir señales extrañas al arduino y este se bloqueaba. Para
solucionarlo se decidió que los motores estuviesen controlados por el arduino
UNO y la pantalla y el NFC por el MEGA, de manera que se mandase una señal
desde el MEGA al UNO indicando que motor tiene que girar, y ya que las
operaciones que tiene que hacer el arduino UNO son sencillas, no se producía un
bloqueo.

4. Conclusiones y posibles mejoras.

El proyecto de la máquina de
vending nos ha resultado tan difícil como considerábamos en un principio, y ha
requerido bastantes horas de desarrollo. Habíamos pensado en una serie de
mejoras para esta, sin embargo, ha faltado tiempo para poder llevarlo a cabo.
Para empezar, nuestra intención
era que la iluminación interior de la máquina estuviese regulada también con
arduino, de tal forma que si seleccionas el botón “1”, se ilumine su celda
correspondiente, y así con todas.
La máquina expendedora podría ser
más grande y tener más “celdas” sin embargo, consideramos que esto es absurdo,
ya que con cuatro es suficiente para mostrar el manejo del código y los
elementos electrónicos.
Por último, una posible mejora
que se nos había ocurrido, es que en vez de que el artículo caiga directamente
al fondo de la máquina para cogerlo, una “cesta” lo recogiese y lo depositase
en una rampilla de tal modo que el artículo saliese de la máquina y fuese más
cómodo de coger, sin embargo, para realizar esto, llegamos a la conclusión de
que necesitaríamos más tiempo, por lo que no lo vimos viable.
Para concluir la descripción de
nuestro “Venduino” debemos destacar, que desde bajo nuestro punto de vista
consideramos que es un proyecto bastante completo, ya que, además de ser algo
bastante llamativo visualmente, también utiliza varios componentes electrónicos
que se comunican entre sí, además de que el código para hacerlos funcionar es
relativamente complejo, puesto que los componentes deben interactuar entre
ellos y la cantidad de estos es elevada.

5. Video demostración.

Video Demostración Venduino

También te podría gustar...

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *