光电传感器是将光信号转换为电信号的一种器件。其工作原理基于光电效应。光电效应是指光照射在某些物质上时,物质的电子吸收光子的能量而发生了相应的电效应现象。
光电传感器简介
光电传感器一般由处理通路和处理元件两部分组成。其基本原理是以光电效应为基础,把被测量的变化转换成光信号的变化,然后借助光电元件进一步将非电信号转换成电信号。光电效应是指用光照射某一物体,可以看作是一连串带有一定能量为的光子轰击在这个物体上,此时光子能量就传递给电子,并且是一个光子的全部能量一次性地被一个电子所吸收,电子得到光子传递的能量后其状态就会发生变化,从而使受光照射的物体产生相应的电效应。
光电传感器
光电传感器在一般情况下,有三部分构成,它们分为:发送器、接收器和检测电路。
- 发送器对准目标发射光束,发射的光束一般来源于半导体光源,发光二极管(LED)、激光二极管及红外发射二极管。光束不间断地发射,或者改变脉冲宽度。
- 接收器由光电二极管、光电三极管、光电池组成。在接收器的前面,装有光学元件如透镜和光圈等。
- 在其后面是检测电路,它能滤出有效信号和应用该信号。
分类和工作方式
⑴槽型光电传感器
把一个光发射器和一个接收器面对面地装在一个槽的两侧组成槽形光电。发光器能发出红外光或可见光,在无阻情况下光接收器能收到光。但当被检测物体从槽中通过时,光被遮挡,光电开关便动作,输出一个开关控制信号,切断或接通负载电流,从而完成一次控制动作。槽形开关的检测距离因为受整体结构的限制一般只有几厘米。
⑵对射型光电传感器
若把发光器和收光器分离开,就可使检测距离加大,一个发光器和一个收光器组成对射分离式光电开关,简称对射式光电开关。对射式光电开关的检测距离可达几米乃至几十米。使用对射式光电开关时把发光器和收光器分别装在检测物通过路径的两侧,检测物通过时阻挡光路,收光器就动作输出一个开关控制信号。
⑶反光板型光电开关
把发光器和收光器装入同一个装置内,在前方装一块反光板,利用反射原理完成光电控制作用,称为反光板反射式(或反射镜反射式)光电开关。正常情况下,发光器发出的光源被反光板反射回来再被收光器收到;一旦被检测物挡住光路,收光器收不到光时,光电开关就动作,输出一个开关控制信号。
⑷扩散反射型光电开关
扩散反射型光电开关的检测头里也装有一个发光器和一个收光器,但扩散反射型光电开关前方没有反光板。正常情况下发光器发出的光收光器是找不到的。在检测时,当检测物通过时挡住了光,并把光部分反射回来,收光器就收到光信号,输出一个开关信号。
今天我们就重点介绍其中的一种:槽型光电传感器模块。
槽型光电传感器模块
模块介绍
- 槽型光电传感器
- 槽宽度:10mm
- 带输出状态指示灯
- 槽内有遮挡,输出高电平,指示灯灭;槽内无遮挡,输出低电平,灯亮
- 宽电压LM393比较器输出,信号干净,波形好,驱动能力强
- 工作电压:3.3v-5v
- 输出形式:数字开关量输出(0和1)
- 模块尺寸大小为:23mm x 20 mm x 20mm
- 用途:电机测速,脉冲计数,位置限位等
引脚定义:
- VCC:电源正极
- GND:接地
- OUT:信号输出端
Arduino驱动实例
下面我们就用Arduino加光电传感器做一个投币计数器
硬件设备:
- Arduino UNO控制器 × 1
- 光电传感器模块 × 1
- 硬币 × n
- 投币装置 × 1
- 数码管模块 × 1
- 电源 × 1
- 杜邦线 × n
接线图:
将数码管模块的DIO、SCK、RCK分别连到Arduino 9/10/11数字引脚上,连接电源和接地线,用来显示硬币数量;光电传感器模块的OUT连接Arduino的6数字引脚,连接电源和接地线。
下面是实物图;图中Arduino模块增加了扩展板,方便接线。
然后再简单制作一个投币器;硬币投入槽中,会遮挡光传感器,激活计数。
程序:
int n = 0; // 硬币数量n
int core = 6; // 光电传感器引脚
int val_core = 0; // 低电平灯亮;高电平,有东西灯灭
uint8_t SEGPLAY[] = { 0xC0, //"0"
0xF9, //"1"
0xA4, //"2"
0xB0, //"3"
0x99, //"4"
0x92, //"5"
0x82, //"6"
0xF8, //"7"
0x80, //"8"
0x90, //"9"
};
uint8_t DIG[] = {0b10000000,
0b01000000,
0b00100000,
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001,
};
#define dataPin 9 //数码管 DIO
#define clockPin 10 //数码管 SCK
#define latchPin 11 //数码管 RCK
void setup()
{
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(core, INPUT);
}
void loop()
{
val_core = digitalRead(core); //读取输入
if ( val_core == 1) //光电传感器输出1
{
n = n+1; //硬币数加1
delay(50);
}
playnum (n, n); //数码管显示硬币数
}
//函数作用:用于四位数码管显示数字
//输入值:unsigned int 范围0-9999 //
void playnum (unsigned int i, unsigned int n)
{
SegDisplay(i / 1000, 0);
SegDisplay((i % 1000) / 100, 1);
SegDisplay((i % 100) / 10, 2);
SegDisplay((i % 10), 3);
SegDisplay(n / 1000, 4);
SegDisplay((n % 1000) / 100, 5);
SegDisplay((n % 100) / 10, 6);
SegDisplay((n % 10), 7);
//delay(5);
}
//函数作用:用于单位数码管显示数字
//输入值:i 范围0-11 //
// 显示位置 1-4 //
void SegDisplay(int i, int j)
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, DIG[j]); //位选
shiftOut(dataPin, clockPin, MSBFIRST, SEGPLAY[i]);//段选
digitalWrite(latchPin, HIGH);
delayMicroseconds(500);//调节这个和下面的参数可以调整显示亮度,建议这两个数加起来为860。这样是为了显示时间准确
// delayMicroseconds(360);
}
效果展示: