如何让小型云台机械手实现按颜色分拣物品?

news2024/9/29 1:16:30

1. 功能说明

       在小型云台机械手附近设置一个工作台,并安装一个TCS3200颜色识别传感器。将红色、蓝色工件分别放置在传感器上,如果检测的物料的颜色为红色,机械臂将物体放在机械臂的左侧,如果检测的物料的颜色为蓝色,机械臂将物体放在机械臂的右侧,否则,机械臂不动作。

2. 使用样机

本实验使用的样机是用探索者兼容零件制作的。

3. 功能实现

3.1 电子硬件

在这个示例中,采用了以下硬件,请大家参考:

 Basra主控板(兼容Arduino Uno)、Bigfish2.1扩展板、TCS3200颜色识别传感器、7.4V锂电池

       将夹爪、腕关节、底座关节的舵机分别接在扩展板的D4、D7以及D11舵机接口上,颜色传感器接在A0、A4、A3口上。

3.2 编写程序

编写并烧录以下程序(Color_Sorting_Robot.ino),该程序将实现演示视频中的动作。

编程环境:Arduino 1.8.19

/*******************************************************************************************

版权说明:Copyright 2022 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved.

           Distributed under MIT license.See file LICENSE for detail or copy at

           https://opensource.org/licenses/MIT

           by 机器谱 2022-12-21 https://www.robotway.com/

---------------------------------------------------------------------------------------

实验需求:

         用颜色传感器实现颜色识别。

实现思路:

         程序的整体思路为:在机械臂前方安装颜色传感器,如果检测的物料的颜色为红色,机械臂将

         物体放在机械臂的左侧,如果检测的物料的颜色为蓝色,机械臂将物体放在机械臂的右侧,

         否则,机械臂不动作。

实验接线:

         最上端的机械爪舵机接D4;

         中间的机械身躯舵机接D7;

         最下端的机械底座舵机接D11;

         颜色传感器的接线为         

         S1   S2   5V   GND        S3   S2   5V   GND        OUT   LED   5V   GND

         |     |    |    |            |     |    |      |            |      |      |      |

         A0   A1   5V   GND        A5   A4   5V   GND         D2    A3   5V   GND

********************************************************************************************/

//颜色传感器原理

/*首先进行白平衡,把一个白色物体放置在TCS3200颜色传感器之下,两者相距10mm左右,点亮传感器上的

4个白光LED灯,用Arduino控制器的定时器设置一固定时间1s,然后选通三种颜色的滤波器,让被测物体反

射光中红、绿、蓝三色光分别通过滤波器,计算1s时间内三色光分别对应的TCS3200的输出脉冲数,再通过

算式得到白色物体RGB值255与三色光脉冲数的比例因子。有了白平衡后,得到的RGB比例因子,则其他颜色

物体反射光中红、绿、蓝三色光对应的1s内TCS3200输出信号脉冲数乘以R、G、B比例因子,就可换算出被测

物体的RGB标准值。*/

#include "TimerOne.h"    //颜色传感器需要用到的定时函数库

#include<ServoTimer2.h>   //舵机驱动需要的函数库

ServoTimer2 myservo[3];   //舵机声明

#define servo_num 3      //舵机数量

#define Servo_Speed   20   //舵机速度

#define Upward_servo_close 66   //机械爪闭合的角度值

#define Upward_servo_open 115   //机械爪张开的角度值

#define Middle_servo_down 105   //机械臂的初始角

#define Middle_servo_init 85    //机械臂的初始角

#define Middle_servo_left 10    //机械臂向左偏的角度

#define Middle_servo_left1 50   //机械臂向左偏的角度

#define Down_servo_middle 75   //机械底座初始角度值

#define Down_servo_left 5      //机械底座向左偏的角度值

#define Down_servo_right 145   //机械底座向右偏的角度值

int servo_pin[3]={4,7,11}; //定义舵机引脚号

float value_init[3]={Upward_servo_open, Middle_servo_left, Down_servo_middle};//舵机初始角度

int f=20;   //舵机从角度A转到角度B分的分数

//把TCS3200颜色传感器各控制引脚连到Arduino数字端口

