Arduino + RS485测温装置

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

测量数据通过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处理数据,涉及到十六进制数据的发送与接收,以及Arduino的数据解析,花费了一些时间,在这里记录一下。

接线方面我是用一个9V电池为测温装置供电,之后RS485数据接口接一个RS485转TTL模块,通过设置软串口与Arduino通信。

编写如下程序:

#include <SoftwareSerial.h>
unsigned char item[8] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B};  //16进制测温命令
String data = ""; // 接收到的16进制字符串
SoftwareSerial tempSerial(8, 7);  // RX, TX

float 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);  // 等待测温数据返回
  data = "";
  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;
}

串口监视器输出解析后的温度数据:

第一行是十六进制的输出,第二行是十进制输出,第三行才是解析后的温度值。

将GPS模块和测温模块集成
#include <SoftwareSerial.h>

// 配置软串口
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 tempData = ""; // 接收到的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);  // 等待测温数据返回
      tempData = "";
      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];
}

串口输出:

蓝牙输出:

  • 32
    点赞
  • 194
    收藏
    觉得还不错? 一键收藏
  • 23
    评论
通常,在工业中,我们有几种机器和设备(PLC,CNC,变频器)来控制和监视最多样化的工业过程。 为了使所有这些设备一起工作,必须在它们之间建立通信网络。 但是,由于电动机,螺线管和其他执行器的激活,该行业环境中存在许多电磁干扰。 RS485通信标准是通信网络的物理层,可以实现多种协议,例如Modbus,Profibus等。 RS485通信标准适合在行业中实施,因为它接受几种网络拓扑,例如星形和环形。 它允许长距离通信,并使用双绞线电缆。由于我们具有差分通信信号,因此该电缆模型减少了电磁干扰,这有助于更好地抵抗噪声和电磁干扰。 除了RS485通讯之外,还有RS232通讯。它允许以点对点模式进行网络通信,并且遭受电磁干扰的影响更大。 但是,许多设备具有RS232通信,需要长距离传输数据。为此,我们需要使用称为MAX485的集成电路。 该集成电路在使TTL逻辑电平适应RS485通信所需的逻辑电平中发挥作用。 如今,已经有使用该集成电路的现成的低成本模块。它们允许信号调理并促进不同设备之间的通信。 因此,由于其坚固性,RS485通信可用于任何类型的环境。 因此,在本文中,我们将学习如何监视环境温度以及如何通过两个Arduino之间的串行/ RS485通信接收测量值。 Arduino Slave(发送器)将使用DS18B20数字传感器执行温度测量,并将测量值通过串行/ RS485发送到Arduino主设备(接收器),该设备将在LCD显示屏上写入20 x 4 I2C接收的温度值。 因此,通过本文您将学到: 在原型板上执行电路组装; 了解RS 485模块的操作; 了解DS18B20传感器的工作原理; 创建通信协议; 使用有线通信网络进行远程温度监控; 现在,我们将开始通过RS485串行通信使用DS18B20传感器进行温度监控项目的开发的完整介绍。 通过RS485串行通信使用DS18B20传感器开发温度监控项目 在图3中,我们具有项目组装所需的原理图电路。Arduino Uno将成为主机(接收器),它将接收温度测量值并将在LCD显示屏上显示20 x 4 I2C。 Arduino Nano将作为从设备(发送器),它将读取DS18B20传感器并通过RS485模块发送测量值。 现在,让我们转到设置项目所需的材料清单。 带有DS18B20和RS485模块的Arduino项目 温度传感器DS18B20是数字温度传感器,因为要传输信息,它使用协议1-Wire。 1-Wire协议由Dallas Semiconductor和Maxim制造。 1线总线对设备使用主/从概念。 微控制器是主机,外围设备是从机。 在制造过程中,每个设备都会收到一个唯一的ID,即设备标识号(地址),以便在有很多设备时可以在总线上对其进行标识。 信息格式: 1线仅使用一条数据线,并使用长脉冲和短脉冲表示1和0。60微秒脉冲表示0,15微秒脉冲表示1。 在VCC与DS18B20传感器的信号引脚之间必须使用4K7的上拉电阻,以使微控制器与传感器之间的通信稳定。 将发射器和接收器电路组装到原型板上之后,我们可以在图6中看到原型板上的物理组装。
Arduino电子书中文PDF是一种在互联网上广泛流传的电子书格式,旨在帮助人们学习和了解Arduino开发平台的相关知识。它是以Arduino为主题,以中文语言编写的书籍的电子版本。 Arduino电子书中文PDF通常包含了关于Arduino的基本知识、硬件及软件方面的介绍,以及一些实践案例和项目示例。这些电子书会详细阐述Arduino的基本概念和原理,介绍如何进行基本的电路连接和编程操作,还会提供一些常用传感器和模块的使用方法。 通过阅读Arduino电子书中文PDF,读者可以系统地学习和理解Arduino开发平台的使用,掌握基本的电子电路设计和编程技巧。同时,电子书中的实践案例和项目示例可以帮助读者将理论知识转化为实际应用,并激发读者的创造力和想象力。 Arduino电子书中文PDF的好处在于它的便携性和易于获取性。读者可以通过下载或在线阅读这些电子书,随时随地进行学习和参考。而且,这些电子书通常是免费提供的,使得广大Arduino爱好者都能够轻松地获取到这些宝贵的学习资源。 总而言之,Arduino电子书中文PDF是帮助人们学习和应用Arduino开发平台的重要工具。它通过系统、详细地介绍Arduino的基本概念和应用,帮助读者掌握相关技能,并鼓励读者进行实践和创新。无论是初学者还是有一定经验的开发者,都可以从中获得很多有价值的知识和经验。
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值