Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Máquina avanzada de clasificación por color con Arduino y sensor RGB

Componentes y suministros

Componente Cantidad
Arduino Nano R3 1
Sensor RGB TCS34725 1
Convertidor buck LM2596 1
Servos MG-90S 2
Rodamiento MR105ZZ (5 x 10 x 4 mm) 3
Rodamiento 608RS o 608ZZ (8 x 22 x 7 mm) 1
Rodamiento 6003RS (17 x 35 x 10 mm) 1
Tornillo avellanado M3 x 15 mm 1
Tornillos autoperforantes M2 x 10 20
LED RGB (ánodo común) 1
Resistencias de 220 ohmios 3
Cables 1
Conector jack 2.1 x 5.5 mm 1
Tubo termorretráctil 1
Conectores Dupont 1
Fuente de alimentación 9V o 12V (mínimo 1 A) 1
Tubos de ensayo 5x 22 mm (OD) x 100 mm (de Danmu Art) 1
Skittles!!!!!!!!!! 1

Herramientas y máquinas necesarias

Sobre este proyecto

Máquina avanzada de clasificación por color con Arduino y sensor RGB
Máquina de clasificación por color completada

Introducción

La curiosa historia es que este proyecto nunca estuvo planeado. Hace unos 3,5 años empecé a diseñar una máquina de clasificación por color mucho más compleja y, como muchos de mis proyectos, quedó a medias acumulando polvo en el alféizar de la ventana (seguro que nadie más se identifica con esto, jaja).

Hace unos meses decidí retomar este viejo proyecto. Lo primero que necesitaba resolver era cómo recoger Skittles de un depósito y comprobar su color de forma fiable manteniendo el sistema lo más compacto posible (lo cual no logré la primera vez). Me convencí a mí mismo de diseñar una máquina más simple solo para acertar con el diseño del sistema de recogida. Ingenuamente pensé que sería un trabajo de dos fines de semana: agradable, fácil y rápido... ¡Qué equivocado estaba!

Me tomó dos diseños completamente diferentes y muchos prototipos ajustados conseguir algo que funcionara de manera aceptable (aún experimento algunos problemas de recogida de vez en cuando).

Máquina avanzada de clasificación por color con Arduino y sensor RGB
Vista lateral del mecanismo
Máquina avanzada de clasificación por color con Arduino y sensor RGB
Mecanismo de alimentación
Máquina avanzada de clasificación por color con Arduino y sensor RGB
Soportes para tubos de ensayo

Aunque no es perfecto, estoy bastante satisfecho con el resultado.

¿Cómo funciona?

La máquina se divide en dos etapas principales:

Etapa 1 - Alimentación y detección: En la parte superior se encuentra el depósito para los Skittles sin clasificar. En la parte inferior de este depósito está el mecanismo de alimentación, responsable de recoger los Skittles y posicionarlos frente al sensor de color donde se comprobará su color.

El mecanismo de alimentación incluye un brazo que agita el contenido del depósito para asegurar que los Skittles fluyan correctamente a través del orificio sin atascarse (desafortunadamente aún ocurre a veces).

Máquina avanzada de clasificación por color con Arduino y sensor RGB
Brazo agitador del depósito

Etapa 2 - Clasificación: Una vez detectado el color del Skittle, entra en acción la segunda etapa. El soporte de tubos de ensayo alinea el tubo correcto frente al mecanismo de alimentación para que el Skittle caiga en él.

El ciclo se repite hasta que el depósito está vacío.

¿Quieres construir la tuya?

Máquina avanzada de clasificación por color con Arduino y sensor RGB
Archivos para impresión 3D disponibles en littlefrenchkev.com

Visita: www.littlefrenchkev.com/colour-sorting-machine

Máquina avanzada de clasificación por color con Arduino y sensor RGB
Detalle de las piezas impresas en 3D

Montaje

Una vez que hayas descargado e impreso las piezas, deberías tener algo como esto:

Máquina avanzada de clasificación por color con Arduino y sensor RGB
Conjunto de piezas impresas

Ten en cuenta que la carcasa frontal viene en dos versiones. No hay diferencia real, solo cambian la estética.

Máquina avanzada de clasificación por color con Arduino y sensor RGB
Dos versiones de la carcasa frontal
Máquina avanzada de clasificación por color con Arduino y sensor RGB
Resto de componentes necesarios
Máquina avanzada de clasificación por color con Arduino y sensor RGB
Componentes electrónicos

Aquí tienes un vídeo del proceso de montaje. ¡Incluso intenté ser artístico haciendo una intro con tomas a cámara lenta de la impresora 3D!

Configuración inicial

Lo primero que hace la máquina al encenderse es mover ambos servos a su posición inicial. Cuando enciendes la máquina por primera vez, debes asegurarte de que el eje/piñón que recoge los Skittles está en su posición superior y que el soporte de tubos está alineado con el mecanismo de alimentación.

Máquina avanzada de clasificación por color con Arduino y sensor RGB
Posición inicial correcta

Solución de problemas

Si decides construir esta máquina de clasificación, podrías encontrarte con algunos problemas comunes. Aquí te explico cómo resolverlos:

LED parpadeando en rojo - sin secuencia de inicio:

Después de moverse a su posición inicial, la máquina debería ejecutar su secuencia de inicio. Si no lo hace y en su lugar el LED parpadea en rojo, significa que hay problemas con el sensor RGB no detectado. Hay un problema con el cableado o el sensor está defectuoso.

Los tubos no se alinean correctamente:

Causa 1: Durante la secuencia de inicio, el soporte de tubos se mueve 5 veces, una por cada color. Podrías notar que los tubos no se alinean bien con el mecanismo de alimentación. Esto podría deberse a que los servos no son súper precisos o a variaciones en las dimensiones de impresión.

Esto se puede corregir mediante software modificando el array colour_angle. Cada valor en este array representa la posición del servo para cada color; al cambiar esos valores puedes ajustar finamente dónde se detiene el tubo para cada color.

Causa 2: Debido a las tolerancias de impresión, también podrías tener algo de juego en los engranajes del soporte de tubos. Dependiendo de la dirección en que giren los tubos, su inercia puede hacer que sobrepasen su posición de parada. Esto también se puede corregir mediante software modificando las variables forward y backward anti-backlash. Esos valores se sumarán o restarán de los valores del ángulo de color dependiendo de la dirección en que gire el soporte para compensar este juego.

Mezcla de colores:

Máquina avanzada de clasificación por color con Arduino y sensor RGB
Ejemplo de mezcla de colores

Si experimentas mezcla de colores, tendrás que modificar los arrays colour_limit_values. Cada valor en esos arrays representa los valores mínimo y máximo para Rojo, Verde y Azul. Para tener una mejor idea de cuáles deberían ser los valores, carga la máquina con un solo color, conéctala a tu computadora y abre el monitor serie. Cada vez que se comprueba un Skittle, deberías obtener sus valores RGB leídos y qué color cree el programa que es. Esto te dará una mejor idea de qué valores deberían asociarse con cada color.

Algunas características interesantes

(¡Al menos yo creo que lo son!)

El LED RGB:

Hay un LED RGB instalado en la base de la máquina. Durante el proceso de clasificación, cambia de color para coincidir con el color del Skittle que se está dejando caer. Recorre continuamente todos los colores de los Skittles una vez que el depósito está vacío.

También parpadeará en rojo al inicio si se detecta un problema con el sensor.

Compensación anti-juego:

El soporte de tubos gira usando un par de engranajes rectos. Debido a las tolerancias de impresión, es muy difícil eliminar completamente cualquier juego en los engranajes. Esto significa que el soporte tiende a sobrepasar su posición ideal. El código permite compensar esto deteniendo el soporte antes por una cierta cantidad dependiendo de la dirección en que gira.

