1 Star 0 Fork 0

明哥/bilang_modbus_2

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
mymessagehandlethread.cpp 19.86 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
#include "mymessagehandlethread.h"
#include <QApplication>
#include <QtDebug>
#include "systemstatus.h"
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QTime>
extern SystemStatus *pStatusWindow;
extern QSerialPort ModbusSerial;
QByteArray ModbusReceiveBuf;
uint16_t switch_msg = 0;
uint16_t switch_control = 0;
MyMessageHandleThread::MyMessageHandleThread(QObject *parent)
: QThread(parent)
{
moveToThread(this);
qDebug("消息处理构造函数");
qDebug()<<"构造函数thread thread:"<<currentThreadId();
}
MyMessageHandleThread::~MyMessageHandleThread()
{
qDebug("消息处理析构函数");
}
void MyMessageHandleThread::run()
{
qDebug()<<"thread thread:"<<currentThreadId();
pModbusSerial = new QSerialPort;
//设置串口名
pModbusSerial->setPortName("COM7");
//打开串口
pModbusSerial->open(QIODevice::ReadWrite);
//设置波特率
pModbusSerial->setBaudRate(QSerialPort::Baud19200);//设置波特率为115200
//设置数据位数
pModbusSerial->setDataBits(QSerialPort::Data8);//设置数据位8
//设置校验位
pModbusSerial->setParity(QSerialPort::NoParity);
//设置停止位
pModbusSerial->setStopBits(QSerialPort::OneStop);//停止位设置为1
//设置流控制
pModbusSerial->setFlowControl(QSerialPort::NoFlowControl);//设置为无流控制
//QObject::connect(pModbusSerial,SIGNAL(readyRead()),thread,SLOT(ReadData()));
QObject::connect(pModbusSerial,&QSerialPort::readyRead,this,&MyMessageHandleThread::ReadData);
exec();
}
void MyMessageHandleThread::howie_button_clicked()
{
qDebug("howie_button_clicked");
qDebug()<<"单机事件thread thread:"<<currentThreadId();
pStatusWindow->HowieButton->setText("Hello");
}
void MyMessageHandleThread::ModBusReadAll(void)
{
#if 1
//在这里模拟耗时操作,看看还能否被打断
uint8_t buf[20];
//当前温度
if(ModbusRead(0x01,0x03,0x0068,0x0002,buf) == true)
{
float temp = 0;
uint8_t test[4] = {0};
test[0] = buf[3];
test[1] = buf[2];
test[2] = buf[1];
test[3] = buf[0];
memcpy((uint8_t *)&temp,test,4);
pStatusWindow->CurrentTemp->setText(QString::number(temp) + "°C");
qDebug("当前温度读取成功");
}
else
{
qDebug("当前温度读取失败");
}
//设置温度
if(ModbusRead(0x01,0x03,0x0258,0x0002,buf) == true)
{
float temp = 0;
uint8_t test[4] = {0};
test[0] = buf[3];
test[1] = buf[2];
test[2] = buf[1];
test[3] = buf[0];
memcpy((uint8_t *)&temp,test,4);
pStatusWindow->SettingTemp->setText(QString::number(temp) + "°C");
qDebug("设置温度读取成功");
}
else
{
qDebug("设置温度读取失败");
}
//读取方案编号
if(ModbusRead(0x01,0x03,341,0x0001,buf) == true)
{
uint16_t tmp = 0;
uint8_t test[2] = {0};
test[0] = buf[1];
test[1] = buf[0];
memcpy((uint8_t *)&tmp,test,2);
pStatusWindow->label_current_num->setText(QString::number(tmp));
qDebug("方案编号读取成功");
}
else
{
qDebug("方案编号读取失败");
}
//读取当前段
if(ModbusRead(0x01,0x03,342,0x0001,buf) == true)
{
uint16_t tmp = 0;
uint8_t test[2] = {0};
test[0] = buf[1];
test[1] = buf[0];
memcpy((uint8_t *)&tmp,test,2);
pStatusWindow->label_current_sector->setText(QString::number(tmp));
qDebug("当前段读取成功");
}
else
{
qDebug("当前段读取失败");
}
//读取目标温度
if(ModbusRead(0x01,0x03,345,0x0002,buf) == true)
{
float temp = 0;
uint8_t test[4] = {0};
test[0] = buf[3];
test[1] = buf[2];
test[2] = buf[1];
test[3] = buf[0];
memcpy((uint8_t *)&temp,test,4);
pStatusWindow->label_target_temp->setText(QString::number(temp) + "°C");
qDebug("目标温度读取成功");
}
else
{
qDebug("目标温度读取失败");
}
//读取设置时间
if(ModbusRead(0x01,0x03,343,0x0001,buf) == true)
{
uint16_t tmp = 0;
uint8_t test[2] = {0};
test[0] = buf[1];
test[1] = buf[0];
memcpy((uint8_t *)&tmp,test,2);
pStatusWindow->label_setting_time->setText(QString::number(tmp) + "min");
qDebug("设置时间读取成功");
}
else
{
qDebug("设置时间读取失败");
}
//读取段运行时间
if(ModbusRead(0x01,0x03,344,0x0001,buf) == true)
{
uint16_t tmp = 0;
uint8_t test[2] = {0};
test[0] = buf[1];
test[1] = buf[0];
memcpy((uint8_t *)&tmp,test,2);
pStatusWindow->label_sector_time->setText(QString::number(tmp) + "min");
qDebug("段运行时间读取成功");
}
else
{
qDebug("段运行时间读取失败");
}
//读取总运行时间
if(ModbusRead(0x01,0x03,350,0x0001,buf) == true)
{
uint16_t tmp = 0;
uint8_t test[2] = {0};
test[0] = buf[1];
test[1] = buf[0];
memcpy((uint8_t *)&tmp,test,2);
pStatusWindow->label_total_time->setText(QString::number(tmp) + "min");
qDebug("总运行读取成功");
}
else
{
qDebug("总运行读取失败");
}
//读取当前斜率
if(ModbusRead(0x01,0x03,112,0x0002,buf) == true)
{
float temp = 0;
uint8_t test[4] = {0};
test[0] = buf[3];
test[1] = buf[2];
test[2] = buf[1];
test[3] = buf[0];
memcpy((uint8_t *)&temp,test,4);
pStatusWindow->label_xielv->setText(QString::number(temp) + "°C");
qDebug("当前斜率读取成功");
}
else
{
qDebug("当前斜率读取失败");
}
//读取当前开关量
if(ModbusRead(0x01,0x03,0x02bc,0x0001,buf) == true)
{
//uint8_t test[2] = {0};
//test[0] = buf[1];
//test[1] = buf[0];
//memcpy((uint8_t *)&switch_msg,test,2);
switch_msg = 0;
switch_msg = buf[1];
UpdateSwitchStatus();
qDebug("当前开关量读取成功");
}
else
{
qDebug("当前开关量读取失败");
}
//读取暂停,终止开关量
if(ModbusRead(0x01,0x03,348,0x0001,buf) == true)
{
switch_control = 0;
switch_control = buf[1];
UpdateSwitchStatus();
qDebug("暂停,终止读取成功");
}
else
{
qDebug("暂停,终止读取失败");
}
#endif
}
void MyMessageHandleThread::ReadData()
{
qDebug("串口接收程序槽函数");
QByteArray buf;
buf = pModbusSerial->readAll();
if(!buf.isEmpty())
{
ModbusReceiveBuf += buf;
qDebug("buf len= %d;modbus len = %d; line = %d",buf.length(),ModbusReceiveBuf.length(),__LINE__);
}
buf.clear();
}
unsigned short MyMessageHandleThread::CRC16_MODBUS(unsigned char *puchMsg, unsigned int usDataLen)
{
unsigned short wCRCin = 0xFFFF;
unsigned short wCPoly = 0x8005;
unsigned char wChar = 0;
while (usDataLen--)
{
wChar = *(puchMsg++);
InvertUint8(&wChar,&wChar);
wCRCin ^= (wChar << 8);
for(int i = 0;i < 8;i++)
{
if(wCRCin & 0x8000)
wCRCin = (wCRCin << 1) ^ wCPoly;
else
wCRCin = wCRCin << 1;
}
}
InvertUint16(&wCRCin,&wCRCin);
return (wCRCin) ;
}
void MyMessageHandleThread::InvertUint8(unsigned char *dBuf,unsigned char *srcBuf)
{
int i;
unsigned char tmp[4];
tmp[0] = 0;
for (i=0; i< 8; i++)
{
if (srcBuf[0]& (1 << i))
{
tmp[0]|=1<<(7-i);
}
}
dBuf[0] = tmp[0];
}
void MyMessageHandleThread::InvertUint16(unsigned short *dBuf,unsigned short *srcBuf)
{
int i;
unsigned short tmp[4];
tmp[0] = 0;
for (i=0; i< 16; i++)
{
if (srcBuf[0]& (1 << i))
{
tmp[0]|=1<<(15 - i);
}
}
dBuf[0] = tmp[0];
}
bool MyMessageHandleThread::ModbusWrite(uint8_t SlaveAddr, uint8_t CMD,uint16_t Reg, uint16_t value)
{
int retryCnt = 0;
int totalCnt = 2000;
char buf[1 + 1 + 2 + 2 + 2];
char *data = NULL;
uint32_t len = 0;
buf[0] = SlaveAddr;
buf[1] = CMD;
buf[2] = Reg>>8;
buf[3] = Reg;
/* 这里应当读取线圈内容,然后做取反处理,下位机不可读,下位机做取反操作 */
buf[4] = value>>8;
buf[5] = value;
/* CRC 校验内容 */
unsigned short crc_value = 0;
crc_value = CRC16_MODBUS((unsigned char *)buf, 6);
buf[6] = crc_value;
buf[7] = crc_value >> 8;
if(pModbusSerial->isOpen() == false)
{
qDebug("在写的时候,现在串口还没打开");
return false;
}
ModbusReceiveBuf.clear();
pModbusSerial->clear();
pModbusSerial->write(buf, sizeof(buf));
do{
//msleep(1);
msecSleep(1);
retryCnt++;
}while((ModbusReceiveBuf.length() < 8) && (retryCnt < totalCnt));
qDebug("Modbus Write ACK retryCnt:%d",retryCnt);
if(retryCnt >= totalCnt)
{
return false;
}
else
{
data = ModbusReceiveBuf.data();
len = ModbusReceiveBuf.length();
for(uint8_t i = 0; i < len; i++)
{
qDebug("data[%d] = 0x%x",i, data[i]);
}
if(data == NULL)
{
return false;
}
}
if(memcmp(data, buf, 8) != 0)
{
qDebug("06 命令,ACK 的数据和写进去的不一样");
return false;
}
ModbusReceiveBuf.clear();
return true;
}
bool MyMessageHandleThread::ModbusRead(uint8_t SlaveAddr, uint8_t CMD,uint16_t Reg, uint16_t Count, uint8_t *readBuf)
{
int retryCnt = 0;
int totalCnt = 200;
char *data = NULL;
uint32_t len = 0;
char buf[1 + 1 + 2 + 2 + 2];
buf[0] = SlaveAddr;
buf[1] = CMD;
buf[2] = Reg>>8;
buf[3] = Reg;
/* 这里应当读线圈内容,然后做取反处理,下位机不可读,下位机做取反操作 */
buf[4] = Count>>8;
buf[5] = Count;
/* CRC 校验内容 */
unsigned short crc_value = 0;
crc_value = CRC16_MODBUS((unsigned char *)buf, 6);
buf[6] = crc_value;
buf[7] = crc_value >> 8;
if(pModbusSerial->isOpen() == false)
{
qDebug("在读的时候,现在串口还没打开");
return false;
}
ModbusReceiveBuf.clear();
pModbusSerial->write(buf, sizeof(buf));
do{
//msleep(1);
msecSleep(1);
retryCnt++;
}while((ModbusReceiveBuf.length() < (5 + Count*2)) && (retryCnt < totalCnt));
qDebug("Modbus Read ACK retryCnt:%d",retryCnt);
if(retryCnt >= totalCnt)
{
return false;
}
else
{
data = ModbusReceiveBuf.data();
len = ModbusReceiveBuf.length();
for(uint8_t i = 0; i < len; i++)
{
qDebug("data[%d] = 0x%x",i, data[i]);
}
if(data == NULL)
{
return false;
}
crc_value = CRC16_MODBUS((unsigned char *)data, len - 2 );
uint16_t receive_crc_l = 0;
uint16_t receive_crc_h = 0;
uint16_t receive_crc = 0;
receive_crc_h = *(data + len - 1);
receive_crc_l = *(data + len - 2);
receive_crc = (0xff00&(receive_crc_h<<8)) + (0x00ff&receive_crc_l);
qDebug("CCRC VALUE: 计算0x%x 接收0x%x receive_crc_h=0x%x;receive_crc_l=0x%x",crc_value,receive_crc,receive_crc_h,receive_crc_l);
if(crc_value == receive_crc )
{
memcpy(readBuf, data + 3, *(data + 2));
}
else
{
return false;
}
}
return true;
}
void MyMessageHandleThread::UpdateSwitchStatus(void)
{
if(switch_msg&0x0001)
{
pStatusWindow->LoopButton->setText(tr("循环关"));
}
else
{
pStatusWindow->LoopButton->setText(tr("循环开"));
}
if(switch_msg&0x0002)
{
pStatusWindow->ColdButton->setText(tr("制冷关"));
}
else
{
pStatusWindow->ColdButton->setText(tr("制冷开"));
}
if(switch_msg&0x0004)
{
pStatusWindow->HeatButton->setText(tr("加热关"));
}
else
{
pStatusWindow->HeatButton->setText(tr("加热开"));
}
if(switch_msg&0x0008)
{
pStatusWindow->StirButton->setText(tr("搅拌关"));
}
else
{
pStatusWindow->StirButton->setText(tr("搅拌开"));
}
if(switch_control&0x0001)
{
pStatusWindow->PauseButton->setText(tr("运行"));
}
else
{
pStatusWindow->PauseButton->setText(tr("暂停"));
}
}
void MyMessageHandleThread::loop_button_clicked()
{
qDebug("点击循环开关按键");
if(pStatusWindow->LoopButton->text() == tr("循环开"))
{
if(ModbusWrite(0x01,0x06,0x02bc,switch_msg & 0xFFFE) == true)
{
pStatusWindow->LoopButton->setText(tr("循环关"));
pStatusWindow->LoopButton->setStyleSheet("background-color: rgb(0, 170, 0);");
StatusGreenLED(pStatusWindow->label_loop_status);
}
else
{
pStatusWindow->LoopButton->setText(tr("循环开"));
pStatusWindow->LoopButton->setStyleSheet("background-color: rgb(255, 0, 0);");
StatusRedLED(pStatusWindow->label_loop_status);
}
}
else
{
if(ModbusWrite(0x01,0x06,0x02bc,switch_msg | 0x0001) == true)
{
pStatusWindow->LoopButton->setText(tr("循环开"));
pStatusWindow->LoopButton->setStyleSheet("background-color: rgb(255, 0, 0);");
StatusRedLED(pStatusWindow->label_loop_status);
}
else
{
pStatusWindow->LoopButton->setText(tr("循环关"));
pStatusWindow->LoopButton->setStyleSheet("background-color: rgb(0, 170, 0);");
StatusGreenLED(pStatusWindow->label_loop_status);
}
}
}
void MyMessageHandleThread::cold_button_clicked()
{
qDebug("点击制冷开关按键");
if(pStatusWindow->ColdButton->text() == tr("制冷开"))
{
if(ModbusWrite(0x01,0x06,0x02bc,switch_msg & 0xfffd) == true)
{
pStatusWindow->ColdButton->setText(tr("制冷关"));
pStatusWindow->ColdButton->setStyleSheet("background-color: rgb(0, 170, 0);");
StatusGreenLED(pStatusWindow->label_cold_status);
}
else
{
pStatusWindow->ColdButton->setText(tr("制冷开"));
pStatusWindow->ColdButton->setStyleSheet("background-color: rgb(255, 0, 0);");
StatusRedLED(pStatusWindow->label_cold_status);
}
}
else
{
if(ModbusWrite(0x01,0x06,0x02bc,switch_msg | 0x0003) == true)
{
pStatusWindow->ColdButton->setText(tr("制冷开"));
pStatusWindow->ColdButton->setStyleSheet("background-color: rgb(255, 0, 0);");
StatusRedLED(pStatusWindow->label_cold_status);
}
else
{
pStatusWindow->ColdButton->setText(tr("制冷关"));
pStatusWindow->ColdButton->setStyleSheet("background-color: rgb(0, 170, 0);");
StatusGreenLED(pStatusWindow->label_cold_status);
}
}
}
void MyMessageHandleThread::heat_button_clicked()
{
qDebug("点击加热开关按键");
if(pStatusWindow->HeatButton->text() == tr("加热开"))
{
if(ModbusWrite(0x01,0x06,0x02bc,switch_msg & 0xfffb) == true)
{
pStatusWindow->HeatButton->setText(tr("加热关"));
pStatusWindow->HeatButton->setStyleSheet("background-color: rgb(0, 170, 0);");
StatusGreenLED(pStatusWindow->label_heat_status);
}
else
{
pStatusWindow->HeatButton->setText(tr("加热开"));
pStatusWindow->HeatButton->setStyleSheet("background-color: rgb(255, 0, 0);");
StatusRedLED(pStatusWindow->label_heat_status);
}
}
else
{
if(ModbusWrite(0x01,0x06,0x02bc,switch_msg | 0x0004) == true)
{
pStatusWindow->HeatButton->setText(tr("加热开"));
pStatusWindow->HeatButton->setStyleSheet("background-color: rgb(255, 0, 0);");
StatusRedLED(pStatusWindow->label_heat_status);
}
else
{
pStatusWindow->HeatButton->setText(tr("加热关"));
pStatusWindow->HeatButton->setStyleSheet("background-color: rgb(0, 170, 0);");
StatusGreenLED(pStatusWindow->label_heat_status);
}
}
}
void MyMessageHandleThread::stir_button_clicked()
{
qDebug("点击搅拌开关按键");
if(pStatusWindow->StirButton->text() == tr("搅拌开"))
{
if(ModbusWrite(0x01,0x06,0x02bc,switch_msg & 0xfff7) == true)
{
pStatusWindow->StirButton->setText(tr("搅拌关"));
pStatusWindow->StirButton->setStyleSheet("background-color: rgb(0, 170, 0);");
StatusGreenLED(pStatusWindow->label_stir_status);
}
else
{
pStatusWindow->StirButton->setText(tr("搅拌开"));
pStatusWindow->StirButton->setStyleSheet("background-color: rgb(255, 0, 0);");
StatusRedLED(pStatusWindow->label_stir_status);
}
}
else
{
if(ModbusWrite(0x01,0x06,0x02bc,switch_msg | 0x0008) == true)
{
pStatusWindow->StirButton->setText(tr("搅拌开"));
pStatusWindow->StirButton->setStyleSheet("background-color: rgb(255, 0, 0);");
StatusRedLED(pStatusWindow->label_stir_status);
}
else
{
pStatusWindow->StirButton->setText(tr("搅拌关"));
pStatusWindow->StirButton->setStyleSheet("background-color: rgb(0, 170, 0);");
StatusGreenLED(pStatusWindow->label_stir_status);
}
}
}
void MyMessageHandleThread::pause_button_clicked()
{
qDebug("运行界面暂停按键");
if(pStatusWindow->PauseButton->text() == tr("运行"))
{
if(ModbusWrite(0x01,0x06,348,switch_control & 0xFFFE) == true)
{
qDebug("暂停发送成功");
pStatusWindow->PauseButton->setText(tr("暂停"));
}
else
{
qDebug("暂停发送失败");
pStatusWindow->PauseButton->setText(tr("运行"));
}
}
else if(pStatusWindow->PauseButton->text() == tr("暂停"))
{
if(ModbusWrite(0x01,0x06,348,switch_control | 0x0001) == true)
{
pStatusWindow->PauseButton->setText(tr("运行"));
}
else
{
pStatusWindow->PauseButton->setText(tr("暂停"));
}
}
}
void MyMessageHandleThread::stop_button_clicked()
{
qDebug("运行界面终止按键");
if(ModbusWrite(0x01,0x06,348,0x0000) == true)
{
qDebug("终止发送成功");
}
else
{
qDebug("终止发送失败");
}
}
void MyMessageHandleThread::StatusRedLED(QLabel *label)
{
label->setStyleSheet("background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0.494318 rgba(255, 76, 76, 205), stop:0.573864 rgba(255, 76, 76, 205), stop:0.6 rgba(255, 180, 180, 84), stop:1 rgba(255, 255, 255, 0));");
}
void MyMessageHandleThread::StatusGreenLED(QLabel *label)
{
label->setStyleSheet("background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0.494318 rgba(76, 255, 161, 205), stop:0.573864 rgba(94, 255, 178, 205), stop:0.6 rgba(255, 180, 180, 84), stop:1 rgba(255, 255, 255, 0));");
}
/*****************************************************************************************
* 功能描述: 毫秒级非阻塞延时函数
* 参数: 延时毫秒数
* 其他说明: 已试验,可用,但CPU占用率较高
*****************************************************************************************/
void MyMessageHandleThread::msecSleep(int msec)
{
QTime dieTime = QTime::currentTime().addMSecs(msec);
while( QTime::currentTime() <dieTime )
QCoreApplication::processEvents(QEventLoop::DialogExec, 100);
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/mingge8886/bilang_modbus_2.git
git@gitee.com:mingge8886/bilang_modbus_2.git
mingge8886
bilang_modbus_2
bilang_modbus_2
master

搜索帮助