Arduino + RS485测温装置

Arduino + RS485测温装置 因为项目需要,在网上购买了一款T10S-B-HW RS485红外线测温变送器。
Arduino + RS485测温装置
文章图片
参数如下:

额定电压 DC5V~DC12V
探头工作温度 -40~125℃
测量范围 -70℃~380℃
测量精度 ±0.5℃(工作温度0~60℃ 目标温度0~60℃)
物距比 D:S = 12:1 (目标直径:测量距离)
测量分辨率 0.1℃
响应时间 1s
输出接口 RS485
通讯协议 MODBUS RTU
波特率 1200 bit/s,2400 bit/s, 4800 bit/s, 9600 bit/s(默认), 19200 bit/s
通讯地址 1-247
功 耗 <0.1W
产品尺寸 直径14mm,长69mm
测量数据通过RS485串口输出,使用MODUBS RTU 协议标准。
比如读取温度,发送:01 03 00 00 00 01 84 0A
返回:01 03 04 01 13 00 01 CB CA
即 256 * 1 + 16 * 1 + 3 = 275 (对应温度:27.5℃)
【Arduino + RS485测温装置】之后想通过Arduino处理数据,涉及到十六进制数据的发送与接收,以及Arduino的数据解析,花费了一些时间,在这里记录一下。
接线方面我是用一个9V电池为测温装置供电,之后RS485数据接口接一个RS485转TTL模块,通过设置软串口与Arduino通信。
Arduino + RS485测温装置
文章图片
编写如下程序:
#include unsigned char item[8] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B}; //16进制测温命令 String datahttps://www.it610.com/article/= ""; // 接收到的16进制字符串 SoftwareSerial tempSerial(8, 7); // RX, TXfloat getTemp(String temperature); // 函数声明void setup() { tempSerial.begin(9600); Serial.begin(9600); }void loop() { delay(500); // 放慢输出频率 for (int i = 0 ; i < 8; i++) {// 发送测温命令 tempSerial.write(item[i]); // write输出 } delay(100); // 等待测温数据返回 datahttps://www.it610.com/article/= ""; while (tempSerial.available()) {//从串口中读取数据 unsigned char in = (unsigned char)tempSerial.read(); // read读取 Serial.print(in, HEX); Serial.print(','); data += in; data += ','; }if (data.length() > 0) { //先输出一下接收到的数据 Serial.println(); Serial.println(data); Serial.print(getTemp(data)); Serial.println("Temp"); } }float getTemp(String temp) { int commaPosition = -1; String info[9]; // 用字符串数组存储 for (int i = 0; i < 9; i++) { commaPosition = temp.indexOf(','); if (commaPosition != -1) { info[i] = temp.substring(0, commaPosition); temp = temp.substring(commaPosition + 1, temp.length()); } else { if (temp.length() > 0) {// 最后一个会执行这个 info[i] = temp.substring(0, commaPosition); } } } return (info[3].toInt() * 256 + info[4].toInt()) / 10.0; }

串口监视器输出解析后的温度数据:
第一行是十六进制的输出,第二行是十进制输出,第三行才是解析后的温度值。
Arduino + RS485测温装置
文章图片
将GPS模块和测温模块集成
#include // 配置软串口 SoftwareSerial gpsSerial(4, 3); // RX, TX SoftwareSerial bleSerial(6, 5); // RX, TX SoftwareSerial tempSerial(8, 7); // RX, TX// 变量声明 String command = ""; // 用户发送的命令 unsigned char tempCommand[8] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B}; //16进制测温命令 String tempDatahttps://www.it610.com/article/= ""; // 接收到的16进制字符串 String gngga = ""; // 读取到的GNGGA信息 String info[15]; // 存储GPS数据// 函数声明 float getTemp(String temperature); // 获取温度值函数声明 String getTime(); // 获取北京时间 String getLat(); // 获取纬度dd.mmssss String getLng(); // 获取经度dd.mmssss String getStatus(); // 获取当前定位状态,0=未定位,1 = 非差分定位,2=差分定位void setup() { Serial.begin(9600); gpsSerial.begin(38400); bleSerial.begin(9600); tempSerial.begin(9600); } void loop() { bleSerial.listen(); command = ""; while (bleSerial.available() > 0) { command += char(bleSerial.read()); delay(10); } if (command.length() > 0) { Serial.println("command:" + command); //在这里进行命令的解析 if (command.equals("0")) { // 获取gps数据 Serial.println("获取GPS数据"); gpsSerial.listen(); // 监听GPS串口 gngga = ""; delay(200); // 延迟等待GPS数据进入串口 while (gpsSerial.available() > 0) { gngga += char(gpsSerial.read()); delay(1); } if (gngga.length() > 0) { Serial.println(gngga); int commaPosition = -1; for (int i = 0; i < 15; i++) { commaPosition = gngga.indexOf(','); if (commaPosition != -1) { info[i] = gngga.substring(0, commaPosition); gngga = gngga.substring(commaPosition + 1, gngga.length()); } else { if (gngga.length() > 0) {// 最后一个会执行这个 info[i] = gngga.substring(0, commaPosition); } } } Serial.println("time: " + getTime()); Serial.println("lat: " + getLat()); Serial.println("lng: " + getLng()); Serial.println("status: " + getStatus()); bleSerial.println(getTime() + ',' + getLat() + ',' + getLng()); } } else if (command.equals("1")) { // 获取温度数据 Serial.println("获取温度数据"); tempSerial.listen(); // 监听温度串口 for (int i = 0 ; i < 8; i++) {// 发送测温命令 tempSerial.write(tempCommand[i]); // write输出 } delay(100); // 等待测温数据返回 tempDatahttps://www.it610.com/article/= ""; while (tempSerial.available()) {//从串口中读取数据 unsigned char in = (unsigned char)tempSerial.read(); // read读取 Serial.print(in, HEX); Serial.print(','); tempData += in; tempData += ','; } if (tempData.length() > 0) { //先输出一下接收到的数据 float temp = getTemp(tempData); Serial.println(); Serial.println(tempData); Serial.println(temp); bleSerial.println(temp); } tempSerial.end(); } else { Serial.println("命令无效!"); bleSerial.println("命令无效!"); } } }float getTemp(String temp) { int commaPosition = -1; String info[9]; // 用字符串数组存储 for (int i = 0; i < 9; i++) { commaPosition = temp.indexOf(','); if (commaPosition != -1) { info[i] = temp.substring(0, commaPosition); temp = temp.substring(commaPosition + 1, temp.length()); } else { if (temp.length() > 0) {// 最后一个会执行这个 info[i] = temp.substring(0, commaPosition); } } } return (info[3].toInt() * 256 + info[4].toInt()) / 10.0; }String getTime() { return info[1]; }String getLat() { return info[2]; }String getLng() { return info[4]; }String getStatus() { return info[6]; }

串口输出:
Arduino + RS485测温装置
文章图片
蓝牙输出:
Arduino + RS485测温装置
文章图片

    推荐阅读