CJMCU-GUVA-S12SD紫外线传感器

作者

颜哲锟

摘要

CJMCU-GUVA-S12SD紫外线传感器是2015年刚出来的。但淘宝卖家只提供了简化版的英文数据手册和写在txt文档里的几行代码,Baidu、Google上只有英文版资料和一些淘宝商家在百度云上托管的几行代码,并没有人把玩过的经历共享出来,甚至在Github上无法搜索到任何有关CJMCU-GUVA-S12SD的资料。
所以我把我的爬坑经历共享出来,希望大家都能看懂。

CJMCU-GUVA-S12SD紫外线传感器

8月初淘来一个紫外线传感器,感觉应该很有意思,型号是CJMCU-GUVA-S12SD,谁知这传感器淘宝卖家只提供了简化版的英文数据手册和写在txt文档里的几行代码,Baidu、Google上只有英文版资料和一些淘宝商家在百度云上托管的几行代码,并没有人把玩过的经历共享出来,甚至在Github上无法搜索到任何有关CJMCU-GUVA-S12SD的资料。好吧,某宝一瞧,居然是2015年刚出来的传感器。虽然已经出了半年,但比起那些常见的sensor岁数可小了不知多少,哈哈哈~

入坑

接上VCC和GND,再接好SIG。之前翻淘宝的时候印象有点深,写的是这个sensor用的TTL通信,我没有任何思考直接把SIG接到了RX。

CJMCU-GUVA-S12SD紫外线传感器_第1张图片

勉勉强强啃完英文数据手册,发现经过数据处理可以得到传感器光电流的输出电压,同时输出电压值和紫外线等级基本呈线性关系(如上图)。同时,在txt文件中的几行代码里边发现了一个转换:代码转换,认为这个数据是光电流的输出电压与紫外线等级的转换值。

CJMCU-GUVA-S12SD紫外线传感器_第2张图片

烧录程序,数据读出来,优化一下代码,再对着光电流的输出电压与紫外线强度转换表(如上表)写几行代码让arduino在串口监视器中显示电压的同时,也转换出UV等级。

通过人工对比读出来的数据与紫外线等级的转换表发现,在室内的紫外线等级一直是11级,那么这数据肯定是错的咯。我加入了取平均值的filter函数,依旧是错误数据。

我又重新仔细读了一遍数据手册和代码,发现这明明用的是A0口,sensor传回来的是模拟值,然而淘宝商家说明里写了TTL电平。好吧,这是个坑~

其实,我接RX的时候还一直在奇怪,为什么一根信号线不是单总线通信协议?为什么没有时钟却能用高低电平读出数据?果断更改引脚,读取数据正常。

  • 所以,某宝以及个别说明是有误的,CJMCU-GUVA-S12SD用的是单总线通信协议!

重要的话说三遍,CJMCU-GUVA-S12SD是单总线通信!是单总线通信!是单总线通信!

对于4980这个数据我想说一下我个人的观点:考虑到每个sensor制作的时候会有误差,所以这个具体值在每个CJMCU-GUVA-S12SD是不一样的,厂家提供的4980应该是基于统计学的转换值,如果要想要得到一个精确的光电流输出电压需要用工业级紫外线校准仪校准一下,否则会有点不精确,另外还可以把我的取平均值filter算法替换为限幅滤波法(又称程序判断滤波法)。

数据手册

网上可以找到比某宝店家提供的详细好几倍的英文数据手册,在此一并附上:百度文库版、豆丁版。呃…虽然是英文版~

底层原理图

CJMCU-GUVA-S12SD紫外线传感器_第3张图片

最终布线

我单独测试的时候用的是arduino UNO,然后再把CJMCU-GUVA-S12SD接入我要用的nodMCU,布线图中我就用UNO代替了,其实都是大同小异啦!

最终代码

int sensorValue;//传感器输出的数据包
long sum = 0;//由于测试中发现数据会溢出,就用了long,long目前还未溢出过
int vout = 0;//由于通信中输出的是整一串数据包,所以需要翻译,vout是处理好的数据,也就是CJMCU-GUVA-S12SD传感器光电流的输出电压
int uv = 0;//紫外线等级

void setup(){
Serial.begin(9600);//CJMCU-GUVA-S12SD的波特率为9600
}

void loop()
{    
  sensorValue = 0;
  sum = 0;
  for(int i = 0 ; i < 1024 ; i++ )//这里我用的是最简单的filter算法
  {  
      sensorValue = analogRead(A0);
      sum = sensorValue + sum;
      delay(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);
  }

希望有需要的都可以看懂==不懂可以评论也可以向 [email protected] 砸邮件~~

2016.8.2写于千岛湖

PS:
原文链接:http://blog.csdn.net/dustintime/article/details/52387798

已授权UbiBots系列博客转载

你可能感兴趣的:(硬件传感器)