Wemos D1 mini+RS-485 MODBUS半双工串行通信

Wemos D1 mini+RS-485 MODBUS半双工串行通信

本实验以Wemos D1 mini作为MODBUS主站(Master),2个温湿度变送器作为MODBUS从站(Slave),两者经RS485模块通过软串口进行半双工通信,实现对设备的轮询。


器件

Wemos D1 mini 一块
温湿度变送器 两个
TTL转RS485 模块 MAX485 一个
电源:充电宝 一个
USB线 一条
杜邦线若干


接线

先将温湿度变送器经RS485模块接到电脑的USB,用串口调试助手调通,并设定两个设备地址分别为0X01、0X02。
修改从机地址命令帧

地址码功能码起始地址数据长度校验码低位校验码高位
0x010x060x00 0X010x00 0X080xD80x30

应答帧(与发送帧相同)

地址码功能码起始地址数据长度校验码低位校验码高位
0x010x060x00 0X010x00 0X080xD80x30

然后再接到D1 mini上,MAX485的R0接mini的D1(GPIO5)、DI接mini的D2(GPIO4)、VCC接mini的3V3、GND接mini的G、RE和DE都接到mini的D4(GPIO2),MAX485的A与两个温湿度变送器的A连接、RS485的B与两个温湿度变送器的B连接、大地悬空,温湿度变送器接外接电源5-30V均可。
注意:MAX485的VCC和GND一定要用D1 mini板子的输出电压和地。


实物图

在这里插入图片描述

代码

代码如下(示例):

#include <SoftwareSerial.h>
SoftwareSerial Master(D2, D1); //定义软串口RX、TX
unsigned char Qu_Frame[2][8] = {{0x01, 0x04, 0x00, 0x01, 0x00, 0x02, 0x20, 0x0B},
                                {0x02, 0x04, 0x00, 0x01, 0x00, 0x02, 0x20, 0x38}};//主机请求帧列表 
String Re_Frame="";   //定义一个字符串,用来将从机返回帧
int DE_RE=D4;  //使能端,高电平发送请求,低电平接收数据

void getTH(String th);  // 函数声明
float th_date[2];
float *P_th=th_date;

void setup() {
  Serial.begin(9600);                         
  Serial.println("Master is ready!");
  Master.begin(9600);
  pinMode(DE_RE,OUTPUT);  
  digitalWrite(DE_RE,LOW); 
}
 
void loop() 
{ 
  for(int i = 0 ; i < 2; i++)        //用来对每个从机进行一次大轮询
  {
      digitalWrite(DE_RE,HIGH);    //将主机设为发送状态
     for(int j = 0 ; j < 8; j++)   //给从机发送请求码
      Master.write(Qu_Frame[i][j]); 
      digitalWrite(DE_RE,LOW);   //然后立马换成接收状态 
      delay(500);                //等一下从机反应,否则Maste.available还没反应过来,就过去了,加个 
                                    
      Re_Frame="";  //准备接收从机数据
      int k=0;
      while(Master.available())    //当从机有数据发过来
      { 
      unsigned char in = (unsigned char)Master.read();  // read读取
      Re_Frame += in;
      Re_Frame += ',';   //读数据信息到数组Re_Frame
      k++;
      }
      delay(1000);              
 
    if (Re_Frame.length() > 0) { 
    getTH(Re_Frame);//调用函数计算温湿度值
    Serial.print(i+1);
    Serial.print("号设备");
    Serial.print("温度值:");
    Serial.print(*P_th);//输出温度值
    Serial.print("℃");
    Serial.print("湿度值:");
    Serial.print(*(P_th+1));//输出湿度值
    Serial.println("%");
  }
  }
  delay(5000); 
 }

//计算温湿度值的函数
void getTH(String th) {
  int commaPosition = -1;
  String info[9];  // 用字符串数组存储温湿度返回码
  for (int i = 0; i < 9; i++) {
    commaPosition = th.indexOf(',');
    if (commaPosition != -1)
    {
      info[i] = th.substring(0, commaPosition);
      th = th.substring(commaPosition + 1, th.length());
    }
    else {
      if (th.length() > 0) {  // 最后一个会执行这个
        info[i] = th.substring(0, commaPosition);
      }
    }
  }
  P_th[0] = (info[3].toInt() * 256 + info[4].toInt()) / 10.0;
  P_th[1] = (info[5].toInt() * 256 + info[6].toInt()) / 10.0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值