提示:本文内容仅供学习参考。Author: Jonnie Walker 

目录

前言

一、RS485通信原理?

二、测试步骤

1.硬件

2.软件

1.注意的问题:

2.从机模式通信方式:

3.主从机模式通信方式:

总结


前言

        本文主要介绍了RS485通信的原理及其在工业控制中的应用。RS485通过差分信号传输,具有抗干扰能力强、适合长距离传输的特点,支持多点总线结构和半双工通信。文章还详细描述了RS485的电气特性、抗干扰能力及典型应用场景。此外,文章通过硬件连接图和软件代码示例,展示了如何利用ESP32-C3-PLC控制器开发板实现两个设备之间的RS485通信控制,包括从机模式和主从机模式的通信方式。

        关于RS485通信控制的简单测试!通过我设计的ESP32-C3-PLC控制器向你展示测试过程。测试环境使用的是ArduinoIDE2.0作为本次测试程序编译!主要还是简单。从文章的目录你就知道本文大概在讲什么!我就不废话了,请看下文。希望文章对你有帮助吧!


一、RS485通信原理?

RS-485(又称EIA-485)是一种广泛应用的串行通信标准,主要用于工业控制、仪器仪表等需要长距离、抗干扰的场景。以下是其原理的概括:

1. 差分信号传输

  • 原理:RS-485通过两条线(A和B)的电压差表示逻辑状态,而非单线对地电压。

    • 逻辑1:A线电压比B线高(差分电压 ≥ +0.2V)。

    • 逻辑0:B线电压比A线高(差分电压 ≤ -0.2V)。

  • 优势:差分信号能有效抑制共模干扰(如电磁噪声),适合长距离传输。

2. 多点总线结构

  • 拓扑:支持总线型网络,多个设备(最多32个标准负载)可挂接在同一对双绞线上。

  • 半双工通信:同一时间仅允许一个设备发送数据,其他设备接收,需通过协议(如Modbus)协调主从设备。

3. 电气特性

  • 电压范围:驱动端输出差分电压为-7V至+12V,接收端灵敏度为±0.2V。

  • 传输距离:理论最大距离约1200米(速率≤100kbps),速率与距离成反比(例如:10Mbps时仅支持短距离)。

  • 终端电阻:总线两端需接120Ω电阻,匹配阻抗以减少信号反射。

 4. 抗干扰能力

  • 共模抑制:接收器可容忍高达-7V至+12V的共模电压(A、B线对地电压)。

  • 双绞线屏蔽:推荐使用屏蔽双绞线,进一步降低电磁干扰。

5. 典型应用场景

  • 工业自动化(PLC、传感器通信)

  • 楼宇控制系统(HVAC、安防)

  • 智能仪表(电表、水表集中抄表)

  • Modbus RTU协议(基于RS-485的常见工业协议)

二、测试步骤

1.硬件

图1是本次测试使用的两个相同的开发版,主控为ESP32C3-N4。开发版自带WiFi,蓝牙功能……。且开发板有4路输入输出功能。可以接传感器与负载设备。从图中可以看到我们分别给两个设备标记了:设备A(0x01),设备B(0x02),这个标记我们后面会在程序中用到。这次我们主要讲两个开发版之间485通信控制功能,关于485通信原理这里我们不详细讲,一时半会可能讲不明白!

如果你对485通信不太了解,可以先去阅读一下其他大佬的关于485通信工程文章。我个人认为即使你对485不熟悉也不影响你看懂本文内容。马上开始本次测试实验。以下为本次测试主要硬件:

图1

图2

在本次测试中我们会用到一个485转TTL调试工具,如图2。

图3

图3是本次测试RS-485部分硬件连接的原理图(自动流控)。电路中我没有加短路保护不够严谨,请原谅!如果你使用485电路不是自动流控,使用文章中的程序可能需要做一些修改才可以使用。

2.软件

     1.注意的问题:

 1. 半双工通信机制:

  RS-485采用半双工模式,同一时间只能有一个设备在总线上发送数据。若主设备连续发送指令:

       (1) 总线冲突:多个设备同时发送会导致信号叠加,数据损坏。

       (2) 收发切换延迟:发送完成后需切换为接收模式,若未等待足够时间,可能错过响应。

2. 协议帧间隔要求:

常见协议(如Modbus RTU)要求帧间隔时间(如3.5字符时间):

      (1)连续发送违反间隔:未留足间隔会导致接收方无法区分帧边界,引发解析错误。

      (2)示例:9600波特率下,3.5字符时间≈4ms,需在帧间插入此延时。