Retraso con extra:

El código incluye una función set_led(ms, color). Actúa exactamente como la función delay(ms) pero permite que el LED cambie suavemente a su nuevo color mientras ocurre el retraso. ¡Funciona de maravilla para cambiar los colores del LED mientras el soporte de tubos gira a su posición!

Notas adicionales

Nota 1: Imprimí mi máquina en negro, esto afectará los valores de color que lea el sensor, especialmente cuando no hay Skittles en el mecanismo de alimentación.

Nota 2: Después de pasar por el proceso de clasificación varias veces, los colores de los Skittles parecen volverse más difíciles de leer de forma fiable. Asumo que es debido a que pierden su brillo tras frotarse dentro del depósito muchas veces o se vuelven un poco pegajosos al manipularlos con la mano (¡suena asqueroso!). Al calibrar los valores de color, intenta usar Skittles "frescos".

Nota 3: Asegúrate de tomar todas las precauciones necesarias al manipular alimentos. Esto incluye usar filamento de impresión seguro para alimentos.

Nota 4: Intento publicar trabajos en progreso y en qué proyectos estoy en Instagram. Si te interesa, puedes echar un vistazo aquí: @little_french_kev

Máquina avanzada de clasificación por color con Arduino y sensor RGB
Máquina completada y funcionando

Código

LFK_sorting_machine (C/C++)

Aquí está el código de Arduino para la máquina de clasificación:

#include <Wire.h>
#include "Adafruit_TCS34725.h"
#include <Servo.h>
/* Basado en código de ejemplo para la biblioteca Adafruit TCS34725 */

//======================= Variables relacionadas con el sensor RGB =========================
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_24MS, TCS34725_GAIN_1X);
int colour = 0; // 0-negro, 1-amarillo, 2-verde, 3-naranja, 4-rojo, 5-púrpura
int previous_colour = colour;
int black_count = 0; // contador de color vacío/desconocido
int start_measurment_angle = 88; // posición del servo para alinear skittle frente al sensor
int measurment_sweep = 2; // número de mediciones para promediar error
int measurment_angle_increment = 4; // incremento de ángulo entre mediciones

// limit values[] = {min_red, max_red, min_green, max_green, min_blue, max_blue}
uint16_t black_limit_values[] = {0, 200, 0, 200, 0, 200};
uint16_t yellow_limit_values[] = {850, 2200, 800, 2200, 400, 1100};
uint16_t green_limit_values[] = {400, 800, 700, 1400, 300, 700};
uint16_t orange_limit_values[] = {650, 1800, 300, 850, 210, 600};
uint16_t red_limit_values[] = {400, 950, 150, 450, 150, 400};
uint16_t purple_limit_values[] = {150, 400, 150, 450, 150, 500};

//======================= Variables relacionadas con el LED RGB =========================
byte R_pin = 5;
byte G_pin = 6;
byte B_pin = 11;
int current_red_value = 255;
int current_green_value = 255;
int current_blue_value = 255;
const int orange[] = {0, 230, 255};
const int red[] = {0, 255, 255};
const int green[] = {255, 0, 255};
const int yellow[] = {0, 170, 255};
const int purple[] = {0, 255, 40};

//======================= Variables relacionadas con servos de alimentación =========================
int release_delay = 220;
const int colour_angles[] = {10, 46, 82, 118, 154};
const int backward_anti_backlash = 2;
const int forward_anti_backlash = 2;
Servo feeder_servo;
Servo holder_servo;

