汉扬编程 编程大纲 C语言可以做什么?制作一个可以一直盯着太阳的机器,进来看看吧

C语言可以做什么?制作一个可以一直盯着太阳的机器,进来看看吧

上一节介绍了如何使用C语言编程单片机控制步进电机转动,在文章最后提到,只要再结合感光器件,我们就能够制作一个“人工向日葵”,如下图:

C语言可以做什么?制作一个可以一直盯着太阳的机器,进来看看吧

C语言可以做什么?制作一个可以一直盯着太阳的机器,进来看看吧

可以看出,单片机控制步进电机带着“箭头”始终指向光源,就好像向日葵一直跟着太阳一样。怎么做呢?

C语言可以做什么?制作一个可以一直盯着太阳的机器,进来看看吧

两项基本工作 这里仍然计划使用 51 单片机作为控制中心,那么要制作“人工向日葵”,需要先完成两项基本工作:一是获取光源的方向,知道光源在哪个方向后,还要有能力带着“箭头”转动,直到指向光源。完成这两项基本工作后,剩下的工作就简单了。

C语言可以做什么?制作一个可以一直盯着太阳的机器,进来看看吧

C语言可以做什么?制作一个可以一直盯着太阳的机器,进来看看吧

先来看看怎样带着“箭头”转动 还记得上一节介绍的步进电机吗?它就非常适合完成这些工作,将箭头粘在步进电机的转动轴上,单片机驱动步进电机转动就可以带动“箭头”转动了。关于单片机如何驱动步进电机,这里就不赘述了,感到陌生的朋友可以看看上一节的文章。

C语言可以做什么?制作一个可以一直盯着太阳的机器,进来看看吧

再来看看如何获取光源方向 对我们人类来说,要判断光源方向实在太简单了,看一看周围就知道了,基本上光线最强的方向就是光源的方向。那么,单片机该怎样判断光源方向呢?

C语言可以做什么?制作一个可以一直盯着太阳的机器,进来看看吧

参照人类判断光源方向的方法,单片机首先要能“看到”环境光线情况。如何让单片机“看到”环境光线,第 11 节和第 12 节已经介绍的比较清楚了。这里还是采用和之前一样的方法:借助于光敏电阻。

C语言可以做什么?制作一个可以一直盯着太阳的机器,进来看看吧

光敏电阻的阻值会随着照射在它表面的光纤强度的改变而改变,利用欧姆定律,很容易将这种阻值变化转换为电压值变化,再利用 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语言程序,烧写到单片机,发现我们成功了。

现在有了“人工向日葵”,我们可以在此基础上再做一些好玩又有用的东西:比如一款追着光源跑的小车,再比如一个自动追着太阳方向的晒鞋器,甚至,可以用在现在非常火热的新能源光伏发电上,想想看,光能发电板始终正对着太阳,能提升多少发电效率啊~~

欢迎在评论区一起讨论,质疑。文章都是手打原创,每天最浅显的介绍C语言、linux等嵌入式开发,喜欢我的文章就关注一波吧,可以看到最新更新和之前的文章哦。

本文来自网络,不代表汉扬编程立场,转载请注明出处:http://www.hyzlch.com/mianfei/6939.html

(c语言逻辑运算符的优先级)C语言运算符优先级口诀?

90%以上的大学大一都学C语言,为什么?其他语言不香吗?

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

返回顶部