3. 缓冲区溢出风险:

     (1)发送过快:若接收方处理速度慢,连续发送会导致其缓冲区溢出,丢失数据。

     (2)硬件限制:部分RS-485芯片的缓冲区较小,无法承受高频率数据流。

4. 电气特性限制:

     (1)信号反射:长距离通信时,连续发送可能加剧信号反射问题,需终端电阻匹配。

     (2)驱动能力:总线负载设备过多时,连续发送可能超出驱动芯片的带载能力。

5. 软件实现缺陷:

     (1)未处理应答:发送后未等待响应直接发下一指令,导致协议逻辑混乱。

     (2)缺乏流控机制:未实现硬件/软件流控,无法协调收发节奏。

总结:通过合理设计通信时序、严格遵循协议规范、优化硬件设计,可在保证可靠性的前提下实现高效通信。关键需在发送频率系统响应速度之间找到平衡点。 

   2.从机模式通信方式:

图4

 

      图4.中分别将设备A与设备B并联起来,然后通过PC端发送控制指令,分别对应 设备A/B进行控制。本次测试实验使用ArduinoIDE2.0工具不多说大家都知道!PC端使用调试工具为XCOM V2.0,主要用于发送控制指令与数据监测功能。好了现在开始上代码:

   这里我们给两个设备A/B设定一个简单的通信协议:[设备地址][分隔符][指令内容][结束符]

  示例:
         0x01:ACN1_ON      --> 控制设备A的继电器CN1打开
         0x01:ACN1_OFF    --> 控制设备A的继电器CN1关闭

         .....

 PC端使用调试工具发送控制指令

         发送指令:

                控制设备A:  01:ACN1_OFF      
                         返回:1:OK

               控制设备B:02:BCN1_ON

                         返回:2:OK

图5

图5是本次测试硬件连接实物图,后面我还会用这个硬件连接做测试!

(1)设备A端代码: 

/**
 * @file Equipment-A.ino
 * @author jonnie Walker iTE
 * @brief  485_TestA
 * @version 0.1
 * @date 2025-05-13
 * 
 * @copyright Copyright (c) 2025
 * 
 * ------------------------------------------------------/
 * 
 * Here we are using the automatic flow control 485 chip.
 * 
 */

#include <HardwareSerial.h>


//#define RE_DE_PIN   6
#define DEVICE_ADDR 0x01  
#define BAUDRATE    9600
#define RELAY_BUILTIN  5

HardwareSerial RS485(1);

void setup() {
  Serial.begin(115200);

  pinMode(RELAY_BUILTIN,OUTPUT);
  RS485.begin(BAUDRATE, SERIAL_8N1, 4, 3); // RX, TX
 // pinMode(RE_DE_PIN, OUTPUT);
 // digitalWrite(RE_DE_PIN, LOW);
}

void loop() {
  if (RS485.available() > 0) {
    String data = RS485.readStringUntil('\n');
    data.trim();
    int addr = data.substring(0, data.indexOf(':')).toInt();
    
    if (addr == DEVICE_ADDR) {  // Response when address matching
      String cmd = data.substring(data.indexOf(':') + 1);
      String response = executeCommand(cmd);
      
      // ================= Response sending=================
      RS485.print(DEVICE_ADDR);
      RS485.print(":");
      RS485.println(response);
      RS485.flush();
     
    }
  }
}

//Instruction processing
String executeCommand(String cmd) {
  if (cmd == "ACN1_ON") {
    digitalWrite(RELAY_BUILTIN, HIGH);
    return "OK";
  } else if (cmd == "ACN1_OFF") {
    digitalWrite(RELAY_BUILTIN, LOW);
    return "OK";
  }
  return "ERROR";
}

(2)设备B端代码:

/**
 * @file Equipment-B.ino
 * @author jonnie Walker iTE
 * @brief  485_TestB
 * @version 0.1
 * @date 2025-05-13
 * 
 * @copyright Copyright (c) 2025
 * 
 * -------------------------------------------------------------/
 * 
 * Here we are using the automatic flow control 485 chip.
 * 
 * 
 * 
 */


#include <HardwareSerial.h>

#define RELAY_BUILTIN  6

#define BAUDRATE     9600 // 485 communication baud rate
#define DEVICE_ADDR 0x02  //ID

HardwareSerial RS485(1); // Use UART1

