RS485紫外线传感器

简介

紫外线传感器采用光电测探器,接收紫外光波电信号,可以测量波长范围290-390nm的紫外线强度值和指数值。内部电路采用进口工业级微处理器芯片和高精度紫外线传感器,确保产品优异的可靠性、稳定性。
紫外线传感器采用标准Modbus-RTU 485通信协议,DC5-30V宽电压供电,可以搭配TTL转RS485扩展板(DFR0259)或Gravity: RS485转UART 有源隔离型 信号转换模块(DFR0845)在Arduino UNO R3上读取紫外线强度值和指数值,快速搭建测试环境,接线方式简单,使用方便。紫外线传感器防护等级IP67,采用金属铝壳材质,广泛用于环境监测、健康保护监测、农作物生长监测、光伏系统、实验室研究等领域。

什么是紫外线?

紫外线(UV)是⼀种不可见的电磁波,波长比可见光短,但比X射线长。紫外线波长范围通常从10纳米(nm)到400纳米之间。紫外线按波长可分为三种主要类型:UVA、UVB和UVC。

生物影响:

  • UVA(320-400nm):最常见,穿透力最强,能穿透皮肤的真皮层,长期暴露可能导致皮肤老化、皱纹和皮肤癌。
  • UVB(280-320nm):穿透力较弱,主要作用于皮肤的表皮层,是造成晒伤的主要原因,也是合成维生素D的重要源泉,但也能引起皮肤癌。
  • UVC(100-280nm):具有最强的杀菌作用,通常被地球的大气层吸收,未能到达地表。然而,人工UVC光源(如消毒灯)在工业和医疗中有广泛应用。

自然界的作用:

  • 合成维生素D:紫外线帮助皮肤合成维生素D,对骨骼健康至关重要。
  • 生态系统:UV光影响植物的光合作用及植物的是生长周期,对生态平衡有重要作用。

紫外线的危害:

  • ⽪肤损伤:紫外线能破坏皮肤细胞的DNA,增加皮肤癌的风险。
  • 眼睛损伤:长时间暴露于紫外线下可引发白内障、角膜炎等眼部疾病。
  • 免疫系统抑制:紫外线过量可能会影响免疫系统的正常功能。

紫外线指数(UV Index)范围和健康建议

1. 0-2:低风险

  • 健康影响:对⼤多数人来说,紫外线辐射对健康的影响非常小。
  • 建议:即使在这类低风险情况下,也可以采取⼀些基本的防护措施,如佩戴太阳镜。

2. 3-5:中等风险

  • 健康影响:紫外线辐射对健康的影响开始变得显著,特别是在长时间暴露下。
  • 建议:在户外活动时,建议采取⼀些防护措施,如使⽤防晒霜、穿遮阳衣物和佩戴太阳镜。

3. 6-7:高风险

  • 健康影响:紫外线辐射对健康的影响较大,可能导致皮肤晒伤和眼睛损伤。
  • 建议:避免在中午时分(10:00AM到4:00PM)长时间暴露于阳光下。穿戴保护性衣物、使用高SPF防晒霜,并佩戴太阳镜。

4. 8-10:很高风险

  • 健康影响:紫外线辐射对健康的影响非常显著,晒伤的风险很高。
  • 建议:尽量避免在阳光下长时间活动。采取全面的防护措施,包括穿着遮阳衣物、涂抹高SPF防晒霜、佩戴帽⼦和太阳镜,尤其是在阳光强烈的时段。

5. 11+:极高风险

  • 健康影响:紫外线辐射极其强烈,短时间内就能导致严重的晒伤。
  • 建议:尽量避免在阳光下活动,特别是在中午时分。采取所有可能的防护措施,尽量待在阴凉处。

特性

  • DC 5~30V宽电压供电
  • 采用高精度感光元件,全光谱范围内吸收量高
  • 自带水平仪及调节手轮,现场方便调节
  • 采用RS485接口,标准Modbus-RTU协议
  • 采用高品质余弦校正器,确保标准余弦响应
  • 金属铝壳材质,IP67防护等级

应用场景

  • 环境监测
  • 健康保护监测
  • 农作物生长监测
  • 光伏系统
  • 实验室研究

技术规格

  • 供电电压:DC5~30V
  • 工作电流:<10mA
  • 输出方式:RS485
  • 紫外线强度测量范围:0~15mW/cm²
  • 分辨率:0.01mW/cm²
  • 精度:±10%FS(@365nm,60%RH,25°C)
  • 紫外线指数测量范围:0-15
  • 波长范围:290-390nm
  • 响应时间:0.2s
  • 工作温度:-25°C~+60°C
  • 防护等级:IP67
  • 传感器线长:20cm
  • 转接线线长:70cm

引脚示意图

线序 功能描述
棕线 DC5-30V供电
黑线 GND
黄线 RS485-A
蓝线 RS485-B

尺寸图

通讯协议

1、通讯基本参数

接口 编码 数据位 奇偶校验位 停止位 错误校验 波特率
RS485 8位二进制 8 1 CRC 2400bit/s、4800bit/s、9600 bit/s 可设,默认4800bit/s

2、数据帧格式定义

采用 Modbus-RTU 通讯规约,格式如下:
初始结构 ≥4 字节的时间
地址码 = 1 字节
功能码 = 1 字节
数据区 = N 字节
错误校验 = 16 位 CRC 码
结束结构 ≥4 字节的时间
地址码:为传感器的地址,在通讯网络中是唯一的(出厂默认 0x01)。
功能码:主机所发指令功能指示,本传感器读取寄存器功能码0x03,写入寄存器功能码0x06
数据区:数据区是具体通讯数据,注意 16bits 数据高字节在前!
CRC 码:二字节的校验码。

主机问询帧结构:

地址码 功能码 寄存器起始地址 寄存器长度 检验码低位 检验码高位
1byte 1byte 2byte 2byte 1byte 1byte

从机应答帧结构:

地址码 功能码 有效字节数 数据一区 第二数据区 第N数据区 检验码
1byte 1byte 1byte 2byte 2byte 2byte 2byte

寄存器地址

寄存器地址 内容 操作 范围及定义说明
0000H 紫外线强度 只读 实际值的100倍
0001H 紫外线指数 只读 实际值
0052H 紫外线强度偏差值 读写 实际值的100倍
07D0H 设备地址 读写 1~254(出厂默认1)
07D1H 设备波特率 读写 0代表2400,1代表4800,2代表9600

3、通讯协议示例及解释

3.1、读取当前紫外线强度值

问询帧:

地址码 功能码 寄存器起始地址 寄存器长度 检验码低位 检验码高位
0x01 0x03 0x00 0x00 0x00 0x01 0x84 0x0A

应答帧:

地址码 功能码 返回有效字节数 紫外线强度值 校验码低位 校验码高位
0x01 0x03 0x02 0x01 0x43 0xF8 0x25

紫外线强度值:
0143(16进制) =323=> 紫外线强度=3.23mW/ cm2

3.2、读取当前紫外线指数值

问询帧:

地址码 功能码 寄存器地址 紫外线指数值 检验码低位 检验码高位
0x01 0x03 0x00 0x01 0x00 0x01 0xD5 0xCA

应答帧:

地址码 功能码 返回有效字节数 紫外线指数值 校验码低位 校验码高位
0x01 0x03 0x02 0x00 0x03 0xF8 0x45

紫外线指数:
0003(16进制) =3 =>紫外线指数= 3

3.3、修改当前地址

问询帧:(修改当前地址为 0x02 )

地址码 功能码 寄存器地址 修改数值 检验码低位 检验码高位
0x01 0x06 0x07 0xD0 0x00 0x02 0x08 0x86

应答帧:

地址码 功能码 寄存器地址 修改数值 校验码低位 校验码高位
0x01 0x06 0x07 0xD0 0x00 0x02 0x08 0x86

3.4、修改当前波特率

问询帧:(修改当前波特率为9600 )

地址码 功能码 寄存器地址 修改数值 检验码低位 检验码高位
0x01 0x06 0x07 0xD1 0x00 0x02 0x59 0x46

应答帧:

地址码 功能码 寄存器地址 修改数值 校验码低位 校验码高位
0x01 0x06 0x07 0xD1 0x00 0x02 0x59 0x46

3.5、查询当前地址、波特率

问询帧:

地址码 功能码 寄存器地址 数据长度 检验码低位 检验码高位
0xFF 0x03 0x07 0xD0 0x00 0x02 0xD1 0x58

应答帧:

地址码 功能码 返回有效字节数 地址 波特率 校验码低位 校验码高位
0x01 0x03 0x04 0x00 0x01 0x00 0x01 0x6A 0x33

读取到设备的真实地址为 01,波特率为 0x01,即 4800。

使用教程

硬件准备

软件准备

硬件连接

若RS485设备的功率较小,需求电流小于12V-160mA,RS485转UART信号转换模块则无需12V外部供电,接线更方便。

演示代码

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2,3);//定义软串口,3号端口为TX,2号端口为RX
uint8_t Com[8] = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A };   //紫外线强度
uint8_t Com1[8] = { 0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0xD5, 0xCA };  //紫外线指数
void setup() {
  Serial.begin(9600);  //初始化串口
  mySerial.begin(4800);
}
void loop() {
  float UV = readUV();
  Serial.print("UV = ");
  Serial.print(UV);
  Serial.print(" mW/cm² ");
  uint16_t UVI = readUVI();
  Serial.print("UVI = ");
  Serial.println(UVI);
  delay(1000);
}

float readUV(void) {
  uint8_t Data[10] = { 0 };
  uint8_t ch = 0;
  float data;
  bool flag = 1;
  while (flag) {
    delay(100);
    mySerial.write(Com, 8);
    delay(10);
    if (readN(&ch, 1) == 1) {
      if (ch == 0x01) {
        Data[0] = ch;
        if (readN(&ch, 1) == 1) {
          if (ch == 0x03) {
            Data[1] = ch;
            if (readN(&ch, 1) == 1) {
              if (ch == 0x02) {
                Data[2] = ch;
                if (readN(&Data[3], 4) == 4) {
                  if (CRC16_2(Data, 5) == (Data[5] * 256 + Data[6])) {
                    data= (Data[3] * 256 + Data[4]) / 100.00;
                    flag = 0;
                  }
                }
              }
            }
          }
        }
      }
    }
    mySerial.flush();
  }
  return data;
}

int readUVI(void) {
  uint8_t Data1[10] = { 0 };
  int16_t data1;
  uint8_t ch1 = 0;
  bool flag1 = 1;
  while (flag1) {
    delay(100);
    mySerial.write(Com1, 8);
    delay(10);
    if (readN(&ch1, 1) == 1) {
      if (ch1 == 0x01) {
        Data1[0] = ch1;
        if (readN(&ch1, 1) == 1) {
          if (ch1 == 0x03) {
            Data1[1] = ch1;
            if (readN(&ch1, 1) == 1) {
              if (ch1 == 0x02) {
                Data1[2] = ch1;
                if (readN(&Data1[3], 4) == 4) {
                  if (CRC16_2(Data1, 5) == (Data1[5] * 256 + Data1[6])) {
                    data1 = Data1[3] * 256 + Data1[4];
                    flag1 = 0;
                  }
                }
              }
            }
          }
        }
      }
    }
    mySerial.flush();
  }
  return data1;
}

uint8_t readN(uint8_t *buf, size_t len) {
  size_t offset = 0, left = len;
  int16_t Tineout = 500;
  uint8_t *buffer = buf;
  long curr = millis();
  while (left) {
    if (mySerial.available()) {
      buffer[offset] = mySerial.read();
      offset++;
      left--;
    }
    if (millis() - curr > Tineout) {
      break;
    }
  }
  return offset;
}

unsigned int CRC16_2(unsigned char *buf, int len) {
  unsigned int crc = 0xFFFF;
  for (int pos = 0; pos < len; pos++) {
    crc ^= (unsigned int)buf[pos];
    for (int i = 8; i != 0; i--) {
      if ((crc & 0x0001) != 0) {
        crc >>= 1;
        crc ^= 0xA001;
      } else {
        crc >>= 1;
      }
    }
  }

  crc = ((crc & 0x00ff) << 8) | ((crc & 0xff00) >> 8);
  return crc;
}

结果

打印采集到的紫外线强度值、指数值,室内普通光源无法采集。

常见问题

1.传感器属于精密器件,使用时请不要自行拆解,以免造成产品损坏
2.若读取数值显示为 0,检查是否有光源,检查产品保护盖是否取下
3.485 总线有断开,或者 A、B 线接反
4.检查电源是否符合标注

DFshopping_car1.png DFRobot商城购买链接

WIKI文档修改历史

文档版本号 修改时间 修改人 修改内容
V1.0 2024.11.28 刘念 第一版发布

产品修改历史

产品版本号 修改时间 修改人 产品修改内容
V1.0 2024.11.28 刘念 第一版发布