人脸识别下位机通信协议
版本 | 日期 | 编写 | 说明 |
V1.00 | 2021-03-17 | // | 下位机协议制定 |
V1.1 | 2021-08-20 | // | 心跳包指令的消费数据添加设备状态 |
- 硬件结构
1.485传输接口(A/B:双绞线)
- 传输协议
- 采用异步通信协议,半双工传输。
- 波特率:19200
- 数据格式:1位起始延时,8位数据位,1位停止位。
- 发送数据包结构
代码 | 长度 | 格式 | 数据 | 描述 |
DataHead | 1 | Char | ‘O’ | 帧头 |
DataHead | 1 | Char | ‘P’ | 帧头 |
ADDRESS | 1 | HEX | (默认:00) | 地址:0~15 |
VER | 1 | HEX | 0x11 | 版本标识(人脸水控识别码) |
FRAMEID HBYTE | 1 | HEX | 标识高字节 | |
FRAMEID LBYTE | 1 | HEX | 标识低字节 | |
CMD | 1 | HEX | 命令码 | |
LENGTH | 1 | HEX | 长度:DATA的长度 | |
DATA | N | HEX | 数据 | |
DC | 2 | HEX | 校验(CRC16-MODBUS)(校验:DATA) |
- 帧头(‘O’/’P’)采用ASCII码.
- FRAME ID 号标识上一帧与下一帧的不同,在一段时间内,FRAME ID 不能重复。建
议采用数字累计的方法获取 FRAME ID,比如从 0 一直增加到 65536.
- LENGTH 只表示 DATA 的长度,所以数据长度不超过 255 个字节
- ADDR 表示驱动板地址
- 正常情况下主机发送完一帧数据之后,不能再发其他的数据,除非模块在 500ms
内仍未响应。
- DC校验方法:CRC16-MODBUS。
- 5秒没有收到有效指令关闭全部龙头。
- 消费记录采用fifo保存消费记录。(消费完成保存到eeprom上传成功在删除)
- 协议说明(安卓机器对接)
命令码 | 值(HEX) | 功能描述 |
CMD_HeartBeat | 0x01 | 心跳包指令 |
CMD_Control | 0x02 | 电磁阀控制指令 |
Safe_Status | 0x03 | 消费数据上传状态 |
Address_Set | 0x04 | 控制板地址设置 |
1:心跳包命令
命令码 | CMD_HeartBeat |
功能 | 心跳包命令 |
值 | 0x01 |
发送数据 | BYTE0~BYTE6: 年+月+日+小时+分钟+秒 |
返回数据 | BYTE0:消费状态(00:无消费/01:消费) /******无消费上传信息********/ BYTE1:龙头状态(Bit:0:无开启/1:开启) BYTE2:阀体故障(Bit:0:无故障/1:故障) BYTE3:流量故障(Bit:0:无故障/1:故障) BYTE4:TDS状态(高) BYTE5:TDS状态(低): BYTE6:温度状态(高) BYTE7:温度状态(低): BYTE8:PH值状态 /******消费上传信息*******/ BYTE1: 龙头状态(Bit:0:无开启/1:开启) BYTE2:对应龙头(Bit:) BYTE3:消费方式(00:计时(秒)/01:计量(脉冲)) BYTE4~BYTE12:用户ID BYTE13~BYTE20:开启时间:年+月+日+小时+分钟+秒 BYTE21~24:时间消费/脉冲消费 BYTE25~BYTE28:结束时间(开启->结束) |
2:电磁阀控制命令
命令码 | CMD_Control |
功能 | 电磁阀控制命令 |
值 | 0x02 |
发送数据 | BYTE0:开关方式(00:关闭/01:开启) BYTE1:龙头位号(Bit:) BYTE2:计费方式(00:计时消费/01:计量消费) BYTE3~BYTE11:用户ID号 BYTE12~BYTE19:开启时间:年+月+日+小时+分钟+秒 |
返回数据 | BYTE0:开启方式(00:关闭/01:开启) BYTE1:龙头位号(Bit:) BYTE2:计费方式(00:计时消费/01:计量消费) BYTE3~BYTE11:用户ID号 BYTE12~BYTE19:开启时间:年+月+日+小时+分钟+秒 BYTE20:状态返回(00:正常/01:错误) |
3:消费数据上传成功/失败
命令码 | Safe_Status |
功能 | 下发消费数据上传成功 |
值 | 0x03 |
发送数据 | BYTE0:龙头号(Bit:) BYTE1:状态(0:上传成功/1:上传失败) |
返回数据 | BYTE0: 龙头号(Bit:) BYTE1: 返回状态(0:成功/1:失败) |
4:修改控制板地址
命令码 | Address_Set |
功能 | 地址控制指令 |
值 | 0x04 |
发送数据 | BYTE0:修改地址(0~255)默认:0 |
返回数据 | BYTE0:修改地址(0~255)默认:0 |
public final static String ADDRESS = "0011";//地址+版本 public final static String HART_L = "0108";//心跳包指令+数据长度
String date = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); //这里写入需要生成校验码的字符串 byte[] sbuf = CRC16M.getSendBuf(date + "0" + num); isChange = !isChange; //输出带有校验码的字符串 StringBuilder sb = new StringBuilder(); sb.append(CRC16M.str2HexStr("OP")) .append(CodeUtil.ADDRESS) .append(CodeUtil.getHex())//递增数 .append(CodeUtil.HART_L) .append(CRC16M.getBufHexStr(sbuf)); LogUtils.d("发送心跳指令 " + sb.toString()); serialHelper.sendHex(sb.toString());
//送数据 //5a46 0011 003d 02 14 01 00 00 02 01 0000383638313333 20211105103130 9d27 //接收数据 //5A46 0011 00A6 02 15 01 00 01 02 01 0000383638313333 20211118091436 00 97E9 // 5A46 0011 01 7B01 08 0000000000000000 400B // BYTE1:龙头状态(Bit:0:无开启/1:开启) // BYTE2:阀体故障(Bit:0:无故障/1:故障 // BYTE1:对应龙头(1~8) // BYTE2:消费方式(00:计时(秒)/01:计量(脉冲)) // BYTE3~BYTE11:用户ID // BYTE12~BYTE19:开启时间:年+月+日+小时+分钟+秒 // BYTE20~24:时间消费/脉冲消费 // BYTE25~BYTE29:结束时间(开启->结束)
// 01 09 000000000000868133 0000000000000003 0000000004 000000000005 // BYTE3:流量故障(Bit:0:无故障/1:故障) // BYTE4:TDS状态(高) // BYTE5:TDS状态(低) // BYTE6:温度状态(高) // BYTE7:温度状态(低) // BYTE8:PH值状态