红外传感器
红外传感系统是用红外线为介质的测量系统,按照功能可分成五类, 按探测机理可分成为光子探测器和热探测器。 红外传感技术已经在现代科技、国防和工农业等领域获得了广泛的应用
红外线对射管的驱动分为电平型和脉冲型两种驱动方式。由红外线对射管阵列组成分离型光电传感器。该传感器的创新点在于能够抵抗外界的强光干扰。太阳光中含有对红外线接收管产生干扰的红外线,该光线能够将红外线接收二极管导通,使系统产生误判,甚至导致整个系统瘫痪。本传感器的优点在于能够设置多点采集,对射管阵列的间距和阵列数量可根据需求选取。
红外线技术在测速系统中已经得到了广泛应用,许多产品已运用红外线技术能够实现车辆测速、探测等研究。红外线应用速度测量领域时,最难克服的是受强太阳光等多种含有红外线的光源干扰。外界光源的干扰成为红外线应用于野外的瓶颈。针对此问题,这里提出一种红外线测速传感器设计方案,该设计方案能够为多点测量即时速度和阶段加速度提供技术支持,可应用于公路测速和生产线下料的速度称量等工业生产中需要测量速度的环节。
红外技术已经众所周知,这项技术在现代科技、国防科技和工农业科技等领域得到了广泛的应用。红外传感系统是用红外线为介质的测量系统,按照功能能够分成五类:(1)辐射计,用于辐射和光谱测量;(2)搜索和跟踪系统,用于搜索和跟踪红外目标,确定其空间位置并对它的运动进行跟踪;(3)热成像系统,可产生整个目标红外辐射的分布图像;(4)红外测距和通信系统;(5)混合系统,是指以上各类系统中的两个或者多个的组合。
红外传感器根据探测机理可分成为:光子探测器(基于光电效应)和热探测器(基于热效应)。
原理
待测目标
根据待测目标的红外辐射特性可进行红外系统的设定。
大气衰减
待测目标的红外辐射通过地球大气层时,由于气体分子和各种气体以及各种溶胶粒的散射和吸收,将使得红外源发出的红外辐射发生衰减。
光学接收器
它接收目标的部分红外辐射并传输给红外传感器。相当于雷达天线,常用是物镜。
辐射调制器
对来自待测目标的辐射调制成交变的辐射光,提供目标方位信息,并可滤除大面积的干扰信号。又称调制盘和斩波器,它具有多种结构。
红外探测器
这是红外系统的核心。它是利用红外辐射与物质相互作用所呈现出来的物理效应探测红外辐射的传感器,多数情况下是利用这种相互作用所呈现出的电学效应。此类探测器可分为光子探测器和热敏感探测器两大类型。
探测器制冷器
由于某些探测器必须要在高温下工作,所以相应的系统必须有制冷设备。经过制冷,设备可以缩短响应时间,提高探测灵敏度。
信号处理系统
将探测的信号进行放大、滤波,并从这些信号中提取出信息。然后将此类信息转化成为所需要的格式,最后输送到控制设备或者显示器中。
显示设备
这是红外设备的终端设备。常用的显示器有示波器、显像管、红外感光材料、指示仪器和记录仪等。
依照上面的流程,红外系统就可以完成相应的物理量的测量。红外系统的核心是红外探测器,按照探测的机理的不同,可以分为热探测器和光子探测器两大类。下面以热探测器为例子来分析探测器的原理。
热探测器是利用辐射热效应,使探测元件接收到辐射能后引起温度升高,进而使探测器中依赖于温度的性能发生变化。检测其中某一性能的变化,便可探测出辐射。多数情况下是通过热电变化来探测辐射的。当元件接收辐射,引起非电量的物理变化时,可以通过适当的变换后测量相应的电量变化。
图上所示为欧姆龙公司生产的漫反射式和对射式光电传感器,这两种传感器主要用于事件检测和物体定位。图中的红灯和绿灯表示传感器的状态。
红外传感器已经在现代化的生产实践中发挥着它的巨大作用,随着探测设备和其他部分的技术的提高,红外传感器能够拥有更多的性能和更好的灵敏度。
类型
红外线传感器依动作可分为:
(1) 将红外线一部份变换为热,藉热取出电阻值变化及电动势等输出信号之热型。
(2) 利用半导体迁徙现象吸收能量差之光电效果及利用因PN 接合之光电动势效果的量子型。
热型的现象俗称为焦热效应,其中最具代表性者有测辐射热器 (THERMAL BOLOMETER),热电堆(THERMOPILE)及热电(PYROELECTRIC)元件。
热型的优点有:可常温动作下操作,波长依存性(波长不同感度有很大之变化者)并不存在,造价便宜;
缺点:感度低、响应慢(MS之谱)。
量子型 的优点:感度高、响应快速(ΜS 之谱);
缺点:必须冷却(液体氮气) 、有波长依存性、价格偏高;
红外线传感器特别是利用远红外线范围的感度做为人体检出用,红外线的波长比可见光长而比电波短。红外线让人觉得只由热的物体放射出来,可是事实上不是如此,凡是存在于自然界的物体,如人类、火、冰等等全部都会射出红外线,只是其波长因其物体的温度而有差异而已。人体的体温约为36~37°C,所放射出峰值为9~10微米的远红外线,另外加热至400~700°C的物体,可放射出峰值为3~5微米(不是MM)的中间红外线。
雷达通常在军事领域运用较多,民用方面也有很多,在此就不一一举例说明了。
本次设计主要是想通过红外测距传感器配合单片机系统实现“雷达”硬件,通过异步串口通信,将数据传输至PC,并通过Peocessing开发上位机“雷达”界面用以显示。
在传感器的测试文档中,小楊通过矩形数量来显示传感器输出值。
今天既然说是“雷达”,那小楊就模拟一个“雷达”界面。
雷达硬件组成:
老套路,发烟测试,通过最简单的方法实现效果。
SHARP的GP2Y0A21YK0F传感器性能稳定,好用不贵,且不需要再设计外围电路。
那剩下的就是具备ADC+串口通信功能的单片机系统咯,出于最简单实现的初衷,小楊就用下面这款了:
开发板兼容ArduinoIDE编程。不在这里过多赘述,相关信息请参阅工作室的其他文档。
整体连接如下:
忘了说,扫描需要云台,就用舵机简单模拟一个,关于舵机控制,请参考:
下面直接展示代码:
// Visual Micro is in vMicro》General》Tutorial Mode
//
/*
Name: LeiDa.ino
Created: 2018/7/22 13:23:31
Author: 禾灮\HeGuang
*/
// Define User Types below here or use a .h file
//
#include 《Servo.h》。
// Define Function Prototypes that use User Types below here or use a .h file
//// 初始化设置
const int VoPin = 14;
long duraTIon;
int distance;
Servo myServo; // Creates a servo object for controlling the servo motor
int Range_SHARP(){
duraTIon = analogRead(VoPin);
distance = (1024 - duraTIon)/10 - 50;
return distance;
}
// The setup() funcTIon runs once each time the micro-controller starts
void setup(){
pinMode(VoPin, INPUT);
Serial.begin(9600);
myServo.attach(10);
}
// Add the main program code into the continuous loop() function
void loop(){
for(int i=15;i《=165;i++){
myServo.write(i);
distance = Range_SHARP();
Serial.print(i);
Serial.print(“,”);
Serial.print(distance);
Serial.print(“。”);
delay(50);
}
for(int i=165;i》15;i--){
myServo.write(i);
distance = Range_SHARP();
Serial.print(i);
Serial.print(“,”);
Serial.print(distance);
Serial.print(“。”);
delay(50);
}
}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
完成了这些准备,下面就该上位机开发了。
雷达上位机
开发用到的软件:Processing,一款非常好用的交互上位机设计软件。
上位机界面如下:
不多说,直接上代码:
import processing.serial.*;
import java.awt.event.KeyEvent;
import java.io.IOException;
Serial myPort;
String angle=“”;
String distance=“”;
String data=“”;
String noObject;
float pixsDistance;
int iAngle, iDistance;
int index1=0;
int index2=0;
PFont orcFont;
void setup() {
size (1200, 700); //这个分辨率自己根据你的电脑的配置和显示屏幕配置进行更改。
smooth();
myPort = new Serial(this,“COM7”, 9600); //这个串口号一定要更改。
myPort.bufferUntil(‘。’);
}
void draw() {
fill(98,245,31);
noStroke();
fill(0,4);
rect(0, 0, width, height-height*0.065);
fill(98,245,31);
drawRadar();
drawLine();
drawObject();
drawText();
}
void serialEvent (Serial myPort) {
data = myPort.readStringUntil(‘。’);
data = data.substring(0,data.length()-1);
index1 = data.indexOf(“,”);
angle= data.substring(0, index1);
distance= data.substring(index1+1, data.length());
iAngle = int(angle);
iDistance = int(distance);
}
void drawRadar() {
pushMatrix();
translate(width/2,height-height*0.074);
noFill();
strokeWeight(2);
stroke(98,245,31);
// draws the arc lines
arc(0,0,(width-width*0.0625),(width-width*0.0625),PI,TWO_PI);
arc(0,0,(width-width*0.27),(width-width*0.27),PI,TWO_PI);
arc(0,0,(width-width*0.479),(width-width*0.479),PI,TWO_PI);
arc(0,0,(width-width*0.687),(width-width*0.687),PI,TWO_PI);
// draws the angle lines
line(-width/2,0,width/2,0);
line(0,0,(-width/2)*cos(radians(30)),(-width/2)*sin(radians(30)));
line(0,0,(-width/2)*cos(radians(60)),(-width/2)*sin(radians(60)));
line(0,0,(-width/2)*cos(radians(90)),(-width/2)*sin(radians(90)));
line(0,0,(-width/2)*cos(radians(120)),(-width/2)*sin(radians(120)));
line(0,0,(-width/2)*cos(radians(150)),(-width/2)*sin(radians(150)));
line((-width/2)*cos(radians(30)),0,width/2,0);
popMatrix();
}
void drawObject() {
pushMatrix();
translate(width/2,height-height*0.074);
strokeWeight(9);
stroke(255,10,10); // red color
pixsDistance=iDistance*((height-height*0.1666)*0.025);
if(iDistance《40){
line(pixsDistance*cos(radians(iAngle)),-pixsDistance*sin(radians(iAngle)),(width-width*0.505)*cos(radians(iAngle)),-(width-width*0.505)*sin(radians(iAngle)));
}
popMatrix();
}
void drawLine() {
pushMatrix();
strokeWeight(9);
stroke(30,250,60);
translate(width/2,height-height*0.074);
line(0,0,(height-height*0.12)*cos(radians(iAngle)),-(height-height*0.12)*sin(radians(iAngle)));
popMatrix();
}
void drawText() {
pushMatrix();
if(iDistance》40) {
noObject = “Out of Range”;
}else {
noObject = “In Range”;
}
fill(0,0,0);
noStroke();
rect(0, height-height*0.0648, width, height);
fill(98,245,31);
textSize(25);
text(“10cm”,width-width*0.3854,height-height*0.0833);
text(“20cm”,width-width*0.281,height-height*0.0833);
text(“30cm”,width-width*0.177,height-height*0.0833);
text(“40cm”,width-width*0.0729,height-height*0.0833);
textSize(28);
text(“Object: ” + noObject, width-width*0.875, height-height*0.0277);
text(“Angle: ” + iAngle +“ °”, width-width*0.48, height-height*0.0277);
text(“Distance: ”, width-width*0.26, height-height*0.0277);
if(iDistance《40) {
text(“ ” + iDistance +“cm”, width-width*0.225, height-height*0.0277);
}
textSize(25);
fill(98,245,60);
translate((width-width*0.4994)+width/2*cos(radians(30)),(height-height*0.0907)-width/2*sin(radians(30)));
rotate(-radians(-60));
text(“30°”,0,0);
resetMatrix();
translate((width-width*0.503)+width/2*cos(radians(60)),(height-height*0.0888)-width/2*sin(radians(60)));
rotate(-radians(-30));
text(“60°”,0,0);
resetMatrix();
translate((width-width*0.507)+width/2*cos(radians(90)),(height-height*0.0833)-width/2*sin(radians(90)));
rotate(radians(0));
text(“90°”,0,0);
resetMatrix();
translate(width-width*0.513+width/2*cos(radians(120)),(height-height*0.07129)-width/2*sin(radians(120)));
rotate(radians(-30));
text(“120°”,0,0);
resetMatrix();
translate((width-width*0.5104)+width/2*cos(radians(150)),(height-height*0.0574)-width/2*sin(radians(150)));
rotate(radians(-60));
text(“150°”,0,0);
popMatrix();
}