arduino-clasificador-colores-tcs3200

Cómo construir un clasificador de colores con Arduino

  • 7 min

Si alguna vez has visto esos vídeos hipnóticos de fábricas donde miles de tomates o piezas de plástico son separados a toda velocidad según su calidad o color, has visto visión artificial en acción.

Hoy vamos a traer esa tecnología a nuestro escritorio. Vamos a construir una máquina clasificadora de colores (Color Sorter).

El objetivo es simple: vertemos un puñado de caramelos de colores mezclados (tipo M&Ms, Skittles o Lacasitos) en un embudo, y la máquina debe dosificarlos uno a uno, analizar su color y mover una rampa para depositarlos en su vaso correspondiente.

Este proyecto es el “Hola Mundo” de la Mecatrónica, ya que requiere sincronizar perfectamente el movimiento físico (servos) con la adquisición de datos (sensor).

Cómo mide el color el TCS3200

Para este proyecto usaremos el sensor TCS3200. A diferencia de una cámara que procesa píxeles, este sensor es mucho más primitivo (y rápido).

El TCS3200 es un convertidor de Luz a Frecuencia. Dispone de una matriz de fotodiodos filtrados:

  • Unos tienen filtro Rojo.
  • Otros tienen filtro Verde.
  • Otros tienen filtro Azul.
  • Otros no tienen filtro (Clear).

El funcionamiento es secuencial:

Le decimos al sensor: “Lee solo los fotodiodos Rojos”.

El sensor emite pulsos (onda cuadrada). Cuanta más intensidad de rojo detecte, mayor será la frecuencia de esos pulsos.

Repetimos para Verde y Azul.

Al final, obtenemos tres valores de frecuencia. Si la frecuencia del rojo es muy alta comparada con las otras dos, el objeto es rojo. Simple, ¿verdad?

Diseño mecánico

Antes de programar, necesitamos “hardware”. El mayor reto de este proyecto no es el código, es que los caramelos no se atasquen.

Necesitamos dos mecanismos:

  1. El Alimentador (Feeder): Un disco con un agujero conectado a un servo (Servo Superior). Coge un caramelo del embudo y lo arrastra hasta ponerlo debajo del sensor.
  2. La Rampa (Sorter): Un tubo o canal conectado a otro servo (Servo Inferior) que apunta al vaso correcto.

Es muy importante cubrir el sensor y el caramelo con una carcasa opaca mientras se lee. La luz del sol o de las lámparas de la habitación cambiará drásticamente los valores leídos y confundirá al robot.

Componentes

  • [1x|blue] Arduino Uno | El cerebro del proyecto
  • [1x|orange] Sensor de Color TCS3200 | Módulo con 4 LEDs blancos integrados
  • [1x|green] Servo Superior (SG90) | Alimentador (disco con agujero)
  • [1x|green] Servo Inferior (SG90) | Rampa clasificadora
  • [1x|red] Fuente de alimentación externa (5V 2A) | Para servos
  • [Varios|gray] Estructura | Cartón, madera o impresión 3D

Esquema de conexión

El TCS3200 tiene bastantes pines, así que ¡atentos al cableado!

Sensor TCS3200

El sensor necesita pines para seleccionar filtro, configurar el escalado de frecuencia y leer la salida.

[ { “from”: “TCS3200 VCC”, “to”: “5V Arduino”, “color”: “red” }, { “from”: “TCS3200 GND”, “to”: “GND Arduino”, “color”: “black” }, { “from”: “TCS3200 S0”, “to”: “Pin 2”, “color”: “yellow”, “note”: “Escalado de frecuencia” }, { “from”: “TCS3200 S1”, “to”: “Pin 3”, “color”: “yellow”, “note”: “Escalado de frecuencia” }, { “from”: “TCS3200 S2”, “to”: “Pin 4”, “color”: “orange”, “note”: “Selección de filtro” }, { “from”: “TCS3200 S3”, “to”: “Pin 5”, “color”: “orange”, “note”: “Selección de filtro” }, { “from”: “TCS3200 OUT”, “to”: “Pin 6”, “color”: “green”, “note”: “Salida de frecuencia” } ]

Servos del mecanismo

Un servo dosifica los caramelos y el otro orienta la rampa de salida.

[ { “from”: “Servo Alimentador señal”, “to”: “Pin 9”, “color”: “purple” }, { “from”: “Servo Rampa señal”, “to”: “Pin 10”, “color”: “purple” }, { “from”: “Servos VCC”, “to”: “Fuente externa regulada de 5V”, “color”: “red” }, { “from”: “Servos GND”, “to”: “GND fuente + GND Arduino”, “color”: “black” } ]

El código

Vamos a dividir el código en bloques lógicos. Necesitamos calibrar primero, porque “Rojo” no significa lo mismo en tu casa que en la mía (depende de la luz).

Definiciones y setup

#include <Servo.h>

// Pines TCS3200
#define S0 2
#define S1 3
#define S2 4
#define S3 5
#define sensorOut 6

// Objetos Servo
Servo servoAlimentador;
Servo servoRampa;

// Variables para almacenar las frecuencias leídas
unsigned long frecRojo = 0;
unsigned long frecVerde = 0;
unsigned long frecAzul = 0;

