PROYECTO FINAL DRINKDUINO

PROYECTO FINAL DRINKDUINO

La propuesta para final de curso era elaborar un proyecto final que englobase todo aquello que hemos ido aprendiendo durante él. Por ello, decidimos yo y tres compañeros más centrarnos en un proyecto algo más complicado, en el que cada uno pudiésemos aportar ideas distintas. De todas ellas, surgió el proyecto del Drinkduino.
En esta página explicamos un poco para facilitar su entendimiento.



IMPORTANTE: el código requiere la librería del sensor de proximidad HC-SR04. Puede descargarse aquí.


ARCHIVO DEL CÓDIGO






CÓMO MODIFICAR LA CANTIDAD DE LÍQUIDO Y LA POSICIÓN DEL VASO


Como ya habíamos previsto por falta de tiempo, que era muy complicado crear una interfaz que permitiese al usuario modificar a su gusto diferentes parámetros, hemos decidido crear un archivo en el que la programación aparece clara, y con ayuda de estos pasos serás capaz de adecuar el programa a las características de la coctelera real.


Para modificar el líquido que sale cuando pulsamos un botón vamos a explicar como funcionan los botones. Tenemos 8 botones, de los cuales los cuatro primeros expulsan un solo líquido correspondiente a su válvula (botón 1 - válvula 1). Sin embargo, los cuatro restantes (botones 5-8) expulsan mezclas de líquidos (botón 5 - válvulas 1 y 2) (botón 6 - válvulas 2 y 3) (botón 7 - válvulas 3 y 4) (botón 8 - válvulas 1, 2, 3 y 4). El volumen de líquido que sale viene dado por el tiempo que está abierta la válvula, y por ello las variables que vamos a modificar son "tiempos de apertura".

Ve al principio de la programación y busca esto:




//PARÁMETROS: Cambie los diferentes parámetros para configurar los botones. Los parametros que se presentan son variables que cambian el tiempo de apertura de las válvulas de los depósitos.
//El tiempo aparece expresado en milisegundos.


float t1 = 1000; //Tiempo apertura primer líquido
float t2 = 1000; //Tiempo apertura segundo líquido
float t3 = 1000; //Tiempo apertura tercer líquido
float t4 = 1000; //Tiempo apertura cuarto líquido
float combina11 = 500; //Tiempo apertura liquido 1 de la mezcla 1
float combina12 = 500; //Tiempo apertura liquido 2 de la mezcla 1
float combina21 = 500; //Tiempo apertura líquido 1 de la mezcla 2
float combina22 = 500; //Tiempo apertura líquido 2 de la mezcla 2
float combina31 = 500; //Tiempo apertura líquido 1 de la mezcla 3
float combina32 = 500; //Tiempo apertura líquido 2 de la mezcla 3
float combina41 = 500; //Tiempo apertura líquido 1 de la mezcla 4
float combina42 = 500; //Tiempo apertura líquido 2 de la mezcla 4
float combina43 = 500; //Tiempo apertura líquido 3 de la mezcla 4
float combina44 = 500; //Tiempo apertura líquido 4 de la mezcla 4


Ahora hay que entender que el tiempo aparece en milisegundos (1000 milisegundos = 1 segundo). Las cuatro primeras variables son las que regulan la salida de los cuatro primeros botones (líquidos solos). Supongamos que nuestro vaso ideal se llena en 4 segundos. Para que pulsando uno de los botones el vaso se llenase tendríamos que hacer lo siguiente:

Cómo está: float t1 = 1000; //Tiempo apertura primer líquido
Cómo debería quedar: float t1 = 4000; //Tiempo apertura primer líquido


Esto se aplicaría con todos los botones. Solo hay que calcular cual es el tiempo que tiene que estar abierta la válvula para que el vaso se llene un volumen coherente. Sin embargo, las combinaciones son algo más complicadas. Si nuestro vaso ideal se sigue llenado en 4 segundos (4000 milisegundos), habrá que repartir ese tiempo entre cada uno de los líquidos de la combinación. Supongamos que el usuario quiere combinar dos zumos y queremos la mitad de cada uno. En las dos primeras válvulas colocamos nuestros zumos y por lo tanto deberíamos usar el botón cinco. Como queremos que sea la mitad de cada uno y deben sumar 4000, cada uno de los parámetros deberá ser sustituido por 2000.


