色选机
组件和用品
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 3 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 20 | ||||
| × | 1 | ||||
| × | 3 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
必要的工具和机器
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
|
关于这个项目
介绍。
有趣的是,这个项目本来就不是。
大约 3.5 年前,我开始设计一个更时髦的颜色分类机,就像我的许多项目一样,它最终在窗台上收集了一半的灰尘(我相信没有其他人可以与此相关,哈哈)。
长话短说,几个月前我决定重新开始这个旧项目。我需要解决的第一件事是如何从水库中收集彩虹糖并非常可靠地检查它们的颜色,同时尽可能保持系统紧凑(我第一次未能实现)。我设法说服自己设计一个更简单的颜色分类机,只是为了让收集系统的设计正确。我愚蠢地认为这将是一个 2 个周末的工作,很好,简单快捷......哦,天哪!!!我错了吗...
我使用了 2 个完全不同的设计和许多经过调整的原型,以获得以可接受的方式工作的东西(我仍然不时遇到一些拾取问题)。
尽管它并不完美,但我对结果非常满意。
图> 图>
它是如何运作的。
机器可分为两个主要阶段。
在顶部,您可以找到用于存放未分类的彩虹糖的水库。在这个水库的底部是负责收集彩虹糖并将它们放置在颜色传感器前面的进料机构,在那里将检查它们的颜色。
进料机构包括一个摇动水箱内容物的臂,以确保彩虹糖顺利地通过进料机构的孔口而不会卡在水箱内(不幸的是它有时仍然会发生)。
一旦找到了彩虹糖的颜色,机器的第二阶段就会开始工作。试管架将右试管对准进料机构前面,以便将 Skittle 放入。
然后可以重复该循环,直到容器为空。
想要自己制作???
.................... https://www.littlefrenchkev.com/colour-sorting-machine.................. ......
组装。
下载并打印部件后,您应该会得到如下结果:
请注意,前壳有 2 个版本。没有真正的区别,它们只是看起来不同。
所需的其余部分。
图>这是组装过程的视频。我什至试图通过使用慢速 3D 打印机拍摄的介绍来成为一名艺术家!!!
初始设置。
打开电源后,机器做的第一件事就是将两个伺服系统移动到初始位置。首次启动机器时,您需要确保收集Skittles的齿轮/轴处于其顶部位置,并且管架与进料机构对齐。
故障排除。
如果您决定自己制造这种分拣机,您可能会遇到一些常见问题。这是您解决问题的方法。
LED 闪烁红色 - 无启动顺序:
移动到初始位置后,机器应执行其启动顺序。如果没有,而是 LED 呈红色闪烁,则表示未找到 RBG 传感器存在一些问题。要么是你的接线有问题,要么是传感器有问题。
管子没有正确对齐:
原因 1
在启动过程中,试管架将移动 5 次,每种颜色各一次。您可能会注意到管子与进料机构的对齐不太好。这可能是由于伺服系统不是非常精确或打印尺寸的一些变化。
这可以通过软件通过修改 colour_angle 变量数组来纠正。此数组中的每个值代表每种颜色的伺服位置,通过更改这些值,您可以微调每种颜色的管将停止的位置。
原因 2
由于印刷公差,您可能还会在管架齿轮中产生一些间隙。根据管子旋转惯性的方式可以使它们超出其停止位置。这也可以通过软件通过修改正向和反向反向间隙变量来纠正。这些值将被添加到颜色角度值或从颜色角度值中删除,具体取决于支架旋转的方式以补偿这种反向间隙。
颜色混合:
如果您遇到一些颜色混合,则必须修改 colour_limit_values 数组。这些数组中的每个值代表红色、绿色和蓝色的最小值和最大值。为了更好地了解这些值应该是什么,只加载一种颜色的机器,将机器插入您的计算机并打开串行监视器。每次检查 Skittle 时,您都应该获取其读取的 RGB 值以及程序认为它是什么颜色。这应该会让您更好地了解应该与每种颜色关联的值类型。
一些很酷的功能。
(好吧,我认为他们无论如何都是!)
RGB LED:
机器底部装有一个 RGB LED。在分类过程中,它会改变颜色以匹配掉落的 Skittle 的颜色。一旦水库空了,它就会不断地检查每一种彩虹色。
如果传感器检测到问题,它也会在启动时闪烁红色。
消隙补偿:
管架使用几个正齿轮旋转。由于印刷公差是很难完全摆脱齿轮中的任何间隙。这意味着管架往往会超出其理想位置。该代码允许通过根据支架旋转的方向提前一定量停止支架来对此进行补偿。
额外延迟:
代码包括一个“set_led(ms, color)”函数。它的作用与“延迟(毫秒)”功能完全一样,但允许 LED 在延迟发生时平滑地切换到新颜色。当灯管支架旋转到其位置时,改变 LED 的颜色是一种享受!
额外说明。
注 1:我用黑色打印了我的机器,这会影响传感器读取的颜色值,尤其是当进纸机构没有收集到彩虹糖时。
注意 2:经过多次排序过程后,Skittles 颜色似乎变得更难以可靠读取。我认为这是因为它们在水库内摩擦多次后失去光泽,或者用手处理时会变得有点粘(听起来很恶心!)。校准颜色值时,请尝试使用“新鲜”的彩虹糖。
注意 3:请确保在处理食物时采取一切必要的预防措施。这包括确保您使用食品安全的打印耗材。
注 4:我尝试在 Instagram 上发布一些正在进行的工作以及我正在进行的项目。如果这是你的东西,你可以看看这里:https://www.instagram.com/little_french_kev/
代码
- LFK_sorting_machine
LFK_sorting_machineC/C++
这是分拣机的 Arduino 代码。#include#include "Adafruit_TCS34725.h"#include /* 基于 Adafruit TCS34725 突破库的示例代码 */// ========================与RGB传感器相关的变量=========================Adafruit_TCS34725 tcs =Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_24MS, TCS34725_GAIN_1X); // 设置 RGB sensorint color =0;//0-black, 1-yelow, 2-green, 3-orange, 4-red, 5-purpleint previous_colour =colour;int black_count =0; // 空/未知颜色的计数 int start_measurment_angle =88; //伺服位置在sensorint measurment_sweep =2之前对齐skittle //采取的措施数量。用于平均误差int measurment_angle_increment =4; //测量值之间的角度增量//限制值[] ={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, 2160t Yellow_value}; {850, 2200, 800, 2200, 400, 1100};uint16_t green_limit_values[] ={400, 800, 700, 1400, 300, 700};uint16_t orange_limit_5,0,0,0,0,100, 100 };uint16_t red_limit_values[] ={400, 950, 150, 450, 150, 400};uint16_t Purple_limit_values[] ={150, 400, 150, 450, 150, 50====};//================与RGB LED相关的变量==========================byte R_pin =5;字节 G_pin =6;字节 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};//=======================供料器伺服相关的变量 =========================int release_delay =220;const int colour_angles[] ={10, 46, 82, 118, 154};//{10, 46, 82, 118, 154};//int holder_offset =0; // 管架的偏移调整。保持在 0 和 36const 之间。 int backward_anti_backlash =2;const int forward_anti_backlash =2;Servo feeder_servo; //声明供料器servoServo holder_servo; //声明管架伺服//====================================SETUP ==========================================void setup(void) { Serial.begin(9600); pinMode(R_pin,输出); //设置 LED 引脚 pinMode(G_pin, OUTPUT); pinMode(B_pin,输出);模拟写入(R_pin,255); //关闭LED模拟写入(G_pin, 255);模拟写入(B_pin,255); feeder_servo.attach(3); //将送料器伺服连接到引脚 3 holder_servo.attach(2); //将支架伺服连接到引脚 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); // 打开 LED(白色) if (tcs.begin()) { //检查传感器是否找到 Serial.println("Found sensor");起始序列(); } else { Serial.println("未找到 TCS34725 ... 检查您的连接"); while (1) //如果没有找到传感器,红色闪烁{ set_led(300, red); set_led(300, 黑色); } }//====================================循环========================================void loop(void) { if (black_count <10) { feeder_servo.write(0 ); // 将舵机位置设置为顶部以获取skittle 收集延迟(450); // 延迟让送料器伺服有足够的时间进入位置 previous_colour =colour;获取颜色(); // 读取skittle color if (colour ==0) { black_count ++; //如果没有找到颜色,增加黑色计数shake();//即使没有skittle,也会给水库更多的震动} else if (colour ==6) { black_count ++; //如果颜色未知,则增加黑色计数 - 没有弹跳释放 } else { //如果找到颜色 move_holder(); // 移动管架 release_skittle(); // 释放skittle black_count =0; } } else { end_loop(1000); }}//====================================获取颜色==========================================void get_colour() { uint16_t r, g, b, c;//, colorTemp ,勒克斯; uint16_t total_r =0; uint16_t total_g =0; uint16_t total_b =0; feeder_servo.write(start_measurment_angle); //移动开始测量角度延迟(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.print(" "); Serial.println(" "); //比较值以确定颜色。 if ((total_r =Yellow_limit_values[0]) &&//检查黄色(total_r =Yellow_limit_values[2]) &&(total_g =Yellow_limit_values[4]) &&(total_b =green_limit_values[0]) &&//检查绿色(total_r =green_limit_values[2]) &&(total_g =green_limit_values[4]) &&(total_b =orange_limit_values[0]) &&//检查橙色(total_r =orange_limit_values[2]) &&(total_g =orange_limit_values[4]) &&(total_b =red_limit_values[0]) &&//检查红色(total_r =red_limit_values[2]) &&(total_g =red_limit_values[4]) &&(total_b =Purple_limit_values[0]) &&//检查紫色(total_r =Purple_limit_values[2]) &&(total_g =Purple_limit_values[4]) &&(total_b colour) { //强制支架伺服比正常位置回退得更远以补偿齿轮齿隙 int anti_backlash_angle =new_holder_position -backward_anti_backlash; holder_servo.write(anti_backlash_angle); //延迟(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); // 移动支架到位置 //delay(holder_delay); } if (color ==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 (color ==4) { set_led(holder_delay , red); } else if (colour ==5) { set_led(holder_delay , Purple); } else {}}//==============================释放SKITTLE ==========================void release_skittle() { feeder_servo.write(180); // 将舵机位置设置为底部,用于skittle 释放延迟(release_delay);}//==================================摇 ==================================void 摇(){ int 摇_延迟 =80; int震动量=5; INT 晃动_min_value =90; INT 震动最大值 =180; feeder_servo.write(180); // 将舵机位置设置为底部,用于skittle 释放延迟(release_delay); feeder_servo.write(120); // 将舵机位置设置为底部,以实现skittle 释放延迟(80); for (int i =0; i <=shake_amount; i++) //每个度量循环 { feeder_servo.write(shake_min_value); // 将舵机位置设置为底部以实现skittle 释放延迟(shake_delay); feeder_servo.write(shake_max_value); // 将舵机位置设置为底部以实现skittle 释放延迟(shake_delay); }}//==========================开始序列 ============================voidstarting_sequence() { color =1;移动持有人(); set_led(300, 黄色);延迟(400);颜色 =2;移动持有人(); set_led(300, 绿色);延迟(400);颜色 =3;移动持有人(); set_led(300, 橙色);延迟(400);颜色 =4;移动持有人(); set_led(300, 红色);延迟(400);颜色 =5;移动持有人(); set_led(300, 紫色);延迟(400);以前的颜色 =颜色;颜色 =3;移动持有人(); end_loop(200);}//================================结束循环 ================================void end_loop(int duration) { set_led(duration , orange); set_led(持续时间,红色); set_led(持续时间,绿色); set_led(持续时间,黄色); set_led(duration , Purple);}//============================设置 RGB LED 颜色 ======================// 这相当于一个延迟(),但允许 LED 在等待时改变颜色 .void set_led(int duration, int color[3]) { int start_time =毫秒(); // 开始时间值 int current_time =start_time; // 当前时间值 int current_duration =0; // 总持续时间 while (current_duration
示意图
接线非常简单。在插入任何东西之前,请确保您的降压转换器输出 5V !!!!!制造工艺