4自由度串联机械臂按颜色分拣物品功能的实现

news2024/12/23 16:13:35

1. 功能说明

       本实验要实现的功能是:将黑、白两种颜色的工件分别放置在传感器上时,机械臂会根据检测到的颜色,将工件搬运至写有相应颜色字样区域。

2. 使用样机

本实验使用的样机为4自由度串联机械臂。

 3. 运动功能实现

3.1 电子硬件

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

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

在4自由度串联机械臂底座上安装一个 TCS3200颜色识别传感器 ,用于检测工件的RGB值。

3.2 编写程序

编程环境:Arduino 1.8.19

       可以事先利用TCS3200颜色识别传感器检测一下两个工件的的颜色数据,根据颜色数据的特征来确定判断语句的写法,尽量利用R、G、B数值中差别最大的那个作为区分颜色的主要依据。TCS3200颜色识别传感器的检测方法可以参考 TCS3200颜色识别传感器

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

/*------------------------------------------------------------------------------------

  版权说明:Copyright 2023 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 机器谱 2023-02-03 https://www.robotway.com/

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

  实验接线:舵机接口依次D4、D7、D11、D3、D8; 颜色传感器接在A0、A2、A3口上                                     

------------------------------------------------------------------------------------*/

/*I will sorting black and white things according to the color_test Code.

Put the black things in the left.Put the white thing int the right*/

#include <MsTimer2.h>

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

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

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

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

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

#define S3     0

#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比例因子

int color=0;

 

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

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





int a=0,b=0,c=0,d=0,e=0,f=0;

#include <Servo.h>

Servo servo_pin_4;

Servo servo_pin_7;

Servo servo_pin_11;

Servo servo_pin_3;

Servo servo_pin_8;

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 != 0)

    Level01 = HIGH;

  if(Level02 != 0)

    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:

         Serial.println("->WB Start");

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

         break;

    case 1:

         Serial.print("->Frequency R=");

         Serial.println(g_count);   //打印1s内的红光通过滤波器时,TCS3200输出的脉冲个数

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

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

         break;

    case 2:

         Serial.print("->Frequency G=");

         Serial.println(g_count);   //打印1s内的绿光通过滤波器时,TCS3200输出的脉冲个数

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

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

         break;

    case 3:

         Serial.print("->Frequency B=");

         Serial.println(g_count);   //打印1s内的蓝光通过滤波器时,TCS3200输出的脉冲个数

         Serial.println("->WB End");

         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); //滤波器模式

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

}

//初始化

void grab_put_left()

{   for(e=70;e>=50;e-=1)           

  {servo_pin_8.write(e);delay(30);}  

   

  for(d=158;d>=36;d-=3)

  {servo_pin_3.write(d);delay(30);}

   

  for(c=68;c<142;c+=3)

  {servo_pin_11.write(c);delay(30);}

   

   for(e=50;e<=70;e+=1)

  {servo_pin_8.write(e);delay(30);}

   

  for(c=142;c>=103;c-=3)

  {servo_pin_11.write(c);delay(30);}

 

  for(a=76;a<=120;a+=3)

  {servo_pin_4.write(a); delay(30);}



 

  for(e=70;e>=50;e-=1)

  {servo_pin_8.write(e);delay(30);}

 

  for(a=120;a>=76;a-=3)

  {servo_pin_4.write(a); delay(30);}

 

   for(c=103;c>=68;c-=3)

  {servo_pin_11.write(c);delay(30);}

 

    for(d=36;d<=157;d+=3)

  {servo_pin_3.write(d);delay(30);}

 

    for(e=50;e<=70;e+=1)

  {servo_pin_8.write(e);delay(30);}

delay(1000);

 

}

void grab_put_right()