//=================================== SETUP =========================================
void setup(void) {
  Serial.begin(9600);
  pinMode(R_pin, OUTPUT);
  pinMode(G_pin, OUTPUT);
  pinMode(B_pin, OUTPUT);
  analogWrite(R_pin, 255); // apagar LED
  analogWrite(G_pin, 255);
  analogWrite(B_pin, 255);
  feeder_servo.attach(3);
  holder_servo.attach(2);
  feeder_servo.write(0);
  holder_servo.write(colour_angles[0]);
  int white[] = {0, 0, 0};
  int black[] = {255, 255, 255};
  set_led(1000, white); // encender LED (blanco)
  if (tcs.begin()) {
    Serial.println("Found sensor");
    starting_sequence();
  } else {
    Serial.println("No TCS34725 found ... check your connections");
    while (1) { // parpadeo rojo rápido si no se encuentra sensor
      set_led(300, red);
      set_led(300, black);
    }
  }
}

//=================================== LOOP =========================================
void loop(void) {
  if (black_count < 10) {
    feeder_servo.write(0);
    delay(450);
    previous_colour = colour;
    get_colour();
    if (colour == 0) {
      black_count++;
      shake();
    } else if (colour == 6) {
      black_count++;
    } else {
      move_holder();
      release_skittle();
      black_count = 0;
    }
  } else {
    end_loop(1000);
  }
}

//=================================== GET COLOUR =========================================
void get_colour() {
  uint16_t r, g, b, c;
  uint16_t total_r = 0;
  uint16_t total_g = 0;
  uint16_t total_b = 0;
  feeder_servo.write(start_measurment_angle);
  delay(200);
  Serial.println("----------------");
  for (int i = 0; i <= measurment_sweep; i++) {
    tcs.getRawData(&r, &g, &b, &c);
    feeder_servo.write(start_measurment_angle + i * measurment_angle_increment);
    total_r += r;
    total_g += g;
    total_b += b;
    delay(15);
  }
  total_r /= measurment_sweep;
  total_g /= measurment_sweep;
  total_b /= measurment_sweep;
  Serial.print(total_r); Serial.print(" ");
  Serial.print(total_g); Serial.print(" ");
  Serial.print(total_b); Serial.println(" ");

  // Comparar valores para determinar el color
  if ((total_r < black_limit_values[1]) && (total_g < black_limit_values[3]) && (total_b < black_limit_values[5])) {
    Serial.println("black"); colour = 0;
  } else if ((total_r >= yellow_limit_values[0]) && (total_r < yellow_limit_values[1]) &&
             (total_g >= yellow_limit_values[2]) && (total_g < yellow_limit_values[3]) &&
             (total_b >= yellow_limit_values[4]) && (total_b < yellow_limit_values[5])) {
    Serial.println("yellow"); colour = 1;
  } else if ((total_r >= green_limit_values[0]) && (total_r < green_limit_values[1]) &&
             (total_g >= green_limit_values[2]) && (total_g < green_limit_values[3]) &&
             (total_b >= green_limit_values[4]) && (total_b < green_limit_values[5])) {
    Serial.println("green"); colour = 2;
  } else if ((total_r >= orange_limit_values[0]) && (total_r < orange_limit_values[1]) &&
             (total_g >= orange_limit_values[2]) && (total_g < orange_limit_values[3]) &&
             (total_b >= orange_limit_values[4]) && (total_b < orange_limit_values[5])) {
    Serial.println("orange"); colour = 3;
  } else if ((total_r >= red_limit_values[0]) && (total_r < red_limit_values[1]) &&
             (total_g >= red_limit_values[2]) && (total_g < red_limit_values[3]) &&
             (total_b >= red_limit_values[4]) && (total_b < red_limit_values[5])) {
    Serial.println("red"); colour = 4;
  } else if ((total_r >= purple_limit_values[0]) && (total_r < purple_limit_values[1]) &&
             (total_g >= purple_limit_values[2]) && (total_g < purple_limit_values[3]) &&
             (total_b >= purple_limit_values[4]) && (total_b < purple_limit_values[5])) {
    Serial.println("purple"); colour = 5;
  } else {
    Serial.println("unknown"); colour = 6;
  }
}