void setup() {
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT);
  
  // Configurar escalado de frecuencia al 20%
  // (Tabla de verdad del datasheet: S0=High, S1=Low)
  digitalWrite(S0, HIGH);
  digitalWrite(S1, LOW);
  
  servoAlimentador.attach(9);
  servoRampa.attach(10);
  
  Serial.begin(9600);
  
  // Posición inicial
  moverRampa(90); // Centro
}
Copied!

Función de lectura de color

Esta función interroga al sensor secuencialmente. Usamos pulseIn(pin, LOW) para medir cuánto dura el pulso. Nota: En el TCS3200, a mayor intensidad de luz, menor es la duración del pulso (más frecuencia).

void leerSensor() {
  // 1. Filtro ROJO (S2=LOW, S3=LOW)
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  delay(10); // Dejamos que la salida se estabilice
  frecRojo = pulseIn(sensorOut, LOW, 100000UL);
  
  // 2. Filtro VERDE (S2=HIGH, S3=HIGH)
  digitalWrite(S2, HIGH);
  digitalWrite(S3, HIGH);
  delay(10);
  frecVerde = pulseIn(sensorOut, LOW, 100000UL);
  
  // 3. Filtro AZUL (S2=LOW, S3=HIGH)
  digitalWrite(S2, LOW);
  digitalWrite(S3, HIGH);
  delay(10);
  frecAzul = pulseIn(sensorOut, LOW, 100000UL);

  // Debug: Imprimimos valores para calibrar
  Serial.print("R="); Serial.print(frecRojo);
  Serial.print(" G="); Serial.print(frecVerde);
  Serial.print(" B="); Serial.println(frecAzul);
}
Copied!

Clasificación

Ahora toca calibrar. Coloca una muestra roja y anota los valores del monitor serie. Repite varias veces con cada color y también sin objeto; no basta con una única lectura.

Con esos datos, escribimos los condicionales.

void loop() {
  // 1. Cargar caramelo (Mover servo superior)
  cargarCaramelo();
  delay(500); 
  
  // 2. Leer
  leerSensor();
  
  // 3. Decidir (Estos valores SON UN EJEMPLO, usa los tuyos)
  // pulseIn devuelve duración. MENOR valor suele indicar MÁS intensidad.
  
  if (frecRojo == 0 || frecVerde == 0 || frecAzul == 0) {
    Serial.println("-> Lectura invalida / sin señal");
  }
  else if (frecRojo < frecVerde && frecRojo < frecAzul && frecRojo < 80) {
    Serial.println("-> Detectado ROJO");
    moverRampa(45); // Vaso Izquierda
  }
  else if (frecAzul < frecRojo && frecAzul < frecVerde && frecAzul < 80) {
    Serial.println("-> Detectado AZUL");
    moverRampa(135); // Vaso Derecha
  }
  else if (frecVerde < frecRojo && frecVerde < frecAzul) {
    Serial.println("-> Detectado VERDE");
    moverRampa(90); // Vaso Centro
  }
  else {
    Serial.println("-> Color desconocido / Vacío");
    // No movemos la rampa, o la mandamos a "descartes"
  }
  
  delay(500);
  
  // 4. Soltar caramelo
  descargarCaramelo();
}

// Funciones auxiliares de movimiento
void moverRampa(int angulo) {
  servoRampa.write(angulo);
  delay(300); // Dar tiempo a que llegue
}

void cargarCaramelo() {
  servoAlimentador.write(0); // Posición de recogida
  delay(500);
  servoAlimentador.write(90); // Posición bajo el sensor
}

void descargarCaramelo() {
  servoAlimentador.write(180); // Posición de caída
  delay(500);
  servoAlimentador.write(90); // Vuelta a reposo
}
Copied!

Distinguir colores parecidos

El gran enemigo de este proyecto es distinguir colores parecidos, como los M&Ms Marrones de los Rojos o Naranjas. El sensor TCS3200 es RGB. El marrón, técnicamente, es un “naranja oscuro”.

  • Rojo: R alto, G bajo, B bajo.
  • Marrón: R medio, G medio-bajo, B bajo.

Para distinguirlos, no basta con mirar cuál es el valor más bajo. Conviene usar relaciones entre canales, normalizar con muestras de referencia y considerar la intensidad total. Si la suma de los tres es muy alta (valores de pulseIn altos), significa que el objeto es oscuro -> Marrón.

Los objetos brillantes reflejan los LED blancos y pueden crear puntos especulares que falsean la lectura. No lijes el sensor. Usa iluminación difusa, una cámara opaca y una geometría fija entre muestra, LED y fotodiodos.

Siguientes pasos

¿Te ha funcionado? Ahora hazlo industrial:

  1. Contador: Añade una pantalla LCD que cuente cuántos caramelos de cada color has procesado (“Rojos: 15, Azules: 12”).
  2. Velocidad: Optimiza el código para hacerlo más rápido. ¿Puedes procesar 1 caramelo por segundo?
  3. Machine Learning: Si usas un Arduino más potente (como el Nano 33 BLE Sense) o conectas esto a un PC, podrías entrenar una pequeña red neuronal para que aprenda a distinguir colores complejos sin que tú tengas que escribir mil if/else.

¡A clasificar se ha dicho!