Clasificador de paquetes.
PRIMERA IDEA
El objetivo principal del separador de correo es dar la posibilidad al usuario de poder clasificar el correo que llega de la siguiente forma: correo nacional, correo internacional y correo local, de forma que únicamente se tenga que situar el paquete recibido en la cinta transportadora y un seleccionador se encargará de clasificarlo en el lugar correspondiente en el cual se debe destinar el paquete.
Se busca que el seleccionador trabaje de la forma más rápida posible para que el usuario tenga un menor tiempo de espera.
Esto surgió de la noticia de un periódico en el que relataban cómo debido a la cantidad de pedidos realizados a China durante el periodo de Navidad, y la falta de personal en Barajas, había derivado en una acumulación de paquetes en el aeropuerto hasta llegar al extremo de tenerlos que apilar fuera del almacén.
RESULTADO FINAL
El resultado final ha sido un poco diferente, ya que en lugar de usar una cinta transportadora, hemos usado un plato giratorio porque nos resultaba más fácil. El clasificador determina si el paquete es correcto o no atendiendo al color (que se lee con un sensor de color) y atendiendo al peso (que se determina con un sensor resistivo de fuerza).
De ser correcto, el plato gira hasta la posición correspondiente dependiendo del color del paquete, y de ser incorrecto, el plato gira hasta la posición de color rojo. Una vez que el plato gira, el servomotor se encarga de empujar el paquete.
MATERIALES ESQUEMA
PROBLEMAS
Sensor de color: el problema que nos hemos encontrado es que nos hemos quedado sin pines en el Arduino, por tanto al final sólo hemos puesto uno.
Sensor resistivo de fuerza: el problema que hemos tenido es que no pesa bien para valores bajos. Una solución más o menos válida ha sido comprar una puerta operacional que se llama LM358 que invierte los valores (pasando a ser los valores altos, los bajos, y viceversa) mejorando considerablemente el resultado.
Motor paso a paso: no tenía suficiente fuerza, por tanto las paredes, que en un principio iban a ser de madera, han tenido que ser de cinta americana para que no pesase tanto, y además hemos usado unas ruedas de microondas para ayudar a que rote bien.
Servomotor: no posee demasiada fuerza, por lo que hemos tenido que poner un trozo de madera en el extremo, para aumentar la superficie de empuje.
El motor paso a paso y el servomotor ya los teníamos, de no haber sido así habríamos comprado otros más eficaces.
FOTOS
CÓDIGO
//LIBRERIAS #include <Stepper.h> #define STEPS_PER_MOTOR_REVOLUTION 32 #define STEPS_PER_OUTPUT_REVOLUTION 32 * 64 //2048
//VARIABLES
//sensor presencia
long distancia;
long tiempo;
//Sensor RGB
const int s0 = 8;
const int s1 = 9;
const int s2 = 12;
const int s3 = 11;
const int out = 10;
//pines de led conectados a arduino
int greenLed =4 ;
int blueLed = 5;
//variables
int green = 0;
int blue = 0;
int red = 0;
int color; // Tiene que tomar los valores [0,510,1020,1530] con los cuales se determinara la distancia que girara el motor
//Bascula int pAnalogicoBascula = 0; int bascula = 0; int peso = 0;
//Motor paso a paso Stepper small_stepper(STEPS_PER_MOTOR_REVOLUTION, 0, 2, 1, 3); const int verde = 0; const int amarillo = 510; const int azul = 1020; const int rojo = 1530; int posicion = verde;
//Servomotor int servoPin = 13; // servo conectado al pin digital 2 int myAngle; // ángulo del servo de 0-180 int pulseWidth; // anchura del pulso para la función servoPulse
//CONFIGURACION INICIAL void setup() {
Serial.begin(9600); //inicia el protocolo de comunicación a PC
small_stepper.setSpeed(700);
//pines de sensor de presencia
pinMode(7, OUTPUT); /*activación del pin 7 como salida: para el pulso ultrasónico*/
pinMode(6, INPUT); /*activación del pin 6 como entrada: tiempo del rebote del ultrasonido*/
//pines de sensor rgb
pinMode(s0, OUTPUT);
pinMode(s1, OUTPUT);
pinMode(s2, OUTPUT);
pinMode(s3, OUTPUT);
pinMode(out, INPUT);
pinMode(greenLed, OUTPUT);
pinMode(blueLed, OUTPUT);
digitalWrite(s0, HIGH);
digitalWrite(s1, HIGH);
pinMode(servoPin, OUTPUT); // configura pin 2 como salida }
//FUNCION UTILIZADA POR EL SENSOR RGB
void recogeColor()
{ digitalWrite(s2, LOW); digitalWrite(s3, LOW); //count OUT, pRed, RED red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH); digitalWrite(s3, HIGH); //count OUT, pBLUE, BLUE blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH); digitalWrite(s2, HIGH); //count OUT, pGreen, GREEN green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
}
void servoPulse(int servoPin, int myAngle)
{
pulseWidth = (myAngle * 10) + 600; // determina retardo
digitalWrite(servoPin, HIGH); // activa el servo
delayMicroseconds(pulseWidth); // pausa
digitalWrite(servoPin, LOW); // desactiva el servo
delay(20); // retardo de refresco
}
//LOOP void loop() {
//SENSOR DE PRESENCIA
digitalWrite(7,LOW); /* Por cuestión de estabilización del sensor*/
delayMicroseconds(5);
digitalWrite(7, HIGH); /* envío del pulso ultrasónico*/
delayMicroseconds(10);
tiempo=pulseIn(6, HIGH); /* Función para medir la longitud del pulso entrante. Mide el tiempo que transcurrido entre el envío del pulso ultrasónico y cuando el sensor recibe el rebote, es decir: desde que el pin 12 empieza a recibir el rebote, HIGH, hasta que deja de hacerlo, LOW, la longitud del pulso entrante*/
distancia= int(0.017*tiempo); /*fórmula para calcular la distancia obteniendo un valor entero*/
/*Monitorización en centímetros por el monitor serial*/
delay(500);
if(distancia<10){
Serial.println(«Hay un paquete!!!»);
Serial.println(«Distancia «);
Serial.println(distancia);
Serial.println(» cm»);
//SENSOR RGB
recogeColor();
Serial.print(«R Intensidad:»);
Serial.print(red, DEC);
Serial.print(» G Intensidad: «);
Serial.print(green, DEC);
Serial.print(» B Intensidad: «);
Serial.print(blue, DEC);
if (red < blue && red < green && red < 20) {
Serial.println(» – ( Color Amarillo)»);
color=amarillo;
digitalWrite(greenLed, HIGH);
digitalWrite(blueLed, HIGH);
} else if (blue < red && blue < green) {
Serial.println(» – ( Color Azul)»);
color=azul;
digitalWrite(greenLed, LOW);
digitalWrite(blueLed, HIGH);
} else if (green < red && green < blue) {
Serial.println(» – ( Color Verde )»);
color=verde;
digitalWrite(greenLed, HIGH);
digitalWrite(blueLed, LOW);
}
delay(500);
//SENSOR RESISTIVO (BASCULA)
delay(500);
Serial.println(«Pesando…»);
//Se pesa 10 veces y se hace la media para un mejor resultado.
bascula = analogRead(pAnalogicoBascula);
delay(300);
for (int i=0; i<9; i++) { //Para una mejor medicion lo mido 10 veces y hago la media
bascula = (bascula + analogRead(pAnalogicoBascula)) / 2;
delay(300);
}
Serial.print(«Lectura = «);
Serial.println(bascula);
if (bascula > 160 && bascula < 601 ) { //condicion para 200g bascula
Serial.println(«200 gramos»);
peso = 200;
}
if (bascula > 124 && bascula < 160 ) { //condicion para 300g
Serial.println(«300 gramos»);
peso = 300;
}
if (bascula > 75 && bascula < 95 ) { //condicion para 400g
Serial.println(«400 gramos»);
peso = 400;
}
if (bascula >= 50 && bascula < 60 ) { //condicion para 500g
Serial.println(«500 gramos»);
peso = 500;
}
if (bascula < 50 ) { //condicion para mas de 500g
Serial.println(«Fuera de rango»);
digitalWrite(greenLed, HIGH);
delay(200);
digitalWrite(greenLed, LOW);
delay(200);
digitalWrite(blueLed, HIGH);
delay(200);
digitalWrite(blueLed, LOW);
digitalWrite(greenLed, HIGH);
delay(200);
digitalWrite(greenLed, LOW);
delay(200);
digitalWrite(blueLed, HIGH);
delay(200);
digitalWrite(blueLed, LOW);
digitalWrite(greenLed, HIGH);
delay(200);
digitalWrite(greenLed, LOW);
delay(200);
digitalWrite(blueLed, HIGH);
delay(200);
digitalWrite(blueLed, LOW);
peso = -1;
}
digitalWrite(greenLed, LOW);
digitalWrite(blueLed, LOW);
delay(500);
//MOTOR PASO A PASO
if (color==verde && peso<200){
if (posicion > verde) {
small_stepper.step(-posicion + verde);
} else {
small_stepper.step(verde – posicion);
}
posicion = verde;
}
if (color== amarillo && peso<300){
if (posicion > amarillo) {
small_stepper.step(-posicion + amarillo);
} else {
small_stepper.step(amarillo – posicion);
}
posicion = amarillo;
}
if (color== azul && peso<500){
if (posicion > azul) {
small_stepper.step(-posicion + azul);
} else {
small_stepper.step(azul – posicion);
}
posicion = azul;
}
if (peso> 500){ //Color rojo
if (posicion > rojo) {
small_stepper.step(-posicion + rojo);
} else {
small_stepper.step(rojo – posicion);
}
posicion = rojo;
}
Serial.print(«Posicion: «);
Serial.println(posicion);
delay(2000);
//SERVOMOTOR
servoPulse(servoPin, 170); //Empuja el paquete
for (myAngle=170; myAngle>=10; myAngle–) { //Vuelve a la posicion inicial
servoPulse(servoPin, myAngle);
}
delay(500);
} //FIN DEL IF DE DISTANCIA INFERIOR A 10CM
}
VIDEO |