Clasificador M&M’s por cor

Reto:

Tiñamos no instituto unha máquina de cartón que separa cilindros de tres cores, pero queríamos mellorala ou buscar algo máis complexo. Que tal separar caramelos? Se buscamos en internet como clasificar M&M’s por cor con arduino atopamos unha chea de máquinas de todo tipo. Para este proxecto collemos a idea de “Arduino Color Sorter Project” e modificamos un pouco as pezas par adaptalas ás nosas necesidades:

  • Estrutura feita con corte láser (3mm)
  • No canto do sensor que viña no exemplo utilizamos un sensor de cor TCS34725, pois é máis preciso e require menos cables.
  • Fixémoslle ao sensor un soporte en 3D para que quedase máis preto do caramelo.
  • Puxemos dous pulsadores coma no proxecto de separador de fichas brancas e negras, un de marcha e outro para calibrar.
  • Probamos incorporar unha pantalla LCD, TFT ou OLED para que nos dea información, e deseñamos un soporte para ela.
  • Deseñamos un tubo para que os M&M’s pasen sen atascarse, e fixémoslle un soporte para poder axustar o tubo á altura máis axeitada
  • Utilizamos un arduino UNO, pois son os que máis abondan no taller. Aínda que por ocupación de espazo iría mellor un nano, o UNO cabe perfectamente.
  • Deseñamos e imprimimos unhas caixas de cores para recoller os caramelos.

Con isto xa temos un primeiro prototipo a partir do que podemos traballar. Podemos quedar na programación básica ou engadir novos elementos e funcións, pois temos outras ideas para desenvolver a partir desta máquina nos vindeiros cursos:

  • Engadir unhas melloras: calibrado inicial, LEDs RGB, pulsador de parada, …
  • Utilizar un teclado matricial para podes introducir unha petición (número e cor dos caramelos)
  • Fabricar un selector de moedas para convertela nunha máquina expendedora.
  • Subir de novo os caramelos clasificados ao tubo superior.
  • o que se nos ocorra…

Montaxe:

1. Material necesario

Compoñentes

O modelo básico necesita:

  • Material para a estrutura (madeira de 3mm, cartón, cartón pluma, plástico, … elixe ti o material)
  • Arduino UNO (É o que usamos nós por ser o que tiñamos, pero se o prefires podes usar un arduino nano, que ocupa menos espazo)
  • 2 microservos SG90
  • Un sensor de cor TCS34725
  • 2 pulsadores (A peza superior está adaptada a un ancho de 7 mm. Se usas outro modelo de pulsador axusta o diámetro antes de cortar)
  • 2 resistencias de 10kΩ para os pulsaores
  • Cables dupont m-f, m-m
  • Clemas pequenas (para unir todos os pins que van a VCC e GND)
  • Tirafondos para aparafusar os servos e soporte do sensor
  • Separadores ou parafusos e porcas M2 para a peza do colector.
  • Suxeición e protección das conexións (O que teñas: Cinta illante, macarrón termorretráctil, bridas, material soldadura, …)
  • Cola para pegar as pezas da estrutura

Aparte, podes engadir outros compoñentes:

  • pantalla LCD ou OLED

Pezas da estrutura

Descarga os planos das pezas para corte láser (SelectorCor_PezasLaser.zip) e corta madeira ou cartón-pluma de 3mm de espesor.

Se non tes cortadora láser tamén podes imprimir os modelos extruíndo cun espesor de 3mm. Igual tes que lixar un pouco para que as pezas encaixen, xa que o corte sempre come algo de material, pero a impresión 3D non. Para facer os buratos máis amplos podes poñer no laminador Cura un valor negativo ao parámetro “expansión horizontal” que se atopa na sección de paredes.

   

Accesorios

Descarga os ficheiros STL (SelectorCor_PezasSTL.zip) para o soporte do sensor, o tubo, o soporte do tubo, o soporte da pantalla e as caixas. Utilizamos para o tubo un filamento translúcido para que se vexan as cores e usamos o modo “espiralizar” para que se impriman cunha sola liña de parede. Para as caixas utilizamos o mesmo sistema de impresión.

2. Preparación e suxeición dos compoñentes

Antes de montar a estrutura completa aparafusa os compoñentes  que correspondan a cada estante (servos, pulsadores, soporte do sensor, e soporte da pantalla) e dirixe os cables ata a rañura traseira. Cómpre etiquetalos para saber cal é cal cando os conectes no arduino.

Sensor de Cor

Fixándote na serigrafía, conecta 4 cables dupont f-m longos (deben chegar ata a parte inferior da estrutura) nos pins correspondentes. Cómpre suxeitalos cun pouco de cinta illante para que non se desconecten ao manipular o sensor, utilizar vermello para VCC, negro para GND, e etiquetar os cables SDA (A4) e SCL(A5) para conectalos despois á placa arduino. Finalmente introduce os cables polo burato do sensor, fai presión sobre o sensor ata o fondo (a peza ten unhas pequenos saíntes para suxeitalo) e aparafusa o soporte á madeira. A posición é a que se mostra na última imaxe.

Mecanismo colector

Imos aparafusar o servo superior na seguinte posición e suxeitar as pezas do colector.

Despois de calibrar as cores e para distinguir ben os caramelos de cando o tubo está baleiro vimos que o mellor era que o soporte tivese unha cor ben distinguible, como o maxenta, así que forramos a peza desa cor. Podes facer unha proba previa de calibración e facer algo similar.

No noso caso utilizamos uns parafusos e porcas, pero podes usar un espaciador ou calquera peza que suxeite a peza á altura axeitada. Se usas este sistema de parafusos, cómpre que non atravesen por completo a peza e botar un pouco de cola nas porcas para que se manteñan na posición.

Despois aparafusamos a peza en forma de sector circular ao servo. Comproba que fai todo o percorrido necesario. Despois, no programa, xa axustarás os ángulos do movemento.

Rampla clasificadora

Para construír a rampla que leva os caramelos ata a caixa correspondente debes primeiro suxeitar o servo na súa posición e aparafusar a peza inferior da rampla. Antes de aparafusar comproba que o movemento do servo fai todo o percorrido necesario.

Despois podes construír a estrutura da rampla, pero é mellor que deixes para o final a suxeición co servo, pois así será máis fácil montar toda a estrutura da máquina.

Pulsadores

Imos engadir dous pulsadores na estrutura. Un deles usarémolo para facer que a máquina arranque ou pare. O segundo pulsador usarémolo para a calibración.

Necesitas os cables de alimentación e dous cables dupont para conectar á placa arduino, que deben ser o suficientemente longos para chegar a ela. Se non os tes tan longos sempre podes facer empalmes. Despois conecta os cables tal e como aparece no seguinte esquema. Cómpre protexer as conexións con macarrón termorretráctil ou, se non tes, con cinta illante e así evitar que se toquen ao montar a estrutura.

3. Montaxe da estrutura e cableado

Por último imos montar a estrutura cos compoñentes, realizar as conexións e facer uns primeiros tests para comprobar que todo funciona correctamente. Para suxeitar os cables nós usamos cinta illante, pois era o que tiñamos a man, pero quedaría mellor con macarrón termorretráctil.

Cableado

Coloca cada peza na súa posición e dirixe os cables cara abaixo pola rañura traseira, suxeitándoos ben con cinta illante ou bridas para evitar que queden soltos e se desconecten. Cómpre que teñas previamente os cables ben identificados.

Nos servos conecta cables m-m respectando o código de cores (vermello VCC, negro GND e o pin de control a cor que elixas). Suxéitaos ben con cinta illante e etiqueta o cable que vai a arduino.

Utiliza unha clema para conectar todos os cables de alimentación que veñen dos compoñentes. De alí saca dous cables (vermello 5V e negro GND ) que se conectarán a arduino. Despois conecta os cables de sinal do sensor, os pulsadores e os servos a cada pin correspondente de arduino. Nós usamos:

  • Sensor: SDA (A4) e SCL (A5)
  • Servo superior: pin 12
  • Servo inferior: pin 11
  • Pulsador marcha (negro): pin 3
  • Pulsador calibrado (branco): pin 2

Podes usar un pouco de cinta illante para suxeitar ben as conexións ao arduino e así evitar que se desconecten ao manipular a máquina.

