diff --git a/Modbus/Modbus_Function.c b/Modbus/Modbus_Function.c new file mode 100644 index 0000000..bcb7f96 --- /dev/null +++ b/Modbus/Modbus_Function.c @@ -0,0 +1,428 @@ + +#include "Modbus_Function.h" +#include "Modbus_Registers.h" + +#include "stm32f1xx_hal.h" +#include "usart.h" +#include "bsp.h" +#include "string.h" + +uint8_t MODBUS_SLAVE_ID = 0x01; + +/* + + 帧结构 = 地址 + 功能码+ 数据 + 校验 + + |--ADDR--|--CMD--|--DAT--|--CRC--| + |--Byte--|--Byte-|-nByte-|-2Byte-| + + +线圈(Coils) +离散量输入(Discrete Input) +输入寄存器(Input registers) +保持寄存器(Holding registers) + + +功能码 解释翻译 作用 +0x01 Read Coils 读线圈状态 读取远程设备中1到2000个连续的线圈的状态 +0x02 Read Discrete Inputs 读离散输入状态 读取远程设备中1到2000个连续的离散输入的状态 +0x03 Read Holding Registers 读保持寄存器内容 读取远程设备中1到125个连续的保持寄存器的内容 +0x04 Read Input Registers 读输入寄存器内容 读取远程设备中1到125个连续的输入寄存器的内容 +0x05 Write Single Coil 写单个线圈 在远程设备中把单个线圈状态改变为打开或关闭的状态 +0x06 Write Single Register 写单个保持寄存器 在远程设备中写入单个保持寄存器 +0x07 Read Exception Status (Serial Line only) 读取异常状态(仅限串行线路) 读取远程设备中八个异常状态输出的内容 +0x08 Diagnostics (Serial Line only) 通信系统诊断(仅限串行线路) +0x0B Get Comm Event Counter (Serial Line only) 获取通讯事件计数器(仅限串行线路) 从远程设备的通信事件计数器获取状态字和事件计数 +0x0C Get Comm Event Log (Serial Line only) 获取通讯事件日志(仅限串行线路) 从远程设备获取状态字、事件计数、消息计数和事件字节字段 +0x0F Write Multiple Coils 写多个线圈 强制远程设备中线圈序列中的每个线圈接通或断开 +0x10 Write Multiple registers 写多个保持寄存器 在远程设备中写入连续寄存器块 +0x11 Report Slave ID (Serial Line only) 报导从机信息(仅限串行线路) 读取远程设备特有的类型、当前状态和其他信息的说明。数据内容特定于每种类型的设备 +0x14 Read File Record 读取文件记录 +0x15 Write File Record 写文件记录 +0x16 Mask Write Register 带屏蔽字写入寄存器 +0x17 Read/Write Multiple registers 读、写多个寄存器 执行一次连续写和连续读,写入操作在读取之前执行 +0x18 Read FIFO Queue 读取先进先出队列 +0x2B Encapsulated Interface Transport 封装接口传输 + + + +*/ + + + + +MODEBUS_t modbus; + + +typedef enum { + + ReadCoils = 0x01, + ReadDiscreteInputs = 0x02, + ReadHoldingRegisters = 0x03, + ReadInputRegisters = 0x04, + WriteSingleCoil = 0x05, + WriteSingleRegister = 0x06, + ReadExceptionStatus = 0x07, + Diagnostics = 0x08, + GetCommEventCounter = 0x0B, + GetCommEventLog = 0x0C, + WriteMultipleCoils = 0x0F, + WriteMultipleRegisters = 0x10, + ReportSlaveID = 0x11, + ReadFileRecord = 0x14, + WriteFileRecord = 0x15, + MaskWriteRegister = 0x16, + Read_WriteMultipleregisters = 0x17, + ReadFIFOQueue = 0x18, + EncapsulatedInterfaceTransport = 0x2B + +}modbus_cmd_e; + + + + + +static uint16_t Modbus_CRC16(uint8_t* data, uint16_t length) +{ + uint16_t crc = 0xFFFF; + for (int i = 0; i < length; i++) { + crc ^= data[i]; + + for (int j = 0; j < 8; j++) { + if ((crc & 0x0001) != 0) { + crc >>= 1; + crc ^= 0xA001; + } else { + crc >>= 1; + } + } + } + + return crc; +} + + +void Modbus_Init(void) +{ + //串口初始化 + //选择485通讯 + COMM_setSel(COMM_TYPE_485); + COMM_setDir(COMM_DIR_RX); + + SERIAL_Init(&serial3,"UART3",&huart3,50, 50); + serial3.setDir = COMM_setDir; + + //设备硬件初始化 + SERIAL_StartRecv(&serial3); + + + //modbus寄存器初始化 + + + memset(&modbus,0,sizeof(modbus)); + + + //函数绑定 + + + Modbus_Write("asdfghjkl",9); + + +} + + + uint8_t serial3_buff[50]; +void Modbus_Poll(void) +{ + + //收到主机信息, 绿灯闪 + + size_t len = SERIAL_Read(&serial3, serial3_buff, 50); + + if(len > 4)//这个长度不出意外的话是一包的长度 + { + if(serial3_buff[0] == MODBUS_SLAVE_ID) + { + uint16_t crc = serial3_buff[len - 2] | (serial3_buff[len - 1] << 8); + + if(crc == Modbus_CRC16(serial3_buff,len-2)) + { + + + //通讯成功,红灯闪烁 + LED_setToggle(LED_RED); + /* + 0x03 read + 0x06 write + 0x10 write multi + */ + + //赋值给modbus结构体 + modbus.addr = serial3_buff[0]; + modbus.cmd = serial3_buff[1]; + modbus.crc = crc; + memcpy(modbus.payload,&serial3_buff[2],len - 4); + + + switch(modbus.cmd) + { + case ReadCoils: + { + + }break; + + case ReadDiscreteInputs: + { + + uint16_t regis = modbus.payload[0] | (modbus.payload[1] << 8); + uint16_t value = modbus.payload[2] | (modbus.payload[3] << 8); + + + + }break; + case ReadHoldingRegisters: + { + // 0x03 + /* + reg value + 0xFF 0xFFFFFFFF + + 0x00 Di + + */ + + + uint16_t addr = modbus.payload[1] << 0 | + modbus.payload[0] << 8; + + uint16_t cmd = modbus.payload[3] << 0 | + modbus.payload[2] << 8; + + switch(addr) + { + case 0x00: + {//DI + + uint16_t regis = 0x0000; + uint16_t value = SYS_getDi(); + + + uint8_t sendbuff[50] = {0}; + + size_t send_len = 0; + + sendbuff[send_len++] = modbus.addr; + sendbuff[send_len++] = modbus.cmd; + sendbuff[send_len++] = regis; + sendbuff[send_len++] = regis >> 8; + sendbuff[send_len++] = value; + sendbuff[send_len++] = value >> 8; + uint16_t crc_f = Modbus_CRC16(sendbuff,send_len); + sendbuff[send_len++] = crc_f; + sendbuff[send_len++] = crc_f >> 8; + + + + Modbus_Write(sendbuff,send_len); + + + }break; + case 0x01: + {//ADC + uint16_t regis = 0x0001; + uint16_t value = SYS_getReg(); + + + uint8_t sendbuff[50] = {0}; + + size_t send_len = 0; + + sendbuff[send_len++] = modbus.addr; + sendbuff[send_len++] = modbus.cmd; + sendbuff[send_len++] = regis; + sendbuff[send_len++] = regis >> 8; + sendbuff[send_len++] = value; + sendbuff[send_len++] = value >> 8; + uint16_t crc_f = Modbus_CRC16(sendbuff,send_len); + sendbuff[send_len++] = crc_f; + sendbuff[send_len++] = crc_f >> 8; + + + + Modbus_Write(sendbuff,send_len); + }break; + case 0x02: + {//当前位置 + + }break; + } + + }break; + case ReadInputRegisters: + { + //Modbus_Write(buff,len); + }break; + case WriteSingleCoil: + { + + }break; + case WriteSingleRegister: + {//0x06 + uint16_t addr = modbus.payload[1] << 0 | + modbus.payload[0] << 8; + + uint16_t cmd = modbus.payload[3] << 0 | + modbus.payload[2] << 8; + + switch(addr) + { + case 0x00://设置DO输出 + { + SYS_setDo(1,(cmd & 0x01)); + SYS_setDo(2,(cmd & 0x02)); + }break; + case 0x01://设置电机使能 + { + MOTOR_setEn((cmd & 0x01)?(MOTOR_ENABLE):(MOTOR_DISABLE)); + }break; + case 0x02://设置电机方向 + { + MOTOR_setDir((cmd & 0x8000)?(MOTOR_DIR_CW):(MOTOR_DIR_CCW)); + }break; + case 0x03://设置电机细分 + { + MOTOR_setMS(MOTOR_MS_1); + }break; + case 0x04://设置电机步数 + { + MOTOR_setStep(cmd & 0x7fff); + }break; + case 0x05://设置电机步数,同时启动 + { + MOTOR_setDir((cmd & 0x8000)?(MOTOR_DIR_CW):(MOTOR_DIR_CCW)); + MOTOR_setStep(cmd & 0x7fff);//最大32767步 + MOTOR_setEn(MOTOR_ENABLE); + }break; + case 0x06://获取原点 + { + MOTOR_setGetFlag(MOTOR_GET_MIN); + MOTOR_setDir(MOTOR_DIR_CCW); + MOTOR_setStep(MOTOR_MAX_STEP); + MOTOR_setEn(MOTOR_ENABLE); + + + }break; + case 0x07://获取最大值 + { + MOTOR_setLenght(0); + MOTOR_setGetFlag(MOTOR_GET_MAX); + MOTOR_setDir(MOTOR_DIR_CW); + MOTOR_setStep(MOTOR_MAX_STEP); + MOTOR_setEn(MOTOR_ENABLE); + }break; + case 0x08:// + { + + }break; + + } + + }break; + case ReadExceptionStatus: + { + //Modbus_Write(buff,len); + }break; + case Diagnostics: + { + //Modbus_Write(buff,len); + }break; + case GetCommEventCounter: + { + //Modbus_Write(buff,len); + }break; + case GetCommEventLog: + { + //Modbus_Write(buff,len); + }break; + case WriteMultipleCoils: + { + //Modbus_Write(buff,len); + }break; + case WriteMultipleRegisters: + { + //0x10 + + //用来写配置数据 + + + + + + + + }break; + case ReportSlaveID: + { + uint16_t regis = modbus.cmd; + uint16_t value = modbus.addr; + + + uint8_t sendbuff[50] = {0}; + + size_t send_len = 0; + + sendbuff[send_len++] = modbus.addr; + sendbuff[send_len++] = modbus.cmd; + sendbuff[send_len++] = regis; + sendbuff[send_len++] = regis >> 8; + sendbuff[send_len++] = value; + sendbuff[send_len++] = value >> 8; + uint16_t crc_f = Modbus_CRC16(sendbuff,send_len); + sendbuff[send_len++] = crc_f; + sendbuff[send_len++] = crc_f >> 8; + + + + Modbus_Write(sendbuff,send_len); + }break; + case ReadFileRecord: + { + //Modbus_Write(buff,len); + }break; + case WriteFileRecord: + { + //Modbus_Write(buff,len); + }break; + case MaskWriteRegister: + { + //Modbus_Write(buff,len); + }break; + case Read_WriteMultipleregisters: + { + //Modbus_Write(buff,len); + }break; + case ReadFIFOQueue: + { + //Modbus_Write(buff,len); + }break; + case EncapsulatedInterfaceTransport: + { + //Modbus_Write(buff,len); + }break; + + } + } + } + } +} + +void Modbus_Write(uint8_t *data, size_t len) +{ + //只能一包一包发,不允许一次发很多包 + SERIAL_Write(&serial3,data,len); +} + + + + + diff --git a/Modbus/Modbus_Function.h b/Modbus/Modbus_Function.h new file mode 100644 index 0000000..c25ed1e --- /dev/null +++ b/Modbus/Modbus_Function.h @@ -0,0 +1,40 @@ +#ifndef __MODBUS_FUNCTION_H__ +#define __MODBUS_FUNCTION_H__ + +#include "stm32f1xx_hal.h" + +#include "bsp.h" + + +typedef struct MODBUS_s { + + uint8_t addr; + uint8_t cmd; + uint16_t crc; + uint8_t payload[256]; + + +}MODEBUS_t; + +typedef MODEBUS_t* MODEBUS_ptr; + +extern MODEBUS_t modbus; + + + + +extern uint8_t MODBUS_SLAVE_ID; + + +void Modbus_Init(void); + +void Modbus_Poll(void); + +void Modbus_Write(uint8_t *data, size_t len); + + + + + + +#endif diff --git a/Modbus/Modbus_Registers.h b/Modbus/Modbus_Registers.h new file mode 100644 index 0000000..e69de29 diff --git a/ParsePack.c b/ParsePack.c new file mode 100644 index 0000000..5aba96c --- /dev/null +++ b/ParsePack.c @@ -0,0 +1,135 @@ +/* + * ParserPack.c + * + * Created on: Jun 24, 2020 + * Author: matth + */ + +#include "ParsePack.h" + +static uint16_t CRC_CheckSum (uint8_t *pBuffer, uint16_t len) +{ + uint16_t poly = 0x8408; + uint16_t crc = 0; + uint8_t carry; + uint8_t i_bits; + uint16_t j; + + for (j = 0; j < len; j++) { + crc = (uint16_t) (crc ^ (uint8_t) pBuffer[j]); + for (i_bits = 0; i_bits < 8; i_bits++) { + carry = (uint8_t) (crc & 1); + crc = (uint16_t) (crc / 2); + if (carry) { + crc = (uint16_t) (crc ^ poly); + } + } + } + return crc; +} + + +void Packer_init(Packer_t *pack) +{ + pack->buff[0] = 0xEB; + pack->buff[1] = 0x90; + pack->seq = 0; +} + +size_t Packer_pack(Packer_t *pack, uint8_t id, uint8_t pkg[], uint16_t len) +{ + uint16_t j; + size_t i; + + pack->buff[2] = pack->seq++; + pack->buff[3] = id; + pack->buff[4] = (len >> 8) & 0xFF; + pack->buff[5] = len & 0xFF; + for (i=6,j=0u;jbuff[i] = pkg[j]; + } + uint16_t crc16 = CRC_CheckSum(&pack->buff[6], len); + pack->buff[i++] = (crc16 & 0xFF); + pack->buff[i++] = (crc16 >> 8)&0xFF; + return i; +} + +void Parser_init(Parser_t *parser) +{ + parser->stage = 0; +} + + +int Parser_char(Parser_t *parser, uint8_t c) +{ + int rslt = -1; + + switch (parser->stage) + { + case 0: + if (c == 0xEB) + { + parser->stage++; + } + break; + case 1: + if (c == 0x90) + { + parser->stage++; + } + else + { + parser->stage = 0; + } + break; + case 2: + parser->seq = c; + parser->stage++; + break; + case 3: + parser->id = c; + parser->stage++; + break; + case 4: + parser->len = c; + parser->stage++; + break; + case 5: + parser->len = (parser->len << 8) + c; + if (parser->len <=PARSER_BUFF_LEN) + { + parser->idx = 0; + parser->stage++; + } + else + { + parser->stage = 0; + } + break; + case 6: + parser->buff[parser->idx++] = c; + if (parser->idx == parser->len) + { + parser->stage++; + } + break; + case 7: + parser->crc16 = c; + parser->stage++; + break; + case 8: + parser->crc16 += (c<<8); + if (parser->crc16 == CRC_CheckSum(parser->buff, parser->len)) + { + rslt = parser->id; + } + parser->stage = 0; + break; + default: + parser->stage = 0; + break; + } + + return rslt; +} \ No newline at end of file diff --git a/ParsePack.h b/ParsePack.h new file mode 100644 index 0000000..1edae1b --- /dev/null +++ b/ParsePack.h @@ -0,0 +1,52 @@ +/* + * ParserPack.h + * + * Created on: Jun 24, 2020 + * Author: matth + */ + +#ifndef MATT_PARSEPACK_H_ +#define MATT_PARSEPACK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#ifndef PARSER_BUFF_LEN +#define PARSER_BUFF_LEN (512) +#endif + +#ifndef PACKER_BUFF_LEN +#define PACKER_BUFF_LEN (512+6) +#endif + +typedef struct{ + int stage; + uint16_t idx; + uint16_t len; + uint8_t seq; + uint16_t id; + uint16_t crc16; + uint32_t crc_cal; + uint32_t head_err_cnt; + uint8_t buff[PARSER_BUFF_LEN]; +} Parser_t; + +typedef struct{ + uint8_t seq; + uint8_t buff[PARSER_BUFF_LEN]; +} Packer_t; + +void Parser_init(Parser_t *parser); +void Packer_init(Packer_t *pack); + +int Parser_char(Parser_t *parser, uint8_t c); +size_t Packer_pack(Packer_t *pack, uint8_t id, uint8_t pkg[], uint16_t len); + +#ifdef __cplusplus +} +#endif +#endif /* MATT_PARSEPACK_H_ */ diff --git a/RS485_TestTool.pro b/RS485_TestTool.pro index 80c43dd..332c8d9 100644 --- a/RS485_TestTool.pro +++ b/RS485_TestTool.pro @@ -8,11 +8,17 @@ CONFIG += c++17 # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 +include(./dlink/dlink.pri) + + + SOURCES += \ + ParsePack.c \ main.cpp \ mainwindow.cpp HEADERS += \ + ParsePack.h \ mainwindow.h FORMS += \ diff --git a/RS485_TestTool.pro.user b/RS485_TestTool.pro.user index 26ec857..a8e2132 100644 --- a/RS485_TestTool.pro.user +++ b/RS485_TestTool.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -57,6 +57,36 @@ true + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + + 0 + true + + true + true + Builtin.DefaultTidyAndClazy + 8 + + + + true + + + + + + + ProjectExplorer.Project.Target.0 @@ -69,7 +99,7 @@ 0 0 - D:\2_code\1_qt\RS485_TestTool\..\build-RS485_TestTool-Desktop_Qt_5_15_2_MinGW_32_bit-Debug + D:\2_code\1_qt\BAT_TestTool\..\build-RS485_TestTool-Desktop_Qt_5_15_2_MinGW_32_bit-Debug D:/2_code/1_qt/build-RS485_TestTool-Desktop_Qt_5_15_2_MinGW_32_bit-Debug @@ -108,7 +138,7 @@ 2 - D:\2_code\1_qt\RS485_TestTool\..\build-RS485_TestTool-Desktop_Qt_5_15_2_MinGW_32_bit-Release + D:\2_code\1_qt\BAT_TestTool\..\build-RS485_TestTool-Desktop_Qt_5_15_2_MinGW_32_bit-Release D:/2_code/1_qt/build-RS485_TestTool-Desktop_Qt_5_15_2_MinGW_32_bit-Release @@ -149,7 +179,7 @@ 0 - D:\2_code\1_qt\RS485_TestTool\..\build-RS485_TestTool-Desktop_Qt_5_15_2_MinGW_32_bit-Profile + D:\2_code\1_qt\BAT_TestTool\..\build-RS485_TestTool-Desktop_Qt_5_15_2_MinGW_32_bit-Profile D:/2_code/1_qt/build-RS485_TestTool-Desktop_Qt_5_15_2_MinGW_32_bit-Profile diff --git a/dlink/DLINK_zh_CN.qm b/dlink/DLINK_zh_CN.qm new file mode 100644 index 0000000..d4df25d Binary files /dev/null and b/dlink/DLINK_zh_CN.qm differ diff --git a/dlink/DLINK_zh_CN.ts b/dlink/DLINK_zh_CN.ts new file mode 100644 index 0000000..7af3301 --- /dev/null +++ b/dlink/DLINK_zh_CN.ts @@ -0,0 +1,42 @@ + + + + + DLink + + + Serial Port Open Success + 涓插彛鎵撳紑鎴愬姛 + + + + Serial Port Open Fail + 涓插彛鎵撳紑澶辫触 + + + + %1 close + %1 鍏抽棴 + + + + UdpSocket open + UDP 绔彛鎵撳紑鎴愬姛 + + + + Bind and join the gdt multicast group + 鍔犲叆缁勬挱鎴愬姛 + + + + Fail to join gdt multicast group. + 鍔犲叆缁勬挱澶辫触. + + + + Fail to bind gdt multicast socket. + 鍔犲叆缁勬挱澶辫触. + + + diff --git a/dlink/dlink.cpp b/dlink/dlink.cpp new file mode 100644 index 0000000..ee1d38b --- /dev/null +++ b/dlink/dlink.cpp @@ -0,0 +1,696 @@ +#include "dlink.h" +#include +#include "QDateTime" +#include "QThread" + + + + + + +DLink::DLink(QObject *parent) : QObject(parent) +{ + + QTimer *Timer = new QTimer(this); + Timer->setInterval(1000); + + //瀹氭椂鍒锋柊姣忎釜鎺ュ彛鐨勯氳鐘舵 + connect(Timer,&QTimer::timeout,this,[=](){ + static qint64 last = QDateTime::currentMSecsSinceEpoch(); + qint64 time = QDateTime::currentMSecsSinceEpoch() - last; + + if(time >= 1000) + { + foreach(clientNode node,sockets) + { + if(node.sock) + { + node.in.total += node.in.count; + node.out.total += node.out.count; + + node.in.rate = (double)node.in.count / (time * 0.001); + node.out.rate = (double)node.out.count / (time * 0.001); + + node.in.frequency = (double)node.in.frame / (time * 0.001); + node.out.frequency = (double)node.out.frame / (time * 0.001); + + emit status(node.addr,node.port,node.in.total,node.in.rate,node.in.frequency,node.out.total,node.out.rate,node.out.frequency); + + node.in.count = 0; + node.out.count = 0; + node.in.frame = 0; + node.out.frame = 0; + + sockets.replace(sockets.indexOf(node),node); + + //qDebug() << node.out.rate << node.out.frequency; + } + } + last = QDateTime::currentMSecsSinceEpoch(); + } + }); + + connect(this,&DLink::destroyed,Timer,&QTimer::deleteLater); + + Timer->start(); + +} +DLink::~DLink() +{ + foreach (serialNode node, serials) { + if(node.port) + { + if(node.port->isOpen()) + { + node.port->close(); + } + delete node.port; + node.port = nullptr; + } + } + + foreach(clientNode node,sockets) + { + if(node.sock) + { + node.sock->leaveMulticastGroup(node.addr); + node.sock->abort(); + qWarning("leave multicast Group"); + delete node.sock; + node.sock = nullptr; + } + } + + disconnect(this, nullptr, nullptr, nullptr); +} + +void DLink::transmit(QHostAddress ip,quint16 port,QByteArray data) +{ + //qDebug() << "dlink transmit:" << QThread::currentThreadId(); + + QElapsedTimer time; + + time.start(); + + foreach(clientNode node,sockets) + { + if((node.addr == ip) && (node.port == port)) + { + qint64 flag = node.sock->writeDatagram(data,node.addr, node.port); + if(flag != -1) + { + node.out.count += flag; + node.out.frame += 1; + sockets.replace(sockets.indexOf(node),node); + } + else + { + qDebug() << "udp Send Msg failure"; + } + + } + } + + //qDebug() << "dlink transmit time:" << time.nsecsElapsed() / 1000000.0 ; +} + + +void DLink::transmit(QString name,QByteArray data) +{ + //qDebug() << "dlink transmit:" << QThread::currentThreadId(); + + QElapsedTimer time; + + time.start(); + + foreach (serialNode node, serials) { + if((node.port)&&(node.name == name)) + { + if(node.port->isOpen()||node.port->isWritable()) + { + if(node.type == devtype::datalink) + { + qint64 flag = node.port->write(data); + if(flag != -1) + { + //qDebug() << data.toHex(); + node.out.count += flag; + node.out.frame += 1; + serials.replace(serials.indexOf(node),node); + } + else + { + qDebug() << "serialPort Send Msg failure"; + } + } + } + } + } + + + //qDebug() << "dlink transmit time:" << time.nsecsElapsed() / 1000000.0 ; +} + + +int DLink::SendMessageTo(quint8 ch, quint8 *msg, quint16 len) +{ + //璁╄繖涓嚱鏁板湪鍏朵粬绾跨▼杩愯 + outCount += len; + //qDebug() << "Send Msg"; + //鏇村姞ch閫夋嫨 + + foreach(clientNode node,sockets) + { + if(node.sock->isOpen()||node.sock->isWritable()||node.sock->isValid()) + { + if(node.type == devtype::datalink) + { + qint64 flag = node.sock->writeDatagram((const char *)msg,len,node.addr, node.port); + if(flag != -1) + { + node.out.count += flag; + node.out.frame += 1; + sockets.replace(sockets.indexOf(node),node); + } + else + { + qDebug() << "udp Send Msg failure"; + } + } + } + } + + foreach (serialNode node, serials) { + if(node.port) + { + if(node.port->isOpen()||node.port->isWritable()) + { + if(node.type == devtype::datalink) + { + qint64 flag = node.port->write((const char *)msg,len); + if(flag != -1) + { + node.out.count += flag; + node.out.frame += 1; + serials.replace(serials.indexOf(node),node); + } + else + { + qDebug() << "serialPort Send Msg failure"; + } + } + } + } + } + + return outCount; +} + +/* 鏂版兂娉 + * dlink 褰撲綔涓涓嚎绋嬩竴鐩村惊鐜紝涓鏃︽煇涓涓覆鍙h繛鎺ワ紝灏变細鎶婁簨浠跺惊鐜姞鍏ュ叾涓紝寰楀埌浜嬩欢椹卞姩 + * 鎸囦护鎸変笅浼氭妸鏁版嵁瀛樺埌缂撳瓨锛岀瓑寰呭彂閫佸嚭鍘伙紝绾跨▼灏变細缁撴潫 + * 鍙戣捣浠诲姟璇诲啓锛屾柊寤轰竴涓嚎绋嬶紝鑸嚎璇诲彇鍙戦佺粨鏉燂紝鑸嚎绾跨▼缁撴潫 + * 鍙戣捣鍙傛暟璇诲啓锛屾柊寤轰竴涓嚎绋嬶紝鍙傛暟璇诲彇鍙戦佺粨鏉燂紝鍙傛暟绾跨▼缁撴潫 + */ +bool DLink::PortSetup(const QString &name, qint32 baudrate, QSerialPort::Parity parity) +{ + bool isSuccess = false; + + qDebug() << "Q_INVOKABLE" << baudrate << parity; + + foreach (serialNode node, serials) { + if(node.port) + { + if(node.name == name) + { + if(node.port->isOpen()) + { + node.port->close(); + } + + //鏂帀鎵鏈夌殑杩炴帴 + disconnect(node.port,nullptr,nullptr,nullptr); + + delete node.port; + node.port = nullptr; + + + serials.removeAt(serials.indexOf(node)); + } + } + } + + QSerialPort *serialPort = new QSerialPort(name,this); + + if (serialPort->open(QIODevice::ReadWrite)) + { + serialPort->setBaudRate(baudrate); + serialPort->setParity(parity); + serialPort->setDataBits(QSerialPort::Data8); + serialPort->setStopBits(QSerialPort::OneStop); + + connect(serialPort, SIGNAL(readyRead()), this, SLOT(readPendingDatagramsSerialPort()));//鏈嚎绋嬪唴璋冪敤 + isSuccess = true; + + serialNode node; + + node.port = serialPort; + node.baud = baudrate; + node.parity = parity; + node.name = name; + node.type = devtype::datalink; + + serials.append(node); + + emit showMessage(tr("Serial Port Open Success"),10000); + qWarning() << "Serial Port Open Success"; + } + else + { + isSuccess = false; + emit showMessage(tr("Serial Port Open Fail"),10000); + qWarning() << "Serial Port Open Fail"; + delete serialPort; + serialPort = nullptr; + } + + return isSuccess; +} + +bool DLink::PortState(const QString &name) +{ + bool flag = false; + + foreach (serialNode node, serials) { + if(node.port) + { + if(node.name == name) + { + flag = true; + break; + } + } + } + + return flag; +} + +bool DLink::PortStop(const QString &name) +{ + bool flag = false; + + foreach (serialNode node, serials) { + if(node.port) + { + if(node.name == name) + { + if(node.port->isOpen()) + { + qDebug() << "close" << node.name; + emit showMessage(tr("%1 close").arg(node.name),10000); + node.port->close(); + } + + //鏂帀鎵鏈夌殑杩炴帴 + disconnect(node.port,nullptr,nullptr,nullptr); + + delete node.port; + node.port = nullptr; + + serials.removeOne(node); + + flag = true; + } + } + } + + + return flag; +} + + + +bool DLink::setupClient(const QHostAddress &local_addr,int local_port,const QHostAddress &remote_addr,int remote_port) +{ + bool isSuccess = false; + + + foreach (clientNode node, sockets) { + if(node.sock) + { + if((node.addr == remote_addr)&&(node.port == remote_port)) + { + if(node.sock->isOpen()) + { + node.sock->leaveMulticastGroup(node.addr); + node.sock->close(); + } + //鏂帀鎵鏈夌殑杩炴帴 + disconnect(node.sock,nullptr,nullptr,nullptr); + + node.sock->deleteLater(); + //node.sock = nullptr; + + sockets.removeAt(sockets.indexOf(node)); + + } + } + } + + QUdpSocket *clientsock = new QUdpSocket(this); + clientsock->setProxy(QNetworkProxy::DefaultProxy);//蹇呴』鍏堣缃笉浠g悊锛屽惁鍒欒繛涓嶄笂 + int rst = clientsock->open(QIODevice::ReadWrite); + if(rst) + { + if(clientsock->bind(local_addr,local_port,QAbstractSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) + { + connect(clientsock, SIGNAL(readyRead()), + this, SLOT(readPendingDatagramsClient())); + + clientNode node; + node.sock = clientsock; + node.addr = remote_addr; + node.port = remote_port; + node.type = devtype::datalink; + + sockets.append(node); + qWarning() << "UdpSocket open:" + << remote_addr + << local_port + << remote_port; + + isSuccess = true; + emit showMessage(tr("UdpSocket open"),10000); + } + else + { + clientsock->close(); + isSuccess = false; + qWarning() << "sock open failure" << clientsock->state(); + delete clientsock; + clientsock = nullptr; + } + } + else + { + isSuccess = false; + clientsock->close(); + qWarning("sock is not binded."); + delete clientsock; + clientsock = nullptr; + } + + return isSuccess; +} + + +bool DLink::setup_multicast_recieve(const QHostAddress &ip, const quint16 &port, QHostAddress newip, quint16 newport) +{ + bool isSuccess = false; + + foreach (clientNode node, sockets) { + if(node.sock) + { + if((node.addr == QHostAddress(ip))&&(node.port == port)) + { + if(node.sock->isOpen()) + { + if(node.sock->state() != QAbstractSocket::UnconnectedState) + { + node.sock->leaveMulticastGroup(node.addr); + } + node.sock->disconnectFromHost(); + node.sock->close(); + } + //鏂帀鎵鏈夌殑杩炴帴 + disconnect(node.sock,nullptr,nullptr,nullptr); + + node.sock->deleteLater(); + + sockets.removeAt(sockets.indexOf(node)); + + } + } + } + + QHostAddress m_ip = ip; + quint16 m_port = port; + + if((newip != QHostAddress("0,0,0,0")) && + (newport != 0)) + { + m_ip = newip; + m_port = newport; + } + + + QUdpSocket *clientsock = new QUdpSocket(this); + clientsock->setProxy(QNetworkProxy::DefaultProxy);//蹇呴』鍏堣缃笉浠g悊锛屽惁鍒欒繛涓嶄笂 + + //clientsock->open(QIODevice::ReadWrite); + if(clientsock->bind(QHostAddress::AnyIPv4,m_port,QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint))// + { + if (clientsock->joinMulticastGroup(QHostAddress(m_ip))) + { + // clientsock->setSocketOption(QAbstractSocket::SendBufferSizeSocketOption,1024*1024*100); + clientsock->setSocketOption (QAbstractSocket::ReceiveBufferSizeSocketOption, 1024*1024*100); + clientsock->setSocketOption(QAbstractSocket::LowDelayOption, 1); + clientsock->setSocketOption(QAbstractSocket::KeepAliveOption, 1); + //clientsock->setSocketOption(QAbstractSocket::MulticastTtlOption, 10); + //clientsock->setSocketOption(QAbstractSocket::MulticastLoopbackOption, 0);//绂佹鏈満鎺ユ敹 + + clientNode node; + node.sock = clientsock; + node.addr = m_ip; + node.port = m_port; + node.type = devtype::datalink; + + sockets.append(node); + qWarning() << "multicast open recieve:" + << node.addr + << node.port; + + isSuccess = true; + + + connect(clientsock, SIGNAL(readyRead()), + this, SLOT(readPendingDatagramsClient())); + + emit showMessage(tr("Bind and join the multicast group"),10000); + } + else + { + clientsock->close(); + isSuccess = false; + qWarning() << "sock open failure" << clientsock->state(); + delete clientsock; + clientsock = nullptr; + emit showMessage(tr("Fail to join multicast group."),10000); + } + } + else + { + isSuccess = false; + clientsock->close(); + qWarning("sock is not binded."); + delete clientsock; + clientsock = nullptr; + emit showMessage(tr("Fail to bind multicast socket."),10000); + } + + return isSuccess; +} + + +bool DLink::setup_multicast_transmit(const QHostAddress &ip,const quint16 &port, QHostAddress newip, quint16 newport) +{ + bool isSuccess = false; + + foreach (clientNode node, sockets) { + if(node.sock) + { + if((node.addr == QHostAddress(ip))&&(node.port == port)) + { + if(node.sock->isOpen()) + { + if(node.sock->state() != QAbstractSocket::UnconnectedState) + { + node.sock->leaveMulticastGroup(node.addr); + } + node.sock->disconnectFromHost(); + node.sock->close(); + } + //鏂帀鎵鏈夌殑杩炴帴 + disconnect(node.sock,nullptr,nullptr,nullptr); + + node.sock->deleteLater(); + + sockets.removeAt(sockets.indexOf(node)); + + } + } + } + + QHostAddress m_ip = ip; + quint16 m_port = port; + + if((newip != QHostAddress("0,0,0,0")) && + (newport != 0)) + { + m_ip = newip; + m_port = newport; + } + + + QUdpSocket *clientsock = new QUdpSocket(this); + clientsock->setProxy(QNetworkProxy::DefaultProxy);//蹇呴』鍏堣缃笉浠g悊锛屽惁鍒欒繛涓嶄笂 + + clientsock->setSocketOption(QAbstractSocket::SendBufferSizeSocketOption,1024); + //clientsock->setSocketOption (QAbstractSocket::ReceiveBufferSizeSocketOption, 1024*1024*100); + clientsock->setSocketOption(QAbstractSocket::LowDelayOption, 1); + clientsock->setSocketOption(QAbstractSocket::KeepAliveOption, 1); + + clientNode node; + node.sock = clientsock; + node.addr = m_ip; + node.port = m_port; + node.type = devtype::datalink; + + sockets.append(node); + qWarning() << "multicast open transmit:" + << node.addr + << node.port; + + isSuccess = true; + + + emit showMessage(tr("Bind and join the multicast group"),10000); + + return isSuccess; +} + + +bool DLink::setup_multicast_close(const QHostAddress &ip,const quint16 &port) +{ + bool isSuccess = false; + + foreach (clientNode node, sockets) { + if(node.sock) + { + if((node.addr == QHostAddress(ip))&&(node.port == port)) + { + if(node.sock->isOpen()) + { + node.sock->close();//鍏堝叧闂啀閫鍑 + node.sock->leaveMulticastGroup(node.addr); + } + //鏂帀鎵鏈夌殑杩炴帴 + disconnect(node.sock,nullptr,nullptr,nullptr); + + node.sock->deleteLater(); + + sockets.removeAt(sockets.indexOf(node)); + + qWarning() << "multicast delete:" + << node.addr + << node.port; + + isSuccess = true; + } + } + } + + return isSuccess; +} + + + + +void DLink::readPendingDatagramsSerialPort(void) +{ + //QElapsedTimer time; + + //time.start(); + + + QObject *obj = sender(); + + if(obj) + { + QSerialPort *serialport = qobject_cast(obj); + if(serialport) + { + QByteArray datagram = serialport->readAll(); + + //inCount += datagram.size(); + + foreach (serialNode node, serials) { + if(node.port) + { + if(node.port == serialport) + { + emit recieve(node.name,datagram); + node.in.count += datagram.size(); + node.in.frame +=1; + serials.replace(serials.indexOf(node),node); + break; + } + } + } + } + } + + //qDebug() << "dlink recieve time:" << time.nsecsElapsed() / 1000000.0 ; + +} + + +void DLink::readPendingDatagramsClient(void) +{ + //QElapsedTimer time; + + //time.start(); + + QObject *obj = sender(); + + if(obj) + { + QUdpSocket *clientsock = qobject_cast(obj); + if(clientsock) + { + //QUdpSocket::readChannelFinished() + + while (clientsock->hasPendingDatagrams()) { + QByteArray datagram; + datagram.resize(clientsock->pendingDatagramSize()); + + QHostAddress address;//ip + quint16 port;//绔彛鍙 + + clientsock->readDatagram(datagram.data(), datagram.size(),&address,&port); + + //emit recieve(address,port,datagram); + + foreach (clientNode node, sockets) { + if(node.sock) + { + if(node.sock == clientsock) + { + emit recieve(node.addr,node.port,datagram); + //qDebug() << "dlink" << QThread::currentThread(); + + node.in.count += datagram.size(); + node.in.frame +=1; + sockets.replace(sockets.indexOf(node),node); + + break; + } + } + } + } + } + } + //qDebug() << "dlink recieve time:" << time.nsecsElapsed() / 1000000.0 ; +} + + diff --git a/dlink/dlink.h b/dlink/dlink.h new file mode 100644 index 0000000..703bedd --- /dev/null +++ b/dlink/dlink.h @@ -0,0 +1,185 @@ +#ifndef DLINK_H +#define DLINK_H + +#include +#include "QtSerialPort" +#include +#include +#include "QDebug" +#include +#include "QEvent" +#include "QNetworkInterface" + + +QT_BEGIN_NAMESPACE + + +#ifdef QtDlink +#include +class DLINKSHARED_EXPORT DLink : public QObject { +#else +class DLink : public QObject +{ +#endif + Q_OBJECT + //Q_DECLARE_PRIVATE(DLink) + + enum devtype{ + ganeral = 0, + datalink, + remote, + rtk, + video, + exportinfo + }; + + + typedef struct { + + uint64_t total = 0; + uint64_t count = 0;//鎬诲瓧鑺傛暟 + uint64_t lastcount = 0;//涓婁竴娆″瓧鑺傛暟 + uint64_t rate = 0;//姣忕瀛楄妭鏁 + uint64_t frame = 0;//鍖 + uint64_t lastframe = 0;//涓婁竴娆″寘 + qreal frequency = 0;//鍖呴鐜 + }_node_status; + + + struct clientNode{ + QUdpSocket * sock; + QHostAddress addr; + quint16 port; + devtype type; + + _node_status in; + _node_status out; + + uint32_t tansmit_mode; + + bool operator==(const clientNode& other) + { + if (this->sock == other.sock) + { + return true; + } + return false; + } + }; + + struct serialNode{ + QSerialPort * port; + QString name; + qint32 baud; + QSerialPort::Parity parity; + devtype type; + + _node_status in; + _node_status out; + + bool operator==(const serialNode& other) + { + if (this->name == other.name) + { + return true; + } + return false; + } + }; + + +public: + explicit DLink(QObject *parent = nullptr); + ~DLink(); + + //璁剧疆涓插彛锛屾湰杞欢娌$敤鍒 + Q_INVOKABLE bool PortSetup(const QString &name, qint32 baudrate = 115200, QSerialPort::Parity parity = QSerialPort::NoParity); + + Q_INVOKABLE bool PortState(const QString &name); + + Q_INVOKABLE bool PortStop(const QString &name); + + //璁剧疆UDP锛屾湰杞欢娌$敤鍒 + Q_INVOKABLE bool setupClient(const QHostAddress &local_addr,int local_port,const QHostAddress &remote_addr,int remote_port); + + //璁剧疆缁勬挱鎺ユ敹 + Q_INVOKABLE bool setup_multicast_recieve(const QHostAddress &ip, const quint16 &port, QHostAddress newip = QHostAddress("0,0,0,0"), quint16 newport = 0); + + //璁剧疆缁勬挱鍙戦 + Q_INVOKABLE bool setup_multicast_transmit(const QHostAddress &ip, const quint16 &port, QHostAddress newip = QHostAddress("0,0,0,0"), quint16 newport = 0); + + //璁剧疆缁勬挱鍏抽棴 + Q_INVOKABLE bool setup_multicast_close(const QHostAddress &ip,const quint16 &port); + + bool isExportInfo = true; + +signals: + void showMessage(const QString &message,int TimeOut = 0); + + void recieveMessage(quint32 src,QByteArray data); + + + void status(QHostAddress ip, quint16 port, qreal in_all, qreal in_rate, qreal in_frq,qreal out_all, qreal out_rate, qreal out_frq); + + void recieve(QHostAddress ip,quint16 port,QByteArray data); + + void recieve(QString name,QByteArray data); + + + +public slots: + + void readPendingDatagramsSerialPort(void); + + void readPendingDatagramsClient(void); + + int SendMessageTo(quint8 ch, quint8 *msg, quint16 len); + + void transmit(QHostAddress ip,quint16 port,QByteArray data); + + void transmit(QString name,QByteArray data);//QOverload::of(&DLink::recieve) 淇″彿閲嶈浇鐨勮皟鐢ㄦ柟寮 + +private slots: + + +protected: + + enum SourceType{ + + c_sock = 0, + s_port = 1, + p_port = 2, + }; + + + + + QMap cnts_in; + QMap cnts_out; + + QList sockets; + QList serials; + + QMap Device; + + + quint32 outCount = 0; + quint32 inCount = 0; + quint32 errCount = 0; + quint32 frameCount = 0; + + double out_bits = 0; + double in_bits = 0; + double rssi_bits = 0; + + +}; + + + + +QT_END_NAMESPACE + + + +#endif // DLINK_H diff --git a/dlink/dlink.pri b/dlink/dlink.pri new file mode 100644 index 0000000..a009dc8 --- /dev/null +++ b/dlink/dlink.pri @@ -0,0 +1,9 @@ + +QT += core gui network +QT += serialport + +HEADERS += \ + $$PWD/dlink.h + +SOURCES += \ + $$PWD/dlink.cpp diff --git a/dlink/dlink.pro b/dlink/dlink.pro new file mode 100644 index 0000000..631dfe0 --- /dev/null +++ b/dlink/dlink.pro @@ -0,0 +1,108 @@ + +QT += serialport +QT += network + + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = Dlink + +# Capture whether this is a release/debug build. +CONFIG(debug, debug|release) { + # Target name. + TARGET = $$join(TARGET,,,d) +} + + +TEMPLATE = lib + + +DEFINES += DLINK_LIBRARY \ + QtDlink + +CONFIG += c++11 \ + dll \ + resources_big \ + warn_off + +DESTDIR = $$PWD/../bin +MOC_DIR = $$PWD/../build +OBJECTS_DIR = $$PWD/../build + +TRANSLATIONS += DLINK_zh_CN.ts + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +HEADERS += \ + $$PWD/dlink.h \ + $$PWD/dlinkglobal.h + +SOURCES += \ + $$PWD/dlink.cpp + +#鍔犲叆绗笁鏂瑰簱 +INCLUDEPATH += $$DESTDIR/include + +#娣诲姞mavlink鐩綍 +INCLUDEPATH += $$PWD/../mavlink \ + $$PWD/../mavlink/ardupilotmega \ + $$PWD/../mavlink/common \ + $$PWD/../mavlink/icarous \ + $$PWD/../mavlink/uAvionix \ + $$PWD/../mavlink/XYK \ + $$PWD/../mavlink/message_definitions + + + + + + + +# Capture whether this is a release/debug build. +CONFIG(debug, debug|release) { + LIBS += -L$$DESTDIR -lMavLinkNoded +} +CONFIG(release, debug|release) { + LIBS += -L$$DESTDIR -lMavLinkNode +} + + + + + + +win32|win64 { + src_dir = $$PWD\\*.h + dst_dir = $$PWD\\..\\bin\\include\\ + # dst_dir 鏈鍚庣殑 \\ 鏄繀椤荤殑锛岀敤鏉ユ爣绀 xcopy 鍒颁竴涓枃浠跺す锛岃嫢涓嶅瓨鍦紝鍒涘缓涔 + + # Replace slashes in paths with backslashes for Windows + src_dir ~= s,/,\\,g + dst_dir ~= s,/,\\,g + + system(xcopy $$src_dir $$dst_dir /y /e) +} + +unix { + src_dir = $$PWD/*.h + dst_dir = $$PWD/../bin/include/ + + !exists($$dst_dir): system(mkdir -p $$dst_dir) + + system(cp $$src_dir $$dst_dir -arf ) +} + + + + + diff --git a/dlink/dlinkglobal.h b/dlink/dlinkglobal.h new file mode 100644 index 0000000..be051d0 --- /dev/null +++ b/dlink/dlinkglobal.h @@ -0,0 +1,22 @@ +锘#ifndef DLINKGLOBAL_H +#define DLINKGLOBAL_H + +#include + +QT_BEGIN_NAMESPACE + +#ifdef QtDlink + #if defined(DLINK_LIBRARY) + # define DLINKSHARED_EXPORT Q_DECL_EXPORT + #else + # define DLINKSHARED_EXPORT Q_DECL_IMPORT + #endif +#else +define DLINKSHARED_EXPORT +#endif + + +QT_END_NAMESPACE + + +#endif // DLINKGLOBAL_H diff --git a/mainwindow.cpp b/mainwindow.cpp index 41a26bd..758fddd 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,15 +1,1220 @@ #include "mainwindow.h" #include "ui_mainwindow.h" + + +MODEBUS_t modbus; + + + +typedef enum { + + ReadCoils = 0x01, + ReadDiscreteInputs = 0x02, + ReadHoldingRegisters = 0x03, + ReadInputRegisters = 0x04, + WriteSingleCoil = 0x05, + WriteSingleRegister = 0x06, + ReadExceptionStatus = 0x07, + Diagnostics = 0x08, + GetCommEventCounter = 0x0B, + GetCommEventLog = 0x0C, + WriteMultipleCoils = 0x0F, + WriteMultipleRegisters = 0x10, + ReportSlaveID = 0x11, + ReadFileRecord = 0x14, + WriteFileRecord = 0x15, + MaskWriteRegister = 0x16, + Read_WriteMultipleregisters = 0x17, + ReadFIFOQueue = 0x18, + EncapsulatedInterfaceTransport = 0x2B + +}modbus_cmd_e; + +void delay_ms(unsigned int msec) +{ + QTime _Timer = QTime::currentTime().addMSecs(msec); + while( QTime::currentTime() < _Timer ) + QCoreApplication::processEvents(QEventLoop::AllEvents, 100); +} + + +static uint16_t Modbus_CRC16(uint8_t* data, uint16_t length) +{ + uint16_t crc = 0xFFFF; + for (int i = 0; i < length; i++) { + crc ^= data[i]; + + for (int j = 0; j < 8; j++) { + if ((crc & 0x0001) != 0) { + crc >>= 1; + crc ^= 0xA001; + } else { + crc >>= 1; + } + } + } + + return crc; +} + +void Modbus_Write(uint8_t* data, size_t len) +{ + //鍙兘涓鍖呬竴鍖呭彂锛屼笉鍏佽涓娆″彂寰堝鍖 + //SERIAL_Write(&serial3,data,len); + + + +} + + + +void Modbus_Poll(QByteArray data) +{ + + //鏀跺埌涓绘満淇℃伅锛 缁跨伅闂 + + size_t len = data.size(); + + if(len > 4)//杩欎釜闀垮害涓嶅嚭鎰忓鐨勮瘽鏄竴鍖呯殑闀垮害 + { + if(data[0] != 0x00) + { + uint16_t crc = data[len - 2] | (data[len - 1] << 8); + + if(crc == Modbus_CRC16((uint8_t *)data.data(),len-2)) + { + + + //閫氳鎴愬姛锛岀孩鐏棯鐑 + /* + 0x03 read + 0x06 write + 0x10 write multi + */ + + //璧嬪肩粰modbus缁撴瀯浣 + modbus.addr = data[0]; + modbus.cmd = data[1]; + modbus.crc = crc; + memcpy(modbus.payload,&data.data()[2],len - 4); + + + switch(modbus.cmd) + { + case ReadCoils: + { + + }break; + + case ReadDiscreteInputs: + { + + uint16_t regis = modbus.payload[0] | (modbus.payload[1] << 8); + uint16_t value = modbus.payload[2] | (modbus.payload[3] << 8); + + + + }break; + case ReadHoldingRegisters: + { + // 0x03 + /* + reg value + 0xFF 0xFFFFFFFF + + 0x00 Di + + */ + + + uint16_t addr = modbus.payload[1] << 0 | + modbus.payload[0] << 8; + + uint16_t cmd = modbus.payload[3] << 0 | + modbus.payload[2] << 8; + + switch(addr) + { + case 0x00: + {//DI + + uint16_t regis = 0x0000; + uint16_t value = 0x00; + + + uint8_t sendbuff[50] = {0}; + + size_t send_len = 0; + + sendbuff[send_len++] = modbus.addr; + sendbuff[send_len++] = modbus.cmd; + sendbuff[send_len++] = regis; + sendbuff[send_len++] = regis >> 8; + sendbuff[send_len++] = value; + sendbuff[send_len++] = value >> 8; + uint16_t crc_f = Modbus_CRC16(sendbuff,send_len); + sendbuff[send_len++] = crc_f; + sendbuff[send_len++] = crc_f >> 8; + + + + Modbus_Write(sendbuff,send_len); + + + }break; + case 0x01: + {//ADC + uint16_t regis = 0x0001; + uint16_t value = 0x00; + + + uint8_t sendbuff[50] = {0}; + + size_t send_len = 0; + + sendbuff[send_len++] = modbus.addr; + sendbuff[send_len++] = modbus.cmd; + sendbuff[send_len++] = regis; + sendbuff[send_len++] = regis >> 8; + sendbuff[send_len++] = value; + sendbuff[send_len++] = value >> 8; + uint16_t crc_f = Modbus_CRC16(sendbuff,send_len); + sendbuff[send_len++] = crc_f; + sendbuff[send_len++] = crc_f >> 8; + + + + Modbus_Write(sendbuff,send_len); + }break; + case 0x02: + {//褰撳墠浣嶇疆 + + }break; + } + + }break; + case ReadInputRegisters: + { + //Modbus_Write(buff,len); + }break; + case WriteSingleCoil: + { + + }break; + case WriteSingleRegister: + {//0x06 + uint16_t addr = modbus.payload[1] << 0 | + modbus.payload[0] << 8; + + uint16_t cmd = modbus.payload[3] << 0 | + modbus.payload[2] << 8; + + switch(addr) + { + case 0x00://璁剧疆DO杈撳嚭 + { + //SYS_setDo(1,(cmd & 0x01)); + //SYS_setDo(2,(cmd & 0x02)); + }break; + case 0x01://璁剧疆鐢垫満浣胯兘 + { + //MOTOR_setEn((cmd & 0x01)?(MOTOR_ENABLE):(MOTOR_DISABLE)); + }break; + case 0x02://璁剧疆鐢垫満鏂瑰悜 + { + //MOTOR_setDir((cmd & 0x8000)?(MOTOR_DIR_CW):(MOTOR_DIR_CCW)); + }break; + case 0x03://璁剧疆鐢垫満缁嗗垎 + { + //MOTOR_setMS(MOTOR_MS_1); + }break; + case 0x04://璁剧疆鐢垫満姝ユ暟 + { + //MOTOR_setStep(cmd & 0x7fff); + }break; + case 0x05://璁剧疆鐢垫満姝ユ暟锛屽悓鏃跺惎鍔 + { + //MOTOR_setDir((cmd & 0x8000)?(MOTOR_DIR_CW):(MOTOR_DIR_CCW)); + //MOTOR_setStep(cmd & 0x7fff);//鏈澶32767姝 + //MOTOR_setEn(MOTOR_ENABLE); + }break; + case 0x06://鑾峰彇鍘熺偣 + { + //MOTOR_setGetFlag(MOTOR_GET_MIN); + // MOTOR_setDir(MOTOR_DIR_CCW); + //MOTOR_setStep(MOTOR_MAX_STEP); + //MOTOR_setEn(MOTOR_ENABLE); + + + }break; + case 0x07://鑾峰彇鏈澶у + { + //MOTOR_setLenght(0); + //MOTOR_setGetFlag(MOTOR_GET_MAX); + //MOTOR_setDir(MOTOR_DIR_CW); + //MOTOR_setStep(MOTOR_MAX_STEP); + //MOTOR_setEn(MOTOR_ENABLE); + }break; + case 0x08:// + { + + }break; + + } + + }break; + case ReadExceptionStatus: + { + //Modbus_Write(buff,len); + }break; + case Diagnostics: + { + //Modbus_Write(buff,len); + }break; + case GetCommEventCounter: + { + //Modbus_Write(buff,len); + }break; + case GetCommEventLog: + { + //Modbus_Write(buff,len); + }break; + case WriteMultipleCoils: + { + //Modbus_Write(buff,len); + }break; + case WriteMultipleRegisters: + { + //0x10 + + //鐢ㄦ潵鍐欓厤缃暟鎹 + + + + + + + + }break; + case ReportSlaveID: + { + uint16_t regis = modbus.cmd; + uint16_t value = modbus.addr; + + + uint8_t sendbuff[50] = {0}; + + size_t send_len = 0; + + sendbuff[send_len++] = modbus.addr; + sendbuff[send_len++] = modbus.cmd; + sendbuff[send_len++] = regis; + sendbuff[send_len++] = regis >> 8; + sendbuff[send_len++] = value; + sendbuff[send_len++] = value >> 8; + uint16_t crc_f = Modbus_CRC16(sendbuff,send_len); + sendbuff[send_len++] = crc_f; + sendbuff[send_len++] = crc_f >> 8; + + + + Modbus_Write(sendbuff,send_len); + }break; + case ReadFileRecord: + { + //Modbus_Write(buff,len); + }break; + case WriteFileRecord: + { + //Modbus_Write(buff,len); + }break; + case MaskWriteRegister: + { + //Modbus_Write(buff,len); + }break; + case Read_WriteMultipleregisters: + { + //Modbus_Write(buff,len); + }break; + case ReadFIFOQueue: + { + //Modbus_Write(buff,len); + }break; + case EncapsulatedInterfaceTransport: + { + //Modbus_Write(buff,len); + }break; + + } + } + } + } +} + + + + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) + , dlink(new DLink) { ui->setupUi(this); + + + Parser_init(&parser); + Packer_init(&packer); + + + QIntValidator *baudValidator = new QIntValidator(0, 9999999); + + ui->lineEdit_com_baud->setValidator(baudValidator); + + ui->pushButton_dev_flush->setEnabled(false); + + + QIntValidator *intValidator = new QIntValidator(0, 9999999); + + + ui->comboBox_setMode->addItem("Init",0); + ui->comboBox_setMode->addItem("Discharge",1); + ui->comboBox_setMode->addItem("Charge",2); + ui->comboBox_setMode->addItem("Balance",3); + ui->comboBox_setMode->addItem("Storage",4); + ui->comboBox_setMode->setCurrentIndex(2); + + ui->comboBox_setRun->addItem("Stop",0); + ui->comboBox_setRun->addItem("Start",1); + ui->comboBox_setRun->setCurrentIndex(1); + + ui->comboBox_setType->addItem("LiHv",1); + ui->comboBox_setType->addItem("LiPo",2); + ui->comboBox_setType->addItem("Lilon",3); + ui->comboBox_setType->addItem("LiFe",4); + ui->comboBox_setType->addItem("LiXX",5); + ui->comboBox_setType->addItem("NiZn",6); + ui->comboBox_setType->addItem("NiCd",7); + ui->comboBox_setType->addItem("NiMH",8); + ui->comboBox_setType->addItem("Pb",9); + ui->comboBox_setType->setCurrentIndex(1); + + ui->comboBox_setRelay_in->addItem("Close",0); + ui->comboBox_setRelay_in->addItem("Open",1); + ui->comboBox_setRelay_in->setCurrentIndex(1); + + ui->comboBox_setRelay_out->addItem("Close",0); + ui->comboBox_setRelay_out->addItem("Open",1); + ui->comboBox_setRelay_out->setCurrentIndex(1); + + ui->comboBox_setFan->addItem("Close",0); + ui->comboBox_setFan->addItem("Open",1); + ui->comboBox_setFan->setCurrentIndex(1); + + + + + + + QObjectList obj = ui->groupBox_BAT_STATUS->children(); + + for(int i = 0;i < obj.size();i++) + { + QLabel *lab = qobject_cast(obj[i]); + + if(lab) + { + if(lab->objectName().contains("label_B")) + { + QStringList namelist = lab->objectName().split('B'); + + if(namelist.size() >=2) + { + QString name = namelist[1]; + lab_map.insert(name.toInt(),lab); + } + } + } + } + + QTimer *serial_timer = new QTimer(); + serial_timer->setInterval(2000); + + connect(this,&MainWindow::destroyed,serial_timer,&QTimer::deleteLater); + + connect(serial_timer,&QTimer::timeout,this,[=](){ + + QStringList str_list; + for(int idx=0; idxcomboBox_com_name->count(); idx++){ + str_list.append(ui->comboBox_com_name->itemText(idx)); + } + + + QList ports = QSerialPortInfo::availablePorts(); + if (ports.count() == str_list.count()) { + return; + } + + ui->comboBox_com_name->clear(); + // 閬嶅巻褰撳墠宸叉湁涓插彛 + foreach (QSerialPortInfo port, ports) { + + ui->comboBox_com_name->addItem(port.portName()); + } + + + + + }); + + serial_timer->start(); + + //璁剧疆鏁版嵁杩炴帴鍦ㄥ彟澶栦竴涓嚎绋 + connect(dlink,&DLink::showMessage,this,&MainWindow::showMessage); + + dlink->moveToThread(&dlink_thread); + dlink_thread.start(); + dlink_thread.setPriority(QThread::TimeCriticalPriority); + + + + connect(dlink,QOverload::of(&DLink::recieve),this,[=](QString name,QByteArray data){ + + size_t len = data.size(); + if(len) + { + int rst = -1; + for(int i = 0;idoubleSpinBox_setVP->setValue(src.F); + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->doubleSpinBox_setVI->setValue(src.F); + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->doubleSpinBox_setVD->setValue(src.F); + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->doubleSpinBox_setCP->setValue(src.F); + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->doubleSpinBox_setCI->setValue(src.F); + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->doubleSpinBox_setCD->setValue(src.F); + }break; + case 0x10: + { + size_t recv_len = 0; + union {float F; uint32_t W;int32_t w; uint16_t H[2];int16_t h[2]; uint8_t B[4];}src; + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->label_voltage_pwr->setText(QString::number(src.F,'f',2)); + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->label_voltage_buck_in->setText(QString::number(src.F,'f',2)); + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->label_voltage_buck_out->setText(QString::number(src.F,'f',2)); + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->label_voltage_bat->setText(QString::number(src.F,'f',2)); + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->label_voltage_current->setText(QString::number(src.F,'f',2)); + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->label_voltage_temp->setText(QString::number(src.F,'f',2)); + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->label_cmd_voltage->setText(QString::number(src.F,'f',2)); + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->label_cmd_current->setText(QString::number(src.F,'f',2)); + }break; + case 0x11: + { + size_t recv_len = 0; + union {float F; uint32_t W;int32_t w; uint16_t H[2];int16_t h[2]; uint8_t B[4];}src; + + for(int i = 0;i<24;i++) + { + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->label_B1->setText(QString::number(src.F,'f',2)); + + + QLabel *lab = lab_map.value(i+1); + + if(lab) + { + lab->setText(QString::number(src.F,'f',2)); + } + + } + + + }break; + case 0x12: + { + size_t recv_len = 0; + union {float F; uint32_t W;int32_t w; uint16_t H[2];int16_t h[2]; uint8_t B[4];}src; + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->label_POWER_PWM->setText(QString::number(src.w)); + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->label_relay_in_state->setText(QString::number(src.W)); + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->label_relay_out_state->setText(QString::number(src.W)); + + src.B[0] = parser.buff[recv_len++]; + src.B[1] = parser.buff[recv_len++]; + src.B[2] = parser.buff[recv_len++]; + src.B[3] = parser.buff[recv_len++]; + ui->label_FAN_PWM->setText(QString::number(src.W)); + + }break; + } + } + } + + + + }); + + + connect(ui->pushButton_com_setting,&QPushButton::clicked,this,[=](){ + + if(ui->pushButton_com_setting->text() == tr("Open")) + { + QString name = ui->comboBox_com_name->currentText(); + qint32 baud = ui->lineEdit_com_baud->text().toUInt(); + + if(name.size() > 0) + { + bool ret; + QMetaObject::invokeMethod(dlink, "PortSetup", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(bool, ret), + Q_ARG(const QString &, name), + Q_ARG(qint32 , baud), + Q_ARG(QSerialPort::Parity, QSerialPort::NoParity) + ); + + if(ret) + { + ui->pushButton_com_setting->setText(tr("Close")); + + ui->lineEdit_com_baud->setEnabled(false); + ui->comboBox_com_name->setEnabled(false); + + ui->pushButton_dev_flush->setEnabled(true); + } + + qDebug() << ret << name; + } + } + else + { + QString name = ui->comboBox_com_name->currentText(); + qint32 baud = ui->lineEdit_com_baud->text().toUInt(); + + if(name.size() > 0) + { + bool ret; + QMetaObject::invokeMethod(dlink, "PortStop", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(bool, ret), + Q_ARG(const QString &, name) + ); + + if(ret) + { + ui->pushButton_com_setting->setText(tr("Open")); + + ui->lineEdit_com_baud->setEnabled(true); + ui->comboBox_com_name->setEnabled(true); + + ui->pushButton_dev_flush->setEnabled(false); + } + + qDebug() << ret << name; + } + } + }); + + + connect(ui->pushButton_dev_flush,&QPushButton::clicked,dlink,[=](){ + + for(uint16_t i = 0x01;i <= 0xFF;i++) + { + + QByteArray data; + + uint8_t cmd = 0x11; + uint16_t regis = 0x0000; + uint16_t value = 0x0000; + + uint8_t sendbuff[50] = {0}; + + size_t send_len = 0; + + sendbuff[send_len++] = i; + sendbuff[send_len++] = cmd; + sendbuff[send_len++] = regis >> 8; + sendbuff[send_len++] = regis; + sendbuff[send_len++] = value >> 8; + sendbuff[send_len++] = value; + uint16_t crc_f = Modbus_CRC16(sendbuff,send_len); + sendbuff[send_len++] = crc_f; + sendbuff[send_len++] = crc_f >> 8; + + data.setRawData((char *)sendbuff,send_len); + + + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + delay_ms(10); + } + }); + +//==============================鎸夐敭鎸囦护=============================== + + connect(ui->pushButton_setNormalMode,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { uint32_t W; uint8_t B[4];}src; + + size_t send_len = 0; + + src.W = (uint32_t)0x00;//setPower + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + src.W = (uint32_t)0x00; + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x00,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + connect(ui->pushButton_setPower,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { uint32_t W; uint8_t B[4];}src; + + size_t send_len = 0; + + src.W = (uint32_t)0x01;//setPower + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + src.W = (uint32_t)ui->spinBox_setPower->value(); + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x00,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + connect(ui->pushButton_setRelay_in,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { uint32_t W; uint8_t B[4];}src; + + size_t send_len = 0; + + src.W = (uint32_t)0x02;//setRelayin + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + src.W = (uint32_t)ui->comboBox_setRelay_in->currentData().toUInt(); + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x00,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + connect(ui->pushButton_setRelay_out,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { uint32_t W; uint8_t B[4];}src; + + size_t send_len = 0; + + src.W = (uint32_t)0x03;//setRelayin + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + src.W = (uint32_t)ui->comboBox_setRelay_out->currentData().toUInt(); + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x00,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + connect(ui->pushButton_setFan,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { uint32_t W; uint8_t B[4];}src; + + size_t send_len = 0; + + src.W = (uint32_t)0x04;//setRelayin + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + src.W = (uint32_t)ui->comboBox_setFan->currentData().toUInt(); + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x00,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + connect(ui->pushButton_readParam,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { uint32_t W; uint8_t B[4];}src; + + size_t send_len = 0; + + src.W = (uint32_t)0x01;//璇诲彇PID + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x01,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + connect(ui->pushButton_setVP,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { float f; uint8_t B[4];}src; + + size_t send_len = 0; + + src.f = (float)ui->doubleSpinBox_setVP->value(); + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x02,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + connect(ui->pushButton_setVI,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { float f; uint8_t B[4];}src; + + size_t send_len = 0; + + src.f = (float)ui->doubleSpinBox_setVI->value(); + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x03,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + connect(ui->pushButton_setVD,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { float f; uint8_t B[4];}src; + + size_t send_len = 0; + + src.f = (float)ui->doubleSpinBox_setVD->value(); + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x04,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + connect(ui->pushButton_setCP,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { float f; uint8_t B[4];}src; + + size_t send_len = 0; + + src.f = (float)ui->doubleSpinBox_setCP->value(); + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x05,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + connect(ui->pushButton_setCI,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { float f; uint8_t B[4];}src; + + size_t send_len = 0; + + src.f = (float)ui->doubleSpinBox_setCI->value(); + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x06,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + connect(ui->pushButton_setCD,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { float f; uint8_t B[4];}src; + + size_t send_len = 0; + + src.f = (float)ui->doubleSpinBox_setCD->value(); + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x07,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + + connect(ui->pushButton_setMode,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { uint32_t W; uint8_t B[4];}src; + + size_t send_len = 0; + + src.W = (uint32_t)ui->comboBox_setMode->currentData().toUInt(); + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x10,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + connect(ui->pushButton_setRun,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { int32_t w; uint8_t B[4];}src; + + size_t send_len = 0; + + src.w = (int32_t)ui->comboBox_setRun->currentData().toUInt(); + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x11,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + connect(ui->pushButton_setNum,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { int32_t w; uint8_t B[4];}src; + + size_t send_len = 0; + + src.w = (int32_t)ui->spinBox_setNum->value(); + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x12,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + + connect(ui->pushButton_setType,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { int32_t w; uint8_t B[4];}src; + + size_t send_len = 0; + + src.w = (int32_t)ui->comboBox_setType->currentData().toUInt(); + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x13,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + connect(ui->pushButton_setCurrent,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { float f; uint8_t B[4];}src; + + size_t send_len = 0; + + src.f = (float)ui->doubleSpinBox_setCurrent->value(); + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x14,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + connect(ui->pushButton_setCapacity,&QPushButton::clicked,dlink,[=](){ + + QByteArray data; + uint8_t sendbuff[250] = {0}; + + union { float f; uint8_t B[4];}src; + + size_t send_len = 0; + + src.f = (float)ui->doubleSpinBox_setCapacity->value(); + + sendbuff[send_len++] = src.B[0]; + sendbuff[send_len++] = src.B[1]; + sendbuff[send_len++] = src.B[2]; + sendbuff[send_len++] = src.B[3]; + + send_len = Packer_pack(&packer,0x15,sendbuff,send_len); + + data.setRawData((char *)packer.buff,send_len); + dlink->transmit(ui->comboBox_com_name->currentText(),data); + + }); + + + + } MainWindow::~MainWindow() { + + dlink_thread.quit(); + dlink_thread.wait(); + delete ui; } +void MainWindow::showMessage(const QString &message,int TimeOut) +{ + //鐢ㄤ簬鍏ㄥ眬鏄剧ず鐘舵 + ui->statusbar->showMessage(message,TimeOut); +} + diff --git a/mainwindow.h b/mainwindow.h index 4643e32..958ecac 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -2,6 +2,27 @@ #define MAINWINDOW_H #include +#include "dlink/dlink.h" +#include "QList" +#include "QThread" +#include "QStandardItemModel" +#include "QLabel" +#include "ParsePack.h" + +typedef struct MODBUS_s { + + uint8_t addr; + uint8_t cmd; + uint16_t crc; + uint8_t payload[256]; + + +}MODEBUS_t; + +typedef MODEBUS_t* MODEBUS_ptr; + +extern MODEBUS_t modbus; + QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } @@ -15,7 +36,32 @@ public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); + + QThread dlink_thread; +public slots: + + + //void setSave(const QHostAddress &ip, const uint16_t &port, QByteArray data); + + void showMessage(const QString &message,int TimeOut = 0); private: Ui::MainWindow *ui; + + DLink *dlink = nullptr; + + + QList serial_list; + + + QList slave_list; + uint8_t slave_id = 0x40; + uint8_t master_id = 0x01; + + Parser_t parser; + Packer_t packer; + + QMap lab_map; + + }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index 1316f6c..d0b9392 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -6,233 +6,812 @@ 0 0 - 780 - 573 + 472 + 799 MainWindow - - - - 180 - 10 - 591 - 521 - - - - - - 10 - 10 - 271 - 191 - - - - HMI - - - - - 30 - 30 - 75 - 24 - - - - PushButton - - - - - - 130 - 30 - 75 - 24 - - - - PushButton - - - - - - - 10 - 210 - 571 - 301 - - - - MOTOR - - - - - 20 - 30 - 75 - 24 - - - - PushButton - - - - - - 20 - 70 - 75 - 24 - - - - PushButton - - - - - - 20 - 110 - 75 - 24 - - - - PushButton - - - - - - 20 - 150 - 75 - 24 - - - - PushButton - - - - - - 20 - 190 - 75 - 24 - - - - PushButton - - - - - - - 300 - 10 - 281 - 191 - - - - WEIGHT - - - - - 20 - 30 - 75 - 24 - - - - PushButton - - - - - - 120 - 30 - 75 - 24 - - - - PushButton - - - - - - 20 - 90 - 75 - 24 - - - - PushButton - - - - - - - - 10 - 10 - 160 - 521 - - - - - - - - - - - - Setting + + + + + + + + BAT_STATUS + + + + + + + TEMPERATURE + + + + + + + VALUE + + + + + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + + + + + BUCK_IN + + + + + + + VALUE + + + + + + + + + + + CURRENT + + + + + + + VALUE + + + + + + + + + + + BAT_IN + + + + + + + VALUE + + + + + + + + + + + BUCK_OUT + + + + + + + VALUE + + + + + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + + + + + POWER + + + + + + + VALUE + + + + + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + + + + + CMD VOL + + + + + + + VALUE + + + + + + + + + + + CMD CUR + + + + + + + VALUE + + + + + + - - - - Flush + + + + Setting + + + + + + + + Open + + + + + + + Flush + + + + + + + 115200 + + + + + + + READ + + + + + + + NORMAL + + + + + + + + + + BAT_CTRL + + + + + + + + 99999999.000000000000000 + + + 1300.000000000000000 + + + + + + + SET CAPACITY + + + + + + + + + + + + + + SET MODE + + + + + + + + + + + 1 + + + 24 + + + + + + + SET NUM + + + + + + + + + + + 10.000000000000000 + + + 0.300000000000000 + + + + + + + SET CURRENT + + + + + + + + + + + 0 + + + 999999999 + + + + + + + SET POWER + + + + + + + + + + + + + + SET TYPE + + + + + + + + + + + + + + SET RELAY IN + + + + + + + + + + + + + + SET RUN + + + + + + + + + + + + + + SET FAN + + + + + + + + + + + + + + SET RELAY OUT + + + + + + + + + + + + CTRL_STATUS + + + + + + + + 2 + + + -10000000.000000000000000 + + + 10000000.000000000000000 + + + 1.000000000000000 + + + + + + + SET VP + + + + + + + + + + + RELAY IN + + + + + + + VALUE + + + + + + + + + + + -10000000.000000000000000 + + + 10000000.000000000000000 + + + 1.000000000000000 + + + + + + + SET VI + + + + + + + + + + + 10.000000000000000 + + + 1.000000000000000 + + + + + + + SET CI + + + + + + + + + + + -10000000.000000000000000 + + + 10000000.000000000000000 + + + 1.000000000000000 + + + + + + + SET CP + + + + + + + + + + + POWER + + + + + + + VALUE + + + + + + + + + + + FAN + + + + + + + VALUE + + + + + + + + + + + RELAY OUT + + + + + + + VALUE + + + + + + + + + + + -10000000.000000000000000 + + + 10000000.000000000000000 + + + 1.000000000000000 + + + + + + + SET VD + + + + + + + + + + + 10.000000000000000 + + + 1.000000000000000 + + + + + + + SET CD + + + + + + - - - + + + 0 0 - 780 + 472 22