Qt_C++ RFID网络读卡器Socket Udp通讯示例源码
本示例使用的设备: WIFI/TCP/UDP/HTTP协议RFID液显网络读卡器可二次开发语音播报POE-淘宝网 (taobao.com)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QHostInfo>
#include <QNetworkInterface>
#include <QStringList>
#include <QUdpSocket>
#include <QException>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass Setnetpara; // 前向声明class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void sockinit(); //初始化Socket Udpvoid listadditems(int ctr,QString listinfo); //显示通读报文void read_data(); //UDP端口接收数据void DisableSendAgain(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len); //确认接收到数据void Analyze_c1(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len); //解析读取M1卡卡号void Analyze_c3(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len); //主动读取M1卡扇区数据的返回void Analyze_c5(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len); //指定区号密钥读取M1卡扇区数据void Analyze_cd(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len); //指定区号密钥写数据到M1卡扇区的返回void Analyze_d1(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len); //解析读取ID卡卡号void Analyze_cf_df(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len); //解析IC、ID卡离开读卡器void Analyze_f2(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len); //解析设备开机、响应搜索指令的返回void Analyze_f6(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len); //响应查询设备型号固件日期指令的返回void Analyze_a4(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len); //查询wifi连接状态void Respondinfo(QString Dispinf,QHostAddress ip,quint16 port,QString DeviceNumber); //接收到设备信息立即回应void SendBuffAct();void on_PBSearch_clicked();void on_CBIP_currentIndexChanged(int index);void on_PBClear_clicked();void on_tableWidget_cellClicked(int row, int column);void on_PBEditpara_clicked();void on_PBSendDispBeep_clicked();void on_PBbeep_clicked();void on_PBSwitchOn_clicked();void on_PBSwitchOff_clicked();void on_PBSendDispTTS_clicked();void on_PBSendDispSpk_clicked();void on_PBReadCard_clicked();void on_PBWriteCard_clicked();void on_PBChangeKey_clicked();void on_PBSetRW_clicked();void on_PBcopylist_clicked();void on_pushButton_9_clicked();void on_pushButton_clicked();void on_pushButton_2_clicked();void on_pushButton_4_clicked();void on_pushButton_3_clicked();void on_pushButton_7_clicked();void on_pushButton_8_clicked();void on_pushButton_SetTCP_clicked();void on_pushButton_SetHttp_clicked();void on_pushButton_16_clicked();void on_PBClear_2_clicked();void on_radioButton_IP_toggled(bool checked);void on_pushButton_SetUp_clicked();void on_pushButton_Read_clicked();private:Ui::MainWindow *ui;QUdpSocket * udpSocket;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include "QMessageBox"
#include <QUdpSocket>
#include <exception>
#include <QByteArray>
#include <QString>
#include <string>
#include <QTime>
#include <QStringList>
#include <QClipboard>bool listening=false; //sock侦听标志
QByteArray sendData; //发送数据缓冲
unsigned char readcardbuf[1024]; //接收M1卡扇区数据缓冲//获取本机所有网卡IP------------------------------------------------------------------------------------------------------
QStringList getAllIPAddresses() {QStringList ips;QList<QHostAddress> list = QNetworkInterface::allAddresses();for (int i = 0; i < list.size(); ++i) {QHostAddress address = list.at(i);// 检查是否为IPv4地址,并排除回环地址if (address.protocol() == QAbstractSocket::IPv4Protocol && address != QHostAddress::LocalHost) {ips << address.toString();}}return ips;
}//判断IP地址是否合法---------------------------------------------------------------------------------------------------------
bool isValidIP(const QString &ip) {QHostAddress address(ip);return address.protocol() != QAbstractSocket::UnknownNetworkLayerProtocol;
}//判断是否有效MAC------------------------------------------------------------------------------------------------------------
bool isValidMac(const QString &mac) {try{QStringList liststr = mac.split("-");for (int i=0 ;i<6;i++){bool ok;quint8 macb =liststr[i].toInt(&ok,16);if (!ok){return false;}}return true;}catch (QException& e) {return false;}
}//根据IP地址获取MAC----------------------------------------------------------------------------------------------------------
QString getMacByIp(const QString &ip) {QHostInfo info = QHostInfo::fromName(ip);foreach (const QHostAddress &address, info.addresses()) {if (address.protocol() == QAbstractSocket::IPv4Protocol) {foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) {if (interface.flags().testFlag(QNetworkInterface::IsUp) && interface.flags().testFlag(QNetworkInterface::IsRunning)) {foreach (const QNetworkAddressEntry &entry, interface.addressEntries()) {if (entry.ip() == address) {return interface.hardwareAddress();}}}}}}return QString();
}//获取系统现时间-------------------------------------------------------------------------------------------------------------
QString getsystime(){QTime time = QTime::currentTime();QString timeStr = time.toString("hh:mm:ss.zzz");return timeStr;
}//获取系统日期时间-------------------------------------------------------------------------------------------------------------
QString getsysdatetime(){QDateTime currentDateTime = QDateTime::currentDateTime();QString dateTimeString = currentDateTime.toString("yy-MM-dd hh:mm:ss");return dateTimeString;
}//QByteArray转16进制QString------------------------------------------------------------------------------------------------
QString ByteArrayToHexString(QByteArray data){QString ret(data.toHex().toUpper());int len = ret.length()/2;for(int i=1;i<len;i++){ret.insert(2*i+i-1," ");}return ret;
}//检测输入数据是否为16进制数,将正确的16进制字符存入数组,并返回长度--------------------------------------------------------------------
static int checkhexdata(QString inputstr,unsigned char *databuf){QChar ch;QString writinf = inputstr.trimmed();QString writinf1 = "";int m = 0;int n = 0;char s;if(writinf.length()<1){return -1;}ch = writinf.at(0);s = writinf.at(0).toLatin1();for(int i=0; i<writinf.length() ; i++){ch = writinf.at(i);s = writinf.at(i).toLatin1();if((('0' <= s) && (s <= '9')) || (('A' <= s) && (s <= 'F')) || (('a' <= s) && (s <= 'f'))){writinf1 += ch;n++;if(n==2){bool ok;databuf[m++] = writinf1.toInt(&ok,16);writinf1 = "";n = 0;}}else if(s == ' '){}}return m;
}MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ ui->setupUi(this);ui->TEPort->setPlainText("39169"); //出厂默认39169端口ui->textEdit_remoiport->setText("255.255.255.255:39169");ui->textEdit_DeviceNumber->setText("00000");ui->textEdit_tts->setText("欢迎您使用我们的网络读卡器!");ui->textEdit_disp->setText("欢迎您使用我们的网络读卡器!");ui->spinBox_dispdelay->setValue(5);ui->spinBox_swit->setValue(30);ui->spinBox_voice->setValue(8);ui->textEdit_M1UID->setText("00000000");ui->textEdit_authkey->setText("FFFFFFFFFFFF");ui->textEdit_newkey->setText("FF FF FF FF FF FF FF 07 80 69 FF FF FF FF FF FF");ui->scrollArea->setVisible(false); ui->scrollArea->move(180,40);ui->scrollArea_wifi->setVisible(false);ui->scrollArea_wifi->move(250,130);ui->groupBox_dhcp->setVisible(false);QStringList ips = getAllIPAddresses(); foreach (QString ip, ips) {ui->CBIP->addItem(ip);}if(ui->CBIP->count()<1){QMessageBox::information(NULL, "提示", "未搜索到本机的网卡,系统不能正常运行!");delete ui;}sockinit();
}MainWindow::~MainWindow()
{delete ui;
}//通讯报文显示-----------------------------------------------------------------------------------------------------
void MainWindow::listadditems(int ctr,QString listinfo){switch (ctr){case 0:if(ui->listWidget->count()>10){ui->listWidget->clear();}ui->listWidget->addItem(listinfo);ui->listWidget->setCurrentRow(ui->listWidget->count()-1);break;case 1:ui->textEdit_msg->setText(listinfo);}
}//广播发送搜索所有在线的设备-------------------------------------------------------------------------------------------
void MainWindow::on_PBSearch_clicked()
{int n = ui->tableWidget->rowCount();//总行数for (int i = 0;i <= n;i++)ui->tableWidget->removeRow(0);//遍历删除第0行QHostAddress broadcastAddress("255.255.255.255");quint16 port1 = 39169;sendData.clear();sendData.append(0xA6);udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1); //搜索所有在线设备QString dispinf=getsystime()+" Send To: "+("255.255.255.255:"+QString::number(port1)+" ").mid(0,22)+"A6" ;listadditems(0,dispinf);sendData.clear();sendData.append(0xA8);udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1); //查询在线设备型号、固件日期dispinf=getsystime()+" Send To: "+("255.255.255.255:"+QString::number(port1)+" ").mid(0,22)+"A8" ;listadditems(0,dispinf);
}void MainWindow::sockinit(){ //初始化Socket UDP侦听端口try{if(!listening){QString ipstr=ui->CBIP->currentText();QHostAddress localeip(ipstr);quint16 port=ui->TEPort->toPlainText().toUInt();udpSocket =new QUdpSocket(this);udpSocket->bind(localeip,port); //udpSocket->bind(QHostAddress::Any,port); 这个方式是绑定所有网卡,这样发不出广播包connect(udpSocket, &QUdpSocket::readyRead, this,&MainWindow::read_data);listening=true;listadditems(0,getsystime()+" Sock已启动侦听"+ipstr+":"+ui->TEPort->toPlainText());}}catch(_exception){listening=false;udpSocket->close();listadditems(0,getsystime()+" Sock侦听已关闭!");}
}//Socket UDP端口接收数据---------------------------------------------------------------------------------------------------------
void MainWindow::read_data(){unsigned char databuff[1024] = {0};QHostAddress ip;quint16 port;qint64 buflen = udpSocket->readDatagram((char *)databuff, sizeof(databuff), &ip, &port);QString str;for (int i = 0; i < buflen; i++){str +=QString::asprintf("%02X ", databuff[i]);} QString dispinf=getsystime()+" Receive: "+(ip.toString()+":"+QString::number(port)+" ").mid(0,22)+str ;listadditems(0,dispinf);switch (databuff[0]){case 0xc1:Analyze_c1(ip, port,databuff,buflen); //解析读取IC卡卡号break;case 0xc3:Analyze_c3(ip, port,databuff,buflen); //主动读取M1卡扇区数据的返回break;case 0xc5:Analyze_c5(ip, port,databuff,buflen); //指定区号密钥读取M1扇区数据返回break;case 0xcd:Analyze_cd(ip, port,databuff,buflen); //指定区号密钥写数据到M1卡扇区返回break;case 0xd1:Analyze_d1(ip, port,databuff,buflen); //解析读取ID卡卡号break;case 0xcf:case 0xdf:Analyze_cf_df(ip, port,databuff,buflen); //解析IC、ID卡离开读卡器break;case 0xf2:Analyze_f2(ip, port,databuff,buflen); //在线设备响应搜索指令的返回、读卡器上电开机上传设备信息break;case 0xf6:Analyze_f6(ip, port,databuff,buflen); //在线设备响应查询型号、固件日期指令的返回break;case 0xa4:Analyze_a4(ip, port,databuff,buflen); //查询WIFI叁数的返回break;default:break;}
}//确认接收到的信息----------------------------------------------------------------------------------------------------------------
void MainWindow::DisableSendAgain(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{QString SendHex=getsystime()+" Send To: "+(ip.toString()+":"+QString::number(port)+" ").mid(0,22)+"69 " ;sendData.clear();sendData.append(0x69);for (int i=1;i<9;i++){sendData.append(databuff[i]);SendHex=SendHex+QString::asprintf("%02X ", databuff[i]);}udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress(ip), port); listadditems(0,SendHex+" 确定接收,不要再次发送此帧数据啦...");
}//解析读取IC卡卡号-------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_c1(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{DisableSendAgain(ip, port,databuff,buflen);//确认接收到的信息,否则同一信息读卡器会重发三次QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //设备自编机号QString FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256); //数据包号QString CardnoHexZ=QString::asprintf("%02X%02X%02X%02X", databuff[10],databuff[11],databuff[12],databuff[13]); //16进制卡号正码QString CardnoHexF=QString::asprintf("%02X%02X%02X%02X", databuff[13],databuff[12],databuff[11],databuff[10]); //16进制卡号反码bool status;QString Cardno8H10D=QString::asprintf("%010u",CardnoHexF.toUInt(&status,16)); //转8H10D反码卡号QString SerialNumber=""; //设备全球唯一硬件序号for (int i=14;i<buflen;i++){SerialNumber=SerialNumber+QString::asprintf("%02X", databuff[i]);}QString DispInf="读取M1卡号,设备IP:"+IPAddress+",机号:"+DeviceNumber+",数据包号:"+FrameNumber+",16进制卡号:"+CardnoHexZ+",转8H10D反码:"+Cardno8H10D+",设备全球唯一序号:"+SerialNumber;listadditems(1,DispInf);ui->textEdit_M1UID->setText(CardnoHexZ);if(ui->checkBox_Resp->isChecked()){Respondinfo(getsysdatetime()+"卡号:"+Cardno8H10D,ip,port,DeviceNumber);} //回应驱动设备显示+蜂鸣响声
}//主动读取扇区数据的返回--------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_c3(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //设备自编机号QString CardnoHex="";for (int i=12;i<16;i++){CardnoHex=CardnoHex+QString::asprintf("%02X", databuff[i]);}int j=databuff[10]*48;int m=databuff[11]*48;for(int i=0;i<m;i++){readcardbuf[j+1]=databuff[16+i];}if((databuff[10]+databuff[11])>=databuff[9]){m=databuff[9]*48;QString DataHex="";for (int i=0;i<m;i++){DataHex=DataHex+QString::asprintf("%02X ",readcardbuf[i]);}ui->textEdit_data->setPlainText(DataHex);QString DispInf="读取M1卡扇区数据成功,设备IP:"+IPAddress+",机号:"+DeviceNumber+",16进制卡号:"+CardnoHex;listadditems(1,DispInf);ui->textEdit_M1UID->setText(CardnoHex);if(ui->checkBox_Resp->isChecked()){Respondinfo(getsysdatetime()+"卡号:"+CardnoHex,ip,port,DeviceNumber);} //回应驱动设备显示+蜂鸣响声}
}//指定区号密钥读取M1扇区数据返回-----------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_c5(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //设备自编机号QString CardnoHex=""; QString DispInf="";for (int i=8;i<12;i++){CardnoHex=CardnoHex+QString::asprintf("%02X", databuff[i]);}QString Sector=QString::asprintf("%d", databuff[12]); //扇区号DispInf="读取M1卡"+Sector+"扇区数据";switch (databuff[13]){case 0:{QString DataHex="";for (int i=0;i<48;i++){DataHex=DataHex+QString::asprintf("%02X ", databuff[i]);}DispInf=DispInf+"成功,设备IP:"+IPAddress+",机号:"+DeviceNumber+",16进制卡号:"+CardnoHex;ui->textEdit_data->setPlainText(DataHex);break;}case 8:DispInf=DispInf+"失败,设备IP:"+IPAddress+",机号:"+DeviceNumber+",没有卡片在感应区!";break;case 12:DispInf=DispInf+"失败,设备IP:"+IPAddress+",机号:"+DeviceNumber+",16进制卡号:"+CardnoHex+",卡密码认证失败!";break;default:DispInf=DispInf+"失败,设备IP:"+IPAddress+",机号:"+DeviceNumber+",错误代码:"+QString::asprintf("%d", databuff[13]);break;}listadditems(1,DispInf);ui->textEdit_M1UID->setText(CardnoHex);if(ui->checkBox_Resp->isChecked()){Respondinfo(DispInf,ip,port,DeviceNumber);} //回应驱动设备显示+蜂鸣响声
}//指定区号密钥写数据到M1卡扇区返回状态---------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_cd(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{QString IPAddress=QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4])+"."+QString::asprintf("%d", databuff[5]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应QString DeviceNumber=QString::asprintf("%05d",databuff[6]+databuff[7]*256); //设备自编机号QString CardnoHex="";for (int i=9;i<13;i++){CardnoHex=CardnoHex+QString::asprintf("%02X", databuff[i]); //16进制卡号}QString Sector=QString::asprintf("%d", databuff[13]); //扇区号QString Pages=QString::asprintf("%d", databuff[8]); //本次操作的扇区总数QString DispInf="";if(databuff[1]==0x3a){DispInf="修改M1卡"+Sector+"扇区密钥";}else if(databuff[1]==0x3d){DispInf="写数据到M1卡"+Sector+"扇区";}switch (databuff[14]){case 0:DispInf=DispInf+"成功,设备IP:"+IPAddress+",机号:"+DeviceNumber+",16进制卡号:"+CardnoHex;break;case 8:DispInf=DispInf+"失败,设备IP:"+IPAddress+",机号:"+DeviceNumber+",没有卡片在感应区!";break;case 12:DispInf=DispInf+"失败,设备IP:"+IPAddress+",机号:"+DeviceNumber+",16进制卡号:"+CardnoHex+",卡密码认证失败!";break;default:DispInf=DispInf+"失败,设备IP:"+IPAddress+",机号:"+DeviceNumber+",错误代码:"+QString::asprintf("%d", databuff[13]);break;}listadditems(1,DispInf);if(ui->checkBox_Resp->isChecked()){Respondinfo(DispInf,ip,port,DeviceNumber);} //回应驱动设备显示+蜂鸣响声
}//解析读取ID卡卡号-----------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_d1(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{DisableSendAgain(ip, port,databuff,buflen);//确认接收到的信息,否则同一信息读卡器会重发三次QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //设备自编机号QString FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256); //数据包号QString CardnoHexZ=QString::asprintf("%02X%02X%02X%02X%02X", databuff[9],databuff[10],databuff[11],databuff[12],databuff[13]); //16进制卡号正码,databuff[13]为厂商代码QString CardnoHexF=QString::asprintf("%02X%02X%02X%02X", databuff[12],databuff[11],databuff[10],databuff[9]); //16进制卡号反码,databuff[13]为厂商代码bool status;QString Cardno8H10D=QString::asprintf("%010u",CardnoHexF.toUInt(&status,16)); //转8H10D反码卡号QString SerialNumber=""; //设备全球唯一硬件序号for (int i=14;i<buflen;i++){SerialNumber=SerialNumber+QString::asprintf("%02X", databuff[i]);}QString DispInf="读取ID卡号,设备IP:"+IPAddress+",机号:"+DeviceNumber+",数据包号:"+FrameNumber+",16进制卡号:"+CardnoHexZ+",转8H10D反码:"+Cardno8H10D+",设备全球唯一序号:"+SerialNumber;listadditems(1,DispInf);if(ui->checkBox_Resp->isChecked()){Respondinfo(getsysdatetime()+"卡号:"+Cardno8H10D,ip,port,DeviceNumber);} //回应驱动设备显示+蜂鸣响声
}//解析IC\ID卡离开读卡器-----------------------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_cf_df(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{DisableSendAgain(ip, port,databuff,buflen);//确认接收到的信息,否则同一信息读卡器会重发三次QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //设备自编机号QString FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256); //数据包号int infotype=databuff[9]; //数据说明,1表示只读取UID卡号int cardnolen=databuff[10]; //UID卡号长度QString CardnoHexZ=""; //16进制卡号正码for (int i=0;i<cardnolen;i++){CardnoHexZ=CardnoHexZ+QString::asprintf("%02X", databuff[11+i]);}QString CardnoHexF=CardnoHexZ.mid(6,2)+CardnoHexZ.mid(4,2)+CardnoHexZ.mid(2,2)+CardnoHexZ.mid(0,2); //16进制卡号反码bool status;QString Cardno8H10D=QString::asprintf("%010u",CardnoHexF.toUInt(&status,16)); //转8H10D反码卡号QString SerialNumber=""; //设备全球唯一硬件序号for (int i=11+cardnolen;i<buflen;i++){SerialNumber=SerialNumber+QString::asprintf("%02X", databuff[i]);}QString DispInf="";if(databuff[0]==0xcf){DispInf="M1卡离开读卡器,";}else{DispInf="ID卡离开读卡器,";}DispInf=DispInf+"设备IP:"+IPAddress+",机号:"+DeviceNumber+",数据包号:"+FrameNumber+",16进制卡号:"+CardnoHexZ+",转8H10D反码:"+Cardno8H10D+",设备全球唯一序号:"+SerialNumber;listadditems(1,DispInf);
}//在线设备响应搜索指令的返回、读卡器上电开机上传设备信息-------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_f2(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IPQString mask=QString::asprintf("%d", databuff[5])+"."+QString::asprintf("%d", databuff[6])+"."+QString::asprintf("%d", databuff[7])+"."+QString::asprintf("%d", databuff[8]); //设备掩码QString PortStr=QString::asprintf("%05d",databuff[9]+databuff[10]*256); //通讯端口QString DeviceNumber=QString::asprintf("%05d",databuff[11]+databuff[12]*256); //设备自编机号QString GetWay=QString::asprintf("%d", databuff[13])+"."+QString::asprintf("%d", databuff[14])+"."+QString::asprintf("%d", databuff[15])+"."+QString::asprintf("%d", databuff[16]); //设备网关QString GetWayMAC=QString::asprintf("%02X", databuff[17])+"-"+QString::asprintf("%02X", databuff[18])+"-"+QString::asprintf("%02X", databuff[19])+"-"+QString::asprintf("%02X", databuff[20])+"-"+QString::asprintf("%02X", databuff[21])+"-"+QString::asprintf("%02X", databuff[22]); //设备网关MACQString ServerIp=QString::asprintf("%d", databuff[23])+"."+QString::asprintf("%d", databuff[24])+"."+QString::asprintf("%d", databuff[25])+"."+QString::asprintf("%d", databuff[26]); //远程服务器IPQString ServerMAC=QString::asprintf("%02X", databuff[27])+"-"+QString::asprintf("%02X", databuff[28])+"-"+QString::asprintf("%02X", databuff[29])+"-"+QString::asprintf("%02X", databuff[30])+"-"+QString::asprintf("%02X", databuff[31])+"-"+QString::asprintf("%02X", databuff[32]); //远程服务器MACQString MACPara=QString::asprintf("%d", databuff[33]); //MAC获取方式QString NetPara=QString::asprintf("%d", databuff[34]); //设备参数QString ModuleNumber=QString::asprintf("%d", databuff[35])+"-"+QString::asprintf("%d", databuff[36])+"-"+QString::asprintf("%d", databuff[37])+"-"+QString::asprintf("%d", databuff[38]); //网络模块编号QString STMAC="16-88-"+QString::asprintf("%02X", databuff[35])+"-"+QString::asprintf("%02X", databuff[36])+"-"+QString::asprintf("%02X", databuff[37])+"-"+QString::asprintf("%02X", databuff[38]); //STC版设备MACQString CHMAC=""; //CH系列设备MACQString SerialNumber=""; //唯一设备硬件序号for (int i=39;i<buflen;i++){SerialNumber=SerialNumber+QString::asprintf("%02X", databuff[i]);if (i<45){CHMAC=QString::asprintf("%02X", databuff[i])+CHMAC;if(i<44){CHMAC="-"+CHMAC;}}}int row = 0;ui->tableWidget->insertRow(row);QTableWidgetItem* item = new QTableWidgetItem;item->setText(DeviceNumber);ui->tableWidget->setItem(row,0, item);item = new QTableWidgetItem;item->setText(IPAddress);ui->tableWidget->setItem(row,1, item);item = new QTableWidgetItem;item->setText(mask);ui->tableWidget->setItem(row,2, item);item = new QTableWidgetItem;item->setText(PortStr);ui->tableWidget->setItem(row,3, item);item = new QTableWidgetItem;item->setText(GetWay);ui->tableWidget->setItem(row,4, item);item = new QTableWidgetItem;item->setText(GetWayMAC);ui->tableWidget->setItem(row,5, item);item = new QTableWidgetItem;item->setText(ServerIp);ui->tableWidget->setItem(row,6, item);item = new QTableWidgetItem;item->setText(ServerMAC);ui->tableWidget->setItem(row,7, item);item = new QTableWidgetItem;item->setText(MACPara);ui->tableWidget->setItem(row,8, item);item = new QTableWidgetItem;item->setText(NetPara);ui->tableWidget->setItem(row,9, item);item = new QTableWidgetItem;item->setText(ModuleNumber);ui->tableWidget->setItem(row,10, item);item = new QTableWidgetItem;item->setText(STMAC);ui->tableWidget->setItem(row,11, item);item = new QTableWidgetItem;item->setText(SerialNumber);ui->tableWidget->setItem(row,12, item);item = new QTableWidgetItem;item->setText(CHMAC);ui->tableWidget->setItem(row,13, item);for (int i=0;i<=13;i++){ui->tableWidget->resizeColumnToContents(i); //自动列宽}
}//响应查询设备型号固件日期指令的返回---------------------------------------------------------------------------------------------------
void MainWindow::Analyze_f6(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IPQString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //设备自编机号int NameLen=databuff[7]; //设备型号名称长度QByteArray namebuf; //设备型号for (int i=0;i<NameLen;i++){namebuf.append(databuff[8+i]);}QString namestr=namebuf;int VersionDateLen=databuff[8 + NameLen]; //固件日期长度QByteArray verbuf; //固件日期for (int i=0;i<VersionDateLen;i++){verbuf.append(databuff[8 + NameLen + 1+i]);}QString verdatestr=verbuf;int rowCount = ui->tableWidget->rowCount();for (int row = 0; row < rowCount; ++row) {QTableWidgetItem *item = ui->tableWidget->item(row, 1);QString ipstr = item->text();if (IPAddress==ipstr){item = new QTableWidgetItem;item->setText(namestr);ui->tableWidget->setItem(row,14, item);ui->tableWidget->resizeColumnToContents(14); //自动列宽item = new QTableWidgetItem;item->setText(verdatestr);ui->tableWidget->setItem(row,15, item);ui->tableWidget->resizeColumnToContents(15); //自动列宽return;}}
}//查询wifi连接状态---------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_a4(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{QString IPAddress=QString::asprintf("%d", databuff[7])+"."+QString::asprintf("%d", databuff[8])+"."+QString::asprintf("%d", databuff[9])+"."+QString::asprintf("%d", databuff[10]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应ui->listWidget_wifi->addItem("WIFI的IP地址:"+IPAddress);QString mask=QString::asprintf("%d", databuff[11])+"."+QString::asprintf("%d", databuff[12])+"."+QString::asprintf("%d", databuff[13])+"."+QString::asprintf("%d", databuff[14]); //设备掩码ui->listWidget_wifi->addItem("WIFI子网掩码:"+mask);QString MACStr=QString::asprintf("%02X", databuff[15])+"-"+QString::asprintf("%02X", databuff[16])+"-"+QString::asprintf("%02X", databuff[17])+"-"+QString::asprintf("%02X", databuff[18])+"-"+QString::asprintf("%02X", databuff[19])+"-"+QString::asprintf("%02X", databuff[20]); //MAC地址ui->listWidget_wifi->addItem("WIFI_MAC地址:"+MACStr);QString GateWay=QString::asprintf("%d", databuff[21])+"."+QString::asprintf("%d", databuff[22])+"."+QString::asprintf("%d", databuff[23])+"."+QString::asprintf("%d", databuff[24]); //设备网关ui->listWidget_wifi->addItem("WIFI网关地址:"+GateWay);QString GatewayMAC=QString::asprintf("%02X", databuff[25])+"-"+QString::asprintf("%02X", databuff[26])+"-"+QString::asprintf("%02X", databuff[27])+"-"+QString::asprintf("%02X", databuff[28])+"-"+QString::asprintf("%02X", databuff[29])+"-"+QString::asprintf("%02X", databuff[30]); //网关MACui->listWidget_wifi->addItem("网关 MAC地址:"+GatewayMAC);switch (databuff[31]){case 0:ui->listWidget_wifi->addItem("WIFI网络状态:已连接wifi");break;case 1:ui->listWidget_wifi->addItem("WIFI网络状态:连接失败!");break;case 2:ui->listWidget_wifi->addItem("WIFI网络状态:已初始化!");break;default:ui->listWidget_wifi->addItem("WIFI网络状态:未初始化!");break;}QByteArray devname;for(int i=0 ;i<databuff[32];i++){devname.append(databuff[34+i]);}QString devnamestr=devname;ui->listWidget_wifi->addItem("读卡器 名称:"+devnamestr);QByteArray wifname;for(int i=0 ;i<databuff[33];i++){wifname.append(databuff[44+i]);}QString wifinamestr=wifname;ui->listWidget_wifi->addItem("WIFI热点名称:"+wifinamestr);
}//更换不同的网卡----------------------------------------------------------------------------------------------------
void MainWindow::on_CBIP_currentIndexChanged(int index)
{if (listening){disconnect(udpSocket, &QUdpSocket::readyRead, this,&MainWindow::read_data);udpSocket->close();listening=false;listadditems(0,getsystime()+" Sock侦听已关闭!");}sockinit();
}void MainWindow::on_PBClear_clicked()
{ui->listWidget->clear();ui->textEdit_msg->setText("");
}//在在线设备列表中选取一台设备IP端口
void MainWindow::on_tableWidget_cellClicked(int row, int column)
{int currentRow = ui->tableWidget->currentIndex().row();QString DeviceNumber = ui->tableWidget->item(currentRow,0)->text();QString IPAddress= ui->tableWidget->item(currentRow,1)->text();QString PortStr= ui->tableWidget->item(currentRow,3)->text();ui->textEdit_DeviceNumber->setText(DeviceNumber);ui->textEdit_remoiport->setText(IPAddress+":"+PortStr);ui->New_Nember->setText(DeviceNumber);ui->New_IP->setText(IPAddress);ui->New_ServerIP->setText( ui->tableWidget->item(currentRow,6)->text());ui->ServerMAC->setText( ui->tableWidget->item(currentRow,7)->text());ui->New_Mask->setText( ui->tableWidget->item(currentRow,2)->text());ui->New_Gateway->setText( ui->tableWidget->item(currentRow,4)->text());ui->GateWayMac->setText( ui->tableWidget->item(currentRow,5)->text());ui->New_Port->setText( ui->tableWidget->item(currentRow,3)->text());ui->Serial_Number->setText( ui->tableWidget->item(currentRow,10)->text());quint8 functionid=ui->tableWidget->item(currentRow,9)->text().toInt();if((functionid % 2)>0){ui->checkBox_beep->setChecked(true);}else{ui->checkBox_beep->setChecked(false);}functionid=functionid/2;if((functionid % 2)>0){ui->checkBox_dhcp->setChecked(true);}else{ui->checkBox_dhcp->setChecked(false);}functionid=functionid/2;ui->comboBox_out->setCurrentIndex(functionid % 2);functionid=functionid/2;functionid=functionid % 8;if (functionid<=4){ui->comboBox_in->setCurrentIndex(functionid);}else{ui->comboBox_in->setCurrentIndex(0);}quint8 automac=ui->tableWidget->item(currentRow,8)->text().toInt();switch (automac){case 0:ui->radioButton1->setChecked(false);ui->radioButton2->setChecked(true);ui->radioButton3->setChecked(false);ui->radioButton4->setChecked(true);break;case 1:ui->radioButton1->setChecked(true);ui->radioButton2->setChecked(false);ui->radioButton3->setChecked(false);ui->radioButton4->setChecked(true);break;case 2:ui->radioButton1->setChecked(false);ui->radioButton2->setChecked(true);ui->radioButton3->setChecked(true);ui->radioButton4->setChecked(false);break;default:ui->radioButton1->setChecked(true);ui->radioButton2->setChecked(false);ui->radioButton3->setChecked(true);ui->radioButton4->setChecked(false);break;}
}void MainWindow::on_PBEditpara_clicked()
{int currentRow = ui->tableWidget->currentIndex().row();if (currentRow<0){QMessageBox::critical(this, "警告", "请选择一台在线设备再执行此功能!", QMessageBox::Ok);}else{ui->scrollArea_wifi->setVisible(false);ui->scrollArea->setVisible(true);}
}//将sendData缓冲数据发送到指定的设备IP端口---------------------------------------------------------------------------------------
void MainWindow:: SendBuffAct()
{QString RemoIPort=ui->textEdit_remoiport->toPlainText();QStringList liststr = RemoIPort.split(":");QHostAddress Remoip(liststr[0]);quint16 Remoport=liststr[1].toUInt();udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress(Remoip), Remoport);QString SendHex=getsystime()+" Send To: "+(Remoip.toString()+":"+QString::asprintf("%d",Remoport)+" ").mid(0,22);SendHex=SendHex+ByteArrayToHexString(sendData);listadditems(0,SendHex);
}//驱动设备蜂鸣响声+文字显示-------------------------------------------------------------------------------------------------
void MainWindow::on_PBSendDispBeep_clicked()
{sendData.clear();sendData.append(0x5A); //功能码quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();sendData.append(devno % 256); //机号低位sendData.append(devno / 256); //机号高位,高低位都为0表示所有机sendData.append(ui->CBbeep->currentIndex()); //蜂鸣响声代码,255表示不响声sendData.append(ui->spinBox_dispdelay->value()); //文字显示时长,QString dispstr=ui->textEdit_disp->toPlainText()+" "; //加空格是为了确保满屏34位显示QByteArray Dispbyte=dispstr.toLocal8Bit();for(int i=0;i<34;i++){sendData.append(Dispbyte[i]);}SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口
}//驱动设备蜂鸣响声-----------------------------------------------------------------------------------------------------------
void MainWindow::on_PBbeep_clicked()
{sendData.clear();sendData.append(0x96); //功能码quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();sendData.append(devno % 256); //机号低位sendData.append(devno / 256); //机号高位,高低位都为0表示所有机sendData.append(ui->CBbeep->currentIndex()); //蜂鸣响声代码SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口
}//驱动设备开启继电器----------------------------------------------------------------------------------------------------------
void MainWindow::on_PBSwitchOn_clicked()
{sendData.clear();sendData.append(0x78); //功能码quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();sendData.append(devno % 256); //机号低位sendData.append(devno / 256); //机号高位,高低位都为0表示所有机QString swithno="F"+QString::asprintf("%d",ui->CBSwitch->currentIndex());bool status;sendData.append(swithno.toUInt(&status,16)); //选择继电器quint16 deltime=ui->spinBox_swit->value();sendData.append(deltime % 256); //开启延时低位sendData.append(deltime / 256); //开启延时高位SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口
}//驱动设备关闭继电器----------------------------------------------------------------------------------------------------------
void MainWindow::on_PBSwitchOff_clicked()
{sendData.clear();sendData.append(0x78); //功能码quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();sendData.append(devno % 256); //机号低位sendData.append(devno / 256); //机号高位,高低位都为0表示所有机QString swithno="E"+QString::asprintf("%d",ui->CBSwitch->currentIndex());bool status;sendData.append(swithno.toUInt(&status,16)); //选择继电器quint16 deltime=ui->spinBox_swit->value();sendData.append(deltime % 256); //延时低位sendData.append(deltime / 256); //延时高位SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口
}//驱动设备显示文字+蜂鸣响声+播报TTS语音+开启继电器开关------------------------------------------------------------------------------
void MainWindow::on_PBSendDispTTS_clicked()
{if(ui->spinBox_voice->value()>16){ui->spinBox_voice->setValue(16);} //tts最大语音取值16QString strls="[v"+QString::asprintf("%d",ui->spinBox_voice->value())+"]";strls=strls+ui->textEdit_tts->toPlainText().trimmed();QByteArray SpeakArr=strls.toLocal8Bit(); //TS语音转换为Ansi码quint8 speakbytes=SpeakArr.size();quint8 dispbytes=34; //双行显示屏显示长度34,四行屏显示长度72sendData.clear();sendData.append(0x5c); //功能码quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();sendData.append(devno % 256); //机号低位sendData.append(devno / 256); //机号高位,高低位都为0表示所有机sendData.append(ui->CBbeep->currentIndex()); //蜂鸣响声代码,取值255表示不响QString swithno="F"+QString::asprintf("%d",ui->CBSwitch->currentIndex());bool status;sendData.append(swithno.toUInt(&status,16)); //选择继电器quint16 deltime=ui->spinBox_swit->value();sendData.append(deltime % 256); //延时低位sendData.append(deltime / 256); //延时高位sendData.append(ui->spinBox_dispdelay->value()); //文字显示时长,quint8 begindisp =0; //在显示屏中的哪个位置开始显示,一般取0sendData.append(begindisp);sendData.append(dispbytes); //显示文字长度sendData.append(speakbytes); //tts语音长茺QString dispstr=ui->textEdit_disp->toPlainText()+" "; //加空格是为了确保满屏34位显示QByteArray Dispbyte=dispstr.toLocal8Bit();for(int i=0;i<dispbytes;i++){sendData.append(Dispbyte[i]); //显示信息}for(int i=0;i<speakbytes;i++){sendData.append(SpeakArr[i]); //TTS语音信息}sendData.append(0x55); //防干扰后缀sendData.append(0xaa);sendData.append(0x66);sendData.append(0x99);SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口
}//驱动设备显示文字+蜂鸣响声+播报固定组合语音+开启继电器开关------------------------------------------------------------------------------
void MainWindow::on_PBSendDispSpk_clicked()
{QByteArray speakcode; //选择加入要播报的语音代码,最多可加入21个,各语音代码参看 语音列表栏speakcode.append(36);speakcode.append(1);speakcode.append(11);speakcode.append(2);speakcode.append(10);speakcode.append(3);speakcode.append(17);speakcode.append(4);speakcode.append(16);speakcode.append(5);speakcode.append(15);qint8 lensy=speakcode.size(); //语音代码长度quint8 begindisp =0; //在显示屏中的哪个位置开始显示,一般取0quint8 dispbytes=34; //双行显示屏显示长度34sendData.clear();sendData.append(0x5b); //功能码quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();sendData.append(devno % 256); //机号低位sendData.append(devno / 256); //机号高位,高低位都为0表示所有机sendData.append(ui->CBbeep->currentIndex()); //蜂鸣响声代码,取值255表示不响QString swithno="F"+QString::asprintf("%d",ui->CBSwitch->currentIndex());bool status;sendData.append(swithno.toUInt(&status,16)); //选择继电器quint16 deltime=ui->spinBox_swit->value();sendData.append(deltime % 256); //延时低位sendData.append(deltime / 256); //延时高位sendData.append(ui->spinBox_dispdelay->value()); //文字显示时长,sendData.append(begindisp); //显示起始位置sendData.append(dispbytes); //显示字符串长度sendData.append(lensy); //语音代码条数QString dispstr=ui->textEdit_disp->toPlainText()+" "; //加空格是为了确保满屏34位显示QByteArray Dispbyte=dispstr.toLocal8Bit();for(int i=0;i<dispbytes;i++){sendData.append(Dispbyte[i]); //显示信息}for(int i=0;i<lensy;i++){sendData.append(speakcode[i]); //语音信息}sendData.append(0x55); //防干扰后缀sendData.append(0xaa);sendData.append(0x66);sendData.append(0x99);SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口
}//指定扇区密钥读取M1卡扇区数据----------------------------------------------------------------------------------------
void MainWindow::on_PBReadCard_clicked()
{unsigned char cardnobuf[4]; //卡号unsigned char keybuf[6]; //密钥int keylen;int cardnolen;QString cardnostr ="00000000"; // ui->textEdit_M1UID->toPlainText().trimmed(); "00000000"表示可能操作感应区内任意卡,如要操作特定卡可指定卡号cardnolen=checkhexdata(cardnostr,cardnobuf);if(cardnolen<4){QMessageBox::critical(NULL, "提示", "请输入8位正确的16进制卡号!");ui->textEdit_M1UID->setFocus();return;}QString keyinf = ui->textEdit_authkey->toPlainText().trimmed();keylen=checkhexdata(keyinf,keybuf);if(keylen<6){QMessageBox::critical(NULL, "提示", "请输入12位正确的16进制卡密码!");ui->textEdit_authkey->setFocus();return;}sendData.clear();sendData.append(0x3b); //功能码quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();sendData.append(devno % 256); //机号低位sendData.append(devno / 256); //机号高位,高低位都为0表示所有机sendData.append(0x01); //本次操作的区数for (int i=0 ;i<4;i++){ //指定读写的卡号,全为0 表示可读写任意卡sendData.append(cardnobuf[i]);}sendData.append(ui->CBPage->currentIndex()); //本次操作的扇区号sendData.append(ui->CBauth->currentIndex()); //为1以B密码来验证旧密码,为0以A密码来验证旧密码for (int i=0 ;i<6;i++){sendData.append(keybuf[i]); //认证密钥}SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口
}//指定扇区密钥写入数据到M1卡扇区----------------------------------------------------------------------------------------
void MainWindow::on_PBWriteCard_clicked()
{unsigned char cardnobuf[4]; //卡号unsigned char keybuf[6]; //密钥unsigned char databuf[50]; //写卡数据int keylen;int cardnolen;int datalen;QString cardnostr ="00000000"; // ui->textEdit_M1UID->toPlainText().trimmed(); "00000000"表示可能操作感应区内任意卡,如要操作特定卡可指定卡号cardnolen=checkhexdata(cardnostr,cardnobuf);if(cardnolen<4){QMessageBox::critical(NULL, "提示", "请输入8位正确的16进制卡号!");ui->textEdit_M1UID->setFocus();return;}QString keyinf = ui->textEdit_authkey->toPlainText().trimmed();keylen=checkhexdata(keyinf,keybuf);if(keylen<6){QMessageBox::critical(NULL, "提示", "请输入12位正确的16进制卡密码!");ui->textEdit_authkey->setFocus();return;}QString datastr = ui->textEdit_data->toPlainText().trimmed();datalen=checkhexdata(datastr,databuf);if(datalen<48){int answ=QMessageBox::question (this, "警告", "有效的写卡数据不足一扇区48字节,是否要补0写入?", QMessageBox::Ok, QMessageBox::Cancel);if (answ !=1024){ui->textEdit_data->setFocus();return;}}sendData.clear();sendData.append(0x3d); //功能码quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();sendData.append(devno % 256); //机号低位sendData.append(devno / 256); //机号高位,高低位都为0表示所有机sendData.append(0x01); //本次操作的区数for (int i=0 ;i<4;i++){ //指定读写的卡号,全为0 表示可读写任意卡sendData.append(cardnobuf[i]);}sendData.append(ui->CBPage->currentIndex()); //本次操作的扇区号sendData.append(ui->CBauth->currentIndex()); //为1以B密码来验证旧密码,为0以A密码来验证旧密码for (int i=0 ;i<6;i++){sendData.append(keybuf[i]); //认证密钥}for (int i=0 ;i<48;i++){sendData.append(databuf[i]); //写卡数据}sendData.append(0x55); //防干扰后缀sendData.append(0xaa);sendData.append(0x66);sendData.append(0x99);SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口
}//修改M1卡扇区密钥-------------------------------------------------------------------------------------------------
void MainWindow::on_PBChangeKey_clicked()
{int answ=QMessageBox::question (this, "警告", "执行此操作前请记住卡片新密钥,否则卡片将报废!是否继续?", QMessageBox::Ok, QMessageBox::Cancel);if (answ !=1024){ui->textEdit_data->setFocus();return;}unsigned char cardnobuf[4]; //卡号unsigned char keybuf[6]; //密钥unsigned char newkeybuf[20]; //新密钥int keylen;int cardnolen;int newkeylen;QString cardnostr ="00000000"; // ui->textEdit_M1UID->toPlainText().trimmed(); "00000000"表示可能操作感应区内任意卡,如要操作特定卡可指定卡号cardnolen=checkhexdata(cardnostr,cardnobuf);if(cardnolen<4){QMessageBox::critical(NULL, "提示", "请输入8位正确的16进制卡号!");ui->textEdit_M1UID->setFocus();return;}QString keyinf = ui->textEdit_authkey->toPlainText().trimmed();keylen=checkhexdata(keyinf,keybuf);if(keylen<6){QMessageBox::critical(NULL, "提示", "请输入12位正确的16进制卡密码!");ui->textEdit_authkey->setFocus();return;}QString newkey = ui->textEdit_newkey->toPlainText().trimmed();newkeylen=checkhexdata(newkey,newkeybuf);if(newkeylen<16){QMessageBox::critical(NULL, "提示", "请输16进制 6字节A密码+4字节控制位+6字节B密码 !");ui->textEdit_newkey->setFocus();return;}sendData.clear();sendData.append(0x3a); //功能码quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();sendData.append(devno % 256); //机号低位sendData.append(devno / 256); //机号高位,高低位都为0表示所有机sendData.append(0x01); //本次操作的区数for (int i=0 ;i<4;i++){ //指定读写的卡号,全为0 表示可读写任意卡sendData.append(cardnobuf[i]);}sendData.append(ui->CBPage->currentIndex()); //本次操作的扇区号quint8 auth=ui->CBauth->currentIndex(); //为1以B密码来验证旧密码,为0以A密码来验证旧密码auth=auth+ui->ChangeKey->currentIndex()*2; //修改A、B、控制位sendData.append(auth);for (int i=0 ;i<6;i++){sendData.append(keybuf[i]); //认证密钥}for (int i=0 ;i<16;i++){sendData.append(newkeybuf[i]); //新A密钥、控制位、B密钥}sendData.append(0x55); //防干扰后缀sendData.append(0xaa);sendData.append(0x66);sendData.append(0x99);SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口
}void MainWindow::on_PBSetRW_clicked()
{unsigned char keybuf[6]; //密钥int keylen;QString keyinf = ui->textEdit_authkey->toPlainText().trimmed();keylen=checkhexdata(keyinf,keybuf);if(keylen<6){QMessageBox::critical(NULL, "提示", "请输入12位正确的16进制卡密码!");ui->textEdit_authkey->setFocus();return;}quint8 Sector= ui->CBPage->currentIndex(); //扇区号quint8 pages;int answ=QMessageBox::information (this, "提示", "按 OK 键把读写器设为主动读取"+QString::asprintf("%d",Sector)+"扇区数据,按 No 键将读写器设为只读卡号不读扇区数据,按 Cancel 退出本次操作。", QMessageBox::Ok | QMessageBox::No | QMessageBox::Cancel);if (answ==QMessageBox::No){pages=0;sendData.clear();sendData.append(0x4b); //功能码quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();sendData.append(devno % 256); //机号低位sendData.append(devno / 256); //机号高位,高低位都为0表示所有机sendData.append(pages); //本次操作的区数sendData.append(0x55); //防干扰后缀sendData.append(0xaa);sendData.append(0x66);sendData.append(0x99);SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口}else if(answ==QMessageBox::Ok){pages=1;sendData.clear();sendData.append(0x4b); //功能码quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();sendData.append(devno % 256); //机号低位sendData.append(devno / 256); //机号高位,高低位都为0表示所有机sendData.append(pages); //主动读取的扇区数,如果要开通几个扇区这里就填几if (ui->CBauth->currentIndex()==0){Sector=Sector+128;}sendData.append(Sector); //扇区号及密码认证类型for (int i=0;i<6;i++){sendData.append(keybuf[i]); //扇区认证密钥} //如果读多个扇区也按此结构加入,可以开通全部的16个扇区sendData.append(0x55); //防干扰后缀sendData.append(0xaa);sendData.append(0x66);sendData.append(0x99);SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口}
}void MainWindow::on_PBcopylist_clicked()
{QString listinf;int row=ui->listWidget->count();if (row<1){return;}else{for (int i=0;i<row;i++){QListWidgetItem *item = ui->listWidget->item(i);listinf=listinf+item->text()+"\n";}QClipboard *clipboard = QApplication::clipboard();clipboard->setText(listinf);QMessageBox::information(this, "提示", "显示数据报文已拷贝到剪切板");}
}//接收到刷卡数据立即回应--------------------------------------------------------------------------
void MainWindow::Respondinfo(QString Dispinf,QHostAddress ip,quint16 port,QString DeviceNumber)
{QByteArray RespBuff;RespBuff.append(0x5A); //功能码quint16 devno=DeviceNumber.toUInt();RespBuff.append(devno % 256); //机号低位RespBuff.append(devno / 256); //机号高位,高低位都为0表示所有机RespBuff.append(ui->CBbeep->currentIndex()); //蜂鸣响声代码,255表示不响声RespBuff.append(ui->spinBox_dispdelay->value()); //文字显示时长,QString dispstr=Dispinf+" "; //加空格是为了确保满屏34位显示QByteArray Dispbyte=dispstr.toLocal8Bit();for(int i=0;i<34;i++){RespBuff.append(Dispbyte[i]);}udpSocket->writeDatagram(RespBuff.constData(), RespBuff.size(), QHostAddress(ip), port);QString SendHex=getsystime()+" Send To: "+(ip.toString()+":"+QString::asprintf("%d",port)+" ").mid(0,22);SendHex=SendHex+ByteArrayToHexString(RespBuff);listadditems(0,SendHex);
}void MainWindow::on_pushButton_9_clicked()
{ui->scrollArea->setVisible(false);
}void MainWindow::on_pushButton_clicked()
{ui->New_ServerIP->setText(ui->CBIP->currentText().trimmed());
}void MainWindow::on_pushButton_2_clicked()
{ui->New_ServerIP->setText("255.255.255.255");ui->ServerMAC->setText("FF-FF-FF-FF-FF-FF");ui->radioButton1->setChecked(true);ui->radioButton2->setChecked(false);
}void MainWindow::on_pushButton_4_clicked()
{ui->New_ServerIP->setText("119.29.167.63");ui->ServerMAC->setText("FF-FF-FF-FF-FF-FF");ui->radioButton1->setChecked(true);ui->radioButton2->setChecked(false);
}void MainWindow::on_pushButton_3_clicked()
{QString serverip=ui->CBIP->currentText().trimmed();ui->New_ServerIP->setText(serverip);QString servermac=getMacByIp(serverip);servermac=servermac.replace(":","-");if(servermac==""){servermac="FF-FF-FF-FF-FF-FF";}ui->ServerMAC->setText(servermac);
}void MainWindow::on_pushButton_7_clicked()
{QString gateway=ui->New_Gateway->text().trimmed();QString gatemac=getMacByIp(gateway);gatemac=gatemac.replace(":","-");if (gatemac==""){gatemac="FF-FF-FF-FF-FF-FF";}ui->GateWayMac->setText(gatemac);
}void MainWindow::on_pushButton_8_clicked()
{if (ui->radioButton1->isChecked()){ui->ServerMAC->setText("FF-FF-FF-FF-FF-FF");}if (ui->radioButton3->isChecked()){ui->GateWayMac->setText("FF-FF-FF-FF-FF-FF");}QString newip=ui->New_IP->text().trimmed();if (!isValidIP(newip)){QMessageBox::critical(NULL, "提示", "请输入有效的设备IP!");ui->New_IP->setFocus();return;}QString newmask=ui->New_Mask->text().trimmed();if (!isValidIP(newmask)){QMessageBox::critical(NULL, "提示", "请输入有效的设备掩码!");ui->New_Mask->setFocus();return;}QString newserverip=ui->New_ServerIP->text().trimmed();if (!isValidIP(newserverip)){QMessageBox::critical(NULL, "提示", "请输入有效的远程服务器ip!");ui->New_ServerIP->setFocus();return;}QString newgateway=ui->New_Gateway->text().trimmed();if (!isValidIP(newgateway)){QMessageBox::critical(NULL, "提示", "请输入有效的网关!");ui->New_Gateway->setFocus();return;}QString servermac=ui->ServerMAC->text().trimmed();if (!isValidMac(servermac)){QMessageBox::critical(NULL, "提示", "请输入有效的远程服务器MAC!");ui->ServerMAC->setFocus();return;}QString gatemac=ui->GateWayMac->text().trimmed();if (!isValidMac(gatemac)){QMessageBox::critical(NULL, "提示", "请输入有效的网关MAC!");ui->GateWayMac->setFocus();return;}bool ok;sendData.clear();sendData.append(0xf9); //功能码QStringList liststr = newip.split("."); //新IPfor (int i=0 ;i<4;i++){sendData.append(liststr[i].toInt());}liststr = newmask.split("."); //掩码for (int i=0 ;i<4;i++){sendData.append(liststr[i].toInt());}liststr = newserverip.split("."); //远程服务器IPfor (int i=0 ;i<4;i++){sendData.append(liststr[i].toInt());}liststr = servermac.split("-"); //远程服务器MACfor (int i=0 ;i<6;i++){sendData.append(liststr[i].toInt(&ok,16));}liststr = newgateway.split("."); //网关for (int i=0 ;i<4;i++){sendData.append(liststr[i].toInt());}liststr = gatemac.split("-"); //网关MACfor (int i=0 ;i<6;i++){sendData.append(liststr[i].toInt(&ok,16));}quint16 devno=ui->New_Nember->text().toUInt();sendData.append(devno % 256); //机号低位sendData.append(devno / 256); //机号高位,高低位都为0表示所有机quint16 newport=ui->New_Port->text().toInt();sendData.append(newport % 256); //端口低位sendData.append(newport / 256); //端口高位QString seri=ui->Serial_Number->text().trimmed();liststr = seri.split("-"); //模块序号for (int i=0 ;i<4;i++){sendData.append(liststr[i].toInt());}quint8 searchid=0;if (ui->checkBox_beep->isChecked()){searchid=searchid+1;}if (ui->radioButton1->isChecked()){searchid=searchid+2;}if (ui->radioButton3->isChecked()){searchid=searchid+4;}if (ui->checkBox_dhcp->isChecked()){searchid=searchid+8;}if (ui->comboBox_out->currentIndex()==1){searchid=searchid+16;}searchid=searchid+ ui->comboBox_in->currentIndex()*32;sendData.append(searchid);sendData.append(0x55); //防干扰后缀sendData.append(0xaa);sendData.append(0x66);sendData.append(0x99);if (ui->checkBox_broadcast->isChecked()){ //使用广播方式发送指令QHostAddress broadcastAddress("255.255.255.255");quint16 port1 = 39169;udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1);QString dispinf=getsystime()+" Send To: "+("255.255.255.255:"+QString::number(port1)+" ").mid(0,22) ;dispinf=dispinf+ByteArrayToHexString(sendData);listadditems(0,dispinf);}else{SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口}
}void MainWindow::on_pushButton_SetTCP_clicked()
{sendData.clear();sendData.append(0x1d); //功能码quint16 devno=0; //机号,0表示所有机sendData.append(devno % 256); //机号低位sendData.append(devno / 256); //机号高位,高低位都为0表示所有机sendData.append(7); //指令长度sendData.append(0x5c); //修改TCP通讯端口功能码sendData.append(4); //数据长度quint16 devport=ui->New_Port->text().toUInt(); //读卡器端口sendData.append(devport % 256); //低位sendData.append(devport / 256); //高位quint16 serverport=ui->lineEdit_TCPRemoPort->text().toUInt(); //远程TCP服务器端口sendData.append(serverport % 256); //低位sendData.append(serverport / 256); //高位quint8 crc=sendData[6]^sendData[7]^sendData[8]^sendData[9]; //数据校验位sendData.append(crc);sendData.append(0x55); //防干扰后缀sendData.append(0xaa);sendData.append(0x66);sendData.append(0x99);if (ui->checkBox_broadcast->isChecked()){ //使用广播方式发送指令QHostAddress broadcastAddress("255.255.255.255");quint16 port1 = 39169;udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1);QString dispinf=getsystime()+" Send To: "+("255.255.255.255:"+QString::number(port1)+" ").mid(0,22) ;dispinf=dispinf+ByteArrayToHexString(sendData);listadditems(0,dispinf);}else{SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口}
}void MainWindow::on_pushButton_SetHttp_clicked()
{QString filenamestr=ui->lineEdit_filename->text().trimmed();QByteArray filebyte=filenamestr.toLocal8Bit();if(filebyte.size()<1){QMessageBox::critical(NULL, "提示", "请输入正确的访问文件,可以是.asp\\.jsp\\.php等脚本文件!");ui->lineEdit_filename->setFocus();return;}sendData.clear();sendData.append(0x1d); //功能码quint16 devno=0; //机号,0表示所有机sendData.append(devno % 256); //机号低位sendData.append(devno / 256); //机号高位,高低位都为0表示所有机sendData.append(filebyte.size()+7); //指令长度sendData.append(0x5b); //设置http协议读卡器访问文件、端口、提效方式的识别码sendData.append(filebyte.size()+4); //数据长度sendData.append(ui->comboBox_Sendmodel->currentIndex()); //提交方式sendData.append(0xff);quint16 serverport=ui->lineEdit_HttpRemoPort->text().toUInt(); //远程http服务器端口sendData.append(serverport % 256); //低位sendData.append(serverport / 256); //高位quint8 crc= sendData[6]^ sendData[7]^ sendData[8]^sendData[9];for(int i=0;i<filebyte.size();i++){sendData.append(filebyte[i]); //访问文件crc=crc ^filebyte[i];}sendData.append(crc);sendData.append(0x55); //防干扰后缀sendData.append(0xaa);sendData.append(0x66);sendData.append(0x99);if (ui->checkBox_broadcast->isChecked()){ //使用广播方式发送指令QHostAddress broadcastAddress("255.255.255.255");quint16 port1 = 39169;udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1);QString dispinf=getsystime()+" Send To: "+("255.255.255.255:"+QString::number(port1)+" ").mid(0,22) ;dispinf=dispinf+ByteArrayToHexString(sendData);listadditems(0,dispinf);}else{SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口}
}void MainWindow::on_pushButton_16_clicked()
{ui->scrollArea_wifi->setVisible(false);
}void MainWindow::on_PBClear_2_clicked()
{ui->scrollArea->setVisible(false);ui->scrollArea_wifi->setVisible(true);
}void MainWindow::on_radioButton_IP_toggled(bool checked)
{if(ui->radioButton_IP->isChecked()){ui->groupBox_dhcp->setVisible(true);}else{ui->groupBox_dhcp->setVisible(false);}
}void MainWindow::on_pushButton_SetUp_clicked()
{QString wifiName=ui->lineEdit_SSID->text().trimmed();QByteArray wifiNamearry=wifiName.toUtf8(); //注意编码格式if(wifiNamearry.size()<1 || wifiNamearry.size()>60){QMessageBox::critical(NULL, "提示", "WIFI热点名称长度不可大于60,不可为空!");ui->lineEdit_SSID->setFocus();return;}QString wifipass=ui->lineEdit_Password->text().trimmed();QByteArray wifipassarry=wifipass.toUtf8(); //注意编码格式if(wifipassarry.size()>64){QMessageBox::critical(NULL, "提示", "WIFI密码长度不可以大于64!");ui->lineEdit_Password->setFocus();return;}sendData.clear();sendData.append(0xf7); //功能码quint16 devno=0; //机号,0表示所有机sendData.append(devno % 256); //机号低位sendData.append(devno / 256); //机号高位,高低位都为0表示所有机sendData.append(wifiNamearry.size()); //热点名称长度quint8 passlen=0;if(ui->checkBox_wifikey->isChecked()){passlen=wifipassarry.size();}sendData.append(passlen); //密码长度int i=0;for (i=0;i<wifiNamearry.size();i++){sendData.append(wifiNamearry[i]);}quint8 bytebit=0;while (sendData.size()<65){sendData.append(bytebit);}for (i=0;i<passlen;i++){sendData.append(wifipassarry[i]);}while (sendData.size()<129){sendData.append(bytebit);}if(ui->radioButton_IP->isChecked()){sendData.append(1);QString ipstr=ui->lineEdit_IP->text().trimmed();if (!isValidIP(ipstr)){QMessageBox::critical(NULL, "提示", "请输入有效的设备IP!");ui->lineEdit_IP->setFocus();return;}QString mskstr=ui->lineEdit_mask->text().trimmed();if (!isValidIP(mskstr)){QMessageBox::critical(NULL, "提示", "请输入正确的读卡器子网掩码!");ui->lineEdit_mask->setFocus();return;}QString gatewaystr=ui->lineEdit_gateway->text().trimmed();if (!isValidIP(gatewaystr)){QMessageBox::critical(NULL, "提示", "请输入正确的读卡器网关!");ui->lineEdit_mask->setFocus();return;}QStringList liststr = ipstr.split("."); //IPfor (int i=0 ;i<4;i++){sendData.append(liststr[i].toInt());}liststr = mskstr.split("."); //掩码for (int i=0 ;i<4;i++){sendData.append(liststr[i].toInt());}liststr = gatewaystr.split("."); //网关for (int i=0 ;i<4;i++){sendData.append(liststr[i].toInt());}}else{sendData.append(bytebit);while (sendData.size()<142){sendData.append(bytebit);}}sendData.append(ui->comboBox_Sendmode->currentIndex());sendData.append(0x55); //防干扰后缀sendData.append(0xaa);sendData.append(0x66);sendData.append(0x99);SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口
}void MainWindow::on_pushButton_Read_clicked()
{ui->listWidget_wifi->clear();sendData.clear();sendData.append(0xa4); //功能码quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();sendData.append(devno % 256); //机号低位sendData.append(devno / 256); //机号高位,高低位都为0表示所有机SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口
}
相关文章:

Qt_C++ RFID网络读卡器Socket Udp通讯示例源码
本示例使用的设备: WIFI/TCP/UDP/HTTP协议RFID液显网络读卡器可二次开发语音播报POE-淘宝网 (taobao.com) #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QHostInfo> #include <QNetworkInterface> #include <…...
C++ 实现Python 列表list 的两种方法
1、vector里面放多种参数。在C中,如果你想要在std::vector中存储不同类型的参数,你可以使用std::any(C17及以上)或std::variant(C17以前的版本需要使用Boost库或者C17及以上标准)。以下是使用std::vector&l…...

vue3+ elementPlus PC端开发 遇到页面已进入就form校验了的问题
form表单一进页面就校验了 rules里配置的 require 提示语 如图所示代码是这样的 最后发现是form表单下面的一个按钮的展示规则 会导致规则校验 canAddInsured 这个字段的变化会导致form表单校验 这个字段是computed maxInsureds 也是个computed监听 maxInsured.value >1 就…...
transformers DataCollator介绍
本博客主要介绍 transformers DataCollator的使用 from transformers import AutoTokenizer, AutoModel, \DataCollatorForSeq2Seq, DataCollatorWithPadding, \DataCollatorForTokenClassification, DefaultDataCollator, DataCollatorForLanguageModelingPRETRAIN_MODEL &qu…...

rust学习(字节数组转string)
最新在写数据传输相关的操作,发现string一个有趣的现象,代码如下: fn main() {let mut data:[u8;32] [0;32];data[0] a as u8;let my_str1 String::from_utf8_lossy(&data);let my_str my_str1.trim();println!("my_str len is…...

Docker:技术架构演进
文章目录 基本概念架构演进单机架构应用数据分离架构应用服务集群架构读写分离/主从分离架构冷热分离架构垂直分库微服务容器编排架构 本篇开始进行对于Docker的学习,Docker是一个陌生的词汇,那么本篇开始就先从技术架构的角度出发,先对于技术…...

汽车MCU虚拟化--对中断虚拟化的思考(2)
目录 1.引入 2.TC4xx如何实现中断虚拟化 3.小结 1.引入 其实不管内核怎么变,针对中断虚拟化无非就是上面两种,要么透传给VM,要么由Hypervisor统一分发。汽车MCU虚拟化--对中断虚拟化的思考(1)-CSDN博客 那么,作为车规MCU龙头…...

python的继承
本章正式开始之前,先让我们回顾一下什么是 对象 ? 什么是 类 ? 小贝 喜欢 猫咪,今年领养了一只名叫 Kitty 的 布偶猫。则下列哪项是 对象 呢? A. 猫咪 B. Kitty C. 布偶猫 相比之下,闻闻 更喜欢 犬科 动…...

组件的注册和引用
在Vue中,开发者可以将页面中独立的、可重用的部分封装成组件,对组件的结构,样式和行为进行设置。组件是 Vue 的基本结构单元,组件之间可以相互引用。 一.注册组件 当在Vue项目中定义了一个新的组件后,要想在其他组件中…...

诊所如何赢得患者?做好这两点很关键!
大家都知道,社区周边的诊所原本是居民看病的第一选择,方便又快捷。但现在很多诊所服务都差不多,没有自己的特色,这就让患者有点难选择了。那诊所怎么做才能更吸引患者呢?其实,关键是要抓住患者的心…...

Qwen2本地部署的实战教程
大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…...

html+CSS+js部分基础运用15
1、完成输入框内容的实时反向输出。 2、银行账户余额变动自动通知项目。 设计要求:单击按钮后,余额按照输入框的数额减少,同时将按钮式的提示信息(金额)同步改变。利用侦听属性实现余额发生变化时发出提示信息&#x…...

从零开始学JAVA
一、编写Hello world程序 public class JavaMain1 {//主程序执行入口,main方法public static void main(String[] args){System.out.println("Hello world!");} } 运行结果 Hello world! java编写主程序常见错误: 1、System ---首字母没有…...
MySQL(四)查询
1、MySQL限性约束 —非空、唯一(自增)、主外键、检查(MySQL存在但是不能用)。 约束主要完成对数据的校验,保证数据库数据的完整性;如果有相互依赖数据,保证该数据不被删除。 1)常用五类约束 not null :非空约束,指定某列不为空。 unique:唯一约束,指定某列和几列组…...
嵌入式学习——网络编程(TCP)——day31
1. TCP和UDP的区别 TCP(Transmission Control Protocol,传输控制协议) UDP(User Datagram Protocol,用户数据报协议) 1.1 连接方式 TCP 是面向连接的协议,它在数据传输前需要通过三次握手建立…...

[STM32]定位器与PWM的LED控制
目录 1. 深入了解STM32定时器原理,掌握脉宽调制pwm生成方法。 (1)STM32定时器原理 原理概述 STM32定时器的常见模式 使用步骤 (2)脉宽调制pwm生成方法。 2. 实验 (1)LED亮灭 代码 测试效果 (2)呼吸灯 代码 测试效果 3.总结 1. 深入了解STM32定时器原…...

可视化数据科学平台在信贷领域应用系列五:零代码可视化建模
信贷风控模型是金融机构风险管理的核心工具,在信贷风险管理工作中扮演着至关重要的角色。随着信贷市场的环境不断变化,信贷业务的风险日趋复杂化和隐蔽化,开发和应用准确高效的信贷风控模型显得尤为重要。信贷风险控制面临着越来越大的挑战和…...
Windows 11广告植入“另辟蹊径”:PC Manager暗示若不使用必应搜索,你的系统可能需要“修复”
Edge浏览器近期增添了许多实用的新功能,如侧边栏、休眠标签页和沉浸式阅读器。话虽如此,浏览器中仍有一部分功能被部分用户视为“冗余软件”和不必要的累赘。 随着Windows 11用户逐渐习惯操作系统关键位置出现越来越多的广告,微软似乎正尝试以…...

一线教师教学工具汇总
亲爱的教师们!我们的教学工具箱里也该更新换代啦!今天,就让我来给大家安利一波超实用的教学神器: 百度文库小程序 —— 在线图书馆 百度文库,一个宝藏级的在线文档分享平台!在这里,你可以找到海…...

【数据结构】栈和队列-->理解和实现(赋源码)
Toc 欢迎光临我的Blog,喜欢就点歌关注吧♥ 前面介绍了顺序表、单链表、双向循环链表,基本上已经结束了链表的讲解,今天谈一下栈、队列。可以简单的说是前面学习的一特殊化实现,但是总体是相似的。 前言 栈是一种特殊的线性表&…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...

接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...

windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...