// =================init =================
void setup() {
  Serial.begin(115200);
  
  pinMode(RELAY_BUILTIN,OUTPUT);
 
  RS485.begin(BAUDRATE, SERIAL_8N1, 4, 3); // RX, TX
 
  //Serial.print("Device B Ready. Addr:");
  //Serial.println(DEVICE_ADDR, HEX);
}

// ================= 主循环 =================
void loop() {
  handleRS485Communication();
}

// ================= 通信处理函数 =================
void handleRS485Communication() {
  // 接收数据
  if (RS485.available() > 0) {
    String data = RS485.readStringUntil('\n');
    data.trim();
    int addr = data.substring(0, data.indexOf(':')).toInt();
    
    if (addr == DEVICE_ADDR) {  // Response when address matching
      String cmd = data.substring(data.indexOf(':') + 1);
      String response = executeCommand(cmd);
      
     // ================= Response sending =================
      RS485.print(DEVICE_ADDR);
      RS485.print(":");
      RS485.println(response);
      RS485.flush();
     
    }
  }
}

// ================= Instruction processing=================
String executeCommand(String cmd) {
  if (cmd == "BCN1_ON") {
    digitalWrite(RELAY_BUILTIN, HIGH);
    return "OK";
  } else if (cmd == "BCN1_OFF") {
    digitalWrite(RELAY_BUILTIN, LOW);
    return "OK";
  }
  return "ERROR";
}

3.主从机模式通信方式:

      图5

从图5中就可以看出主从通信原理。这里我们依然需要给两个设备A/B设定一个简单的通信协议:

协议格式:[目标地址]:[源地址]:[指令内容]:[参数]

示例:

   01:02:ACN1_R1:ON     --> 设备B(02)控制设备A(01)的继电器打开

   02:01:ACN1_R1;ON     --> 设备A(01)控制设备B(02)的继电器打开 

   ........ 

 通过设备B发送指令给设备A:01:02:ACN1_R1:ON  -->控制设备继电器CN1打开

 通过设备B发送指令给设备A:01:02:ACN1_R1:OFF  -->控制设备继电器CN1关闭                     

(1)设备A端代码:

/**
 * @file Equipment-A_T2.ino
 * @author jonnie Walker iTE
 * @brief  485_A_Test2
 * @version 0.1
 * @date 2025-05-14
 * 
 * @copyright Copyright (c) 2025
 * 
 * --------------------------------------------/
 * 
 *  示例:V2.0
 * 01:02:ACN1_ON:ON    # 设备B(02)请求设备A(01)的控制继电器
 * 02:01:BCN1_ON:ON    # 设备A(01)请求设备B(02)的控制继电器
 * 
 */


#include <HardwareSerial.h>

// 硬件配置(保持不变)
#define DEVICE_ADDR   0x01
#define BAUDRATE      9600

#define SEND_ADDR     0x02  //B.使用A设备才能开启

// 输出端子
#define RELAY_CN1_OUT1_PIN  5
#define RELAY_CN2_OUT2_PIN  6
#define RELAY_CN3_OUT3_PIN  7
#define RELAY_CN4_OUT4_PIN  10

// 输入端子
#define PCI_IN1_PIN 0
#define PCI_IN2_PIN 1
#define PCI_IN3_PIN 2
#define PCI_IN4_PIN 9

#define BUTTON_PIN 8

HardwareSerial RS485(1);
unsigned long lastSendTime = 0;
const unsigned long SEND_INTERVAL = 5000;
const unsigned long INPUT_READ_INTERVAL = 1000;

// 状态变量优化为位操作
volatile uint8_t inputStates = 0;
volatile uint8_t pendingCommands = 0;

void setup() {
  Serial.begin(115200);

  // 初始化输出
  const uint8_t relayPins[] = {RELAY_CN1_OUT1_PIN, RELAY_CN2_OUT2_PIN, 
                              RELAY_CN3_OUT3_PIN, RELAY_CN4_OUT4_PIN};
  for(uint8_t i=0; i<4; i++) pinMode(relayPins[i], OUTPUT);

  // 初始化输入(内部上拉)
  const uint8_t inputPins[] = {PCI_IN1_PIN, PCI_IN2_PIN, PCI_IN3_PIN, PCI_IN4_PIN, BUTTON_PIN};
  for(uint8_t i=0; i<5; i++) pinMode(inputPins[i], INPUT_PULLUP);

  RS485.begin(BAUDRATE, SERIAL_8N1, 4, 3);
  Serial.println("Device A Ready (Addr:01)");
}

void loop() {
  static unsigned long lastInputCheck = 0;
  
  processIncomingData();  // 优先处理接收数据

  // 输入检测(1秒间隔)
  if (millis() - lastInputCheck >= INPUT_READ_INTERVAL) {
    readInputSignals();
    lastInputCheck = millis();
  }

  // 命令发送处理(5秒间隔)
  if (millis() - lastSendTime >= SEND_INTERVAL) {
    processPendingCommands();
    lastSendTime = millis();
  }
}

// 输入信号读取优化
void readInputSignals() {
  static const uint8_t inputPins[] = {PCI_IN1_PIN, PCI_IN2_PIN, PCI_IN3_PIN, PCI_IN4_PIN};
  uint8_t newStates = 0;
  
  for(uint8_t i=0; i<4; i++) {
    // 修正1:补全括号并修正逻辑
    if(digitalRead(inputPins[i])) {  // 当使用INPUT_PULLUP时,HIGH表示未触发
      continue;  // 保持原状态
    }
    // 只有当输入为LOW(触发)时执行以下操作
    newStates |= (1 << i);         // 记录新状态
    pendingCommands |= (1 << i);   // 设置需要发送命令的标志位
    sendImmediateCommand(i);          // 立即发送ON命令
  }

  inputStates = newStates;
}

/*
// 优化输入信号读取
void readInputSignals() {
  static const uint8_t inputPins[] = {PCI_IN1_PIN, PCI_IN2_PIN, PCI_IN3_PIN, PCI_IN4_PIN};
  uint8_t newStates = 0;
  
  for(uint8_t i=0; i<4; i++) {
    if(digitalRead(inputPins[i])) continue;  // INPUT_PULLUP模式下HIGH表示未触发
    
    newStates |= (1 << i);
    if(!(pendingCommands & (1 << i))) {  // 避免重复发送
      pendingCommands |= (1 << i);
      sendImmediateCommand(i);          // 立即发送ON命令
    }
  }
  
  inputStates = newStates;
}

*/

// 立即发送ON命令
void sendImmediateCommand(uint8_t index) {
  const char* commands[] = {
    "BCN1_R1:ON", "BCN2_R2:ON", "BCN3_R3:ON", "BCN4_R4:ON"
  };
  sendCommand(SEND_ADDR, commands[index]);
}


// 命令处理优化
void processPendingCommands() {
  static const char* commands[] = {
    "BCN1_R1:OFF", "BCN2_R2:OFF", "BCN3_R3:OFF", "BCN4_R4:OFF"
  };

  for(uint8_t i=0; i<4; i++) {
    if(pendingCommands & (1 << i)) {
      sendCommand(SEND_ADDR, commands[i]);
      pendingCommands &= ~(1 << i); // 清除对应位
    }
  }
}

// 数据接收处理优化(使用缓冲区)
void processIncomingData() {
  static char buffer[32];
  static size_t idx = 0;
  
  while(RS485.available()) {
    char c = RS485.read();
    if(c == '\n' || idx >= sizeof(buffer)-1) {
      buffer[idx] = '\0';
      parseMessage(buffer);
      idx = 0;
      return;
    }
    buffer[idx++] = c;
  }
}

// 消息解析优化
void parseMessage(char* msg) {
  uint8_t targetAddr, sourceAddr;
  char cmd[16], param[16];
  
  if(sscanf(msg, "%hhu:%hhu:%15[^:]:%15s", &targetAddr, &sourceAddr, cmd, param) != 4)
    return;

  if(targetAddr != DEVICE_ADDR) return;

  // 继电器控制统一处理
  const struct {
    const char* prefix;
    uint8_t pin;
  } relayMap[] = {
    {"ACN1_R1", RELAY_CN1_OUT1_PIN},
    {"ACN2_R2", RELAY_CN2_OUT2_PIN},
    {"ACN3_R3", RELAY_CN3_OUT3_PIN},
    {"ACN4_R4", RELAY_CN4_OUT4_PIN}
  };

  for(uint8_t i=0; i<4; i++) {
    if(strcmp(cmd, relayMap[i].prefix) == 0) {
      digitalWrite(relayMap[i].pin, (strcmp(param, "ON") == 0) ? HIGH : LOW);
      sendResponse(sourceAddr, "OK:%s", param);
      return;
    }
  }
  
  sendResponse(sourceAddr, "ERR:UNKNOWN_CMD");
}

// 响应发送优化(支持格式化输出)
void sendResponse(uint8_t targetAddr, const char* format, ...) {
  char buffer[32];
  va_list args;
  va_start(args, format);
  vsnprintf(buffer, sizeof(buffer), format, args);
  va_end(args);

  RS485.printf("%d:%d:%s\n", targetAddr, DEVICE_ADDR, buffer);
  delay(4);
}

// 命令发送优化
void sendCommand(uint8_t targetAddr, const char* cmd) {
  RS485.printf("%d:%d:%s\n", targetAddr, DEVICE_ADDR, cmd);
  delay(4);// 9600bps时插入3.5字符时间延时
}


                      

(2)设备B端代码:

/**
 * @file Equipment-B_T2.ino
 * @author jonnie Walker iTE
 * @brief  485_B_Test
 * @version 0.1
 * @date 2025-05-14
 * 
 * @copyright Copyright (c) 2025
 * 
 * ----------------------------------------------------/
 * 
 * 
 * 示例:V2.0
 * 01:02:ACN1_ON:ON    # 设备B(02)请求设备A(01)的控制继电器
 * 02:01:BCN1_ON:ON    # 设备A(01)请求设备B(02)的控制继电器
 * 
 * 
 * 
 */


#include <HardwareSerial.h>

// 硬件配置(保持不变)
#define DEVICE_ADDR   0x02
#define BAUDRATE      9600

#define SEND_ADDR     0x01

// 输出端子
#define RELAY_CN1_OUT1_PIN  5
#define RELAY_CN2_OUT2_PIN  6
#define RELAY_CN3_OUT3_PIN  7
#define RELAY_CN4_OUT4_PIN  10

// 输入端子
#define PCI_IN1_PIN 0
#define PCI_IN2_PIN 1
#define PCI_IN3_PIN 2
#define PCI_IN4_PIN 9
#define BUTTON_PIN  8

HardwareSerial RS485(1);
unsigned long lastSendTime = 0;
const unsigned long SEND_INTERVAL = 5000;
const unsigned long INPUT_INTERVAL = 1000;

// 状态变量优化
volatile uint8_t pendingCommands = 0;  // 使用位掩码管理状态
uint8_t inputStates = 0;

void setup() {
  Serial.begin(115200);

  // 初始化输出引脚
  const uint8_t relayPins[] = {RELAY_CN1_OUT1_PIN, RELAY_CN2_OUT2_PIN,
                              RELAY_CN3_OUT3_PIN, RELAY_CN4_OUT4_PIN};
  for(uint8_t i=0; i<4; i++) pinMode(relayPins[i], OUTPUT);

  // 初始化输入引脚
  const uint8_t inputPins[] = {PCI_IN1_PIN, PCI_IN2_PIN, PCI_IN3_PIN, PCI_IN4_PIN, BUTTON_PIN};
  for(uint8_t i=0; i<5; i++) pinMode(inputPins[i], INPUT_PULLUP);

  RS485.begin(BAUDRATE, SERIAL_8N1, 4, 3);
  Serial.println("Device B Ready (Addr:02)");
}

void loop() {
  processIncomingData();  // 启用接收处理
  
  static unsigned long lastInputCheck = 0;
  if (millis() - lastInputCheck >= INPUT_INTERVAL) {
    readInputSignals();
    lastInputCheck = millis();
  }

  if (millis() - lastSendTime >= SEND_INTERVAL) {
    processPendingCommands();
    lastSendTime = millis();
  }
}

// 优化输入信号读取
void readInputSignals() {
  static const uint8_t inputPins[] = {PCI_IN1_PIN, PCI_IN2_PIN, PCI_IN3_PIN, PCI_IN4_PIN};
  uint8_t newStates = 0;
  
  for(uint8_t i=0; i<4; i++) {
    // 修正1:补全括号并修正逻辑
    if(digitalRead(inputPins[i])) {  // 当使用INPUT_PULLUP时,HIGH表示未触发
      continue;  // 保持原状态
    }
    // 只有当输入为LOW(触发)时执行以下操作
    newStates |= (1 << i);         // 记录新状态
    pendingCommands |= (1 << i);   // 设置需要发送命令的标志位
    sendImmediateCommand(i);          // 立即发送ON命令
  }

  inputStates = newStates;
}