{   for(e=70;e>=50;e-=1)           

  {servo_pin_8.write(e);delay(30);}  

   

  for(d=158;d>=36;d-=3)

  {servo_pin_3.write(d);delay(30);}

   

  for(c=68;c<142;c+=3)

  {servo_pin_11.write(c);delay(30);}

   

   for(e=50;e<=70;e+=1)

  {servo_pin_8.write(e);delay(30);}

   

  for(c=142;c>=103;c-=3)

  {servo_pin_11.write(c);delay(30);}

 

  for(a=76;a>=32;a-=3)

  {servo_pin_4.write(a); delay(30);}



 

  for(e=70;e>=50;e-=1)

  {servo_pin_8.write(e);delay(30);}

 

  for(a=32;a<=76;a+=3)

  {servo_pin_4.write(a); delay(30);}

 

   for(c=103;c>=68;c-=3)

  {servo_pin_11.write(c);delay(30);}

 

    for(d=36;d<=157;d+=3)

  {servo_pin_3.write(d);delay(30);}

 

    for(e=50;e<=70;e+=1)

  {servo_pin_8.write(e);delay(30);}

 

delay(1000);

}

void setup()

{servo_pin_4.attach(4);

  servo_pin_4.write( 76);

  servo_pin_7.attach(7);

  servo_pin_7.write( 110);

  servo_pin_11.attach(11);

  servo_pin_11.write(68);

  servo_pin_3.attach(3);

  servo_pin_3.write(157);

  servo_pin_8.attach(8);

  servo_pin_8.write(71);

  delay(3000);//set up the initial posotion.Each servo is different,

              // so u must use Software of Processing to monitor your initial positions of servo.

  TSC_Init();

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

  MsTimer2::set(2000,TSC_Callback); // 500ms period

  MsTimer2::start();

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

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

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

  attachInterrupt(0, TSC_Count,CHANGE);  

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

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

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

  g_SF[0] =0.04800;//255.0/ g_array[0];     //红色光比例因子

  g_SF[1] =0.05065;// 255.0/ g_array[1] ;    //绿色光比例因子

  g_SF[2] =0.04104;// 255.0/ g_array[2] ;    //蓝色光比例因子

  //打印白平衡后的红、绿、蓝三色的RGB比例因子

  Serial.println(g_SF[0],5);

  Serial.println(g_SF[1],5);

  Serial.println(g_SF[2],5);

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

  //打印被测物体的RGB值

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

    Serial.println(int(g_array[i] * g_SF[i]));

//   int color=g_array[2] * g_SF[2];

}

//主程序

void loop()

{ int a=76;b=110;c=68;d=157;e=81;

  servo_pin_4.write(a);

  servo_pin_7.write(b);

  servo_pin_11.write(c);

  servo_pin_3.write(d);

  servo_pin_8.write(e);

   g_flag = 0;

   //每获得一次被测物体RGB颜色值需时4s

  // delay(4000);

   //打印出被测物体RGB颜色值

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

    Serial.println(int(g_array[i] * g_SF[i]));  

   int color=g_array[2] * g_SF[2];           

Serial.println(color);

if(color>100)

 

grab_put_right();

if(color<=100)

 

grab_put_left();

//delay(5000);

}

4自由度串联机械臂按颜色分拣物品的详细资料请参考 4自由度串联机械臂

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

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

相关文章

快速吃透π型滤波电路-LC-RC滤波器

π型滤波器简介 π型滤波器包括两个电容器和一个电感器&#xff0c;它的输入和输出都呈低阻抗。π型滤波有RC和LC两种&#xff0c; 在输出电流不大的情况下用RC&#xff0c;R的取值不能太大&#xff0c;一般几个至几十欧姆&#xff0c;其优点是成本低。其缺点是电阻要消耗一些…

亚马逊二审来袭,跨境电商传统验证算法真的靠谱吗?

多个大卖突遭二审 已有卖家账号被封 近期有不少卖家在论坛上反映称自己收到了亚马逊的二次视频验证邮件。 邮件上称&#xff1a; 卖家必须要完成额外的身份审查&#xff0c;才有资格在亚马逊继续销售商品&#xff1b;亚马逊要求卖家出示注册时提交的身份证原件和营业执照原件…

