CJMCU-GUVA-S12SD/CJMCU-S12D Solar UV Intensity Sensor(太阳光紫外线强度传感器)是2015年刚出来的。但厂家只提供了简化版的英文数据手册和写在txt的几行代码,Baidu、Google上也只能搜到英文版数据手册和厂家托管在百度云上的几行代码,没有人把经历共享出来,甚至在GitHub上无法搜到任何有关CJMCU-GUVA-S12SD/CJMCU-S12D的资料和代码。
所以我把我的爬坑经历共享出来,希望大家都能看懂。
楼上是摘要~
点击这里查看 CJMCU-GUVA-S12SD/CJMCU-S12D 太阳光紫外线强度传感器 原文
点击这里查看 我托管在GitHub上的代码
CJMCU-GUVA-S12SD/CJMCU-S12D 太阳光紫外线强度传感器
8月初淘来一个太阳光紫外线强度传感器,感觉应该很有意思,型号是CJMCU-GUVA-S12SD/CJMCU-S12D,谁知这传感器淘宝卖家只提供了简化版的英文数据手册和写在txt文档里的几行代码,Baidu、Google上只有英文版资料和一些淘宝商家在百度云上托管的几行代码,并没有人把玩过的经历共享出来,甚至在Github上无法搜索到任何有关CJMCU-GUVA-S12SD/CJMCU-S12D的资料。好吧,某宝一瞧,居然是2015年刚出来的传感器。虽然已经出了半年,但比起那些常见的sensor岁数可小了不知多少,哈哈哈~
入坑
接上VCC和GND,再接好SIG。之前翻淘宝的时候印象有点深,写的是这个sensor用的TTL通信,我没有任何思考直接把SIG接到了RX。
勉勉强强啃完英文数据手册,发现经过数据处理可以得到传感器光电流的输出电压,同时输出电压值和紫外线等级基本呈线性关系(如上图)。同时,在txt文件中的几行代码里边发现了一个转换:,认为这个数据是光电流的输出电压与紫外线等级的转换值。
烧录程序,数据读出来,优化一下代码,再对着光电流的输出电压与紫外线强度转换表(如上表)写几行代码让Arduino在串口监视器中显示电压的同时,也转换出UV等级。
通过人工对比读出来的数据与紫外线等级的转换表发现,在室内的紫外线等级一直是11级,那么这数据肯定是错的咯。我加入了取平均值的filter函数,依旧是错误数据。
我又重新仔细读了一遍数据手册和代码,发现这明明用的是A0口,sensor传回来的是模拟值,然而淘宝商家说明里写了TTL电平。好吧,这是个坑~
其实,我接RX的时候还一直在奇怪,为什么一根信号线不是单总线通信协议?为什么没有时钟却能用高低电平读出数据?果断更改引脚,读取数据正常。
- 所以,某宝以及个别说明是有误的,CJMCU-GUVA-S12SD/CJMCU-S12D用的是单总线通信协议!
对于4980这个数据我想说一下我个人的观点:考虑到每个sensor制作的时候会有误差,所以这个具体值在每个CJMCU-GUVA-S12SD/CJMCU-S12D是不一样的,厂家提供的4980应该是基于统计学的转换值,如果要想要得到一个精确的光电流输出电压需要用工业级紫外线校准仪校准一下,否则会有点不精确,另外还可以把我的取平均值filter算法替换为限幅滤波法(又称程序判断滤波法)。
数据手册
网上可以找到比某宝店家提供的详细好几倍的英文数据手册,在此一并附上:百度文库版、豆丁版。呃…虽然是英文版~
底层原理图
最终布线
我单独测试的时候用的是Arduino UNO,最终再把CJMCU-GUVA-S12SD/CJMCU-S12D紫外线传感器接入我要用的NodeMCU,布线图中我就用UNO代替了,其实都是大同小异啦!
最终代码
int sensorValue;//传感器输出的数据
long sum = 0;//由于测试中发现数据会溢出,就用了long,long目前还未溢出过
int vout = 0;//由于通信中输出的是整一串数据,所以需要翻译,vout是处理好的数据,也就是CJMCU-GUVA-S12SD/CJMCU-S12D传感器光电流的输出电压
int uv = 0;//紫外线等级
void setup(){
Serial.begin(9600);//CJMCU-GUVA-S12SD/CJMCU-S12D的波特率为9600
}
void loop()
{
sensorValue = 0;
sum = 0;
for(int i = 0 ; i < 1024 ; i++ )//这里我用的是最简单的filter算法
{
sensorValue = analogRead(A0);
sum = sensorValue + sum;
delay(2);
}
/*
我认为第一个">>10"是对我们sensor的输出信号进行解码,使之成为我们需要处理的数据,属于从初步处理数据
第二个"/1024"才是我们正式开始处理数据,对我们刚刚相加1024次的数据进行平均处理
至此我们的demo就完成了第一环节的数据处理了
另在代码之后附2张数据输出的截图
*/
vout = sum >> 10;//对输出的信号进行解码
vout = vout * 4980.0 / 1024;//开始数据处理
Serial.print("The Photocurrent value : ");
Serial.print(vout);
Serial.println("mV");
if(vout < 50){ //查表,把得到的光电流值转换成紫外线等级
uv = 0;
}
else if(vout < 227){
uv = 1;
}
else if(vout < 318){
uv = 2;
}
else if(vout < 408){
uv = 3;
}
else if(vout < 503){
uv = 4;
}
else if(vout < 606){
uv = 5;
}
else if(vout < 696){
uv = 6;
}
else if(vout < 795){
uv = 7;
}
else if(vout < 881){
uv = 8;
}
else if(vout < 976){
uv = 9;
}
else if(vout < 1079){
uv = 10;
}
else{
uv = 11;
}
delay(20);
Serial.print("UV Index = ");
Serial.println(uv);
}
另附2张截图:
正确输出:
错误输出:
希望都可以看懂==不懂可以评论也可以向 wycwykds@163.com 砸邮件~~
2016.8.2写于千岛湖
2016.12.25更新于杭州
原文链接:CJMCU-GUVA-S12SD/CJMCU-S12D 太阳光紫外线强度传感器
已授权UbiBots博客原创转载:[转载]CJMCU-GUVA-S12SD 紫外线传感器
本文分享了CJMCU-GUVA-S12SD/CJMCU-S12D太阳光紫外线强度传感器的使用经验,包括入坑过程、数据手册、传感器工作原理及代码实现。作者指出该传感器采用单总线通信协议,而非TTL,并提供了纠正错误的解决方案。
1076

被折叠的 条评论
为什么被折叠?



