Como criar uma máquina separadora de cores com Arduino 4

Nesse artigo vamos construir um protótipo de uma máquina separadora de cores. Ela irá separar M&Ms, aqueles chocolates coloridos que dispensam apresentações. Dessa vez, além das montagens eletrônicas e linhas de código vamos precisar usar nossas habilidades manuais.

Esse é um projeto de média complexidade, devido as montagens das partes mecânicas da máquina, mas não é tão complexo quanto parece e também não é um projeto caro.

Como funciona a máquina separadora de cores

  • Os M&Ms são carregados em um tubo no topo da máquina.
  • O tubo dispõe um M&M por vez na plataforma do primeiro servo motor.
  • O primeiro servo motor rotaciona levando o M&M para ser analisado pelo sensor de cor.
  • Então, o segundo servo motor rotaciona para a posição correspondente a cor detectada.
  • Por fim, o primeiro servo motor rotaciona dispensando o M&M na rampa e volta para a posição inicial.

Materiais Necessários

Imagem 1 - Material necessário para máquina separadora de cores

Eletrônica

Mecânica

  • Caixa de papelão
  • Acetato
  • Cola

Ferramentas

  • Estilete
  • Régua
  • Compasso

Montando a máquina separadora de cores

Neste projeto, utilizamos a própria caixa do SuperMaker (uma utilidade muito bacana, não é mesmo?) confeccionada em papelão com 2 mm de espessura. Utilizamos esta caixa devido a disponibilidade, entretanto pode ser usada qualquer caixa com dimensões similares ou ainda com espessura maior. Faça o download dos planos de corte abaixo e monte a sua própria caixa.

Imagem 1 - Montando a máquina separadora de cores

Projeto e planos de corte:
Plano de corte – parte I
Plano de corte – parte II

Aqui vão algumas dicas:

  • Escolha um papelão mais firme, sem dobras.
  • Ao cortar os círculos retiramos muito material deixando a peça sem resistência, se ela ficar molenga, reforce com palito de dente.
  • O alimentador foi feito enrolando um pedaço de acetato e fixando com fita adesiva. Um alimentador mais simples pode ser feito usando papel sulfite normal.
  • Cole alguns pedaços de papelão embaixo das plataformas, nas laterais da caixa, para deixá-las niveladas. E caso estas se dobrem, faça reforço nas bordas.

Montagem do circuito da máquina separadora de cores

Imagem 3 - Circuito eletrônico

Quando estamos prototipando, uma das coisas que pode transformar nosso projeto em um verdadeiro pesadelo são os fios. Precisamos nos esforçar para manter tudo organizado. Nesse sentido, eu coloquei jumpers que saem do Arduino e vão diretamente para os sensores. A parte da alimentação foi feita usando uma mini protoboard que distribuiu as linhas para os servos e o sensor de cor. Para o sensor de cor, eu soldei um cabo flat diretamente no sensor e na outra ponta eu usei conectores MODU.

O sensor de cor usado é o TCS3200, ele é um chip que possui vários fotodiodos que filtram a luz refletida por objetos colocados em sua frente e disponibiliza a informação no pino OUT para ser interpretada pelo microcontrolador. Se você quer saber o funcionamento detalhado desse módulo, acesse o artigo publicado aqui no blog da MakerHero sobre esse sensor.

Como calibrar e montar sua máquina separadora de cores

Descrição do código

Para esse projeto eu criei dois códigos. O primeiro é o que eu chamei de Calibração, nele temos controle manual dos servos e podemos ler o sensor de cor ininterruptamente. Assim, podemos testar as posições dos servos antes de colocar em definitivo as peças que serão fixadas neles. Também, podemos posicionar o M&M abaixo do sensor de cor e estudar o seu comportamento, quais as faixas de frequência que estão sendo lidas. Segue o código de calibração:

#include <Servo.h> // Biblioteca para os servo motores

#define S0 2 //definição dos pinos do sensor de cor
#define S1 3
#define S2 4
#define S3 5

#define sensorOut 6

Servo topServo; // declaração de cada servo como objeto
Servo bottomServo;

int frequency = 0; //variável auxiliar para ser usada na função readColor()
int color = 0; //variável usada na função readColor() para guardar a cor 

void setup() {
  pinMode(S0, OUTPUT); //definição dos pinos do sensor de cor como saída
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT); //definição do pino do sensor de cor como entrada
  // configura a frequência para 20% 
  digitalWrite(S0, HIGH);
  digitalWrite(S1, LOW);
  
  topServo.attach(7); //definição do servo superior no pino 7 do arduino
  bottomServo.attach(8);//servo inferior no pino 8 
  
  Serial.begin(9600); //inicia a comunicação serial

}

void loop() {
//O loop espera uma entrada no serial monitor 1,2,3,4,5,6,7,8 ou 9.
//enviar 1,2 ou 3 controla as posições do servo superior
//enviar 4,5,6,7,8 ou 9 controla as posições do servo inferior
//envie o número para calibrar as posições e posicionar as peças de
//maneira correta à máquina.

if(Serial.available() > 0){//Checa se há dados disponíveis na porta serial
 char pos = Serial.read();//guarda o dado na variável pos
 if(pos == '1'){//Se for pressionado 1 o servo se move a posição inicial
  topServo.write(115);//Posição inicial do servo; Deve estar alinhado com o furo do alimentador
 }
 if(pos == '2'){//Se for pressionado 2 o servo se move a posição intermediária
  topServo.write(65);// Posição intermediária, deve estar alinhado com o sensor de cor
 }
 if(pos == '3'){//Se for pressionado 3 o servo se move a posição final
  topServo.write(29);// Posição final, deve estar alinhada com o furo do distribuidor
 }
 if(pos== '4'){ //cada cor deve estar atrelada a uma posição do servo inferior
  bottomServo.write(50);
 }
 if(pos== '5'){
  bottomServo.write(75);
 }
  if(pos== '6'){
  bottomServo.write(100);
 }
  if(pos== '7'){
  bottomServo.write(125);
 }
  if(pos== '8'){
  bottomServo.write(150);
 }
  if(pos== '9'){
  bottomServo.write(175);
 }
} 
readColor(); //Função que criamos para fazer a leitura do sensor de cor
}

void readColor() {
//Essa função mostra no serial monitor os valores lidos pelo sensor
//Possibilitando assim a calibração das faixas de cada cor
//Importante pois cada sensor responderá de forma diferente a
//cada objeto colorido colocado em sua área de detecção.
  
  // configura os filtros vermelhos para serem lidos
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  // lê a frequencia da saída
  frequency = pulseIn(sensorOut, LOW);
  int R = frequency; // armazena o resultado na variável correspondente ao vermelho
  // Os valores são mostrados no serial monitor
  Serial.print("R= ");//escreve o nome 
  Serial.print(frequency);//escreve a frequencia
  Serial.print("  ");
  delay(50);
  // Configura os filtros verdes para serem lidos
  digitalWrite(S2, HIGH);
  digitalWrite(S3, HIGH);
  // Lê a frequência de saída
  frequency = pulseIn(sensorOut, LOW);
  int G = frequency;
  // Os valores são mostrados no serial monitor
  Serial.print("G= ");
  Serial.print(frequency);
  Serial.print("  ");
  delay(50);
  // Configura os filtros azuis para serem lidos
  digitalWrite(S2, LOW);
  digitalWrite(S3, HIGH);
  
  frequency = pulseIn(sensorOut, LOW);
  int B = frequency;
  
  Serial.print("B= ");
  Serial.print(frequency);
  Serial.println("  ");
  delay(150);

  //Existe uma faixa de valores para cada cor RGB
  //O valor minimo, exemplo R>42 e o valor máximo,
  //exemplo R<46. 
  //Busque a partir da leitura do serial monitor
  //entender como se comporta o seu objeto.
  //Não detectando nenhuma cor aparecerá a mensagem
  //No Match
  //Então altere as faixas de valores RGB até
  //que apareça a cor colocada no sensor.
  if(R<46 && R>42 && G<59 && G>54 && B<42 && B>36){
    Serial.println(" Laranja ");
  }
  if(R<56 && R>48 && G<58 && G>50 && B<42 && B>37){
    Serial.println(" Verde ");
  }
  if(R<45 && R>38 && G<51 && G>43 && B<39 && B>33){
    Serial.println(" Amarelo ");
  }
  if(R<56 && R>49 && G<56 && G>48 && B<37 && B>31){
    Serial.println(" Azul ");
  }
  else Serial.println("No Match");
}