聊聊混沌工程

这是鼎叔的第五十四篇原创文章。行业大牛和刚毕业的小白&#xff0c;都可以进来聊聊。欢迎关注本专栏和微信公众号《敏捷测试转型》&#xff0c;大量原创思考文章陆续推出。混沌工程是一门新兴学科&#xff0c;它不仅仅只是个技术活动&#xff0c;还包含如何设计能够持续协作的…

xgboost:算法数学原理

xgboost算法数学原理 1、求预测值 y^iϕ(xi)∑k1Kfk(xi),fk∈F,(1)\hat{y}_i\phi\left(\mathbf{x}_i\right)\sum_{k1}^K f_k\left(\mathbf{x}_i\right), \quad f_k \in \mathcal{F},\tag{1} y^​i​ϕ(xi​)k1∑K​fk​(xi​),fk​∈F,(1) F{f(x)wq(x)}(q:Rm→T,w∈RT)\mathca…

即时通讯开发常用加解密算法与通讯安全

平时开发工作中&#xff0c;我们会经常接触加密、解密的技术。尤其在今天移动互联网时代&#xff0c;越来越多的用户会将数据存储在云端&#xff0c;或使用在线的服务处理信息。这些数据有些涉及用户的隐私&#xff0c;有些涉及用户的财产&#xff0c;要是没有一套的方案来解决…

玩转结构体---【C语言】

⛩️博主主页&#xff1a;威化小餅干&#x1f4dd;系列专栏&#xff1a;【C语言】藏宝图&#x1f38f; ✨绳锯⽊断&#xff0c;⽔滴⽯穿&#xff01;一个编程爱好者的学习记录!✨目录结构体类型的声明结构体成员访问结构体传参前言我们是否有想过&#xff0c;为什么会有结构体呢…

stylelint执行插件的全过程

stylelint可以用来扩展插件去实现各种规则&#xff0c;接下来带大家看看stylelint是如何执行插件的 首先遍历absoluteFilePaths路径&#xff08;该路径是我们执行lint命令配置的文件类型eslint --cache --max-warnings 0 \"{src,mock}/**/*.{vue,ts,tsx}\" --fix&…

Spark RDD

RDD RDD 是构建 Spark 分布式内存计算引擎的基石&#xff0c;如 &#xff1a;DAG/调度系统都衍生自 RDD RDD 是对分布式数据集的抽象&#xff0c;囊括所有内存/磁盘的分布式数据实体 RDD/数组差异 对比项数组RDD概念数据结构实体数据模型抽象数据跨度单机进程内跨进程&…

GC简介和监控调优

GC简介&#xff1a; GC(Garbage Collection)是java中的垃圾回收机制&#xff0c;是Java与C/C的主要区别之一&#xff0c;在使用JAVA的时候&#xff0c;一般不需要专门编写内存回收和垃圾清理代 码。这是因为在Java虚拟机中&#xff0c;存在自动内存管理和垃圾清扫机制。 什么…

ThreadLoca基本使用以及与synchronized的区别

文章目录1. ThreadLocal介绍1.1 官方介绍1.2 基本使用1.2.1 常用方法1.2.2 使用案例1.3 ThreadLocal类与synchronized关键字1.3.1 synchronized同步方式1.3.2 ThreadLocal与synchronized的区别2. 运用场景_事务案例2.1 转账案例2.1.1 场景构建2.1.2 引入事务2.2 常规解决方案2.…

k8s servelList(服务列表) 卡死不同步问题分析

提要容器集群版本情况&#xff1a;k8s 1.20客户端k8s client版本&#xff1a; 0.21事情是这样的&#xff0c;运行了一年的服务&#xff0c;突然有一天业务反馈服务使用异常&#xff0c;然后初步调查结果如下以下截图是网关异常以下截图是客户端zull&#xff08;feign&#xff0…

