
ui界面#ifndef PLC_DEMO_QTSNAP7_H #define PLC_DEMO_QTSNAP7_H #include QWidget #include QMutex #include snap7.h namespace Ui { class PLC_Demo_QtSnap7; } class PLC_Demo_QtSnap7 : public QWidget { Q_OBJECT public: explicit PLC_Demo_QtSnap7(QWidget *parent nullptr); ~PLC_Demo_QtSnap7(); public: bool ClientConnectToPlc(); private slots: void on_btn_con_clicked(); void on_btn_disCon_clicked(); void on_btn_write_bit_clicked(); void on_btn_read_bit_clicked(); void on_btn_write_real_clicked(); void on_btn_read_real_clicked(); void on_btn_write_int_clicked(); void on_btn_read_int_clicked(); private: Ui::PLC_Demo_QtSnap7 *ui; std::shared_ptrTS7Client client_; QMutex mutex; bool isCon false; }; #endif // PLC_DEMO_QTSNAP7_H#include plc_demo_qtsnap7.h #include ui_plc_demo_qtsnap7.h #include QMessageBox PLC_Demo_QtSnap7::PLC_Demo_QtSnap7(QWidget *parent) : QWidget(parent) , ui(new Ui::PLC_Demo_QtSnap7) { ui-setupUi(this); ui-btn_con-setEnabled(true); ui-btn_disCon-setEnabled(false); } PLC_Demo_QtSnap7::~PLC_Demo_QtSnap7() { delete ui; } bool PLC_Demo_QtSnap7::ClientConnectToPlc() { client_ std::make_sharedTS7Client(); int res client_-ConnectTo(192.168.88.129,0,1); // 0 连接成功 if(res!0) { ui-lab_concectdState-setText((连接失败)); ui-lab_concectdState-setStyleSheet(background-color:red;color:white;); isCon false; return false; } ui-lab_concectdState-setText((连接成功)); ui-lab_concectdState-setStyleSheet(background-color:green;color:white;); isCon true; ui-btn_con-setEnabled(false); ui-btn_disCon-setEnabled(true); return true; } void PLC_Demo_QtSnap7::on_btn_con_clicked() { ui-btn_con-setEnabled(true); ui-btn_disCon-setEnabled(false); ClientConnectToPlc(); } void PLC_Demo_QtSnap7::on_btn_disCon_clicked() { client_-Disconnect(); ui-lab_concectdState-setText((已断开连接)); ui-lab_concectdState-setStyleSheet(background-color:red;color:white;); } /* PLC 的控制字 假设一个 PLC 的 DB1.DBB4 是一个 16 位的控制字定义如下 位 0启动电机 位 1停止电机 位 2复位故障 位 3自动模式 位 4手动模式 */ // 1个字节 8 0~7位 void PLC_Demo_QtSnap7::on_btn_write_bit_clicked() { quint8 control_byte ; QByteArray buffer; buffer.resize(1); client_-DBRead(1,4,1,buffer.data());//写入到buffer 缓冲区 control_byte static_castquint8(buffer[0]);// 当前控制字 //设置/清除位 //启动电机设置位0为1位1为0 其他位保持不变 // 比如 control_byte 0000 0100 control_byte | (10);//0000 0101 control_byte ~(11);//0000 0101 // 清除位 buffer[0] control_byte; int res client_-DBWrite(1,4,1,buffer.data()); if(res0) { QMessageBox::information(this, 成功, 写入成功); } else { QMessageBox::critical(this, 错误, QString(写入失败错误码%1).arg(res)); qDebug() DBWrite error: res; } //清除位 //停止电机同时清除启动位位 0并设置停止位位 1 control_byte ~(10); // 清除位 0 control_byte | (11); // 设置位 1 buffer[0] control_byte; res client_-DBWrite(1,4,1,buffer.data()); if(res0) { QMessageBox::information(this, 成功, 写入成功); } else { QMessageBox::critical(this, 错误, QString(写入失败错误码%1).arg(res)); qDebug() DBWrite error: res; } } void PLC_Demo_QtSnap7::on_btn_read_bit_clicked() { } void PLC_Demo_QtSnap7::on_btn_write_real_clicked() { if(!client_ || !client_-Connected() ) return; // float 类型占4个字节西门子PLC中是大端序 float real_value ui-write_real_value-text().toFloat(); int start 264; uint32_t value; std::memcpy(value, real_value, sizeof(float)); // 将float值复制到uint32_t中 QByteArray buffer; buffer.resize(4); // 分配4个字节用于写入float值 buffer[0] (value 24) 0xFF; // 高字节在前 buffer[1] (value16) 0xFF; buffer[2] (value 8) 0xFF; buffer[3] value 0xFF; int res client_-DBWrite(1, start, 4, buffer.data());//第四个参数应为 void* 指向存放数据的缓冲区 if(res0) { QMessageBox::information(this, 成功, 写入成功); } else { QMessageBox::critical(this, 错误, QString(写入失败错误码%1).arg(res)); qDebug() DBWrite error: res; } } void PLC_Demo_QtSnap7::on_btn_read_real_clicked() { if(!client_ || !client_-Connected() ) { ui-lab_concectdState-setText((已断开连接)); ui-lab_concectdState-setStyleSheet(background-color:red;color:white;); return; } QByteArray buffer; buffer.resize(4); // 分配4个字节用于读取float值 int start 264; int res client_-DBRead(1,start,4,buffer.data()); if(res0) { // 读取成功将字节转换为float // 注意PLC中可能是高字节在前所以需要转换 // 先将4个字节组合成一个uint32_t值再通过memcpy转换为float // 正确组合先将每个字节转为 uint8_t再按大端序组合 uint32_t value (static_castuint8_t(buffer[0]) 24) | (static_castuint8_t(buffer[1]) 16) | (static_castuint8_t(buffer[2]) 8) | static_castuint8_t(buffer[3]); float real_value; std::memcpy(real_value,value,sizeof(float)); qDebug()value real_value; ui-read_real_value-setText(QString::number(real_value,f)); } else { QMessageBox::warning(this,读取数据,读取失败); } } void PLC_Demo_QtSnap7::on_btn_write_int_clicked() { /* 西门子 int 2个字节 BYTE1 字节 WORD2 字节无符号 DINT4 字节有符号 DWORD4 字节无符号 REAL4 字节浮点数*/ if(!client_ || !client_-Connected() ) { ui-lab_concectdState-setText((已断开连接)); ui-lab_concectdState-setStyleSheet(background-color:red;color:white;); return; } quint16 int_value ui-write_int_value-text().toShort(); int start 262; QByteArray buffer; buffer.resize(2); buffer[0] (int_value8) 0xFF;//高字节在前 buffer[1] int_value 0xFF; int res client_-DBWrite(1,start,2,buffer.data()); if(res0) { QMessageBox::information(this, 成功, 写入成功); } else { QMessageBox::critical(this, 错误, QString(写入失败错误码%1).arg(res)); qDebug() DBWrite error: res; } } void PLC_Demo_QtSnap7::on_btn_read_int_clicked() { if(!client_ || !client_-Connected() ) { ui-lab_concectdState-setText((已断开连接)); ui-lab_concectdState-setStyleSheet(background-color:red;color:white;); return; } QByteArray buffer; buffer.resize(2); int start 262; int res client_-DBRead(1,start,2,buffer.data()); if(res!0) { QMessageBox::critical(this, 错误, QString(读取失败错误码%1).arg(res)); qDebug() DBWrite error: res; return; } // 高字节在前 8 | 低字节 quint16 int_value (static_castquint8(buffer[0]8) | static_castquint8(buffer[1])); ui-read_int_value-setText(QString::number(int_value)); }