O segundo código é o da nossa máquina final. Veja que é necessário alimentar o código da máquina final após termos finalizado a montagem e ter definido as faixas de frequência de cada cor. Vamos a uma breve explicação do código:

Incluímos a biblioteca “Servo.h”, definimos os pinos aos quais o sensor de cores é conectado, criamos os objetos servo e declaramos algumas variáveis ​​necessárias para o programa. Na função setup, precisamos definir os pinos como Saídas e Entradas, definir a escala de frequência para o sensor de cores, definir os pinos do servo e iniciar a comunicação serial para imprimir os resultados da cor lida no monitor serial.

Em síntese, o código da máquina final espera o usuário digital no monitor serial a letra “s” para colocar a máquina em funcionamento, enquanto isso ela espera com o servo na posição 1. Após o usuário enviar o valor “s” o servo leva o M&M para o sensor de cor que só irá jogá-lo na rampa após ter realizado a leitura de uma das 5 cores.

Depois que um M&M é dispensado, o servo do topo retorna a posição 1 onde pega mais um M&M e repete os procedimentos acima em loop. Em caso de problemas ou quando os M&Ms acabarem temos a possibilidade de dar um reset na máquina a colocando na posição inicial novamente, para isso enviamos a letra “r” no monitor serial. Se desejamos ativar a máquina, enviamos “s”. Segue o código:

//Projeto Maquina separadora de M&M's
//Por: Eng. Mauricio Gavina

#include <Servo.h> // Biblioteca para os servo motores

#define S0 2 //definição dos pinos do sensor de cor
#define S1 3
#define S2 4
#define S3 5

#define sensorOut 6

Servo topServo; // declaração de cada servo como objeto
Servo bottomServo;

int frequency = 0; //variável auxiliar para ser usada na função readColor()
int color = 0; //variável usada na função readColor() para guardar a cor 

byte flag = 0; //A variável flag nos ajuda a separar nosso programa em estados

void setup() {
  pinMode(S0, OUTPUT); //definição dos pinos do sensor de cor como saída
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT); //definição do pino do sensor de cor como entrada
  // configura a frequência para 20% 
  digitalWrite(S0, HIGH);
  digitalWrite(S1, LOW);
  
  topServo.attach(7); //definição do servo superior no pino 7 do arduino
  bottomServo.attach(8);//servo inferior no pino 8 
  
  Serial.begin(9600); //inicia a comunicação serial
}

void loop() {
//O primeiro estado do nosso programa é quando a máquina está ligada mas em espera  
if(flag == 0){
  topServo.write(115);//Posição inicial do servo; Deve estar alinhado com o furo do alimentador
  if(Serial.read()== 's' || Serial.read()=='S'){//Assim que pressionamos a letra s a máquina opera
  topServo.write(65);// Posição intermediária, deve estar alinhado com o sensor de cor
  flag=1;//envia a máquina para o segundo estado
  }
}

if(flag == 4){//Esse é o estado em que a máquina está em operação contínua
  topServo.write(115);//Posição inicial do servo; Deve estar alinhado com o furo do alimentador
  delay(1000);//usamos o delay para dar tempo do servo se mover até a posição final
  topServo.write(65);// Posição intermediária, deve estar alinhado com o sensor de cor
  flag=1;//envia a máquina para o segundo estado
}

if(flag == 1){//Nesse estado a máquina lê o sensor e mostra os dados no monitor serial
  readColor();//A função é responsável pela leitura do sensor e por enviar ao terceiro estado
}             //somente quando uma cor for detectada.

if(flag == 2){ //Nesse estado o servo de baixo se move conforme a cor detectada anteriormente
    switch (color) {
    case 1:
    bottomServo.write(75);
    break;
    case 2:
    bottomServo.write(100);
    break;
    case 3:
    bottomServo.write(125);
    break;
    case 4:
    bottomServo.write(150);
    break;
    case 5:
    bottomServo.write(175);
    break;
  }
  delay(1000);//os delays foram incluidos para dar tempo ao servo se mover 
  topServo.write(29);// Posição final, deve estar alinhada com o furo do distribuidor
  delay(1000);
  flag = 4; //enviamos a máquina para funcionamento contínuo, o quarto estado.
}
if(Serial.read()=='r' || Serial.read()=='R'){ //Caso a letra r seja enviada a máquina é 
  flag=0;                                     //resetada e retorna ao estado 1.
}

}

