前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >modbus rtu 灯光控制板查询指令生产及查询结果的解读

modbus rtu 灯光控制板查询指令生产及查询结果的解读

作者头像
拿我格子衫来
发布2024-01-17 08:37:26
1370
发布2024-01-17 08:37:26
举报
文章被收录于专栏:TopFETopFE

查询指令的生成,直接查询多少个寄存器。可以优化成,查询多少个灯。

查询结果,翻译成可读性信息。

代码语言:javascript
复制
/* eslint-disable */
function generateModbusQuery(registerCount) {
  const deviceId = 0x01; // 设备ID
  const functionCode = 0x03; // 功能码(读取保持寄存器)
  const startAddress = 0x0000; // 起始地址
  const buffer = [deviceId, functionCode, startAddress >> 8, startAddress & 0xFF, registerCount >> 8, registerCount & 0xFF];
  const crc = crc16(buffer);
  buffer.push(crc & 0xFF); // 先添加CRC的低位
  buffer.push(crc >> 8); // 再添加CRC的高位
  return buffer.map(byte => byte.toString(16).padStart(2, '0')).join(' ').toUpperCase();
}

// 简单的CRC16计算函数,用于生成查询指令的CRC校验码
function crc16(buffer) {
  let crc = 0xFFFF;
  for (let pos = 0; pos < buffer.length; pos++) {
      crc ^= buffer[pos];
      for (let i = 8; i !== 0; i--) {
          if ((crc & 0x0001) !== 0) {
              crc >>= 1;
              crc ^= 0xA001;
          } else {
              crc >>= 1;
          }
      }
  }
  return crc;
}


// 解释指令
function parseModbusResponse(responseString) {
  // 将字符串转换为字节数组
  const response = responseString.split(' ').map(hex => parseInt(hex, 16));

  // 假设响应数据从第4个字节开始(跳过设备ID,功能码,字节计数)
  // 以及最后两个字节是CRC,不包括在内
  const dataStartIndex = 3;
  const dataEndIndex = response.length - 2;

  for (let i = dataStartIndex; i < dataEndIndex; i += 2) {
      const registerValue = (response[i] << 8) + response[i + 1];
      const binaryString = registerValue.toString(2).padStart(16, '0');
      console.log(`寄存器 ${Math.floor((i - dataStartIndex) / 2)}: ${binaryString}`);
      for (let j = 0; j < binaryString.length; j++) {
          console.log(`灯 ${Math.floor((i - dataStartIndex) / 2) * 16 + j}: ${binaryString[j] === '1' ? '开' : '关'}`);
      }
  }
}

const req = generateModbusQuery(20)
// console.log(req)
parseModbusResponse("01 03 28 00 01 25 80 00 01 00 00 00 00 00 01 00 00 00 FF 00 01 00 30 00 FF F0 F0 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1A E9");
代码语言:javascript
复制
// 生成点亮灯的指令
function generateModbusCommand(lightsToTurnOn) {
  // 初始化所有寄存器为全灭(0)
  let registers = Array(4).fill(0);

  // 遍历灯的数组,设置相应的寄存器位
  lightsToTurnOn.forEach(light => {
      let registerIndex = Math.floor((light - 1) / 16);
      let bitPosition = (light - 1) % 16;
      registers[registerIndex] |= (1 << bitPosition);
  });

  // 将寄存器值转换为十六进制字符串
  let hexData = registers.map(reg => reg.toString(16).padStart(4, '0')).join(' ');

  // 构建Modbus指令
  let deviceAddress = '01';
  let functionCode = '10';
  let startingAddress = '0000';
  let registerCount = '0004';
  let byteCount = '08';
  let command = `${deviceAddress} ${functionCode} ${startingAddress} ${registerCount} ${byteCount} ${hexData}`;

  return command;
}

// 示例:点亮第18、32、56号灯
let command = generateModbusCommand([18, 32, 56]);
console.log(command);
// 01 10 0000 0004 08 0000 8002 0000 0080
代码语言:javascript
复制
function binaryToHex(binaryStr) {
  // 确保输入是16位
  if (binaryStr.length !== 16) {
      return 'Invalid input';
  }

  // 将二进制字符串转换为数字,然后转换为16进制字符串
  let hexStr = parseInt(binaryStr, 2).toString(16).toUpperCase();

  // 保证输出是4位16进制数
  return hexStr.padStart(4, '0');
}

// 示例
let hex = binaryToHex('0000000011111111'); // 应该返回 '00FF'
console.log(hex);
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-01-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档