基于Arduino的视觉暂留现象和频闪效应演示系统程序设计

【前言】:
此项目是为了初学Arduino而做的小练习,耗时3天多,在此做一个记录。
该系统可以演示频闪效应视觉暂留现象,硬件设计已给出,需在此基础上设计程序,满足演示需求

【演示需求】:

  1. 风扇共有7个扇叶,其中一个扇叶上写有标记图案。启动系统,风扇转动,此时并不能观察到标记图案。当按下按键1后,可以观察到1个静止的标记图案。继续按下按键1,观察到多个标记图案,最多7个。
  2. 第8次按下按键1后,可以观察到标记图案一会儿向前旋转,一会儿向后旋转。
  3. 按下按键2,系统停止运行。

【原理概述】:
每当标记图案转动到同一个位置,亮一次灯,因为视觉暂留现象,即可观察到“静止的”标记图案。
激光器接收激光信号,风扇转动,不停打断信号,每打断7次即风扇转动一圈。LED灯带以一定频率闪烁。
每转一圈,在前两次打断时亮灯,即可观察到2个图案。以此类推,每次打断都亮灯可观察到7个图案。
继续改变LED闪烁频率,使其每打断9次亮一次灯,因为频率不同步,可观察到标记图案向前向后交替旋转。

【概念介绍】:
首先解释视觉暂留现象:
如图纸片上一面画了鸟,一面画了笼子,快速转动纸片,可以看到“笼中鸟”的“幻觉”,这就是一种“视觉暂留”现象。

在这里插入图片描述

平常看的动画、电影等,其实就是将图片快速切换,每秒钟切换24张静止的图片,人眼却觉得看到了栩栩如生的画面。
为什么我们的眼睛会受到这样的“欺骗”?
现代医学发现,人眼在观察物体时,物体成像于视网膜上,并由视神经输入大脑,感觉到物体的像。光的作用结束后视觉形象并不立即消失,而是会延续0.1-0.4秒的时间,视觉的这一现象被称为“视觉暂留”。
观察“笼中鸟”时我们还可以察觉到“破绽”,而电影选择24帧则意味着约每0.04秒就切换一张图片,在人眼还没反应过来时已经切换了10张图片了,人眼更加察觉不到这其实是一幅幅静止的图片了。

其次解释频闪效应:
频闪效应是在以一定频率变化的光线照射下,观察到的物体运动呈现出静止或不同于其实际运动状态的现象。
频闪仪就是一种利用频闪效应和视觉暂留现象的设备,用以观察高速运动物体的表面状况或运行状况,广泛应用于检查各类转子、齿轮啮合、振动情况,诊断纺织、印刷、馐、钢板等场景。

【项目代码】:

#include<MsTimer2.h>
int sensor = 2;                                  //传感器引脚
int laser = 3;                                   //激光引脚
int led = 4;                                     //LED引脚
int fan =5;                                      //风扇引脚
int button1 = 8;                                 //按键1引脚
int button2 = 7;                                 //按键2引脚
int currentVal = 0;                              //按键1当前值
int previousVal = 1;                             //按键1前值
int i = 0;                                       //激光中断次数
int j = 0;                                       //图案数量计数
int Fan_Blade = 7;                               //风扇扇叶数量

void setup() {                                   //初始化程序
  Serial.begin(9600);
  pinMode(sensor,INPUT);                         //初始化各引脚状态
  pinMode(laser,OUTPUT);
  pinMode(led,OUTPUT);
  pinMode(fan,OUTPUT);
  pinMode(button2,INPUT);
  pinMode(button1,INPUT);
  delay(100);
  digitalWrite(laser,HIGH);                      //打开激光、风扇,检测2引脚上升沿中断
  digitalWrite(fan,HIGH);
  attachInterrupt(0,Flash,RISING);
}

void loop() {                                    //主体程序
  Press_button1();                               //按下按键1,开始呈现视觉暂留效果,连续按可循环增加图案
  Press_button2();                               //按下按键2,关闭系统(方便调试,省插拔)
}

void Flash() {                                   //频闪程序,每当风扇转动到相同位置时亮灯,每转到多个位置时亮灯则显示多个图案
  delay(1);                                      //消抖:延时1毫秒后再次判定,确定仍是高电平,过滤刚中断时的信号抖动
  if(digitalRead(sensor) == HIGH) {
     i++;
  }
  if(i > Fan_Blade) {                            //以7扇叶为例,i在1到7循环。按下按键1,j=1,每当i=1时亮灯。j=2时则每当i=1和2时都亮灯。
     i = 1;
  }
  if(i <= j) {
     digitalWrite(led,HIGH);
     MsTimer2::set(1,Turn_off_led);              //定时器:亮灯1毫秒后关灯。不关则常亮,立即关则常灭,必须延时后再关。
     MsTimer2::start();
  }
  Serial.println(i);                             //向串口打印i值
}