#define S0     A0   //物体表面的反射光越强,TCS3002D的内置振荡器产生的方波频率越高,

#define S1     A1   //S0和S1的组合决定输出信号频率比率因子,比例因子为2%

                    //比率因子为TCS3200传感器OUT引脚输出信号频率与其内置振荡器频率之比

#define S2     A4   //S2和S3的组合决定让红、绿、蓝,哪种光线通过滤波器

#define S3     A5

#define OUT    2   //TCS3200颜色传感器输出信号输入到Arduino中断0引脚,并引发脉冲信号中断

                  //在中断函数中记录TCS3200输出信号的脉冲个数

#define LED    A3   //控制TCS3200颜色传感器是否点亮

int   g_count = 0;    // 计算与反射光强相对应TCS3200颜色传感器输出信号的脉冲数

// 数组存储在1s内TCS3200输出信号的脉冲数,它乘以RGB比例因子就是RGB标准值

int   g_array[3];   

int   g_flag = 0;     //滤波器模式选择顺序标志

float g_SF[3];       // 存储从TCS3200输出信号的脉冲数转换为RGB标准值的RGB比例因子

// 初始化TSC3200各控制引脚的输入输出模式

//设置TCS3002D的内置振荡器方波频率与其输出信号频率的比例因子为2%

void TSC_Init()

{

  pinMode(S0, OUTPUT);

  pinMode(S1, OUTPUT);

  pinMode(S2, OUTPUT);

  pinMode(S3, OUTPUT);

  pinMode(OUT, INPUT);

  pinMode(LED, OUTPUT);

  digitalWrite(S0, LOW);  

  digitalWrite(S1, HIGH);

}

//选择滤波器模式,决定让红、绿、蓝,哪种光线通过滤波器

void TSC_FilterColor(int Level01, int Level02)

{

  if(Level01 != LOW)

    Level01 = HIGH;

  if(Level02 != LOW)

    Level02 = HIGH;

  digitalWrite(S2, Level01);

  digitalWrite(S3, Level02);

}

//中断函数,计算TCS3200输出信号的脉冲数

void TSC_Count()

{

  g_count ++ ;

}

//定时器中断函数,每1s中断后,把该时间内的红、绿、蓝三种光线通过滤波器时,

//TCS3200输出信号脉冲个数分别存储到数组g_array[3]的相应元素变量中

void TSC_Callback()

{

  switch(g_flag)

  {

    case 0:

         TSC_WB(LOW, LOW);              //选择让红色光线通过滤波器的模式

         break;

    case 1:

         g_array[0] = g_count;       //存储1s内的红光通过滤波器时,TCS3200输出的脉冲个数

         TSC_WB(HIGH, HIGH);         //选择让绿色光线通过滤波器的模式

         break;

    case 2:

         g_array[1] = g_count;       //存储1s内的绿光通过滤波器时,TCS3200输出的脉冲个数

         TSC_WB(LOW, HIGH);          //选择让蓝色光线通过滤波器的模式

         break;

    case 3:

         g_array[2] = g_count;       //存储1s内的蓝光通过滤波器时,TCS3200输出的脉冲个数

         TSC_WB(HIGH, LOW);             //选择无滤波器的模式   

         break;

   default:

         g_count = 0;    //计数值清零

         break;

  }

}

//设置反射光中红、绿、蓝三色光分别通过滤波器时如何处理数据的标志

//该函数被TSC_Callback( )调用

void TSC_WB(int Level0, int Level1)     

{

  g_count = 0;   //计数值清零

  g_flag ++;     //输出信号计数标志

  TSC_FilterColor(Level0, Level1); //滤波器模式

  Timer1.setPeriod(100000);      //设置输出信号脉冲计数时长1s

}

//初始化

void setup()

{

  TSC_Init();

  Serial.begin(9600); //启动串行通信

  Timer1.initialize(100000);   // defaulte is 1s

  Timer1.attachInterrupt(TSC_Callback); //设置定时器1的中断,中断调用函数为TSC_Callback()

  //设置TCS3200输出信号的上跳沿触发中断,中断调用函数为TSC_Count()

  attachInterrupt(0, TSC_Count, RISING);  

  digitalWrite(LED, HIGH);//点亮LED灯

//   delay(1500); //延时4s,以等待被测物体红、绿、蓝三色在1s内的TCS3200输出信号脉冲计数

  //通过白平衡测试,计算得到白色物体RGB值255与1s内三色光脉冲数的RGB比例因子

  g_SF[0] = 0.53;     //红色光比例因子

  g_SF[1] = 0.65;    //绿色光比例因子

  g_SF[2] = 0.54;    //蓝色光比例因子

  //红、绿、蓝三色光对应的1s内TCS3200输出脉冲数乘以相应的比例因子就是RGB标准值

    reset();

}

//主程序

int Now_Color = 0;   //存储上一次颜色传感器检测的数值

int Last_Color = 0;   //存储当前颜色传感器检测的数值

void loop()

{

    Last_Color = Color_Detection();

    Now_Color   = Color_Detection();

    if( Last_Color == Now_Color) //如果两次检测的数值相同

                                 //(这里是为了防止颜色传感器检测出错,所以检测了两次)

    {

      switch(Now_Color)

      {

        case 1:

               Serial.print("Red"); //如果检测到的物料为红色,将物料放到机械臂的左侧

               Servo_Left();

               Now_Color = 0; Last_Color = 0;

               break;     

        case 2:

               Serial.print("Blue");//如果检测到的物料为蓝色,将物料放到机械臂的右侧

               Servo_Right();

               Now_Color = 0; Last_Color = 0;

               break;

        case 3:

               Serial.print("NONE");//否则,机械臂不动作;

               Serial.println();

               Now_Color = 0; Last_Color = 0;

               break;

      }

    }

}

int Color_Detection() //颜色检测函数

{

    int color[3];

    g_flag = 0;

    for(int i=0; i<3; i++) {

    color[i] = g_array[i] * g_SF[i];  

   }

    Serial.println((String)(color[0]) + '+' + (String)(color[1]) + '+' + (String)(color[2]) + '+');

    delay(500);

   if( (color[0] > color[1]) && (color[0] >color[2]) && ( (color[1]+color[2])<color[0] ) ){

     return 1;         //如果检测到的颜色为红色,返回1;

   }

   else if( (color[2] > color[1]) && (color[2] >color[0]) ){

     return 2;         //如果检测到的颜色为蓝色,返回2;

   }

   else { return 3; }   //否则,机械臂不动作;

}

void reset()            //舵机角度初始化

{

   for(int i=0;i<servo_num;i++)

  {

     myservo[i].attach(servo_pin[i]);

     myservo[i].write(map(value_init[i],0,180,500,2500));

  }  

}

void servo_move(float value0, float value1, float value2)   //舵机转动

   {

  float value_arguments[3] = {value0, value1, value2};

  float value_delta[servo_num];

  for(int i=0;i<servo_num;i++)

  {

    value_delta[i] = (value_arguments[i] - value_init[i]) / f;

  }

  for(int i=0;i<f;i++)

  {

    for(int k=0;k<servo_num;k++)

    {

      value_init[k] = value_delta[k] == 0 ? value_arguments[k] : value_init[k] + value_delta[k];

    }

   

    for(int j=0;j<servo_num;j++)

    {

      myservo[j].write(map(value_init[j],0,180,500,2500));

      delay(Servo_Speed);

    }

  }

}

void Servo_Left() //将物料放到机械臂的左侧

{

  servo_move(Upward_servo_open, Middle_servo_left, Down_servo_middle);//初始化动作

  servo_move(Upward_servo_open, Middle_servo_init, Down_servo_middle);//机械臂下降

  servo_move(Upward_servo_close, Middle_servo_init, Down_servo_middle);//机械爪闭合(抓取货物)

  servo_move(Upward_servo_close, Middle_servo_left1, Down_servo_middle);//机械臂上抬

  servo_move(Upward_servo_close, Middle_servo_down, Down_servo_left); //机械臂下降,机械底座向左转

  servo_move(Upward_servo_open, Middle_servo_down, Down_servo_left);   //机械爪张开(释放货物)

  servo_move(Upward_servo_open, Middle_servo_left, Down_servo_middle);//机械臂回复到初始角度

}