Finalmente coloca o tubo co seu soporte e axusta a altura para que os M&M’s vaian entrando ben no colector do servo.

Antes de pegar a estrutura definitivamente con cola branca suxéitaa cun pouco de cinta, xa que primeiro debemos facer unhas probas para comprobar que todo está correctamente conectado. Con todo, cando pegues a estrutura e se tes pensado engadir máis elementos (por exemplo unha pantalla LCD ou OLED), deixa sen pegar con cola a peza inferior, pois así será máis fácil conectar novos cables ao arduino.

-> Mira as outras pestanas para facer os tests ou engadir unha pantalla

Test sensor

Imos comprobar que o sensor funciona. De entrada, cando conectas o arduino debes ver unha luz emitida polo sensor. Se non a ves revisa as conexións de alimentación o sensor.

Carga o seguinte programa e abre a consola. Se ao cargar o programa aparece “Sensor TCS34725 non atopado” revisa as conexións  SDA (A4) e SCL (A5). Se aparece “Sensor atopado” é que se estableceu correctamente a comunicación co sensor.

// Librerías 

#include <Wire.h>
#include <Adafruit_TCS34725.h>
#include <ColorConverterLib.h>

// Declaración de variables

// Sensor TCS34725 RGB

Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);

void setup(){  

  // Comunicación consola serie
  
  Serial.begin(9600);   

  // Iniciar o sensor
  
  if (tcs.begin()) {
    Serial.println("Sensor atopado");
  }
  else {
    Serial.println("Sensor TCS34725 non atopado");
    while (1); // deter!
  }

}

void loop(){

}

Test servos

Agora imos probar este programa para comprobar que tanto os pulsadores como os servos funcionan correctamente e para axustar os ángulos dos servos na posición axeitada. No caso de que algún compoñente non responda revisa as conexións.

Debes modificar os valores dos ángulos do servo superior angRecolle (baixo o tubo), angSensor (baixo o sensor), angBota (sobre o burato) e de momento o servo inferior ímolo situar na posición central angCentral.

// Importamos a librería servo
#include <Servo.h>

// Declaración de variables:

int marchaPin=3;    // Pulsador marcha
int calibradoPin=2; // Pulsador calibrado

Servo topServo;
Servo bottomServo;

// axustar estes valores ata que os servos estean na posición correcta

int angRecolle=158;   // ángulo para recoller
int angSensor=102;    // ángulo para que o sensor detecte a cor
int angBota=68;       // ángulo para botar pola rampla

int angCentral=70;    // ángulo inicial da rampla


// Configuración:

void setup(){
  
  topServo.attach(12);
  bottomServo.attach(11);

  bottomServo.write(90);
  topServo.write(90);
  
}

// LOOP:

void loop(){

  // agardar a premer algún dos pulsadores (probar que funcionen os dous)

  while (digitalRead(marchaPin)==0 &&  digitalRead(calibradoPin)==0);
  delay(20);

  // descomentamos os ángulos que queremos probar ata axustalos e comentamos os que non.
  
  bottomServo.write(angCentral);

  topServo.write(angRecolle);
  // topServo.write(angSensor);
  // topServo.write(angBota);
  
}

Accesorios

O que fixemos ata agora forma parte do prototipo básico. Porén, podemos engadir outros compoñentes á nosa máquina, como unha pantalla LCD ou OLED, un teclado matricial, un selector de moedas para facer unha máquina expendedora, … ou o que queiras engadir. Estes elementos ímolos situar no exterior da máquina e meteremos os cables polo burato lateral inferior. Se tes pensado engadir accesorios é importante que non fagas un pegado definitivo da peza inferior na que está a placa arduino, para así poder realizar novas conexións con facilidade.

Pantalla LCD

As pantallas LCD conéctanse a través do bus I2C. Tanto ten que xa teñas os pins SDA e SCL ocupados polo sensor, xa que podemos conectar varios dispositivos aos mesmos pins. O único que hai que coñecer é o enderezo usado por cada dispositivo. O que imos facer é utilizar unha nova clema para conectar os cables SDA e SCL que veñen do sensor e da pantalla e de alí sacaremos os cables que van á placa arduino. Os cables de alimentación da pantalla irán á clema na que conectamos todos os cables de alimentación dos dispositivos.

