4自由度串联机械臂按颜色分拣物品功能的实现
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 athttps://opensource.org/licenses/MITby 机器谱 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 periodMsTimer2::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自由度串联机械臂
相关文章:

4自由度串联机械臂按颜色分拣物品功能的实现
1. 功能说明 本实验要实现的功能是:将黑、白两种颜色的工件分别放置在传感器上时,机械臂会根据检测到的颜色,将工件搬运至写有相应颜色字样区域。 2. 使用样机 本实验使用的样机为4自由度串联机械臂。 3. 运动功能实现 3.1 电子硬件 在这个…...

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

c语言指针怎么理解 第二部分
第四,指针有啥用。 比方说,我们有个函数,如下: int add(int x){ return (x1); //把输入的值加1并返回结果。 } 好了,应用的时候是这样的: { int a1; aadd(a); //add函数返回的是a1 //现在 a等于…...

GC简介和监控调优
GC简介: GC(Garbage Collection)是java中的垃圾回收机制,是Java与C/C的主要区别之一,在使用JAVA的时候,一般不需要专门编写内存回收和垃圾清理代 码。这是因为在Java虚拟机中,存在自动内存管理和垃圾清扫机制。 什么…...
Understanding The Linux Kernel --- Part2 Memory Addressing
内存寻址 操作系统自身不必完全了解物理内存,如今的微处理器包含的硬件线路使内存管理既高效又健壮,所以编程错误就不会对该程序之外的内存产生非法访问 x86如何进行芯片级内存寻址Linux如何利用寻址硬件 x86 三种不同的地址术语 逻辑地址 逻辑地址…...

前后端分页查询好大的一个坑(已解决)
前言:如果你在做前后端的分页查询,找不到错误,请你来看看是否是和我一样的情况?情况:做了一个前后盾UI的项目,有一个页面是查询系统日志,要进行分页查询;第一页的:第5页的…...
Python批量执行读取ini文件和写入ini文件时,性能比较低怎么办,给出解决方案和源码
Python批量执行读取ini文件和写入ini文件时,性能比较低怎么办,给出解决方案和源码 解决方案: 使用ConfigParser的缓存机制,可以避免频繁读取ini文件造成的性能问题。 将ini文件转换为json格式,使用json库进行读写操作…...
微机原理与接口技术 汇编语言程序设计DOS常用命令
OS(磁盘操作系统)命令,是DOS操作系统的命令,是一种面向磁盘的操作命令,主要包括目录操作类命令、磁盘操作类命令、文件操作类命令和其它命令。 使用技巧 DOS命令不区分大小写,比如C盘的Program Files&…...

4.ffmpeg命令转码规则、过滤器介绍、手动流map选项
在上章我们学习了ffmpeg命令行帮助以及选项查找 本章我们来深入学习ffmpeg命令转码规则、过滤器介绍、手动流map选项 参考链接: 1.ffmpeg命令行转码流程 ffmpeg命令行转码流程如下图所示: 对应中文则是: 步骤如下所示: ffmpeg调用libavformat库(包含解复用器)来读取输入文件…...

【python】标准库详解
注:最后有面试挑战,看看自己掌握了吗 文章目录Standard Library简介python内置对象如何安装发布第三方模块10最好用的模块汇总包的本质datetime模块案例Math模块random模块OS模块sys模块time模块总结自定义模块标准库模块用help查看time模块常用第三方库…...

Golang Map原理(底层结构、查找/新增/删除、扩缩容)
参考: 解剖Go语言map底层实现Go语言核心手册-3.字典 一、Go Map底层结构: Go map的底层实现是一个哈希表(数组 链表),使用拉链法消除哈希冲突,因此实现map的过程实际上就是实现哈希表的过程。 先来看下…...

Java_数组
数组 1.概念 需求:现在需要统计软件技术1班47名同学的成绩情况,例如计算平均成绩、最高成绩等。如果只能使用变量的话,那么需要定义100个变量,这样就比较复杂了。这时我们就可以使用数组来记住这47名同学的成绩,然…...
list与vector的区别
相信大家已经学过list与vector,关于它们的不同,我做了一些总结,如下表: vector list底层结构动态顺序表,一段连续的空间带头结点的双向链表随机访问支持随机访问,访问某个元素的效率…...

【C++、数据结构】位图、布隆过滤器、哈希切割(哈希思想的应用)
文章目录📖 前言1. 位图1.1 海量数据处理思路分析:1.2 位图的具体实现:1.3 用位图解决问题:应用一:应用二:应用三:2. 布隆过滤器2.1 布隆过滤器的概念:2.2 布隆过滤器的测试…...

计算机网络安全基础知识3:网站漏洞,安装phpstudy,安装靶场漏洞DVWA,搭建一个网站
计算机网络安全基础知识3:网站漏洞,安装phpstudy,安装靶场漏洞DVWA,搭建一个网站 2022找工作是学历、能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测…...

大话数据结构-迪杰斯特拉算法(Dijkstra)和弗洛伊德算法(Floyd)
6 最短路径 最短路径,对于图来说,是两顶点之间经过的边数最少的路径;对于网来说,是指两顶点之间经过的边上权值之和最小的路径。路径上第一个顶点为源点,最后一个顶点是终点。 6.1 迪杰斯特拉(Dijkstra&am…...
2023年全国最新食品安全管理员精选真题及答案10
百分百题库提供食品安全管理员考试试题、食品安全员考试预测题、食品安全管理员考试真题、食品安全员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 91.实施日常检查,如果违反关键项的,应当即作出如…...

Unity常见面试题详解(持续更新...)
一丶声明、定义、实例化、初始化 1、首先我们来讨论在C/C中的声明和定义.. 1)我们先从函数声明和定义说起... 一般我们在C里都会先定义一个函数,然后再Main函数前将函数声明,比如: //函数声明 int Add(int);int Main {} //函数…...

java高级篇之三大性质总结:原子性、可见性以及有序性
1. 三大性质简介 在并发编程中分析线程安全的问题时往往需要切入点,那就是两大核心:JMM抽象内存模型以及happens-before规则(在这篇文章中已经经过了),三条性质:原子性,有序性和可见性。关于sy…...

真涨脸,我用 Python 为朋友自动化整理表格
今天,在工作的时候,我的美女同事问我有没有办法自动生成一个这样的表格: 第一列是院校科目,第二列是年份,第三列是数量。 这张表格是基于这一文件夹填充的,之前要一个文件夹一个文件夹打开然后手动填写年份…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...