//============================== MOVE HOLDER =============================
void move_holder() {
  int new_holder_position = colour_angles[colour - 1];
  int holder_delay = (abs(previous_colour - colour) * 70);
  if (holder_delay < 0) holder_delay = 0;
  if (previous_colour > colour) {
    int anti_backlash_angle = new_holder_position - backward_anti_backlash;
    holder_servo.write(anti_backlash_angle);
  } else {
    int anti_backlash_angle = new_holder_position + forward_anti_backlash;
    holder_servo.write(new_holder_position);
  }
  if (colour == 1) set_led(holder_delay, yellow);
  else if (colour == 2) set_led(holder_delay, green);
  else if (colour == 3) set_led(holder_delay, orange);
  else if (colour == 4) set_led(holder_delay, red);
  else if (colour == 5) set_led(holder_delay, purple);
}

//============================= RELEASE SKITTLE ===========================
void release_skittle() {
  feeder_servo.write(180);
  delay(release_delay);
}

//================================= SHAKE =================================
void shake() {
  int shake_delay = 80;
  int shake_amount = 5;
  int shake_min_value = 90;
  int shake_max_value = 180;
  feeder_servo.write(180);
  delay(release_delay);
  feeder_servo.write(120);
  delay(80);
  for (int i = 0; i <= shake_amount; i++) {
    feeder_servo.write(shake_min_value);
    delay(shake_delay);
    feeder_servo.write(shake_max_value);
    delay(shake_delay);
  }
}

//============================ STARTING SEQUENCE ============================
void starting_sequence() {
  colour = 1; move_holder(); set_led(300, yellow); delay(400);
  colour = 2; move_holder(); set_led(300, green); delay(400);
  colour = 3; move_holder(); set_led(300, orange); delay(400);
  colour = 4; move_holder(); set_led(300, red); delay(400);
  colour = 5; move_holder(); set_led(300, purple); delay(400);
  previous_colour = colour;
  colour = 3; move_holder(); end_loop(200);
}

//================================ END LOOP =================================
void end_loop(int duration) {
  set_led(duration, orange);
  set_led(duration, red);
  set_led(duration, green);
  set_led(duration, yellow);
  set_led(duration, purple);
}

//============================ SET RGB LED COLOUR =======================
void set_led(int duration, int color[3]) {
  int start_time = millis();
  int current_time = start_time;
  int current_duration = 0;
  while (current_duration < duration) {
    analogWrite(R_pin, map(current_duration, 0, duration, current_red_value, color[0]));
    analogWrite(G_pin, map(current_duration, 0, duration, current_green_value, color[1]));
    analogWrite(B_pin, map(current_duration, 0, duration, current_blue_value, color[2]));
    current_time = millis();
    current_duration = current_time - start_time;
  }
  current_red_value = color[0];
  current_green_value = color[1];
  current_blue_value = color[2];
}

Esquemas

El cableado es bastante sencillo. ¡Asegúrate de que tu convertidor buck entregue 5V antes de conectar nada a él!

Máquina avanzada de clasificación por color con Arduino y sensor RGB
Diagrama de cableado

Proceso de manufactura

  1. Equipos de EEG: Diseño, fabricación y aplicaciones emergentes
  2. Máquinas expendedoras: Una industria de 36.600 millones de dólares en EE. UU.
  3. Máquinas de Votar: Historia, Tecnología y Estándares
  4. La evolución y fabricación de máquinas de coser: de la innovación del siglo XIX a la automatización moderna
  5. Televisión: De orígenes mecánicos al futuro inteligente
  6. Rodamientos de Husillo: Precisión y Garantía de Calidad
  7. Partes Esenciales del Torno: Funciones, Componentes y Mantenimiento
  8. El Torno: Historia, Tipos, Principio de Funcionamiento, Partes y Aplicaciones
  9. Componentes Clave de una Fresadora Explicados
  10. ¿Qué es una máquina? Guía completa
  11. JW Machine: Servicios de Fabricación por Contrato CNC de Precisión