完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
最近项目中用到了光敏电阻。搜索资料,发现很多人都使用光敏电阻,只是用了AD读取了电压值,或者算出了电阻值,就发送给上位机或者服务器,美其名曰获取了光照度。
搜索一番,也没找到用光敏电阻计算Lux的方法,于是自己做了一些研究,分享一下。 计算光敏电阻值 相信STM32的ADC读者应该会用,教程也一抓一大把,在此不表。接下来先计算电阻值。我的光敏电阻电路图如下: 其中PA6接单片机AD采集引脚,它最大只能输入3.6V电压,而光敏电阻的供电为5V,所以设计了R1与R2两个分压电阻,确保PA6的电压不超过3.6V。 设光敏电阻的阻值为xΩ,PA6的电压为y,可得以下公式: y/1500=5/(x+2500) STM32的ADC精度为12位,则最大值为4096。采集到的AD值与电压成线性对应关系,系统中最高的电压值为3.3V的电源电压,它与4096对应。假设PA6感受到的电压y对应的AD值为z,则: y/z=3.3/4096 联立两式,消去y,得到关于x的表达式: x=10240000/(1.1×z)-2500 使用ADC得到z以后,就可以根据上式算出光敏电阻的值了。 我的代码使用了DMA获取多通道AD值,并且取100个数据求算数平均值滤波,然后打印电阻值的代码如下: //main.c main() while (1) { if(DMA_Flag) { for(int i=0;i uint32_t PhotoResistor = (uint32_t)(10240000/(1.1*ADC1_AVG_Buf[4]) - 2500); //串口打印采样结果 printf("The AD value is %d,the PhotoResistor is %d .rn",ADC1_AVG_Buf[4],PhotoResistor); printf("The DMA count is %d .rn",DMA_CNT); DMA_Flag = 0; } } 现象是能够打印出光敏电阻值。 从电阻值到光照度 之前已经算出来了光敏电阻的电阻值,并且能够分出光照强度的等级,但是仍然无法计算出光照强度。光照强度是指单位面积上所接受可见光的能量,简称照度,单位勒克斯(Lux或lx)。常见环境的光照强度值如表
γ=lg(R10/R100) 将γ=0.6带入,可得R10/R100≈4。即R10=4×R100,对于R10与R1关系仍然成立:R1=4×R10。手册中给出了一个对数坐标系的图,光照强度与Lux的对应关系并非一条直线,而是一个范围。为了简便计算,取范围中稍微靠下的一条直线,直线中包含(1,40),(10,10),(100,2.5)这三个点。 手册中给出的1到100范围太小了,常用光照度可到达1000Lux,因此要通过现有的关系推算出光照度与电阻值的关系式。虽然看上去光照度与电阻值的对应关系是一条直线,但是要注意坐标系是对数坐标系,不能套用一元一次方程。在MATLAB中拟合,拟合过程如图7-19所示。可得关系式为: f(x)=(4e+0.4)×x^(-0.6021) 拟合过程如图。 编写代码算出光照度 在单片机内,用带指数的关系式计算,计算速度会很慢。可以使用查表法,无需计算,只遍历数组得到结果。根据拟合得到的函数,可以推导出Lux从1到1000,各自对应的电阻值,共1000对。观察数据,可以发现在Lux比较大的时候,对应的电阻值过于接近。此处仅要求粗略计算,无需这么多数据。将电阻值的个位数舍去,并删除重复电阻值,可得到281对数据。 定义新的结构体数据如下。 //ADC.h typedef struct { unsigned short ohm; //光敏电阻值 unsigned short lux; //流明 }PhotoRes_TypeDef; //ADC.c //GL5528光敏电阻的阻值与流明对应的关系 const PhotoRes_TypeDef GL5528[281]= { {40000, 1},{26350, 2},{20640, 3},{17360, 4},{15170, 5}, {13590, 6},{12390, 7},{11430, 8},{10650, 9},{9990, 10}, {9440, 11},{8950, 12},{8530, 13},{8160, 14},{7830, 15}, ...... {720, 773},{710, 791},{700, 809},{690, 829},{680, 849}, {670, 869},{660, 891},{650, 914},{640, 937},{630, 961}, {620, 987}, }; 当得到电阻值以后,遍历数据,算出光照度,代码如下。 //ADC.c /** * @brief 通过电阻值算出光照度 * @param 光敏电阻值 * @retval None */ unsigned short GetLux(uint32_t PhotoResistor) { unsigned short lux = 0; //查表法,根据电阻值得出光照度 for(int i = 0 ; i < 281 ; i++) { if (PhotoResistor > GL5528.ohm) { lux = GL5528.lux; break; } } return lux; } 主函数中,打印光照度: //main.c main() while(1) if(DMA_Flag) { unsigned short lux = 0; for(int i=0;i uint32_t PhotoResistor = (uint32_t)(10240000/(1.1*ADC1_AVG_Buf[4]) - 2500); //从电阻值计算光照度 lux = GetLux(PhotoResistor); //串口打印采样结果 printf("The AD value is %d,the PhotoResistor is %d .rn",ADC1_AVG_Buf[4],PhotoResistor); printf("The Lux is %d .rn",lux); printf("The DMA count is %d .rn",DMA_CNT); DMA_Flag = 0; } 下载程序,观察现象,应该看到如图7-19所示的现象,说明算出了Lux的值。 当然,这个计算结果也不会很精确,毕竟光照度与电阻的关系也不是一一对应的。聊胜于无吧。 |
|||||||||
|
|||||||||
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1561 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1501 浏览 1 评论
933 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
665 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1555 浏览 2 评论
1850浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
613浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
506浏览 3评论
510浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
491浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-10 19:22 , Processed in 0.779443 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号