依赖倒置DIP在系统架构中的应用

最近在对项目中的某一模块进行重构和功能的拓展。一直没想到好方法。 简单理解为&#xff1a; R项目 调用了 E项目的打印接口&#xff0c;但是E项目需要对R传来对数据传输对象DTO进行二次处理&#xff0c;甚至夹杂很多R项目的业务逻辑&#xff08;去调用R项目的接口&#xff0…

代码规范书写说明

目录 一&#xff0c;命名风格 二、常量定义 三、代码格式 一&#xff0c;命名风格 &#xff08;1&#xff09;、不能够以下划线或者美元符号开始&#xff0c;也不能以下划线或者美元符号结束 反例&#xff1a;_name / __name / $name / name_ &#xff08;2&#xff09;、所…

春招进行时:“211文科硕士吐槽工资5500” HR:行情和能力决定价值

学历重要&#xff0c;还是能力重要&#xff1f; 春招进行时&#xff0c;不少学生求职遇冷&#xff0c;会把原因归结为学历水平不够高、毕业院校不够档次、专业不够热门、非一线城市就业机会少等等。 直到上海一位211大学的文科男硕士&#xff0c;吐槽招聘会提供的岗位薪资待遇…

10个实用技巧:如何让你的外贸独立站排名直线上升

在当今竞争激烈的互联网市场中&#xff0c;谷歌SEO已经成为了外贸独立站排名提升的必修课程。为了使得自己的网站能够在谷歌上排名更高&#xff0c;网站优化的工作显得尤为重要。 在这篇文章中&#xff0c;我们将分享10个实用技巧&#xff0c;帮助你的外贸独立站排名直线上升。…

【软件测试】接口测试总结

本文主要分为两个部分&#xff1a; 第一部分&#xff1a;主要从问题出发&#xff0c;引入接口测试的相关内容并与前端测试进行简单对比&#xff0c;总结两者之前的区别与联系。但该部分只交代了怎么做和如何做&#xff1f;并没有解释为什么要做&#xff1f; 第二部分&#xff1…

java虚拟机栈解读

虚拟机栈出现的背景 由于跨平台性的设计&#xff0c;Java的指令都是根据栈来设计的。不同平台CPU架构不同&#xff0c;所以不能设计为基于寄存器的。 优点是跨平台&#xff0c;指令集小&#xff0c;编译器容易实现&#xff0c;缺点是性能下降&#xff0c;实现同样的功能需要更…

【微信小程序-原生开发】实用教程11 - 用户登录鉴权(含云函数的创建、删除、使用,通过云函数获取用户的openid)

此篇可在实用教程10&#xff08;见下方链接&#xff09;的基础上继续开发&#xff0c;也可以在任何微信小程序中直接使用。 https://blog.csdn.net/weixin_41192489/article/details/128835069 用户登录鉴权逻辑 核心技术&#xff1a;通过云函数获取用户的openid 要想使用云函数…

网络层IP协议与数据链路层以太网协议

文章目录一、IP协议IP地址地址管理路由选择DNS二、以太网协议以太网帧MTU一、IP协议 IP协议是我们网络层的代表协议&#xff0c;今天我们就来一起学习一下吧&#xff0c;我们这里介绍的主要是IPv4协议。 版本&#xff1a;指定IP协议的版本&#xff0c;版本的取值只有4&#x…

如何使用ExchangeFinder在给定域中寻找Microsoft Exchange实例

关于ExchangeFinder ExchangeFinder是一款功能强大且使用简单的开源工具&#xff0c;该工具能够在给定域中尝试搜索指定的Microsoft Exchange实例&#xff0c;该工具的搜索机制基于Microsoft Exchange的常见DNS名称实现&#xff0c;并且能够识别指定的Microsoft Exchange版本&…