【雕爷学编程】Arduino动手做(78)---槽型光耦红外对射计数传感器模块4

在这里插入图片描述

37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手试试多做实验,不管成功与否,都会记录下来——小小的进步或是搞不掂的问题,希望能够抛砖引玉。

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验七十八:对射光电传感器模块 脉冲计数器 电机马达测速 位置限位槽型光耦

在这里插入图片描述
槽型光耦计数测速传感器模块的实验环境
一、槽型光耦计数测速传感器模块实验所需硬件清单

20栅格测速码盘X2
Arduino Uno开发板 X1
杜邦线 若干(备了9条)
LED发光二极管(蓝色)X1
DC3V-6V直流减速TT马达X2
IIC/I2C 1602 LCD液晶屏模块X1
高电平触发有源蜂鸣器模块 X1
高电平触发单路5V继电器模块X1
Proto Shield原型扩展板(带mini面包板)X1

在这里插入图片描述

5、程序五:测试每分钟的手动遮断次数(单位为次数/分钟)
(1)参考开源代码(Arduino):

/*【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)程序五:测试每分钟的手动遮断次数与TT减速马达的转数实验接线:光耦  unoVCC  5VGND  GNDOUT  D2
*/int U_Pin = 2;
float Val = 0;      //设置变量Val,计数
float time;  //设置变量time,计时
float Speed;  //设置变量Speed,存储转速void setup() {Serial.begin(9600);Serial.println("槽型光耦准备就绪!");attachInterrupt(0, count, CHANGE);  //引脚电平发生改变时触发
}void loop() {time = millis();Speed =  (Val / 40) / (time / 60000) ;//换算为转数,单位 转/分Serial.print("转数=");Serial.print(Speed);Serial.println("转/分");delay(1000);
}void count() {Val += 1;
}

(2)实验串口返回情况(手动冰棒棍的方式)

在这里插入图片描述

(3)使用TT减速马达,来测试速度

在这里插入图片描述
(4)实验场景图之二

在这里插入图片描述

(5)实验串口返回情况之二(TT减速马达的方式)

在这里插入图片描述

(6)程序说明:

attachInterrupt(interrupt,function,mode);  

这是一句中断函数,函数有三个参数:

interrupt —— 中断源。可选值0和1,0 对应2号引脚;1 对应3号引脚。这里我们写的 0 ,即外部中断接数字引脚2号引脚。

function —— 中断处理函数。即发生中断时,去做什么。这里我们让它发生中断时,做 n+=1。用来计数模块被码盘遮挡时,电平变化的次数。

mode —— 触发模式。触发模式有四种类型:LOW(低电平触发)、CHANGE(电平变化时触发)、RISING(低电平变为高电平时触发)、FALLING(高电平变为低电平时触发)。这里我们选择CHANGE(电平变化时触发),前面讲了,码盘有20个缝隙,20个遮挡,这样,电机转一转时,为40次触发,即n=40,为n/40转。

millis();  

此函数用于获取机器运行的时间长度,函数返回值为 unsigned long 型(毫秒ms),系统最长的记录时间为9小时22分钟,如果超出,则从0开始。因此,我们所测的转速,为自系统运行开始时的平均角速度,并不是实时速度。

了解了这两句函数之后,再看上面的代码,不难理解,最终输出的为电机的转速,单位:转/分钟。

6、程序六:使用1602 LCD屏显示电机转速
(1)参考开源代码(Arduino):

/*【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)程序六:使用1602 LCD屏显示电机转速
*/#include  //导入LCD屏的驱动库
LiquidCrystal_I2C lcd (0x27, 16, 2);//设置LCD屏参数const byte PulsesPerRevolution = 2;
const unsigned long ZeroTimeout = 100000;
const byte numReadings = 2;volatile unsigned long LastTimeWeMeasured;
volatile unsigned long PeriodBetweenPulses = ZeroTimeout + 1000;
volatile unsigned long PeriodAverage = ZeroTimeout + 1000;
unsigned long FrequencyRaw;
unsigned long FrequencyReal;
unsigned long RPM;
unsigned int PulseCounter = 1;
unsigned long PeriodSum;unsigned long LastTimeCycleMeasure = LastTimeWeMeasured;
unsigned long CurrentMicros = micros();
unsigned int AmountOfReadings = 1;
unsigned int ZeroDebouncingExtra;
unsigned long readings[numReadings];
unsigned long readIndex;
unsigned long total;
unsigned long average;void setup() {Serial.begin(9600);// 设置串口波特率为9600lcd.init();//LCD初始化lcd.backlight(); //打开LCD背光attachInterrupt(digitalPinToInterrupt(2), Pulse_Event, RISING);//使用中断计数,低电平变为高电平时触发delay(1000);}
void loop() {LastTimeCycleMeasure = LastTimeWeMeasured;CurrentMicros = micros();if (CurrentMicros < LastTimeCycleMeasure) {LastTimeCycleMeasure = CurrentMicros;}FrequencyRaw = 10000000000 / PeriodAverage; //周期平均值if (PeriodBetweenPulses > ZeroTimeout - ZeroDebouncingExtra || CurrentMicros - LastTimeCycleMeasure > ZeroTimeout - ZeroDebouncingExtra) {FrequencyRaw = 0;  // 设置频率为 0ZeroDebouncingExtra = 2000;} else {ZeroDebouncingExtra = 0;}FrequencyReal = FrequencyRaw / 10000;RPM = FrequencyRaw / PulsesPerRevolution * 60;RPM = RPM / 10000;total = total - readings[readIndex];readings[readIndex] = RPM;total = total + readings[readIndex];readIndex = readIndex + 1;if (readIndex >= numReadings) {readIndex = 0;}average = total / numReadings;//串口打印相关五项实时数据值Serial.print("期间: ");Serial.print(PeriodBetweenPulses);Serial.print("\t读数: ");Serial.print(AmountOfReadings);Serial.print("\t频率: ");Serial.print(FrequencyReal);Serial.print("\t转速: ");Serial.print(RPM);Serial.print("\t转速表:");Serial.println(average);//LCD屏显示实时转速lcd.setCursor(0, 0);lcd.print("RPM : ");lcd.print(RPM);lcd.print("   ");delay(1000);
}void Pulse_Event() {PeriodBetweenPulses = micros() - LastTimeWeMeasured;LastTimeWeMeasured = micros();if (PulseCounter >= AmountOfReadings)  {PeriodAverage = PeriodSum / AmountOfReadings;PulseCounter = 1;PeriodSum = PeriodBetweenPulses;int RemapedAmountOfReadings = map(PeriodBetweenPulses, 40000, 5000, 1, 10);RemapedAmountOfReadings = constrain(RemapedAmountOfReadings, 1, 10);AmountOfReadings = RemapedAmountOfReadings;} else {PulseCounter++;PeriodSum = PeriodSum + PeriodBetweenPulses;}
}

(2)实验串口返回情况

在这里插入图片描述

(3)实验场景图,1602 LCD屏显示电机转速

在这里插入图片描述
(4)实验场景图

在这里插入图片描述
在这里插入图片描述


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部