lcd_i2c   

Programación:

Prácticas:

Antes de empezar, fai as prácticas de:

Agora empezamos a programar a máquina. É importante que vaias gardando diferentes versións do programa a medida que vaias engadindo novas funcións.

Os servos:

O primeiro que temos que facer é configurar os dous servos. Podemos chamar “topServo” ao superior (pin 12) que recolle os caramelos, e  “bottomServo” ao inferior (pin 11) que dirixe a rampla ata cada caixa.

O servo inferior debe comezar na posición central (angCentral). O servo superior ten tres posicións. Na nosa máquina montada son os seguintes, pero se construíches unha nova utiliza os ángulos que obtiveches facendo o test do servos.

int angRecolle=178;   // ángulo para recoller o caramelo do tubo
int angSensor=125;    // ángulo para que o sensor detecte a cor
int angBota=68;       // ángulo para botar o caramelo pola rampla

int angCentral=70;    // ángulo inicial da rampla

Podes definir tres funcións que dan as instrucións do movemento do servo superior:

void ir(){ 
  -- instrucións para ir desde o angRecolle ata o angSensor -- 
}

void volver(){ 
  -- instrucións para ir 1º desde o angSensor ata o angBota e despois volver ata angRecolle -- 
}

Fai que o movemento do servo dun ángulo a outro sexa paulatino, e non o faga de golpe (pode saír o caramelo disparado). Crea unha variable tempo no inicio do programa para axustar a velocidade de movemento dos servos. Axúdate co exemplo “pouco a pouco” que vimos nas prácticas co servo.

Comproba que co tubo cheo de M&M’s o servo superior é quen de coller un, parar un pouco debaixo do sensor, depositalo na rampla e repetir o proceso continuamente.

void loop(){
  ir();
  delay(500);
  volver();
  delay(500);
}

O pulsador:

Engade o pulsador negro (pin 3) e fai que a máquina non se poña en marcha ata que premas nel. Utiliza a función de control while que agarda mentres o pulsador non está premido.

Cando remates, ao premer no pulsador debería funcionar recollendo os caramelos e botándoos pola rampla:

A cor:

Crea un novo programa independente do programa anterior dos servos e engade as librerías, funcións e instrucións necesarias para detectar e identificar as cores, tal e como viches no exemplo “Detectar cor” do sensor de cor TCS34725 RGB . Tamén inicia a comunicación serie para poder visualizar os datos na consola.

Calibrado manual: Fai unha primeira proba de calibración co sensor de cor. Visualiza na consola e apunta o valor “nuanceT” para cada cor na posición situada debaixo do sensor. Como referencia podes atopar valores similares a estes, pero apunta os que atopas ti segundo o teu modelo de sensor e as condicións de traballo.

float nada= 350;   // maxenta
float vermello= 15;
float laranxa = 22;
float marron = 32;
float amarelo= 43;
float verde= 96;
float ciano = 195;

Cos valores detectados, axusta a función String printColorNameT() que devolve a cor detectada.

String printColorNameT() {

  if (nuanceT >= nada -50){         // Se usamos maxenta no soporte
    return nameColorT = "nada";
  }
  else if (nuanceT <= vermello +5){
    return nameColorT = "Vermello";
  }

  ... (sigue ti)

}

Proba de identificación: Une o programa que acabas de facer co anterior do movemento do servo superior.  Enche o tubo de caramelos e comproba na consola que a medida que o servo superior vai colocando os elementos baixo o sensor se mostra na consola a cor correspondente. Se algo falla (non identifica ben as cores, os caramelos saen disparados, o tubo se atasca, …) fai os axustes necesarios ata que todo vaia ben. Pon tempos de agarda algo amplos para que che dea tempo a visualizar os datos da consola. No programa definitivo xa o cambiarás. Inicialmente é mellor que vaia lento.

void loop(){
  ir();
  delay(200);
  LerCor(); 
  identificaCor();
  mostrarCor();
  delay(200);
  volver();
  delay(1000); 
}

Cando remates deberás ver na consola os valores das cores dos caramelos, ben identificados:

A clasificación:

Agora debemos dar as instrucións necesarias ao servo inferior para que se mova ata un ángulo diferente segundo a cor. Creamos unha función “separar” que ordene ao servo inferior que se mova ata un ángulo diferente en cada caso. No caso de que estea o tubo baleiro non ordenaremos ao servo que se mova.

Tamén imos definir no inicio unha variable “cor” que toma un valor enteiro segundo a cor detectada, que despois nos pode facilitar contar os caramelos de cada cor ou ver se xa está o tubo baleiro, por exemplo.

void separar(){
  
  if (printColorNameT()=="Vermello"){
    cor=1;
    bottomServo.write(15); // vermello
  }
  else if (printColorNameT()=="Laranxa"){
    cor=2;
    bottomServo.write(38); // laranxa
  }
  ... (sigue ti)

}

No loop poñemos todo xunto:

void loop(){

  ir();
  LerCor(); 
  delay(100);
  identificaCor();
  mostrarCor();
  delay(100); 
  separar();
  volver();
  delay(1000);
    
}

Parada automática

Fai que cando non queden caramelos a máquina pare automaticamente e volva arrancar cando premamos no pulsador. Pensa como facelo: Se o tubo está baleiro o colector para, avisa de que non hai caramelos e agarda a que premas no pulsador. Cando o tubo non está baleiro fai a clasificación.

Quedaría algo así despois de engadir unha pantalla LCD:

 

Propostas de mellora:

  • Contador na consola: engade o necesario para visualizar na consola cantos M&M’s de cada cor contou e o total.
  • Contador nunha pantalla: Engade unha pantalla LCD ou, mellor, unha pantalla OLED na que se mostre cantos M&M’s de cada cor contou, o total e, se te animas, un gráfico de barras de cores que mostre esas cantidades.
  • LEDs RGB: Podemos engadir nalgún sitio un LED RGB ou unha roda de LEDs que se ilumine da cor do caramelo cada vez que detecta un. Cando non detecta ningún caramelo debe estar apagado.
[pulsador con memoria]
  • Pulsador con memoria: Fai que a máquina arranque ao premer no botón e que pare cando prememos de novo premendo durante un tempo.
    Se queremos parar a máquina manualmente cando prememos de novo o pulsador debemos definir unha variable “estado” que garde na memoria se está en ON ou en OFF, e que cambie cada vez que prememos. Está explicado na sección de detección de pulsos “memoria“. A variable na que almacenas a información pode ser booleana e dar coma resultado dous estados: true e false.
bool estado_OnOff = false;

Para complicalo máis:

  • Calibración: Engade un segundo pulsador (pin 2). No inicio, antes de arrancar a máquina cos parámetros preestablecidos o sistema pregunta se queremos calibrar ou arrancar. Se prememos no pulsador de calibrado procede á calibración das diferentes cores que atopa, asignando o valor lido a unhas variables definidas para cada cor. En función dos valores que lea calcula os valores de rango para que a máquina actúe e actualiza eses parámetros no programa. Ao premer no pulsador principal a máquina funcionará cos novos valores. As instrucións deberán lerse na pantalla.
    void calibrar(){
    
      Serial.println("Imos proceder a calibrar");
      delay(500);
    
      Serial.println("Elimina todas as fichas e preme no botón de calibrado");
      agardarPulsadorCalibrado();
      ir();
      LerCor();
      identificaCor();
      delay(100);
      nada= nuanceT;  // asignamos o valor NuanceT lido á variable "nada"
      Serial.println("nada" + String(nada));
      volver();
    
      ... (sigue ti)
    
    }
  • Petición persoal: A máquina nos dará a cantidade de M&M’s e da cor que pida o usuario a través dun teclado matricial. Por exemplo, “5 caramelos verdes”. Para iso separa os caramelos en dúas caixas, unha que será para o usuario, e outra que será para colocar os caramelos rexeitados e que volverán a poñer na máquina. Cando estea preparado o pedido un servo abrirá unha comporta que mostrará a caixa do pedido.
  • Máquina expendedora: Podes engadirlle ao anterior un sistema detector de moedas. A máquina devolverá en múltiplos de 5 (prezo= 1 céntimo/caramelo) un número de caramelos correspondente e da cor elixida.

Vídeos:

Vídeo do primeiro prototipo de proba: