Arduino 获得Gm1020照度计测量值
照度,可以理解为灯泡发出的光的数量(光通量)在某一方向以一定的强度(光强)入射到某一表面,此时可测得这一表面的照度。而亮度是指发光体(反光体)表面发光(反光)强弱的物理量,人眼从一个方向观察光源,在这个方向上的光强与人眼所“见到”的光源面积之比,定义为该光源单位的亮度,即单位投影面积上的发光强度,当我们站在某一位置观察受照面的时候,我们就看到了这个表面的明亮程度(亮度)。以更简单直观的方式来解释:照度是一个客观的参量,是我们用仪器去检测在某一个面上实际到达的光的数量。亮度是指某一物体发射或者反射出来的光被人眼所感知的程度。如同前面所述,光线通过反射进入眼睛是我们“看到”的必要条件,工程师和科学家使用 “光强”来描述光线强度。国际单位是candela( “坎德拉”简写cd),其他单位有烛光,支光。1cd即1000mcd是指单色光源(频率540X10^12HZ)的光,在给定方向上(该方向上的辐射强度为(1/683)瓦特/球面度)的单位立体角发出的光通量。这次需要读取标智科技( Benetech )出品的数字照度计的测量信息,具体型号是GM1020。首先从实验得知,这款设备是通过内置的 Prolific 2302芯片来实现USB对串口的转接。之前我们介绍过 USB HID设备的读取,相较而言串口和 HID相比,从编程角度来说前者更加方便和通用,资料更加丰富,无论什么编程语言都会支持这一传统设备的编程。但是从客户使用的角度来说,USB串口很可能需要用户安装驱动,虽然Win10内置了多种USB串口芯片的驱动,但是仍然有一些型号不支持,在使用过程中如果客户使用 Ghost 精简版也会碰到很多问题。而HID设备只需要Application 即可,驱动完全内置。设备本身没有提供数据格式之类的资料(国产设备大部分如此,提供资料的反倒是异类),但是已经确定了使用串口协议,因此这里使用 Virtual Serial Port Driver 和 GM1020自带的软件进行推导。 Virtual SerialPort Driver 是一款串口模拟软件。我们用它在系统中模拟出2个相互连通的串口 COM1 和 COM2。从一端发送,数据会出现在另外的端口上。因此,我们一端用软件打开,另外一端用串口工具打开。串口通讯需要设置通讯参数,对于这款设备使用的参数为 “19200 BPS/ 8 Data bits/ 1 Stop bits/ No Parity/ no Flow control”。
经过反复试验,通讯协议如下:打开对应串口后,软件通知设备准备开始 1e 00 0000 00 00 00 1e 发送这个命令 3c 01 00 00 00 00 00 3d, 设备会开始不停发送当前的照度信息 发送这个命令 3c 02 0000 00 00 00 3e,,设备会开始停止发送当前的照度信息 数据格式如下:
位数(Bytes)用途解释
00x33固定不变
10x22固定不变
2-3照度计的实时读数BIT 倍数BIT 读取值 BIT 给出当前的倍数00读取值x 0.101读取值 x 1界面显示 X1010读取值x10界面显示 X10011读取值x100界面显示 X010
4该位预留
5-6温度信息实际温度为 Byte x 0.1
70x11固定不变
注意:1. 测量界面可以在不同单位中切换,有:Lux(勒克斯) FC(尺烛光)℃(摄氏度) F(华氏度),但是设备从USB口发出的数据只有以 Lux 和℃为单位的;2. 测量范围和精度
总量程0-200,000Lux 分为四档
照度量程X1 档0...199.9 Lux
X10 档200...1999.9Lux
X100 档2000 … 19999.9Lux
X1000 档20000… 2000000Lux
温度量程0-40℃精度± 1℃
3. 例如设备发送数据 3322 00 12 01 00 b1 11。具体分析如下:Byte==0x0012其中BIT==0,读取值要乘以0.1BIT==0x12==18,所以这个数据表示1.8LuxByte==0xb1=177,实际温度为 177*0.1=17.7℃有了上述的知识,可以使用 USB Host Shield 实现解析USB照度计数据,然后将数据用蓝牙发送到电脑上。
关键代码有2部分:首先是 OnInit 函数,设置通讯参数,然后发送让设备开始发送数据的命令
uint8_t PLAsyncOper::OnInit(ACM *pacm){ uint8_t rcode; // Set DTR = 1 rcode =pacm->SetControlLineState(1); if (rcode) { ErrorMessage<uint8_t>(PSTR("SetControlLineState"),rcode); return rcode; } LINE_CODING lc; lc.dwDTERate =19200; lc.bCharFormat = 0; lc.bParityType = 0; lc.bDataBits = 8; rcode =pacm->SetLineCoding(&lc); if (rcode) ErrorMessage<uint8_t>(PSTR("SetLineCoding"), rcode); delay(100); uint8_tStartCMD ={0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x1e}; uint8_t SndDataCMD={0x3c,0x01,0x00,0x00,0x00,0x00,0x00,0x3d}; //发送起始命令 pacm->SndData(sizeof(StartCMD),&StartCMD); delay(100); //发送数据传输命令 pacm->SndData(sizeof(SndDataCMD),&SndDataCMD); delay(100); return rcode;}接下来是收取串口数据的代码byte Waiting8Bytes=0;void loop(){ Usb.Task(); if(Usb.getUsbTaskState() == USB_STATE_RUNNING ) { uint8_t rcode; uint8_tbuf; uint16_t rcvd= 64; //接收数据 rcode =Pl.RcvData(&rcvd, buf); if (rcode&& rcode != hrNAK) ErrorMessage<uint8_t>(PSTR("Ret"), rcode); //有数据,直接处理 if( rcvd ){ for(uint16_t i=0; i < rcvd; i++ ) { Serial.print((byte)buf,HEX); //printing on the screen Serial.print(" "); } Waiting8Bytes=Waiting8Bytes+rcvd; if(Waiting8Bytes>7) { Serial.println(""); Waiting8Bytes=0; } }//if( rcvd... }//if(Usb.getUsbTaskState() == USB_STATE_RUNNING..}
照度计设备就是这个东西
通过上述的方法可以实现将USB照度计数据发送到电脑上,从而实现将有线设备转成无线设备的功能。在实际生产环境下,还可以通过更换无线模块达到更强的抗干扰更远的发送距离要求。
好好学习,天天向上
页:
[1]