Cómo está:

float combina11 = 500; //Tiempo apertura liquido 1 de la mezcla 1
float combina12 = 500; //Tiempo apertura liquido 2 de la mezcla 1

Cómo debería quedar:

float combina11 = 2000; //Tiempo apertura liquido 1 de la mezcla 1
float combina12 = 2000; //Tiempo apertura liquido 2 de la mezcla 1
Sin embargo, si queremos mezclar Coca-Cola y Ron, no es lógico que mezclemos la misma cantidad de Ron y de Coca-Cola. Por lo tanto siguiendo con el ejemplo de nuestro vaso, si queremos que el 20% sea Ron, (100% - 4000) (20% - 800). Por lo que quedaría así:


Cómo está:

float combina11 = 500; //Tiempo apertura liquido 1 de la mezcla 1
float combina12 = 500; //Tiempo apertura liquido 2 de la mezcla 1

Cómo debería quedar:

float combina11 = 3200; //Tiempo apertura liquido 1 de la mezcla 1
float combina12 = 800; //Tiempo apertura liquido 2 de la mezcla 1

En las demás combinaciones se hará lo propio. No obstante, en la última combinación, en la que salen todos los líquidos, hay que tener en cuenta que la suma de los cuatro tiene que ser en NUESTRO EJEMPLO NO APLICABLE A LA REALIDAD, 4000.

Para modificar la distancia a la que podemos colocar nuestro vaso, debes buscar esto:
//Constantes que indican el rango de distancias entre los que se puede situar el objeto (en centímetros). Cambiar distancia máxima y mínima para ajustar la distancia a la que colocar el vaso.
#define DISTANCIA_MAX 5
#define DISTANCIA_MIN 3

Esto es más sencillo que lo anterior. Tenemos una distancia máxima y una mínima (en centímetros) a la que se puede colocar el vaso. Por lo que si queremos que el vaso esté a una distancia comprendida entre 4 cm y 10 cm solo habría que hacer esta modificación:

Cómo está:
#define DISTANCIA_MAX 5
#define DISTANCIA_MIN 3

Cómo debería quedar:
#define DISTANCIA_MAX 10
#define DISTANCIA_MIN 4


Hay que tener en cuenta que los datos que usaremos para decidir la distancia a la que colocar el vaso, se decidirán cuando el sensor esté colocado en una posición fija en el montaje.


CÓDIGO FUENTE:


//PARÁMETROS: Cambie los diferentes parámetros para configurar los botones. Los parametros que se presentan son variables que cambian el tiempo de apertura de las válvulas de los depósitos.
//El tiempo aparece expresado en milisegundos.

float t1 = 1000; //Tiempo apertura primer líquido
float t2 = 1000; //Tiempo apertura segundo líquido
float t3 = 1000; //Tiempo apertura tercer líquido
float t4 = 1000; //Tiempo apertura cuarto líquido
float combina11 = 500; //Tiempo apertura liquido 1 de la mezcla 1
float combina12 = 500; //Tiempo apertura liquido 2 de la mezcla 1
float combina21 = 500; //Tiempo apertura líquido 1 de la mezcla 2
float combina22 = 500; //Tiempo apertura líquido 2 de la mezcla 2
float combina31 = 500; //Tiempo apertura líquido 1 de la mezcla 3
float combina32 = 500; //Tiempo apertura líquido 2 de la mezcla 3
float combina41 = 500; //Tiempo apertura líquido 1 de la mezcla 4
float combina42 = 500; //Tiempo apertura líquido 2 de la mezcla 4
float combina43 = 500; //Tiempo apertura líquido 3 de la mezcla 4
float combina44 = 500; //Tiempo apertura líquido 4 de la mezcla 4

//Constantes que indican el rango de distancias entre los que se puede situar el objeto (en centímetros). Cambiar distancia máxima y mínima para ajustar la distancia a la que colocar el vaso.
#define DISTANCIA_MAX 5
#define DISTANCIA_MIN 3

#include <Ultrasonic.h>


/*
HC-SR04 sensor de distancia:
VCC a Arduino 5V
GND a Arduino GND
Echo a Arduino pin 7
Trig a Arduino pin 8
*/
/*
Piezoelectrico
Cable negro a Arduino GND
Cable rojo a Arduino pin 2
*/

//Constante que define el número de válvulas en el circuito (una por cada líquido)
#define N_LIQUIDOS 4

Ultrasonic ultrasonic(8,7); //Sensor de proximidad. Trig PIN = 8. Echo PIN = 7
#define Valve1Pin 9 //Pin del LED de la válvula 1
#define Valve2Pin 10 //Pin del LED de la válvula 2
#define Valve3Pin 11 //Pin del LED de la válvula 3
#define Valve4Pin 12 //Pin del LED de la válvula 4
#define LEDEnRangoPin 6 //Pin del LED que se encenderá si hay un objeto a la distancia adecuada
//#define LEDNoRangoPin 6
#define PiezoelectricoPin 2 //Pin del piezoeléctrico que emitirá sonido cuando una mezcla sea servida

boolean enRango; //Variable global que indica si el objeto está situado en el rango permitido
int valvulas[N_LIQUIDOS] = {Valve1Pin, Valve2Pin, Valve3Pin, Valve4Pin}; //Array global que almacena los pines de las válvulas en orden. Posición 0 = primera válvula, etc

//Devuelve true si hay colocado un objeto entre la menor y la mayor distancia hasta el sensor
boolean estaEnRango(int distancia_min, int distancia_max) {
long distancia_medida;
distancia_medida = ultrasonic.Ranging(CM); //Calcula la distancia en cm (libreria Ultrasonic)

return (distancia_medida >= distancia_min && distancia_medida <= distancia_max);
}

/*Abre la electroválvula indicada durante el tiempo justo para expulsar una determinada cantidad (en mililitros) de líquido
void expulsarCantidad(int valvulaPin, int cantidad) {
if (cantidad > 0) { //La cantidad debe ser mayor que 0, de lo contrario no se hace nada
unsigned long milisegundos;
float segundos;
segundos = (float) cantidad / CAUDAL; //Tiempo en segundos que permanecerá abierta la válvula almacenado en coma flotante para no perder precisión
milisegundos = (unsigned long) (segundos * 1000); //Conversión a milisegundos (con casting a long)
digitalWrite(valvulaPin, HIGH); //Se abre la válvula
//Se abre la válvula
delay(milisegundos); //Se espera el tiempo indicado
//Se cierra la valvula
digitalWrite(valvulaPin, LOW); //Se cierra la válvula
}
}*/

const int boton1 = 2;
const int boton2 = 3;
const int boton3 = 4;
const int boton4 = 5;
const int boton5 = 22;
const int boton6 = 24;
const int boton7 = 26;
const int boton8 = 28;

int estado1 = 0;
int estado2 = 0;
int estado3 = 0;
int estado4 = 0;
int estado5 = 0;
int estado6 = 0;
int estado7 = 0;
int estado8 = 0;

void setup(){
Serial.begin(9600); //"Baud rate "tasa de baudios"
pinMode(Valve1Pin, OUTPUT);
pinMode(Valve2Pin, OUTPUT);
pinMode(Valve3Pin, OUTPUT);
pinMode(Valve4Pin, OUTPUT);
pinMode(LEDEnRangoPin, OUTPUT);
// pinMode(LEDNoRangoPin, OUTPUT);
pinMode(PiezoelectricoPin,OUTPUT);
pinMode(boton1, INPUT);
pinMode(boton2, INPUT);
pinMode(boton3, INPUT);
pinMode(boton4, INPUT);
pinMode(boton5, INPUT);
pinMode(boton6, INPUT);
pinMode(boton7, INPUT);
pinMode(boton8, INPUT);
}

