Máquina de classificação de cores
Componentes e suprimentos
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 3 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 20 | ||||
| × | 1 | ||||
| × | 3 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
Ferramentas e máquinas necessárias
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
|
Sobre este projeto
INTRODUÇÃO.
O engraçado é que esse projeto nunca foi feito para acontecer.
Cerca de 3,5 anos atrás eu comecei a projetar uma máquina de classificação de cores muito mais descolada e, como muitos dos meus projetos, ela acabou meio que juntando poeira no parapeito da janela (tenho certeza de que ninguém mais pode se relacionar com isso haha).
Para encurtar a história, há alguns meses decidi retomar este antigo projeto. A primeira coisa que eu precisava descobrir era como coletar Skittles de um reservatório e verificar sua cor de forma bastante confiável, mantendo o sistema o mais compacto que pude (o que não consegui na primeira vez). Consegui me convencer a projetar uma máquina de classificação de cores mais simples apenas para acertar o design do sistema de coleta. Eu tolamente pensei que seria um trabalho de 2 finais de semana, legal, fácil e rápido ... Nossa !!! eu estava errado...
Eu peguei 2 designs completamente diferentes e muitos protótipos ajustados para conseguir algo que funcionasse de maneira aceitável (ainda estou tendo alguns problemas de pega de vez em quando).
Mesmo não sendo perfeito, estou bastante satisfeito com o resultado.
COMO FUNCIONA.
A máquina pode ser dividida em 2 estágios principais.
No topo você pode encontrar o reservatório para os Skittles não classificados. No fundo deste reservatório está o mecanismo de alimentação responsável por coletar os Skittles e posicioná-los em frente ao sensor de cores onde sua cor será verificada.
O mecanismo de alimentação inclui um braço que sacode o conteúdo do reservatório para garantir que o Skittles flua bem através do orifício do mecanismo de alimentação sem emperrar dentro do reservatório (infelizmente isso ainda acontece em algum momento).
Assim que a cor do Skittle for encontrada, o segundo estágio da máquina entra em ação. O suporte de tubos de ensaio alinha o tubo direito na frente do mecanismo de alimentação para que o Skittle seja colocado.
O ciclo pode então ser repetido até que o reservatório esteja vazio.
QUER FAZER A SUA PRÓPRIA ???
.................. https://www.littlefrenchkev.com/colour-sorting-machine ................. ......
MONTAGEM.
Depois de fazer o download e imprimir as partes, você deve terminar com algo assim:
Observe que o shell frontal vem em 2 versões. Sem diferença real, eles apenas parecem diferentes.
O resto das peças necessárias.
Aqui está um vídeo do processo de montagem. Eu até tentei ser um artista fazendo uma introdução com fotos de impressora 3D slowmo !!!
CONFIGURAÇÃO INICIAL.
A primeira coisa que a máquina faz quando você liga a energia é mover ambos os servos para a posição inicial. Ao ligar a máquina pela primeira vez, você precisa se certificar de que a engrenagem / eixo que coleta os Skittles está na posição superior e que o suporte do tubo está alinhado com o mecanismo de alimentação.
RESOLUÇÃO DE PROBLEMAS.
Se você decidir fazer esta máquina de classificação sozinho, poderá encontrar alguns problemas comuns. aqui está como você pode resolvê-los.
LED piscando em vermelho - sem sequência inicial:
Depois de se mover para a posição inicial, a máquina deve passar por sua sequência de partida. Se isso não acontecer e, em vez disso, o LED piscar em vermelho, significa que você tem alguns problemas com o sensor RBG não sendo encontrado. Há um problema com a fiação ou o sensor está com defeito.
Os tubos não se alinham corretamente:
Causa 1
Durante a sequência de partida, o porta-tubos se moverá 5 vezes, uma para cada cor. Você pode notar que os tubos não se alinham muito bem com o mecanismo de alimentação. Isso pode ser devido aos servos não serem superprecisos ou a algumas variações nas dimensões de impressão.
Isso pode ser corrigido por meio do software, modificando o array de variáveis colour_angle. Cada valor nesta matriz representa a posição do servo para cada cor, alterando esses valores, você pode fazer o ajuste fino de onde o tubo irá parar para cada cor.
Causa 2
Devido às tolerâncias de impressão, você também pode obter alguma folga nas engrenagens do porta-tubos. Dependendo de como os tubos estão girando, sua inércia pode fazer com que eles ultrapassem sua posição de parada. Isso também pode ser corrigido por meio do software, modificando a variável anti-retrocesso para frente e para trás. Esse valor será adicionado ou removido dos valores do ângulo de cor, dependendo de qual direção o suporte está girando para compensar essa folga.
Mistura de cores:
Se você experimentar alguma mistura de cores, você terá que modificar os arrays colour_limit_values. Cada valor nessa matriz representa os valores mínimo e máximo para Vermelho, Verde e Azul. Para ter uma ideia melhor de quais devem ser os valores, carregue a máquina com apenas uma cor, conecte a máquina ao computador e abra o monitor serial. Cada vez que um Skittle está sendo verificado, você deve obter seus valores RGB lidos e a cor que o programa pensa que seja. Isso deve dar a você uma ideia melhor de quais tipos de valores devem ser associados a cada cor.
ALGUNS RECURSOS LEGAIS.
(bem, eu acho que eles são mesmo!)
O LED RGB:
Há um LED RGB instalado na base da máquina. Durante o processo de classificação, ele muda de cor para combinar com a cor do Skittle que está sendo largado. Ele passa por todas as cores do Skittle continuamente assim que o reservatório está vazio.
Ele também piscará em vermelho na inicialização se um problema for detectado com o sensor.
Compensação anti-folga:
O suporte dos tubos é girado usando duas engrenagens de dentes retos. Devido à tolerância de impressão, é muito difícil livrar-se completamente de qualquer folga nas engrenagens. Isso significa que o suporte do tubo tende a ultrapassar sua posição ideal. O código permite compensar isso parando o suporte antes de uma certa quantidade, dependendo da direção em que o suporte está girando.
Atraso com extra:
O código inclui uma função "set_led (ms, color)". Ele age exatamente como a função "atraso (ms)", mas permite que o LED mude suavemente para sua nova cor enquanto o atraso ocorre. Funcionou muito bem mudar as cores do LED enquanto o suporte do tubo girava para sua posição!
NOTAS EXTRA.
Nota 1:Eu imprimi minha máquina em preto, isso terá um impacto sobre os valores de cor que o sensor irá ler, especialmente quando nenhum Skittles é coletado pelo mecanismo de alimentação.
Nota 2:Depois de passar pelo processo de classificação várias vezes, as cores do Skittles parecem se tornar mais difíceis de ler de forma confiável. Suponho que isso seja devido a eles perderem o brilho depois de esfregar dentro do reservatório muitas vezes ou ficarem um pouco mais pegajosos quando manuseados manualmente (parece nojento!). Ao calibrar os valores de cor, tente usar Skittles 'frescos'.
Nota 3:Certifique-se de tomar todas as precauções necessárias ao manusear alimentos. Isso inclui certificar-se de usar filamento de impressão seguro para alimentos.
Nota 4:Tento postar alguns trabalhos em andamento e que projeto estou fazendo no Instagram. Se for do seu interesse, você pode dar uma olhada aqui:https://www.instagram.com/little_french_kev/
Código
- LFK_sorting_machine
LFK_sorting_machine C / C ++
Aqui está o código do Arduino para a máquina de classificação.#include#include "Adafruit_TCS34725.h" #include / * Com base no código de exemplo para a biblioteca de breakout Adafruit TCS34725 * /// ===========================Variáveis relacionadas ao sensor RGB =========================Adafruit_TCS34725 tcs =Adafruit_TCS34725 (TCS34725_INTEGRATIONTIME_24MS, TCS34725_GAIN_1X); // configurar RGB sensorint color =0; // 0-preto, 1-amarelo, 2-verde, 3-laranja, 4-vermelho, 5-roxoint previous_colour =color; int black_count =0; // contagem de colorint vazio / desconhecido start_measurment_angle =88; // posição do servo para alinhar o skittle na frente do sensorint mensment_sweep =2; // número de medidas tomadas. usado para calcular a média de errorint Measment_angle_increment =4; // incremento do ângulo entre as medições // valores limite [] ={min_red_values, max_red_values, min_green_values, max_green_values, min_blue_values, max_blue_values} uint16_t black_limit_values [] ={0, 200, 0, 200, 0, 200}; {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}; // =======================Variáveis relacionadas ao 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}; // =========================Variáveis relacionadas a servos alimentadores ===========================int release_delay =220; const int colour_angles [] ={10, 46, 82, 118, 154}; // {10, 46, 82, 118, 154}; // int holder_offset =0; // ajuste de deslocamento para suporte de tubos. a ser mantido entre 0 e 36const int backward_anti_backlash =2; const int forward_anti_backlash =2; Servo feeder_servo; // declara alimentador servoServo holder_servo; // declara servo de suporte de tubos // ===================================CONFIGURAÇÃO ===============================================configuração void (void) {Serial.begin (9600); pinMode (R_pin, OUTPUT); // define pinMode do pino do LED (G_pin, OUTPUT); pinMode (B_pin, OUTPUT); analogWrite (R_pin, 255); // desliga o LED analogWrite (G_pin, 255); analogWrite (B_pin, 255); feeder_servo.attach (3); // conecta o servo do alimentador ao pino 3 holder_servo.attach (2); // conecta o servo do suporte ao pino 2 feeder_servo.write (0); holder_servo.write (colour_angles [0]); branco int [] ={0, 0, 0}; // variável de valores de branco local int black [] ={255, 255, 255}; // variável de valores de preto local set_led (1000, branco); // liga o LED (branco) if (tcs.begin ()) {// verifica se o sensor foi encontrado Serial.println ("Sensor encontrado"); startup_sequence (); } else {Serial.println ("Nenhum TCS34725 encontrado ... verifique suas conexões"); while (1) // piscando rapidamente em vermelho se o sensor não for encontrado {set_led (300, vermelho); set_led (300, preto); }}} // =======================================LOOP =============================================void loop (void) {if (black_count <10) {feeder_servo.write (0 ); // define a posição do servo para o topo para atraso de coleta de skittle (450); // demora para permitir que o servo do alimentador tenha tempo suficiente para chegar na posição previous_colour =color; get_colour (); // lê a cor do skittle if (color ==0) {black_count ++; // se nenhuma cor for encontrada, incrementa a contagem de preto shake (); // dá um pouco mais de vibração ao reservatório, mesmo se não houver skittle lá} else if (color ==6) {black_count ++; // se a cor for desconhecida, incrementar a contagem de preto - sem liberação do skittle} else {// se a cor for encontrada move_holder (); // move o suporte do tubo release_skittle (); // libera skittle black_count =0; }} else {end_loop (1000); }} // =======================================OBTER COR =============================================void get_colour () {uint16_t r, g, b, c; //, colorTemp , Luxo; uint16_t total_r =0; uint16_t total_g =0; uint16_t total_b =0; feeder_servo.write (start_measurment_angle); // move para iniciar o ângulo de medição delay (200); Serial.println ("----------------"); for (int i =0; i <=Measment_sweep; i ++) // loop para cada medida {tcs.getRawData (&r, &g, &b, &c); // obtém os dados de cor feeder_servo.write (start_measurment_angle + i * Measment_angle_increment); // incrementa o ângulo do servo para a próxima medida total_r + =r; // adiciona o valor vermelho ao valor vermelho total total_g + =g; // adiciona o valor verde ao valor verde total total_b + =b; // adiciona o valor de azul ao valor de azul total delay (15); } total_r / =Measment_sweep; // valores médios em todas as medições total_g / =Measment_sweep; total_b / =medição_varredura; Serial.print (total_r); Serial.print (""); Serial.print (total_g); Serial.print (""); Serial.print (total_b); Serial.print (""); Serial.println (""); // compare os valores para determinar a cor. if ((total_r =yellow_limit_values [0]) &&// verificar se há amarelo (total_r =yellow_limit_values [2]) &&(total_g =valores_limite_marelo [4]) &&(total_b =green_limit_values [0]) &&// verificar se há verde (total_r =green_limit_values [2]) &&(total_g =green_limit_values [4]) &&(total_b =orange_limit_values [0]) &&// verificar se há laranja (total_r =orange_limit_values [2]) &&(total_g =orange_limit_values [4]) &&(total_b =red_limit_values [0]) &&// verificar se há vermelho (total_r =red_limit_values [2]) &&(total_g =red_limit_values [4]) &&(total_b =purple_limit_values [0]) &&// verificar se há roxo (total_r =purple_limit_values [2]) &&(total_g =purple_limit_values [4]) &&(total_b color) {// força o servo do suporte a retroceder além da posição normal para compensar a folga da engrenagem int anti_backlash_angle =new_holder_position - backward_anti_backlash; holder_servo.write (anti_backlash_angle); // atraso (holder_delay); } else {int anti_backlash_angle =new_holder_position + forward_anti_backlash; //holder_servo.write(anti_backlash_angle); holder_servo.write (new_holder_position); // move o titular na posição // atraso (holder_delay); } if (cor ==1) {set_led (holder_delay, amarelo); } else if (color ==2) {set_led (holder_delay, green); } else if (color ==3) {set_led (holder_delay, orange); } else if (color ==4) {set_led (holder_delay, red); } else if (color ==5) {set_led (holder_delay, purple); } else {}} // ===============================RELEASE SKITTLE ===========================void release_skittle () {feeder_servo.write (180); // definir a posição do servo na parte inferior para o atraso de liberação do skittle (release_delay);} // ===================================SHAKE =====================================void shake () {int shake_delay =80; valor_mitar_int int =5; int shake_min_value =90; int shake_max_value =180; feeder_servo.write (180); // define a posição do servo para o fundo para atraso de liberação do skittle (release_delay); feeder_servo.write (120); // define a posição do servo para o fundo para atraso de liberação do skittle (80); for (int i =0; i <=shake_amount; i ++) // loop para cada medida {feeder_servo.write (shake_min_value); // define a posição do servo para o fundo para o atraso de liberação do skittle (shake_delay); feeder_servo.write (shake_max_value); // define a posição do servo para o fundo para o atraso de liberação do skittle (shake_delay); }} // ============================INICIANDO SEQUÊNCIA ============================void initial_sequence () {color =1; move_holder (); set_led (300, amarelo); atraso (400); cor =2; move_holder (); set_led (300, verde); atraso (400); cor =3; move_holder (); set_led (300, laranja); atraso (400); cor =4; move_holder (); set_led (300, vermelho); atraso (400); cor =5; move_holder (); set_led (300, roxo); atraso (400); cor_ anterior =cor; cor =3; move_holder (); end_loop (200);} // ================================END LOOP =====================================void end_loop (duração int) {set_led (duração, laranja); set_led (duração, vermelho); set_led (duração, verde); set_led (duração, amarelo); set_led (duration, purple);} // ============================SET RGB LED COLOR =======================// Isso age como um atraso (), mas permite que o LED mude de cor enquanto espera .void set_led (int duration, int color [3]) {int start_time =millis (); // valor da hora de início int current_time =start_time; // valor da hora atual int current_duration =0; // duração total while (current_duration
Esquemas
A fiação é bastante simples. Apenas certifique-se de que sua saída do conversor de buck 5V antes de conectar qualquer coisa a ele !!!!!Processo de manufatura