void Servo_Right() //将物料放到机械臂的右侧

{

  servo_move(Upward_servo_open, Middle_servo_left, Down_servo_middle);//初始化动作

  servo_move(Upward_servo_open, Middle_servo_init, Down_servo_middle);

  servo_move(Upward_servo_close, Middle_servo_init, Down_servo_middle);

  servo_move(Upward_servo_close, Middle_servo_left1, Down_servo_middle);

  servo_move(Upward_servo_close, Middle_servo_down, Down_servo_right);

  servo_move(Upward_servo_open, Middle_servo_down, Down_servo_right);

  servo_move(Upward_servo_open, Middle_servo_left, Down_servo_middle);

}

4. 资料内容

① 按颜色分拣-例程源代码

② 按颜色分拣-样机3D文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/139328.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构与算法-希尔排序、归并排序

目录​​​​​​​ 希尔排序 1.算法描述 2.算法的实现 归并排序 4.1算法描述 2.算法实现 希尔排序 1.算法描述 1959年shell发明&#xff0c;第一批突破O&#xff08;n2&#xff09;时间复杂度的排序算法&#xff0c;是简单插入排序的改进版。它与插入之处在于&#xff0…

Android 深入系统完全讲解(二)

操作系统 操作系统是一套软件&#xff0c;它的任务就是为上层开发的用户&#xff0c;提供一个更方便的开发环境&#xff0c;同时 让硬件连接到系统中&#xff0c;能够非常方便&#xff0c;从而提高开发速度&#xff0c;以及稳定可靠。 操作系统就是这么存在的。 我们理解它&am…

基于低代码平台构筑金融行业IT运维服务体系

我今天分享题目是《基于低代码平台&#xff0c;构筑金融行业的IT运维服务体系》。这是一个大家不太熟悉的领域&#xff0c;首先它的行业是金融&#xff0c;其次它做的事情是IT运维。 关于金科信息 我先介绍一下金科信息。金科信息在1993年成立&#xff0c;到明年我们就整整30…

前端开发技术栈(插件篇):datatables

一、Datatables介绍 官网地址&#xff1a;https://datatables.net/ DataTables中文网&#xff1a;http://datatables.club/ 1、Datatables是一款jquery表格插件。它是一个高度灵活的工具&#xff0c;可以将任何HTML表格添加高级的交互功能。 2、分页&#xff0c;即时搜索和排序…

【Bootstrap】可复用的组件

目录 一、字体图标 二、下拉菜单 1. 步骤 2. 对齐 3. 分割线 4. 禁用的菜单项 三、按钮组 1. 按钮组 2. 按钮工具栏 3. 尺寸 4. 嵌套 5. 垂直排列 四、输入框组 1. 输入框组 2. 尺寸 3. 作为额外元素的按钮 4. 作为额外元素的按钮式下拉菜单 一、字体图标 组件…

55、MySOL数据库

目录 一、MySQL安装和配置 二、数据库 三、表 四、数据库的C [create] R [read] U [update] D [delete] 语句 1、insert语句 2、update语句 3、delete语句 4、select语句 五、Mysql常用数据类型&#xff08;列类型&#xff09;&#xff1a;​编辑 六、函数 *合计 / 统计…

kettle - 清洗 mongodb 数据案例

文章目录前言kettle - 清洗 mongodb 数据案例一、需求二、kettle开发1、新建mongodb数据查询2、配置kettleTest集合与清洗后kettleTestClear集合字段映射3、根据_id进行排序4、使用java脚本将日期格式化5、进行字段选择6、将delete字段进行值映射7、mongo输出8、最后加一个写日…

详解哨兵之间是如何通信的

基于 pub/sub 机制的哨兵集群组成 哨兵实例之间可以相互发现&#xff0c;要归功于 Redis 提供的 pub/sub 机制&#xff0c;也就是发布 / 订阅机制。 哨兵只要和主库建立起了连接&#xff0c;就可以在主库上发布消息了&#xff0c;比如说发布它自己的连接信息&#xff08;IP 和…

PDF如何转换成PPT?教你们几个简单方法

我们在工作经常用PDF文件进行传输&#xff0c;因为PDF体积小&#xff0c;传输速度很快&#xff0c;还不会不同设备上出现不兼容的问题&#xff0c;可以很好的保持文件的排版&#xff0c;不过我们有时候需要进行文件的展示&#xff0c;所以需要将PDF文件转换为PPT文件&#xff0…

2023河南/北京/重庆/南京DAMA-CDGA/CDGP数据治理工程师认证报名

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

论文阅读——Recognizing Emotion Cause in Conversations

文章目录摘要引言相关工作任务定义构造RECCON数据集情绪原因的类型实验任务1&#xff1a;Causal Span Extraction模型任务2&#xff1a;Causal Emotion Entailment模型面临的挑战摘要 识别文本中情绪背后的原因是NLP中一个未被探索的研究领域。这个领域的发展具有着改善情感模…

Docker基础1-3

Docker基础1-3 时间:2023-01-02 https://www.bilibili.com/video/BV1gr4y1U7CY/ xmind文档&#xff1a;https://www.aliyundrive.com/s/6iaQt9zLDVm 一、Docker简介 1、Docker解决了什么问题 Docker打破了过去「程序即应用」的观念。透过镜像(images)将作业系统核心除外&am…

LeetCode:15. 三数之和

15. 三数之和1&#xff09;题目2&#xff09;思路3&#xff09;代码4&#xff09;结果1&#xff09;题目 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] …

【Nginx】核心配置文件结构

文章目录Nginx核心配置文件结构全局块user指令work process指令其他指令events块events指令配置实例http块定义MIME-Type自定义服务日志其他配置指令server块和location块Nginx服务器基础配置实例Nginx核心配置文件结构 从前面的内容学习中&#xff0c;我们知道Nginx的核心配置…

给力!低代码开发平台广州流辰信息科技助您增辉创价值!

低代码平台开发公司流辰信息深耕行业多年&#xff0c;一直以市场为导向&#xff0c;凭借敏锐的市场洞察力砥砺前行、拼搏进取&#xff0c;提升研发创新能力&#xff0c;广州流辰信息科技与各新老客户朋友风雨同舟&#xff0c;携手共创宏伟新蓝图&#xff01; 一、熔铸前沿科技 …

kettle的安装以及注意(迭代中....)

1、下载 kettle的官网下载地址&#xff1a;Pentaho from Hitachi Vantara - Browse Files at SourceForge.net 如果需要下载其他版本&#xff1a; 直接点击对应的版本Name&#xff08;8.0以下的实在Data Integration文件夹里面&#xff09;进去&#xff0c;再选择client-too…

【C++】代码调试的学习笔记

1. IO输出调试&#xff1a;输出重定向 在《第八期-C基础与深度解析》课程中&#xff0c;老师使用了“输出重定向”的语句来查看cout和cerr的结果&#xff1a; ./HelloWorld >txt1 2>txt2 代码含义&#xff1a;将程序HelloWorld的标准输出stdout重定向至文件txt1&#xf…

百趣代谢组学分享:从SWATH到MRM:一种新型高覆盖度靶向代谢组学技术

百趣代谢组学文献分享&#xff0c;SWATHtoMRM: Development of High-Coverage Targeted Metabolomics Method Using SWATH Technology for Biomarker Discovery&#xff0c;是由中国科学院生物与化学交叉研究中心&#xff0c;Dr. Zheng-Jiang Zhu课题组发表在AC上的一篇技术型文…

verilog学习笔记- 3)SignalTap II 软件的使用

目录 SignalTap II简介&#xff1a; SignalTap II使用&#xff1a; SignalTap II简介&#xff1a; SignalTap II 全称 SignalTap II Logic Analyzer&#xff0c;是第二代系统级调试工具&#xff0c;可以捕获和显示实时信号&#xff0c;是 一款功能强大且极具实用性的 FPGA 片…

IO模型详解

什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll跟IO模型有什么关系?有几种经典IO模型呢?BIO、NIO、AIO到底有什么区别的? 什么是IO呢? IO,英文全称是Input/Output,翻译过来就是输入/输出。平时我们听得挺多,就是什么磁盘IO,网络I…