

INTRODUCCIÓN
Hace un tiempo atrás publique un video sobre la creación de un dispensador de agua automático comercial, en dicho proyecto había varios detalles que añadir y mejorar,
- La anterior versión solo aceptaba un solo tipo de monedas. En esta nueva versión se consideró que acepte hasta 6 tipos de monedas.
- La anterior versión no tenía la opción de lavado, en cambio esta nueva versión si tiene.
- La versión anterior no tenía un sensor de nivel de agua, en esta versión si hemos integrado para que haya un límite producto. Cosa que el cliente no insertará más monedas ya que en la pantalla aparecerá un aviso.
- La versión anterior no tenía un límite de inserción de monedas, es decir, la maquina seguía aceptando infinidad de monedas sin importar el máximo valor. En cambio en este, el máximo valor es de 8 soles. A partir de este último valor la maquina ya no recibirá más monedas.
- Por último, pero no menos importante, se ha agradado directamente un conector para las salidas, sin necesidad de hacer puente.
Bien, por el momento estos serían las mejoras que hemos hecho, seguramente más adelante seguiremos mejorando, como por ejemplo agregar un menú de configuración de parámetros.
LISTA DE COMPONENTES
| Quantity | Comment | Designator | Footprint | Value | Supplier Part | Supplier |
| 1 | 470uF | C1 | CAP-SMD_BD10.0-L10.3-W10.3-LS11.3-FD | 470uF | C310845 | LCSC |
| 1 | 1uF | C2 | C1206 | 1uF | C1848 | LCSC |
| 19 | 100nF | C3,C4,C5,C6,C7,C8,C9,C10,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22 | C0603 | 100nF | C14663 | LCSC |
| 1 | 220uF | C11 | CAP-SMD_BD6.3-L6.6-W6.6-LS7.2-R-RD | 220uF | C99836 | LCSC |
| 1 | HCZZ0126-4 | CN1 | CONN-TH_XH-4A-1 | C7433754 | LCSC | |
| 1 | PJ-3136-B | CN2 | AUDIO-TH_PJ-3136-B | C381131 | LCSC | |
| 4 | SS210 | D1,D2,D3,D4 | SMA_L4.3-W2.6-LS5.2-RD | C14996 | LCSC | |
| 6 | M7 | D5,D6,D7,D8,D9,D10 | SMA_L4.3-W2.6-LS5.2-RD | C95872 | LCSC | |
| 1 | BSMD1206-100-24V | F1 | F1206 | C910830 | LCSC | |
| 1 | 2.54-1x6P直针 | H1 | HDR-TH_6P-P2.54-V-M-1 | C37208 | LCSC | |
| 1 | KH-2.54PH180-1X2P-L11.5 | H2 | HDR-TH_2P-P2.54-V-M | C2905434 | LCSC | |
| 4 | TSA063G60-250 | KEY1,KEY2,KEY3,KEY4 | KEY-SMD_4P-L6.1-W6.1-P4.50-LS9.0 | C294566 | LCSC | |
| 1 | 68uH | L1 | IND-SMD_L7.1-W6.6-1 | 68uH | C2983094 | LCSC |
| 13 | KT-0805G | LED1,LED2,LED3,LED4,LED5,LED6,LED7,LED8,LED9,LED10,LED11,LED12,LED13 | LED0805-R-RD | C2297 | LCSC | |
| 11 | WJ128V-5.0-2P | P1,P2,P3,P4,P5,P6,P7,P9,P10,P11,P12 | CONN-TH_2P-P5.00_WJ128V-5.0-2P | C8269 | LCSC | |
| 4 | D882 Y档160~320 | Q1,Q2,Q3,Q4 | SOT-89-3_L4.5-W2.5-P1.50-LS4.2-BR | C9634 | LCSC | |
| 6 | 2.2kΩ | R1,R2,R3,R4,R5,R6 | R0805 | 2.2kΩ | C17520 | LCSC |
| 20 | 10kΩ | R7,R8,R9,R10,R11,R12,R13,R14,R29,R30, R33,R34,R35,R36,R37,R38,R45,R46,R47,R48 |
R0603 | 10kΩ | C25804 | LCSC |
| 2 | 1.2kΩ | R15,R16 | R0805 | 1.2kΩ | C17379 | LCSC |
| 19 | 1kΩ | R17,R18,R19,R20,R21,R22,R23,R24,R25, R26,R27,R31,R32,R43,R44,R49,R50,R51,R52 |
R0603 | 1kΩ | C21190 | LCSC |
| 1 | 1MΩ | R28 | R0603 | 1MΩ | C22935 | LCSC |
| 4 | 330Ω | R39,R40,R41,R42 | R0805 | 330Ω | C17630 | LCSC |
| 4 | 4.7kΩ | R53,R54,R55,R56 | R0603 | 4.7kΩ | C23162 | LCSC |
| 15 | Test-Point | TP1,TP2,TP3,TP4,TP5,TP6,TP7,TP8, TP9,TP10,TP11,TP12,TP13,TP14,TP15 |
Test-Point-0.5mm | |||
| 10 | EL357N(C)(TA)-G | U1,U2,U3,U4,U5,U6,U10,U11,U12,U13 | OPTO-SMD-4_L4.4-W4.1-P2.54-LS7.0-TL | C29981 | LCSC | |
| 1 | XL1509-5.0E1 | U7 | SOIC-8_L5.0-W4.0-P1.27-LS6.0-BL | C61063 | LCSC | |
| 1 | ATMEGA328P-AU | U8 | TQFP-32_L7.0-W7.0-P0.80-LS9.0-BL | C14877 | LCSC | |
| 1 | CH340C | U9 | SOP-16_L10.0-W3.9-P1.27-LS6.0-BL | C84681 | LCSC | |
| 1 | MP3 PLAYER | U14 | mp3 player | |||
| 1 | LM358DR2G | U15 | SOIC-8_L5.0-W4.0-P1.27-LS6.0-BL | C7950 | LCSC | |
| 1 | 74HC14D,653 | U16 | SOIC-14_L8.7-W3.9-P1.27-LS6.0-BL | C5605 | LCSC | |
| 1 | USB-TYPE-C-018 | USB1 | USB-C_SMD-TYPE-C-31-M-12 | C2927038 | LCSC | |
| 1 | 16MHz | X1 | OSC-SMD_3P-L3.2-W1.3-P0.95-L | 16MHz | C32180 | LCSC |
PASOS PARA SUBIR UN PROGRAMA
PASO 1 : SUBIR PROGRAMA BOOTLOADER A UN ARDUINO UNO
Primero subimos este código BOOTLOADER a un arduino UNO como normalmente subimos cualquier programa a nuestra placa arduino UNO.
PASO 2 : CABLEADO PARA SUBIR GESTOR DE ARRANQUE (BOOTLOADER)
Despues de haber subido el programa anterior, ahora vamos aquemar el gestor de arranque al nuevo microcontrolador que tiene nuestro plc.
Recuerden que para poder usar un microcontrolador nuevo (atmega328P-AU), es necesario subir un gestor de arranque como también llamado “BOOTLOADER”, esto nos facilitará subir programas en futuras ocasiones. Especialmente cuando se quiere programar desde el IDE de arduino.
finalmente para quemar el bootloader se tendrá que realizar a través de los pines ISP, que prácticamente serían los pines [(MOSI=PIN 11) (MISO = PIN 12) (SCK=PIN 13) (Slave=PIN 10)]. Para subir y quemar el gestor de arranque necesitaremos un arduino UNO ó MEGA y realizar las siguientes conexiones (ARDUINO UNO – PLC LOGO demo). OJO que este paso solo se hace una sola vez.
CODIGO ARDUINO
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
//============================== PHYSICAL INPUTS ================================================
const int in1 = 2; // Sensor de flujo
const int in2 = 3; // Coin
const int in3 = 4; // pulsador de lavado
const int in4 = 5; // pulsador de start de producto
const int in5 = 6; // pulsador de stop/start
const int in6 = 7; // Sensor de agua
int in7 = A6; // IN7
int in8 = A7; // IN8
//☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼ SWITCH MENUS ☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼
const int left = 8; //izquierda
const int right = 13; //derecha
const int intro = 9; // ok
//===============================================================================================
//============================== TRANSISTOR OUTPUTS ============================================
const int M_LAV = 14; // BOMBA PARA LAVADO
const int M_AGUA = 15; // BOMBA PARA AGUA "producto principal"
const int MONEDERO = 16; // Receptor de monedas
const int Reserva = 17; // SALIDA DE RESERVA
//===============================================================================================
//============================== SENSORS DATA ==================================================
volatile double flujo; // variable que guarda los pulsos
int filling = 0; // variable para captar esos pulsos del sensor de flujo en numeros enteros
boolean B_lavAct = false;
//===============================================================================================
//================================== TIMES =====================================================
int t1 = 0;
int t2 = 0;
int t3 = 0;
int t_lav = 3; // definir tiempo de lavado - ahora 3 seg
int t_est = 4; // definir tiempo de esterilizado - ahora 4seg
int t_thx = 5; // tiempo mensaje final 5seg
//===============================================================================================
boolean lcdClear = false; //TO lcd clear
//================================= ESTATE DATAS ===============================================
boolean E0, E1, E2, E3, E4, E5 = false; // VARIABLES DE ESTADOS
boolean T01, T12, T23, T34, T45, T50 = false; // VARIABLES DE TRANSICIONES
//===============================================================================================
//============================== COIN RECEIVER DATA ============================================
int contadorPulsos = 0; // Variable para contar los pulsos
int acumuladoSoles = 0; // Variable para el monto acumulado en Soles
//===============================================================================================
//==================================== STOP DATA ===============================================
byte STOPvalue = 0; // Variable para contar los pulsos
byte STOPlastState = 0;
boolean STOPstate = false; // Variable para el monto acumulado en Soles
//===============================================================================================
void setup() {
lcd.init();
lcd.backlight();
lcd.clear();
Serial.begin(9600);
//☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼ EXTERNAL INPUTS ☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼
pinMode(left, INPUT);
pinMode(intro, INPUT);
pinMode(right, INPUT);
pinMode(in3, INPUT);
pinMode(in4, INPUT);
pinMode(in5, INPUT);
pinMode(in6, INPUT);
pinMode(in7, INPUT);
pinMode(in8, INPUT);
flujo = 0; // Begin with zero, flow sen
attachInterrupt(0, flujo_pulse, RISING); //DIGITAL Pin 2: Interrupt 0 || to flow sensor
attachInterrupt(1, coin_pulse, RISING); //DIGITAL Pin 3: Interrupt 1 || to coin inputs
pinMode(M_LAV, OUTPUT);
pinMode(M_AGUA, OUTPUT);
pinMode(MONEDERO, OUTPUT);
pinMode(Reserva, OUTPUT);
digitalWrite(MONEDERO, 1);
}
void loop() {
int B_lav = digitalRead(in3); // sensor de presencia
int star = digitalRead(in4); // boton lavado
int STOP = digitalRead(in5);
int sen = digitalRead(in6);
if (STOP != STOPlastState) {
if (STOP == LOW) {
STOPvalue++;
}
}
STOPlastState = STOP;
switch (STOPvalue) {
case 1:
STOPstate = true;
break;
case 2:
STOPstate = false;
STOPvalue = 0;
break;
}
if (sen == 0) {
digitalWrite(MONEDERO, 0);
lcd.setCursor(0, 0);
lcd.print(" NO HAY SUFICIENTE "); // aqui cambiar la bienvenida
lcd.setCursor(2, 1);
lcd.print(" AGUA ");
lcd.setCursor(1, 2);
lcd.print("VUELVA MAS TARDE ");
lcd.setCursor(0, 3);
lcd.print(" POR FAVOR. ");
} else {
if (E0 == true || E1 == true) {
if (acumuladoSoles < 8) {
acumuladoSoles += contadorPulsos; // acumulamos los pulsos
contadorPulsos = 0; // reset pulse
}
}
//█████████████████████████████████████████ INICIALIZACION █████████████████████████████████████████████
if ((!E1 && !E2 && !E3 && !E4 && !E5) == true) {
E0 = true;
}
//█████████████████████████████████████████ TRANSITION █████████████████████████████████████████████
//from
if (E0 == true && (acumuladoSoles >= 1 && acumuladoSoles <= 8)) {
lcd.clear();
T01 = true;
T50 = false;
}
if (E1 == true && B_lav == true && B_lavAct == true) {
lcd.clear();
T12 = true;
T01 = false;
}
if (E2 == true && t1 == t_lav) {
lcd.clear();
T23 = true;
T12 = false;
}
if (E3 == true && star == true) {
lcd.clear();
T34 = true;
T23 = false;
}
if (E4 == true && (filling == 2 || filling == 4 || filling == 8)) {
lcd.clear();
T45 = true;
T34 = false;
}
if (E5 == true && t3 == t_thx) {
lcd.clear();
T50 = true;
T45 = false;
}
//█████████████████████████████████████████ ETAPA █████████████████████████████████████████████
if (E0 && T01 == true) {
E0 = false;
E1 = true;
}
if (E1 && T12 == true) {
E1 = false;
E2 = true;
}
if (E2 && T23 == true) {
E2 = false;
E3 = true;
}
if (E3 && T34 == true) {
E3 = false;
E4 = true;
}
if (E4 && T45 == true) {
E4 = false;
E5 = true;
}
if (E5 && T50 == true) {
E5 = false;
E0 = true;
}
//█████████████████████████████████████████ ACTUADORES █████████████████████████████████████████████
if (E0 == true) { //▄▄▄▄▄▄▄▄▄▄▄▄ E0 REPOSO ▄▄▄▄▄▄▄▄▄▄▄▄
digitalWrite(M_LAV, 0);
digitalWrite(M_AGUA, 0);
flujo = 0;
filling = 0;
if (acumuladoSoles == 0) {
if (acumuladoSoles < 8) digitalWrite(MONEDERO, 1);
lcd.setCursor(0, 0);
lcd.print("****BIENVENIDOS*****"); // aqui cambiar la bienvenida
lcd.setCursor(2, 1);
lcd.print("INSERTE MONEDAS");
lcd.setCursor(1, 2);
lcd.print("SEGUN LOS PRECIOS");
lcd.setCursor(0, 3);
lcd.print(" FIJADOS. ");
}
}
if (E1 == true) { //▄▄▄▄▄▄▄▄▄▄▄▄ E1 COIN RECEIVER ▄▄▄▄▄▄▄▄▄▄▄▄
if (acumuladoSoles < 8) digitalWrite(MONEDERO, 1);
else digitalWrite(MONEDERO, 0); // desactivamos la alimentacion del receptor de monedas
lcd.setCursor(3, 0);
lcd.print("TIENE UN SALDO");
lcd.setCursor(0, 1);
lcd.print("DE: S/. ");
lcd.print(acumuladoSoles);
if (acumuladoSoles == 2 || acumuladoSoles == 4 || acumuladoSoles == 8) {
B_lavAct = true;
if (acumuladoSoles == 2) {
lcd.setCursor(10, 1);
lcd.print("= 500 mL ");
lcd.setCursor(0, 2);
lcd.print("Presione lavado");
lcd.setCursor(0, 3);
lcd.print("PARA CONTINUAR");
}
if (acumuladoSoles == 4) {
lcd.setCursor(10, 1);
lcd.print(" = 1 Ltr ");
lcd.setCursor(0, 2);
lcd.print("Presione lavado");
lcd.setCursor(0, 3);
lcd.print("PARA CONTINUAR");
}
if (acumuladoSoles == 8) {
lcd.setCursor(10, 1);
lcd.print(" = 2 Ltr. ");
lcd.setCursor(0, 2);
lcd.print("Presione lavado");
lcd.setCursor(0, 3);
lcd.print("PARA CONTINUAR");
}
} else {
lcd.setCursor(1, 2);
lcd.print("Cantidad no valido");
lcd.setCursor(0, 3);
lcd.print("INSERTE MAS MONEDAS");
B_lavAct = false;
}
}
if (E2 == true) { //▄▄▄▄▄▄▄▄▄▄▄▄ E2 CLEAN PROCESS ▄▄▄▄▄▄▄▄▄▄▄▄▄
digitalWrite(MONEDERO, 0);
digitalWrite(M_LAV, 1);
lcd.setCursor(1, 1);
lcd.print("***** LAVANDO ****");
t3 = 0;
t1++;
delay(1000);
}
if (E3 == true) { //▄▄▄▄▄▄▄▄▄▄▄▄ E3 PRESS START ▄▄▄▄▄▄▄▄▄▄▄▄▄
digitalWrite(MONEDERO, 0);
digitalWrite(M_LAV, 0);
lcd.setCursor(5, 0);
lcd.print("Press START ");
lcd.setCursor(1, 2);
lcd.print("PARA LLENAR AGUA");
flujo = 0;
}
if (E4 == true) { //▄▄▄▄▄▄▄▄▄▄▄▄ E4 FILLING ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
digitalWrite(MONEDERO, 0);
if (STOPstate) digitalWrite(M_AGUA, 0);
else digitalWrite(M_AGUA, 1);
if (acumuladoSoles == 2) {
lcd.setCursor(5, 0);
lcd.print("LLENANDO...");
lcd.setCursor(3, 1);
lcd.print("500 mL de Producto");
lcd.setCursor(0, 3);
lcd.print("PROCESO Ltrs. = ");
lcd.print(flujo);
if (flujo >= 0.5) {
filling = 2;
}
}
if (acumuladoSoles == 4) {
lcd.setCursor(5, 0);
lcd.print("LLENANDO...");
lcd.setCursor(3, 1);
lcd.print("1 Litro de AGUA");
lcd.setCursor(0, 3);
lcd.print("PROCESO Ltrs. = ");
lcd.print(flujo);
if (flujo >= 1) {
filling = 4;
}
}
if (acumuladoSoles == 8) {
lcd.setCursor(5, 0);
lcd.print("LLENANDO...");
lcd.setCursor(3, 1);
lcd.print("2 Litros de AGUA");
lcd.setCursor(0, 3);
lcd.print("PROCESO Ltrs. = ");
lcd.print(flujo);
if (flujo >= 2) {
filling = 8;
}
}
}
if (E5 == true) { //▄▄▄▄▄▄▄▄▄▄▄▄ E5 COMPLETE ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
digitalWrite(M_AGUA, 0);
lcd.setCursor(1, 0);
lcd.print(" COMPLETO, LLENO");
lcd.setCursor(3, 2);
lcd.print("MUCHAS GRACIAS");
acumuladoSoles = 0;
t1 = 0;
t2 = 0;
t3++;
delay(1000);
}
if (contadorPulsos) { // Limpia la pantalla cada vez que se detecta un pulso
lcd.clear();
}
}
}
void flujo_pulse() { //■■■■■■■■■■■■■■■■■■ FLOW SENSOR DETECT ■■■■■■■■■■■■■■■■■■
flujo += 1.0 / 5350.0; // este es para ir ajustando la cantidad de litros
}
void coin_pulse() { //■■■■■■■■■■■■■■■■■■ COIN PULSE DETECT ■■■■■■■■■■■■■■■■■■
contadorPulsos++;
}
1 comentario. Dejar nuevo
GRACIAS MAESTRO POR SU APORTE , ME GUSTARIA QUE NOS EXPLIQUE LA PROGRAMACION DEL PROGRAMA GRACIAS
ME GUSTARIA CONVERSAR CON USTED SI ME PODRIA MANDAR SU NUMERO DE TELEFONO , EL MIO ES 956211392