Arduino + RS485测温装置 因为项目需要,在网上购买了一款T10S-B-HW 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 |
比如读取温度,发送: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测温装置](https://img.it610.com/image/info8/fca7bf2de24849d78395b9af399731a9.jpg)
文章图片
编写如下程序:
#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测温装置](https://img.it610.com/image/info8/90df30bedf85495a85a26c9f01be0d52.png)
文章图片
将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测温装置](https://img.it610.com/image/info8/3d1022954b59444f9f92c512c596487a.png)
文章图片
蓝牙输出:
![Arduino + RS485测温装置](https://img.it610.com/image/info8/3a0a244463bb48b5b2d1e913755f4950.jpg)
文章图片
推荐阅读
- Arduino连接GPS模块
- ESP8266模块使用
- Arduino 连接JDY-08蓝牙模块
- Arduino串口通信
- Arduino|第一章 - 新手入门 - 第三课 Arduino 上手实战呼吸灯
- Arduino|Arduino TFT_eSPI库来驱动SPI接口的LCD显示文字详解
- ESP32|基于arduino的ESP32 学习笔记(二) TFT_eSPI和LVGL库使用笔记
- esp32|Arduino应用开发——spi flash(以esp32和w25qxx为例)
- esp32|ESP32-S2应用开发——USB通信(虚拟串口)