void Turn_off_led() {                            //关灯
  digitalWrite(led,LOW);
}

void Press_button1() {                           //按下按键1,j在0到7循环,显示图案数量增加
  previousVal = currentVal;                      //时刻保存button1当前值和前值
  currentVal = digitalRead(button1);
  if(previousVal != currentVal) {                //消抖
     delay(50);
  }
  if(previousVal == 1 && currentVal == 0) {      //通电后按键1处于高电平,按下时变为低电平,此时符合条件,j+1
     j++;
  }
  if(j > Fan_Blade) {
     j = 1;
     //Fan_Blade = 9;                            //可在观察完全部扇叶静止图案之后,观察图案正转和反转交替现象
  }
}

void Press_button2() {                           //按下按键2,关闭各组件。可用RESET键重启程序。
  if(digitalRead(button2) == 0) {
     digitalWrite(sensor,LOW);
     digitalWrite(laser,LOW);
     digitalWrite(led,LOW);
     digitalWrite(fan,LOW);
  }
}

【遇到的问题及解决办法】

  1. 中断。一开始检测方式使用digitalRead(sensor)检测高电平来计数打断,引脚输出的信号不太规律,后经陈工提醒可使用上升沿检测,学习了中断相关知识后改为attachInterrupt(0,Flash,RISING),检测更加准确,语句更加简洁。
  2. 消抖。①传感器消抖。设计过程中发现,扇叶打断一次,激光传感器却触发了多次中断。经过示波器观察信号,分析是有信号抖动,传感器很灵敏,刚打断时很小的波动也被检测到,故需要消除抖动。采取的方式是在中断刚开始时延时1毫秒,之后再次检测引脚电平,如果仍然是高电平,即可排除掉抖动。②按键消抖。发现有时按下一次按键,图案却增加了两个,分析是按键也存在抖动,用同样的逻辑,每当按键电平变化时延时50毫秒即可消抖。③为什么传感器消抖选择只延时1毫秒:风扇转动间隙很短,更久的延时会造成错过下一次打断,图案显示将不规则。④除了软件消抖,也学习了硬件消抖,了解到可以加上电容进行滤波
  3. 定时器。在设计Flash()闪烁程序时,调试发现,不关则常亮,立即关则常灭,必须延时后再关。使用delay(1)关灯发现图案晃动严重,尝试多种方案后采用MsTimer2定时器实现延时功能,图像稳定。
  4. 亮度。发现图像虽然稳定,但是亮度很低,看不太清楚,希望能调高亮度分析原因:当检测到中断时,如果能越快开灯,图案就越亮。之前将Serial.println(i)这一语句添加在了开灯之前,使其先去将i值打印到串口再闪烁,浪费了一些时间,将其调整到闪烁之后亮度更亮了,问题解决。

【可改进的地方】
频闪效应除了能观察高速运动物体“静止”的状态,还应该演示与其实际运动状态不相符时的现象。以本系统为例,风扇顺时针旋转,如果能展示图案“倒转”,则可以更充分地演示频闪效应,提高演示过程的趣味性,激发观众兴趣和引起思考。

【改进办法】
改变LED闪烁频率。当闪烁频率高于风扇旋转频率时,图案转向都是顺时针的;当闪烁频率低于风扇旋转频率时,偶尔能观察到“倒转”。经测试,当闪烁频率为每9次和每12次中断闪烁一次时,能观察到正转反转交替的现象。对于扇叶数量不为7的风扇,也可以经过简单测试找到合适的闪烁频率。
代码改动:将Fan_Blade = 9;添加到判断按键次数循环的if语句中即可。

【项目总结】
此项目既适合向观众介绍视觉暂留现象和频闪效应,也适合光电相关专业学生/从业者入门Arduino软件。
因其有趣的视觉现象可以立刻引起人的兴趣,进而引发思考:为什么会产生这样的现象?
了解过视觉暂留现象和频闪效应后,就会思考:该系统的实现原理是什么?如何设计代码?

经过几天的学习,从对Arduino软件一窍不通,到能够动手完成一个小演示系统的代码设计,我学到了很多。
从视觉暂留现象和频闪效应的原理和应用,到Arduino的编程结构、数值和函数,再到中断、定时器和消抖,以及对用到的硬件比如Arduino开发板、风扇、LED灯带、激光、激光传感器、按键、示波器等都有了新的认识和实践经验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值