“智能垃圾桶/zh”的版本间的差异
502748957@qq.com(讨论 | 贡献) |
502748957@qq.com(讨论 | 贡献) |
||
(未显示同一用户的5个中间版本) | |||
第9行: | 第9行: | ||
*耗时:2小时 | *耗时:2小时 | ||
*制作者: | *制作者: | ||
− | + | *简介: | |
+ | 用距离测量传感器,在可测量的范围内,感受人体的接近动作,将采集到的红外的强弱会影响它自己阻值,从而改变输出的电压值。处理器通过判断输出的电压值,决定垃圾桶是否开启、开启的方向,从而用以接收垃圾。 | ||
==材料清单== | ==材料清单== | ||
*Microduino设备 | *Microduino设备 | ||
第30行: | 第31行: | ||
{|class="wikitable" | {|class="wikitable" | ||
|- | |- | ||
− | |舵机(MG996R) ||1||开启、关闭垃圾桶 | + | |名称|| 数量||功能 |
+ | |- | ||
+ | |舵机(MG996R) || 1||开启、关闭垃圾桶 | ||
|- | |- | ||
− | |Microduino servo-cin ||1||连接舵机和hub板 | + | |Microduino servo-cin || 1||连接舵机和hub板 |
|- | |- | ||
− | |sharp 2y0a21 ||1||在10cm~80cm距离检测红外线 | + | |sharp 2y0a21 || 1||在10cm~80cm距离检测红外线 |
|- | |- | ||
− | |电池||1||供电 | + | |电池|| 1||供电 |
|} | |} | ||
− | + | ==实验原理== | |
− | + | *距离测量传感器 | |
− | + | sharp 2y0a21型号的测量传感器,为基于PSD的距离传感器。通过自身电路中热电阻感受外接环境中温度的变化阻值,从而改变传感器两端的电压。但是热电阻的感受温度的变化测量距离有一定的范围,sharp 2y0a21型号的测量距离为10~80cm。在0~8cm左右的距离范围内与距离成正比非线性关系,在10~80cm的距离范围内成反比非线性的关系,平均消耗约为30mA,反应时间约为5ms,并且对背景及温度的适应性较强。有效的测量角度大于40度,输出信号为模拟电压。 | |
− | + | *舵机(MG996R) | |
− | + | 舵机是船舶上的一种大甲板机械。舵机的大小由外舾装按照船级社的规范决定,选型时主要考虑扭矩大小。在航天方面,舵机应用广泛。航天方面,导弹姿态变换的俯仰、偏航、滚转运动,都是靠舵机相互配合完成的。舵机在许多工程上都有应用,不仅限于船舶。 | |
舵机主要是由外壳、电路板、无核心马达、齿轮与位置检测器所构成。其工作原理是由接收机发出讯号给舵机,经由电路板上的 IC判断转动方向,再驱动无核心马达开始转动,透过减速齿轮将动力传至摆臂,同时由位置检测器送回讯号,判断是否已经到达定位。 | 舵机主要是由外壳、电路板、无核心马达、齿轮与位置检测器所构成。其工作原理是由接收机发出讯号给舵机,经由电路板上的 IC判断转动方向,再驱动无核心马达开始转动,透过减速齿轮将动力传至摆臂,同时由位置检测器送回讯号,判断是否已经到达定位。 | ||
− | + | MG996R最大旋转角度为180度,在编写程序代码时,旋转的角度范围为(0~180度)。 | |
− | + | *总体结构 | |
− | + | 距离测量传感器感应两侧的红外线的强度,将感应到的数值传送到核心芯片上,核心芯片通过处理该数据,确定舵机旋转的角度,从而确定垃圾箱是否开门,如果开门开哪侧的门。因为舵机的旋转角度为0~180度,所以最好将平衡位置放在舵机旋转的角度中间。 | |
− | + | 垃圾箱安装的原理图 | |
− | [[File:Smartlitterbox.png|| | + | [[File:Smartlitterbox.png||300px|center|thumb]] |
+ | |||
+ | *主要传感器 | ||
+ | 距离测量传感器 | ||
+ | 距离测量传感器的特性 | ||
+ | *可测量的范围:10~80cm | ||
+ | *消耗电流:标注值30mA | ||
+ | *电源电压:4.5V~5.5V | ||
+ | *检测到该范围内的红外线的强度,其大小通过电压值表示出来。 | ||
+ | [[File:Distancesensor.jpg||300px|center|thumb]] | ||
+ | |||
+ | MG996R舵机 | ||
+ | MG996R舵机的线路说明,如图所示 | ||
+ | |||
+ | 舵机(MG996R)的特性 | ||
+ | *旋转角度:180度 | ||
+ | *工作电压:4.8V-7.2V | ||
+ | *空载工作电流: 120mA | ||
+ | *堵转工作电流: 1450mA | ||
+ | *扭力:4.8V@13kg-cm ,6.0V@15kg-cm | ||
+ | [[File:ServoMG996R.png||300px|center|thumb]] | ||
+ | |||
+ | Microduino servo-cin的连线管脚 | ||
+ | [[File:Microduino servo-cin.png||300px|center|thumb]] | ||
+ | 在程序中,定义舵机的引脚,对应[[Microduino-Sensorhub/zh]]一个插槽(一个插槽中有两个管脚)中的一个管脚,离板子较远的一端为数字较小的管脚。 | ||
+ | ==文档== | ||
+ | |||
+ | ==调试过程== | ||
+ | *下载程序: | ||
+ | 将Microduino Core、Microduino USBTTL堆叠在一起.用数据线将写好的程序通过Microduino USBTTL上传到Microduino Core上。 | ||
+ | 注意:最好不要将所有模块堆叠在一起之后再上传程序 | ||
+ | [[File:Download1.jpg||300px|center|thumb]] | ||
+ | 打开程序,点击程序编译,编译成功后,在【工具】中选择好【端口】、【板】和【处理器】,选择好【板】和【处理器】之后,点击上传即可 | ||
+ | 板卡的选择 | ||
+ | [[File:Download2.jpg||300px|center|thumb]] | ||
+ | 处理器的选择 | ||
+ | [[File:Download3.jpg||300px|center|thumb]] | ||
+ | 端口的选择 | ||
+ | [[File:Download4.jpg||300px|center|thumb]] | ||
+ | *搭建: | ||
+ | *步骤1 | ||
+ | 将[[Microduino-Duo-v/zh]]用螺丝钉固定在垃圾桶上 | ||
+ | [[File:Litter1.jpg||300px|center|thumb]] | ||
+ | *步骤2 | ||
+ | 叠加模块,将[[Microduino-Core/zh]]、[[Microduino-USBTTL/zh]]、[[Microduino-BM/zh]]、[[Microduino-Duo-v/zh]]、[[Microduino-Sensorhub/zh]]模块叠加在一起(无顺序差别) | ||
+ | [[File:Litter2.jpg||300px|center|thumb]] | ||
+ | *步骤3 | ||
+ | 安装测量传感器 | ||
+ | 将测量传感器安放在垃圾箱的两边,固定时要和垃圾箱的侧壁有一定的夹角(45度左右)。 | ||
+ | [[File:Litter3.jpg||300px|center|thumb]] | ||
+ | *步骤4 | ||
+ | 将一字臂安装在垃圾箱的门上 | ||
+ | [[File:Litter5.jpg||300px|center|thumb]] | ||
+ | *步骤5 | ||
+ | 连接线路 | ||
+ | [[Microduino-Sensorhub/zh]]板需要连接的插槽的的引脚说明。 | ||
+ | [[File:Litter6.png||300px|center|thumb]] | ||
+ | *步骤6 | ||
+ | 模块左边的测量传感器接A0,右边的接A2。舵机和[[Microduino servo-cin/zh]]连好后,连接线接到[[Microduino-Sensorhub/zh]]板的D4插槽 | ||
+ | [[File:Litter7.jpg||300px|center|thumb]] | ||
+ | *步骤7 | ||
+ | 连接垃圾箱门,寻找舵机旋转的中间位置 | ||
+ | [[File:Litter8.jpg||300px|center|thumb]] | ||
+ | [[File:Litter9.jpg||300px|center|thumb]] | ||
+ | *步骤8 | ||
+ | 安装舵机 | ||
+ | 将舵机的旋转轴旋转到中间位置(防止安装上只能向一个方向旋转)。垃圾桶的门为旋转开关,将舵机安放、固定在旋转轴上,让舵机旋转带动垃圾桶门的旋转 | ||
+ | [[File:Litter10.jpg||300px|center|thumb]] | ||
+ | *步骤9 | ||
+ | |||
+ | 系统测试 | ||
+ | 通过数据线连接电脑和USB板的USB接口,测试放在两边的测量传感器,修改程序中舵机的选装的角度,调整舵机旋转的角度和方向,使其可以完成用人体感应控制垃圾桶的打开方向。 | ||
+ | 调试舵机方向的代码函数为myservo.write(),在函数括号内设定舵机旋转的角度即可。 | ||
+ | 注意:程序中,更改舵机角度时,不可写成负值。 | ||
+ | ==程序说明== | ||
+ | *主函数 | ||
+ | <source lang="cpp"> | ||
+ | #define sensor_vol 300 //sensor_vol core输入(传感器输出)大于这个值:手靠近;小于这个值:没有手 | ||
+ | #define servo_vol 93 //舵机旋转到的角度 | ||
+ | |||
+ | /*为什么是300? | ||
+ | 红外测距传感器输出量为一个0~5V之间的模拟量。测距越近,电压越高。 | ||
+ | 该模拟量(0~5V)被输入到core模块的A0,A2口(两个模拟输入口)。通过模数转换器(ADC)转换成计算机能识别的量,这个量叫做数字量。数字量为0~1023(5V<-->1023,不同的ADC会有不同的测量范围) | ||
+ | |||
+ | 换算关系: | ||
+ | 输入电压 | 计算机内部用的数字量 | ||
+ | V | V*1023/5. | ||
+ | |||
+ | 经实测红外传感器的输出电压在 | ||
+ | 没有手靠近时为0.3V,对应数字量是,0.3*1023/5=61.38 | ||
+ | 有手靠近时为1.6V,对应数字量是,1.6*1023/5=61.38=327.36 | ||
+ | 选择两者中间的一个数作为区别有没有手靠近的标准。 | ||
+ | 思考,如果换成200可以么?试一试 | ||
+ | */ | ||
+ | |||
+ | int potpin[2] = | ||
+ | { | ||
+ | A0, A2 | ||
+ | }; //定义传感器的输入管脚 | ||
+ | |||
+ | #include "key.h" | ||
+ | |||
+ | #include <Servo.h> //既然用到了舵机,就要加载舵机的库文件,该库文件里包含了对于舵机的各种操作指令。比如myservo.write() | ||
+ | Servo myservo; // create servo object to control a servo | ||
+ | |||
+ | int val[2] = {0, 0}; // variable to read the value from the analog pin | ||
+ | //数组,用来存放两个模拟输入口的输入值(已经被转换为0~1023之间的数字值) | ||
+ | |||
+ | boolean sta[2] = | ||
+ | { | ||
+ | false, false | ||
+ | };//状态标志位。false表示盖子合上了,true表示盖子打开了 | ||
+ | //之所以要用两个元素是因为盖子可以两面打开 | ||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | Serial.begin(9600);//设置串口波特率,用于和电脑进行串口通信 | ||
+ | pinMode(potpin[0], INPUT); | ||
+ | pinMode(potpin[1], INPUT); | ||
+ | myservo.attach(4); //设置舵机控制管脚为D4 | ||
+ | myservo.write(servo_vol); // //舵机旋转到servo_vol的角度 垃圾桶盖子合上 | ||
+ | key_init(); | ||
+ | } | ||
+ | |||
+ | void loop() | ||
+ | { | ||
+ | //------0--------------------------------------------------------------- | ||
+ | val[0] = analogRead(potpin[0]); //读入传感器0的输出电压 reads the value of the potentiometer (value between 0 and 1023) | ||
+ | |||
+ | if((val[0] > sensor_vol) && (sta[0] == false)) //当该电压>阈值(有手接近垃圾箱)并且此时盖子是关着的时候,正向打开盖子 | ||
+ | { | ||
+ | Serial.println("sta[0]!"); | ||
+ | Serial.println("UP"); | ||
+ | myservo.write(180); // sets the servo position according to the scaled value | ||
+ | sta[0] = true; | ||
+ | delay(1000); | ||
+ | } | ||
+ | |||
+ | |||
+ | if((val[0] < sensor_vol) && (sta[0] == true)) //当该电压<阈值(没有手接近垃圾箱)并且此时盖子是开的时候,合上盖子 | ||
+ | { | ||
+ | Serial.println("DOWN"); | ||
+ | myservo.write(servo_vol); | ||
+ | sta[0] = false; | ||
+ | delay(1000); | ||
+ | } | ||
+ | |||
+ | /*为什么要加入sta? | ||
+ | loop函数是不断循环执行的。如果只是“手遮住了传感器就转”,那当手一直遮挡住传感器的时候,盖子就会不断得翻转。 | ||
+ | 所以我们的逻辑必须是“手遮住了传感器”并且“此时盖子是合上的”时候,才转。 | ||
+ | */ | ||
+ | |||
+ | //------------------------------------ | ||
+ | val[1] = analogRead(potpin[1]); // reads the value of the potentiometer (value between 0 and 1023) | ||
+ | |||
+ | if((val[1] > sensor_vol) && (sta[1] == false)) | ||
+ | { | ||
+ | Serial.println("sta[1]!"); | ||
+ | Serial.println("UP"); | ||
+ | myservo.write(0); // sets the servo position according to the scaled value | ||
+ | sta[1] = true; | ||
+ | delay(1000); | ||
+ | } | ||
+ | |||
+ | |||
+ | if((val[1] < sensor_vol) && (sta[1] == true)) | ||
+ | { | ||
+ | Serial.println("DOWN"); | ||
+ | myservo.write(servo_vol); | ||
+ | sta[1] = false; | ||
+ | delay(1000); | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | *key.h | ||
+ | <source lang="cpp"> | ||
+ | #include "arduino.h" | ||
+ | |||
+ | boolean key_status[NUM_DIGITAL_PINS]; //按键 | ||
+ | boolean key_cache[NUM_DIGITAL_PINS]; //检测按键松开缓存 | ||
+ | |||
+ | void key_init() | ||
+ | { | ||
+ | for(int a = 0; a < NUM_DIGITAL_PINS; a++) | ||
+ | { | ||
+ | key_status[a] = LOW; | ||
+ | key_cache[a] = HIGH; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | boolean key_get(int _key_pin, boolean _key_type) | ||
+ | { | ||
+ | key_cache[_key_pin] = key_status[_key_pin]; //缓存作判断用 | ||
+ | |||
+ | key_status[_key_pin] = analogRead(_key_pin) > sensor_vol; //触发时 | ||
+ | |||
+ | switch(_key_type) | ||
+ | { | ||
+ | case 0: | ||
+ | if(!key_status[_key_pin] && key_cache[_key_pin]) //按下松开后 | ||
+ | return true; | ||
+ | else | ||
+ | return false; | ||
+ | break; | ||
+ | case 1: | ||
+ | if(key_status[_key_pin] && !key_cache[_key_pin]) //按下松开后 | ||
+ | return true; | ||
+ | else | ||
+ | return false; | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | ==视频== |
2015年10月13日 (二) 08:43的最新版本
概述
用距离测量传感器,在可测量的范围内,感受人体的接近动作,将采集到的红外的强弱会影响它自己阻值,从而改变输出的电压值。处理器通过判断输出的电压值,决定垃圾桶是否开启、开启的方向,从而用以接收垃圾。 材料清单
实验原理
sharp 2y0a21型号的测量传感器,为基于PSD的距离传感器。通过自身电路中热电阻感受外接环境中温度的变化阻值,从而改变传感器两端的电压。但是热电阻的感受温度的变化测量距离有一定的范围,sharp 2y0a21型号的测量距离为10~80cm。在0~8cm左右的距离范围内与距离成正比非线性关系,在10~80cm的距离范围内成反比非线性的关系,平均消耗约为30mA,反应时间约为5ms,并且对背景及温度的适应性较强。有效的测量角度大于40度,输出信号为模拟电压。
舵机是船舶上的一种大甲板机械。舵机的大小由外舾装按照船级社的规范决定,选型时主要考虑扭矩大小。在航天方面,舵机应用广泛。航天方面,导弹姿态变换的俯仰、偏航、滚转运动,都是靠舵机相互配合完成的。舵机在许多工程上都有应用,不仅限于船舶。 舵机主要是由外壳、电路板、无核心马达、齿轮与位置检测器所构成。其工作原理是由接收机发出讯号给舵机,经由电路板上的 IC判断转动方向,再驱动无核心马达开始转动,透过减速齿轮将动力传至摆臂,同时由位置检测器送回讯号,判断是否已经到达定位。 MG996R最大旋转角度为180度,在编写程序代码时,旋转的角度范围为(0~180度)。
距离测量传感器感应两侧的红外线的强度,将感应到的数值传送到核心芯片上,核心芯片通过处理该数据,确定舵机旋转的角度,从而确定垃圾箱是否开门,如果开门开哪侧的门。因为舵机的旋转角度为0~180度,所以最好将平衡位置放在舵机旋转的角度中间。 垃圾箱安装的原理图
距离测量传感器 距离测量传感器的特性
MG996R舵机 MG996R舵机的线路说明,如图所示 舵机(MG996R)的特性
Microduino servo-cin的连线管脚 在程序中,定义舵机的引脚,对应Microduino-Sensorhub/zh一个插槽(一个插槽中有两个管脚)中的一个管脚,离板子较远的一端为数字较小的管脚。 文档调试过程
将Microduino Core、Microduino USBTTL堆叠在一起.用数据线将写好的程序通过Microduino USBTTL上传到Microduino Core上。 注意:最好不要将所有模块堆叠在一起之后再上传程序 打开程序,点击程序编译,编译成功后,在【工具】中选择好【端口】、【板】和【处理器】,选择好【板】和【处理器】之后,点击上传即可 板卡的选择 处理器的选择 端口的选择
将Microduino-Duo-v/zh用螺丝钉固定在垃圾桶上
叠加模块,将Microduino-Core/zh、Microduino-USBTTL/zh、Microduino-BM/zh、Microduino-Duo-v/zh、Microduino-Sensorhub/zh模块叠加在一起(无顺序差别)
安装测量传感器 将测量传感器安放在垃圾箱的两边,固定时要和垃圾箱的侧壁有一定的夹角(45度左右)。
将一字臂安装在垃圾箱的门上
连接线路 Microduino-Sensorhub/zh板需要连接的插槽的的引脚说明。
模块左边的测量传感器接A0,右边的接A2。舵机和Microduino servo-cin/zh连好后,连接线接到Microduino-Sensorhub/zh板的D4插槽
连接垃圾箱门,寻找舵机旋转的中间位置
安装舵机 将舵机的旋转轴旋转到中间位置(防止安装上只能向一个方向旋转)。垃圾桶的门为旋转开关,将舵机安放、固定在旋转轴上,让舵机旋转带动垃圾桶门的旋转
系统测试 通过数据线连接电脑和USB板的USB接口,测试放在两边的测量传感器,修改程序中舵机的选装的角度,调整舵机旋转的角度和方向,使其可以完成用人体感应控制垃圾桶的打开方向。 调试舵机方向的代码函数为myservo.write(),在函数括号内设定舵机旋转的角度即可。 注意:程序中,更改舵机角度时,不可写成负值。 程序说明
#define sensor_vol 300 //sensor_vol core输入(传感器输出)大于这个值:手靠近;小于这个值:没有手
#define servo_vol 93 //舵机旋转到的角度
/*为什么是300?
红外测距传感器输出量为一个0~5V之间的模拟量。测距越近,电压越高。
该模拟量(0~5V)被输入到core模块的A0,A2口(两个模拟输入口)。通过模数转换器(ADC)转换成计算机能识别的量,这个量叫做数字量。数字量为0~1023(5V<-->1023,不同的ADC会有不同的测量范围)
换算关系:
输入电压 | 计算机内部用的数字量
V | V*1023/5.
经实测红外传感器的输出电压在
没有手靠近时为0.3V,对应数字量是,0.3*1023/5=61.38
有手靠近时为1.6V,对应数字量是,1.6*1023/5=61.38=327.36
选择两者中间的一个数作为区别有没有手靠近的标准。
思考,如果换成200可以么?试一试
*/
int potpin[2] =
{
A0, A2
}; //定义传感器的输入管脚
#include "key.h"
#include <Servo.h> //既然用到了舵机,就要加载舵机的库文件,该库文件里包含了对于舵机的各种操作指令。比如myservo.write()
Servo myservo; // create servo object to control a servo
int val[2] = {0, 0}; // variable to read the value from the analog pin
//数组,用来存放两个模拟输入口的输入值(已经被转换为0~1023之间的数字值)
boolean sta[2] =
{
false, false
};//状态标志位。false表示盖子合上了,true表示盖子打开了
//之所以要用两个元素是因为盖子可以两面打开
void setup()
{
Serial.begin(9600);//设置串口波特率,用于和电脑进行串口通信
pinMode(potpin[0], INPUT);
pinMode(potpin[1], INPUT);
myservo.attach(4); //设置舵机控制管脚为D4
myservo.write(servo_vol); // //舵机旋转到servo_vol的角度 垃圾桶盖子合上
key_init();
}
void loop()
{
//------0---------------------------------------------------------------
val[0] = analogRead(potpin[0]); //读入传感器0的输出电压 reads the value of the potentiometer (value between 0 and 1023)
if((val[0] > sensor_vol) && (sta[0] == false)) //当该电压>阈值(有手接近垃圾箱)并且此时盖子是关着的时候,正向打开盖子
{
Serial.println("sta[0]!");
Serial.println("UP");
myservo.write(180); // sets the servo position according to the scaled value
sta[0] = true;
delay(1000);
}
if((val[0] < sensor_vol) && (sta[0] == true)) //当该电压<阈值(没有手接近垃圾箱)并且此时盖子是开的时候,合上盖子
{
Serial.println("DOWN");
myservo.write(servo_vol);
sta[0] = false;
delay(1000);
}
/*为什么要加入sta?
loop函数是不断循环执行的。如果只是“手遮住了传感器就转”,那当手一直遮挡住传感器的时候,盖子就会不断得翻转。
所以我们的逻辑必须是“手遮住了传感器”并且“此时盖子是合上的”时候,才转。
*/
//------------------------------------
val[1] = analogRead(potpin[1]); // reads the value of the potentiometer (value between 0 and 1023)
if((val[1] > sensor_vol) && (sta[1] == false))
{
Serial.println("sta[1]!");
Serial.println("UP");
myservo.write(0); // sets the servo position according to the scaled value
sta[1] = true;
delay(1000);
}
if((val[1] < sensor_vol) && (sta[1] == true))
{
Serial.println("DOWN");
myservo.write(servo_vol);
sta[1] = false;
delay(1000);
}
}
#include "arduino.h"
boolean key_status[NUM_DIGITAL_PINS]; //按键
boolean key_cache[NUM_DIGITAL_PINS]; //检测按键松开缓存
void key_init()
{
for(int a = 0; a < NUM_DIGITAL_PINS; a++)
{
key_status[a] = LOW;
key_cache[a] = HIGH;
}
}
boolean key_get(int _key_pin, boolean _key_type)
{
key_cache[_key_pin] = key_status[_key_pin]; //缓存作判断用
key_status[_key_pin] = analogRead(_key_pin) > sensor_vol; //触发时
switch(_key_type)
{
case 0:
if(!key_status[_key_pin] && key_cache[_key_pin]) //按下松开后
return true;
else
return false;
break;
case 1:
if(key_status[_key_pin] && !key_cache[_key_pin]) //按下松开后
return true;
else
return false;
break;
}
}
视频 |