

单片机很好玩14,制作“人工向日葵”,自动寻光
source link: https://blog.popkx.com/single-chip-computer-is-very-interesting-14-making-artificial-sunflower-automatic-light-seeking/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

上一节介绍了如何使用C语言编程单片机控制步进电机转动,在文章最后提到,只要再结合感光器件,我们就能够制作一个“人工向日葵”,如下图:
可以看出,单片机控制步进电机带着“箭头”始终指向光源,就好像向日葵一直跟着太阳一样。怎么做呢?
两项基本工作
这里仍然计划使用 51 单片机作为控制中心,那么要制作“人工向日葵”,需要先完成两项基本工作:一是获取光源的方向,知道光源在哪个方向后,还要有能力带着“箭头”转动,直到指向光源。完成这两项基本工作后,剩下的工作就简单了。
先来看看怎样带着“箭头”转动
还记得上一节介绍的步进电机吗?它就非常适合完成这些工作,将箭头粘在步进电机的转动轴上,单片机驱动步进电机转动就可以带动“箭头”转动了。关于单片机如何驱动步进电机,这里就不赘述了,感到陌生的朋友可以看看上一节的文章。
再来看看如何获取光源方向
对我们人类来说,要判断光源方向实在太简单了,看一看周围就知道了,基本上光线最强的方向就是光源的方向。那么,单片机该怎样判断光源方向呢?
参照人类判断光源方向的方法,单片机首先要能“看到”环境光线情况。如何让单片机“看到”环境光线,第 11 节和第 12 节已经介绍的比较清楚了。这里还是采用和之前一样的方法:借助于光敏电阻。
光敏电阻的阻值会随着照射在它表面的光纤强度的改变而改变,利用欧姆定律,很容易将这种阻值变化转换为电压值变化,再利用 ADC 模块,单片机就可以通过 ADC 采样值,间接感知环境的光线情况了。
现在单片机能看到环境光线了,那怎样判断光源方向呢?似乎可以采取这样的办法:将光敏电阻粘在步进电机的转动轴上,然后利用单片机驱动步进电机带着光敏电阻转动,先“看一看”四周的光线,沿途记录光强值,转完一圈后,光强最强的方向就是光源的方向,再驱动步进电机转回来。
可是这种方法有个比较大的缺陷:如果想始终控制“箭头”指向光源,步进电机是不能停的,它得不停的检测四周的光线强度。这时,我们从外界看,箭头的方向是哪里呢?其实没有方向,它一直在转动。
可能你会说:可以在找到光源以后,驱动步进电机带着箭头转回来之后,停一会不就行了吗?可是步进电机停下后,不就没法“始终”指向光源方向了吗?所以,采取一个光敏电阻很难达成目标。
只用一个光敏电阻,至少我想不到好办法,如果读者有什么好办法,可以在评论区回复,让我长长见识。
也是考虑了好一会儿,决定使用两个光敏电阻,中间使用隔板挡开,如下图。
正常情况下,除非正对着光源,否则总有一个光敏电阻接收的光线更强,而接收到更强光线的那个光敏电阻一般就在光源方向,这时驱动步进电机带着光敏电阻往光源方向转动就可以了。
当两个电阻接收的光线强度相差无几时,就可以停下了,一旦光强差较大,就继续驱动步进电机往光较强方向转动,这样就实现了“人工向日葵”的基本功能:始终指向光源方向。
但是这种方法要求两个光敏电阻有相同的光响应曲线,而世界上不可能有一模一样的东西,所以这里使用了可调电阻,如下图:
通过调节可调电阻,可以尽力让两个光敏电阻的响应特性接近。
编写C语言程序,实现“人工向日葵”的设计
现在思路和设计都有了,写C语言代码就简单了,毕竟重在设计,写代码本身没有什么技术含量。ADC 模块的相关C语言代码,我们之前已经写过很多次了,这里需要说明的是,P1ASF 寄存器决定开启几个通道的 ADC,因为我们的设计需要两路,所以给 P1ASF 赋值为 0x03,表示使用单片机的 P1.0 和 P1.1 作为 ADC 采样输入口了。
void adc_init()
{
P1ASF = 0x03;
ADC_RES = 0;
ADC_CONTR = ADC_POWER|ADC_SPEEDLL;
delay_about_100ms(2);
}
步进电机相关的C语言代码上一节已经介绍,这里不再赘述。主控程序的C语言代码如下:
void main()
{
WORD res0 = 0, res1 = 0;
adc_init();
while(1){
res0 = get_adc_res(0);
res1 = get_adc_res(1);
if(res0-20 > res1)
MotorTurnBack(100);
else if(res1-20 > res0)
MotorTurn(100);
}
}
因为两个光敏电阻不可能完全一样,所以代码中有一个 20 的光强阈值,只有光强差超过 20 时,系统才认为需要转动步进电机调整箭头方向。而且,设定 20 作为阈值,也能防止因为电路噪声,或者光源不稳定导致的箭头抖动问题。
现在编译C语言程序,烧写到单片机,发现我们成功了。
现在有了“人工向日葵”,我们可以在此基础上再做一些好玩又有用的东西:比如一款追着光源跑的小车,再比如一个自动追着太阳方向的晒鞋器,甚至,可以用在现在非常火热的新能源光伏发电上,想想看,光能发电板始终正对着太阳,能提升多少发电效率啊
Recommend
-
8
单片机很好玩13,步进电机的使用 发表于 2019-01-27 19:01:29...
-
11
上一节,我们利用C语言编程单片机仿制了达文西的“古怪手电筒”,达成了“在有光的时候就会亮,在没有光的情况下绝对不会亮!”的目标。
-
15
最近重温经典喜剧电影时,发现下面这么一幕:达文西发明了一个“古怪手电筒”,“在有光的时候就会亮,在没有光的情况下绝对不会亮!”,这种手电筒是怎么制作的呢,我们能否自己制作一个类似的手电筒呢?当然可以,情继续往下看。设计“古怪手电筒”
-
13
单片机很好玩10,温敏电阻和ADC制作温度传感器 发表于 2019-01-16 19:01:00...
-
12
单片机很好玩9,ADC介绍,使用电脑测量电压值 发表于 2019-01-15 19:01:33...
-
8
单片机很好玩8,制作一个温度警报器 发表于 2019-01-14 20:01:24...
-
17
软件总是给人一种“无所不能”的感觉,衣有购物软件,食有外卖软件,住有订房软件,行有打车软件。甚至,想知道电脑的主板温度,还可以下载监控软件查看。借助外界传感器看了上一节文章的朋友应该明白,我们之所以能够使用监控软件查看主板温度,...
-
27
单片机常被称作 MCU,MCU 的全称是 Micro Control Unit,就是微型控制器的意思。顾名思义,单片机常被用于控制一些器件工作,因此物联网的终端,或者其他一些智能机器,都是离不开单片机的。小到手机,大到汽车飞机,现在几乎只要是电子器件...
-
7
单片机很好玩3,制作一个呼吸灯 发表于 2019-01-06 13:01:11...
-
13
STC12C5A60S2 单片机,光敏电阻,步进电机,制作寻光器,始终指向光源 发表于...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK