arduino模拟modbus从站

arduino模拟modbus从站

个人笔记,请勿言论

模拟温湿度模块,随机温湿度
在这里插入图片描述

代码:

#include <Arduino.h>
#include <ModbusMaster.h>

const int bufferLength = 10;     // 定义缓存大小为10个字节
char serialBuffer[bufferLength]; // 建立字符数组用于缓存

/*将多个char十六进制字符拼接成一个char字符(如0和a拼接成0x0a)*/
unsigned char catChar2Hex(unsigned char hByte, unsigned char lByte)
{
  unsigned char ucTmp = 0x00;
  unsigned char hight;
  unsigned char low;
  if ((hByte >= 'A') && (hByte <= 'F'))
  {
    hight = hByte - 'A' + 10;
  }
  else if (hByte >= 'a' && hByte <= 'f')
  {
    hight = hByte - 'a' + 10;
  }
  else if (hByte >= '0' && hByte <= '9')
  {
    hight = hByte - '0';
  }
  else
  {
    ucTmp = 0xff;
  }
  if ((lByte >= 'A') && (lByte <= 'F'))
  {
    low = lByte - 'A' + 10;
  }
  else if (lByte >= 'a' && lByte <= 'f')
  {
    low = lByte - 'a' + 10;
  }
  else if (lByte >= '0' && lByte <= '9')
  {
    low = lByte - '0';
  }
  else
  {
    ucTmp = 0xff;
  }
  ucTmp = (hight << 4) | (low << 0); //高位左移4位,低位不移动,组成一个8位十六进制字符
  return ucTmp;
}

void red_adder_sum(char redBuffer[])
{
  int redbufferLength = 0;
  uint16_t u16CRC = 0xFFFF;

  if (redBuffer[5] == 1)
  {
    redbufferLength = 7;
  }
  else if (redBuffer[5] == 2)
  {
    redbufferLength = 9;
  }

  char sendBuffer[redbufferLength]; // 建立字节数组用于缓存
  sendBuffer[0] = redBuffer[0];     //地址
  sendBuffer[1] = redBuffer[1];     //功能码

  char temperature[4] = {0};   //存放温湿度值的十六进制
  char humidity[4] = {0};
  sprintf(temperature, "%X", random(3000, 65535));
  sprintf(humidity, "%X", random(8000, 10000));
  switch (redBuffer[5])
  {
  case 1:
    sendBuffer[2] = 2; //数据长度
    sendBuffer[3] = catChar2Hex(temperature[0], temperature[1]);
    sendBuffer[4] = catChar2Hex(temperature[2], temperature[3]);
    break;
  case 2:
    sendBuffer[2] = 4; //功能码
    sendBuffer[3] = catChar2Hex(temperature[0], temperature[1]);
    sendBuffer[4] = catChar2Hex(temperature[2], temperature[3]);
    sendBuffer[5] = catChar2Hex(humidity[0], humidity[1]);
    sendBuffer[6] = catChar2Hex(humidity[2], humidity[3]);
    break;
  default:
    break;
  }
  for (int s = 0; s < redbufferLength - 2; s++)
  {
    u16CRC = crc16_update(u16CRC, sendBuffer[s]);
  }
  sendBuffer[redbufferLength - 2] = lowByte(u16CRC);
  sendBuffer[redbufferLength - 1] = highByte(u16CRC);
  delay(100);
  for (int i = 0; i < redbufferLength; i++)
  {                              // 然后通过串口监视器输出readBytes
    Serial.print(sendBuffer[i]); // 函数所读取的信息
  }
}

void setup()
{
  // 启动串口通讯
  Serial.begin(9600);
  Serial.println();
}

void loop()
{
  if (Serial.available())
  {                                               // 当串口接收到信息后
    Serial.readBytes(serialBuffer, bufferLength); // 将接收到的信息使用readBytes读取
    red_adder_sum(serialBuffer);
    delay(100);
  }
}

Arduino作为Modbus从设备,通常需要通过串口通信向主机发送数据。以下是基本步骤: 1. **安装库**:首先,你需要在Arduino中安装Modbus RTU或TCP通信库,例如`ModbusMaster`或`modbus-esp`等,以便能够处理Modbus协议。 2. **配置硬件**:连接 Arduino 到主设备(如电脑或其他 Modbus 主机),通常通过串行端口(如UART、USB-TTL等)进行通讯。 3. **初始化通信**:在代码中设置串口参数(波特率、校验位等),并初始化 Modbus 库。 ```c++ #include <ModbusMaster.h> ModbusMaster mb; ``` 4. **准备要发送的数据**:Modbus通常使用寄存器地址和值来表示数据。例如,如果你想发送一个16位的模拟输入值,可以创建一个字节数组: ```c++ uint16_t inputValue = 1000; // 假设读取到的值 byte registerAddress = 0x0001; // 设备的输入寄存器地址 byte data[2] = {registerAddress, (inputValue >> 8) & 0xFF, inputValue & 0xFF}; ``` 5. **发送请求**:调用 `mb.writeCoils()` 或 `mb.writeRegisters()` 函数,将数据和地址传入,发送请求给主机。 ```c++ if (mb.writeRegister(registerAddress, data, 2)) { Serial.println("Data sent successfully"); } else { Serial.println("Failed to send data"); } ``` 6. **响应处理**:主机收到数据后可能会有确认反馈,根据需要处理这些响应。 记得在实际项目中,你需要根据Modbus主机的具体需求调整参数,并添加错误检测和处理机制。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值