void loop(){
enRango = estaEnRango(DISTANCIA_MIN, DISTANCIA_MAX);
if(enRango) { //Si hay un objeto a una distancia adecuada
digitalWrite(LEDEnRangoPin, HIGH); //Enciende el LED que indica si hay un objeto a la distancia adecuada
}
else {
digitalWrite(LEDEnRangoPin, LOW); //Apaga el LED que indica si hay un objeto a la distancia adecuada
}
estado1 = digitalRead(boton1);
estado2 = digitalRead(boton2);
estado3 = digitalRead(boton3);
estado4 = digitalRead(boton4);
estado5 = digitalRead(boton5);
estado6 = digitalRead(boton6);
estado7 = digitalRead(boton7);
estado8 = digitalRead(boton8);

salidaLiquido();
delay(50); //Esperar 50ms antes de la siguiente lectura del sensor de proximidad
}


//Función de salida de líquidos. El líquido se expulsa mientras el botón está pulsado.

void salidaLiquido(){
if (enRango){
if (estado1 == HIGH){
digitalWrite (Valve1Pin, HIGH);
delay (t1);
}else{
digitalWrite(Valve1Pin, LOW);
}
if (estado2 == HIGH){
digitalWrite(Valve2Pin,HIGH);
delay(t2);
}else{
digitalWrite(Valve2Pin, LOW);
}
if (estado3 == HIGH){
digitalWrite(Valve3Pin,HIGH);
delay (t3);
}else{
digitalWrite(Valve3Pin, LOW);
}
if (estado4 == HIGH){
digitalWrite(Valve4Pin,HIGH);
delay(t4);
}else{
digitalWrite(Valve4Pin, LOW);
}
if (estado5 == HIGH){
digitalWrite(Valve1Pin, HIGH);
delay (combina11);
digitalWrite(Valve1Pin, LOW);
digitalWrite(Valve2Pin, HIGH);
delay (combina12);
digitalWrite(Valve2Pin, LOW);
}else{
digitalWrite(Valve1Pin, LOW);
digitalWrite(Valve2Pin, LOW);
}
if (estado6 == HIGH){
digitalWrite(Valve2Pin, HIGH);
delay (combina21);
digitalWrite(Valve2Pin, LOW);
digitalWrite(Valve3Pin, HIGH);
delay (combina22);
digitalWrite(Valve3Pin, LOW);
}else{
digitalWrite(Valve2Pin, LOW);
digitalWrite(Valve3Pin, LOW);
}
if (estado7 == HIGH){
digitalWrite(Valve3Pin, HIGH);
delay(combina31);
digitalWrite(Valve3Pin, LOW);
digitalWrite(Valve4Pin, HIGH);
delay(combina32);
digitalWrite(Valve4Pin, LOW);
}else{
digitalWrite(Valve3Pin,LOW);
digitalWrite(Valve4Pin,LOW);
}
if (estado8 == HIGH){
digitalWrite(Valve1Pin, HIGH);
delay (combina41);
digitalWrite(Valve1Pin,LOW);
digitalWrite(Valve2Pin, HIGH);
delay (combina42);
digitalWrite(Valve2Pin,LOW);
digitalWrite(Valve3Pin, HIGH);
delay (combina43);
digitalWrite(Valve3Pin,LOW);
digitalWrite(Valve4Pin, HIGH);
delay (combina44);
digitalWrite(Valve4Pin,LOW);
}else{
digitalWrite(Valve1Pin, LOW);
digitalWrite(Valve2Pin, LOW);
digitalWrite(Valve3Pin, LOW);
digitalWrite(Valve4Pin, LOW);
}
}else{
digitalWrite(Valve1Pin, LOW);
digitalWrite(Valve2Pin, LOW);
digitalWrite(Valve3Pin, LOW);
digitalWrite(Valve4Pin, LOW);
}
}

No hay comentarios:

Publicar un comentario