/*
// 优化输入信号读取
void readInputSignals() {
  static const uint8_t inputPins[] = {PCI_IN1_PIN, PCI_IN2_PIN, PCI_IN3_PIN, PCI_IN4_PIN};
  uint8_t newStates = 0;
  
  for(uint8_t i=0; i<4; i++) {
    if(digitalRead(inputPins[i])) continue;  // INPUT_PULLUP模式下HIGH表示未触发
    
    newStates |= (1 << i);
    if(!(pendingCommands & (1 << i))) {  // 避免重复发送
      pendingCommands |= (1 << i);
      sendImmediateCommand(i);          // 立即发送ON命令
    }
  }
  
  inputStates = newStates;
}

*/

// 立即发送ON命令
void sendImmediateCommand(uint8_t index) {
  const char* commands[] = {
    "ACN1_R1:ON", "ACN2_R2:ON", "ACN3_R3:ON", "ACN4_R4:ON"
  };
  sendCommand(SEND_ADDR, commands[index]);
}

// 处理待发送命令
void processPendingCommands() {
  const char* commands[] = {
    "ACN1_R1:OFF", "ACN2_R2:OFF", "ACN3_R3:OFF", "ACN4_R4:OFF"
  };

  for(uint8_t i=0; i<4; i++) {
    if(pendingCommands & (1 << i)) {
      sendCommand(SEND_ADDR, commands[i]);
      pendingCommands &= ~(1 << i);  // 清除标志位
    }
  }
}

// 优化数据接收处理
void processIncomingData() {
  static char buffer[32];
  static size_t idx = 0;
  
  while(RS485.available()) {
    char c = RS485.read();
    if(c == '\n' || idx >= sizeof(buffer)-1) {
      buffer[idx] = '\0';
      parseMessage(buffer);
      idx = 0;
      return;
    }
    buffer[idx++] = c;
  }
}

// 统一消息解析
void parseMessage(char* msg) {
  uint8_t targetAddr, sourceAddr;
  char cmd[16], param[16];
  
  if(sscanf(msg, "%hhu:%hhu:%15[^:]:%15s", &targetAddr, &sourceAddr, cmd, param) != 4)
    return;

  if(targetAddr != DEVICE_ADDR) return;

  // 继电器控制映射表
  const struct {
    const char* prefix;
    uint8_t pin;
  } relayMap[] = {
    {"BCN1_R1", RELAY_CN1_OUT1_PIN},
    {"BCN2_R2", RELAY_CN2_OUT2_PIN},
    {"BCN3_R3", RELAY_CN3_OUT3_PIN},
    {"BCN4_R4", RELAY_CN4_OUT4_PIN}
  };

  for(uint8_t i=0; i<4; i++) {
    if(strcmp(cmd, relayMap[i].prefix) == 0) {
      digitalWrite(relayMap[i].pin, (strcmp(param, "ON") == 0) ? HIGH : LOW);
      sendResponse(sourceAddr, "OK:%s", param);
      return;
    }
  }
  
  sendResponse(sourceAddr, "ERR:UNKNOWN_CMD");
}

// 优化响应发送
void sendResponse(uint8_t targetAddr, const char* format, ...) {
  char buffer[32];
  va_list args;
  va_start(args, format);
  vsnprintf(buffer, sizeof(buffer), format, args);
  va_end(args);

  RS485.printf("%d:%d:%s\n", targetAddr, DEVICE_ADDR, buffer);
  delay(4);// 9600bps时插入3.5字符时间延时
}

// 优化命令发送
void sendCommand(uint8_t targetAddr, const char* cmd) {
  RS485.printf("%d:%d:%s\n", targetAddr, DEVICE_ADDR, cmd);
  delay(4);// 9600bps时插入3.5字符时间延时
}



程序实现是通过设备B端输入的开关量,将采集到的信号转换成设定的485通信协议然后发送给设备A,设备A接收数据处理然后控制继电器打开与关闭。反知同理.......

程序我就不详细分析了,特别注明:485通信过程中不要连续发送控制指令!其实这次485通信控制测试我是当成串口使用的!完全没有发挥485通信的全部功能!

图6

图6是测试时485调试工具接收的设备A与设备B之间数据传输内容,也可以通过 调试工具发送控制指令。

下面是我测试时 视频:

5月15日


总结

      本文通过软/硬件结合大概的演示RS-485通信控制过程。  RS-485通信在工业控制应用中也是非常重要的,他的各方面优缺点也是决定在工业通信控制中的地位。经过本文阅读你大概知道RS-485通信控制原理了吧!非常感谢你能看到这里。  iTEM

如果文章内容有误的地方请谅解并指明!Thanks♪(・ω・)ノ

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