void readColor() {
  // configura os filtros vermelhos para serem lidos
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  // lê a frequencia da saída
  frequency = pulseIn(sensorOut, LOW);
  int R = frequency; // armazena o resultado na variável correspondente ao vermelho
  // Os valores são mostrados no serial monitor
  Serial.print("R= ");//escreve o nome 
  Serial.print(frequency);//escreve a frequencia
  Serial.print("  ");
  delay(50);
  // Configura os filtros verdes para serem lidos
  digitalWrite(S2, HIGH);
  digitalWrite(S3, HIGH);
  // Lê a frequência de saída
  frequency = pulseIn(sensorOut, LOW);
  int G = frequency;
  // Os valores são mostrados no serial monitor
  Serial.print("G= ");
  Serial.print(frequency);
  Serial.print("  ");
  delay(50);
  // Configura os filtros azuis para serem lidos
  digitalWrite(S2, LOW);
  digitalWrite(S3, HIGH);
  
  frequency = pulseIn(sensorOut, LOW);
  int B = frequency;
  
  Serial.print("B= ");
  Serial.print(frequency);
  Serial.println("  ");
  delay(150);
  
  if(R<45 && R>40 && G<56 && G>50 && B<36 && B>32 ){
    color = 1; //Para ser usado pelo servo de baixo em seu posicionamento
    flag = 2; // Para enviar a máquina ao terceiro estado
    Serial.println(" Rosa ");//Escreve no monitor serial a cor detectada
  }
  if(R<46 && R>42 && G<59 && G>54 && B<42 && B>36){
    color = 2; 
    flag = 2;
    Serial.println(" Laranja ");
  }
  if(R<56 && R>48 && G<58 && G>50 && B<42 && B>37){
    color = 3; 
    flag = 2;
    Serial.println(" Verde ");
  }
  if(R<45 && R>38 && G<51 && G>43 && B<39 && B>33){
    color = 4; 
    flag = 2;
    Serial.println(" Amarelo ");
  }
  if(R<56 && R>49 && G<56 && G>48 && B<37 && B>31){
    color = 5; 
    flag = 2;
    Serial.println(" Azul ");
  }
  else Serial.println("No Match");
}

Conclusão

Como podemos ver no vídeo, eu usei somente três cores para fazer a demonstração porque o tamanho dos copos que tinha disponível não permitia colocar mais cores, é claro, é possível usar o número de cores que você quiser, nos programas que deixei no artigo já estão configurados cinco cores. Acredito que é possível fazer uma versão melhorada dessa máquina usando impressão 3D, a precisão das peças faz muita diferença no resultado final. Pretendo revisitar esse projeto em breve com uma versão melhorada, inclusive criando uma placa dedicada.

Curtiu do projeto máquina separadora de cores com Arduino? Ajude-nos a melhorar o blog, participe com a sua sugestão, dúvida ou comentário aqui embaixo.

Faça seu comentário

Acesse sua conta e participe

4 Comentários

  1. Boa noite, estou fazendo esse projeto mas o primeiro servo motor não gira e no início quando eu coloco o S para enviar pra máquina começar não gira tanto até o sensor de cor e depois pra girar pra cair o M&M.
    Conseguem me explicar como funciona?

  2. Boa noite!! Será que poderia disponibilizar o arquivo no fritzing?

    LUIZA MORAES DE CASTRO ABDALLA
  3. Boa noite amigo, estou fazendo esse projeto só que adicionei uma esteira transportadora ao projeto porem não estou conseguindo fazer rodar a esteira em conjunto usei um motor de passo 28BYJ -58 não estou conseguindo fazer a programação rodar quando ligo o motor de passo fica travando

    1. Manoel,

      O que trava? O programa?

      Abraços!
      Diogo – Equipe MakerHero