基于QT的电力参数采集系统 课程设计文档和C++源码

完整文档和客户端C++源码

文档预览截图:

目录

1. 设计的任务与要求        1
1.1. 课程设计的任务        1
1.2. 课程设计的要求        1
2. 设计方案制定        2
2.1. 设计的原理        2
2.2. 设计的方案        5
3. 设计方案实施        6
3.1. 开发环境        6
3.2. 主要模拟平台        6
3.3. 设计功能的实施        8
4. 系统测试与数据分析        11
4.1. 系统测试        11
4.2. 数据分析        13
5. 总结及心得体会        14
6. 参考文献        15

1.        设计的任务与要求
1.1.        课程设计的任务
在科技飞速发展与智能用电系统的普及的大背景下,高性能高要求的电力参数系统的相关研究也备受关注。计算机技术与无线传输技术的发展,为由普通功能型电力参数向多功能,高精度,高可靠,可移植,无线抄表的电力参数监测系统的发展提供了充足的技术支持。电力参数采集技术不断发展,朝着越来越智能,成本越来越低的方向发展。
本次实训项目,采用QT设计一个电力参数采集和控制系统。通过这次学习,专业技能和实验技能,调试代码能力得到有效锻炼,不论对于知识系统的巩固还是对以后走到未来岗位上都是起到很好的帮助作用。
此方案由资深讲师向高校学生展示完整嵌入式项目设计开发流程及方法,以及嵌入式核心技术运用等满足企业真实岗位需求的实用内容,帮助学生快速熟悉嵌入式项目开发的代码编写规范,并在行业专家的引导下,体验一个全真案例的模拟过程。
同时通过更多行业典型应用的示范分析帮助学生更贴近企业的真实需求和行业的发展,为进一步在嵌入式研发行业中发展打下坚实基础。
1.2.        课程设计的要求
(1)        使用Peacefail电力参数模块(实训将采用软件模拟的方式来实现,不需要准备硬件)。
(2)        测量电路电压,频率,功率,电能等参数。
(3)        发送至使用由C++的QT creator编制的上位机程序进行数据的显示。

2.        设计方案制定
2.1.        设计的原理
该项目使用的Modbus协议最初由施耐德公司为其PLC制定的一种通讯协议。在本项目中,下位机采用软件模拟的方式来代替Peacefail电力参数模块来实现采集交流电路中的电力参数, 如电压, 电流, 功率等, 并发送至使用由C++的QT creator编制的上位机程序进行数据的显示。
完整内容请下载完整文档附件参阅

部分源码:完整源码请下载附件

void MainWindow::on_btnOpenSerial_clicked()
{
    QPushButton* btn = findChild<QPushButton*>("btnOpenSerial", Qt::FindChildOption::FindChildrenRecursively);
    if(btn->text() == "打开串口"){//打开
        if(m_serialPort->isOpen())//如果串口已经打开了 先给他关闭了
        {
            m_serialPort->clear();
            m_serialPort->close();
        }

        //设置串口名字 假设我们上面已经成功获取到了 并且使用第一个
        QComboBox* serialCbo = findChild<QComboBox*>("cboSerial", Qt::FindChildOption::FindChildrenRecursively);
        m_serialPort->setPortName(serialCbo->currentText());

        QLabel* serialState = findChild<QLabel*>("lblSerialState", Qt::FindChildOption::FindChildrenRecursively);
        if(!m_serialPort->open(QIODevice::ReadWrite))//用ReadWrite 的模式尝试打开串口
        {
            serialState->setText(serialCbo->currentText() + "打开失败!");
            return;
        }
        //打开成功
        serialState->setText(serialCbo->currentText() + "打开成功!");

        m_serialPort->setBaudRate(QSerialPort::Baud9600,QSerialPort::AllDirections);//设置波特率和读写方向
        m_serialPort->setDataBits(QSerialPort::Data8);        //数据位为8位
        m_serialPort->setFlowControl(QSerialPort::NoFlowControl);//无流控制
        m_serialPort->setParity(QSerialPort::NoParity);    //无校验位
        m_serialPort->setStopBits(QSerialPort::OneStop); //一位停止位

        //连接信号槽 当下位机发送数据QSerialPortInfo 会发送个 readyRead 信号,我们定义个槽void receiveInfo()解析数据
        connect(m_serialPort,SIGNAL(readyRead()),this, SLOT(receiveInfo()));
        connect(m_timer,SIGNAL(timeout()),this, SLOT(timeUpdate()));
        btn->setText("关闭串口");
    }else {//关闭
        QComboBox* serialCbo = findChild<QComboBox*>("cboSerial", Qt::FindChildOption::FindChildrenRecursively);
        QLabel* serialState = findChild<QLabel*>("lblSerialState", Qt::FindChildOption::FindChildrenRecursively);
        if (m_serialPort->isOpen())
        {
            m_serialPort->close();
            serialState->setText(serialCbo->currentText() + "关闭成功!");
            btn->setText("打开串口");
            return;
        }
        serialState->setText(serialCbo->currentText() + "不能重复关闭!");
    }
}

float power;
int i = 1;

QByteArray buf;

void MainWindow::receiveInfo()
{
    m_timer->start(100);
    buf.append(m_serialPort->readAll());
}

void MainWindow::timeUpdate(){
    m_timer->stop();
    if(buf.length() > 0){
        qDebug() << "receive..." << buf.length();
        //上述方法不是每次都返回21,每次可能不能完全读完,分几次读取,或一次读完的都有
        if(buf.length() != 25){//只对正确的情况做处理,其余数据不全的忽略
            return;
        }

        //buf[17] 返回类型为 QByteRef 类型,并非char,不能用它
        //而应该用at()

        //取电压
        qDebug("volt %02x-%02x", buf.at(3), buf.at(4));
        float volt = ((unsigned char)buf.at(3) << 8) + (unsigned char)buf.at(4);
        qDebug() << volt;
        volt *= 0.1;
        QString data = QString("电压:%1 V").arg(volt);
        QLabel* lblVolt = findChild<QLabel*>("lblVolt", Qt::FindChildOption::FindChildrenRecursively);
        lblVolt->setText(data);

        //取电流
        float circuit = (buf.at(5) << 8) + buf.at(6);
        circuit += ((buf.at(7) << 8) + buf.at(8)) << 16;

        data = QString("电流:%1 mA").arg(circuit);
        QLabel* lblCircut = findChild<QLabel*>("lblCircut", Qt::FindChildOption::FindChildrenRecursively);
        lblCircut->setText(data);

        //取功率
        power = (buf.at(9) << 8) + buf.at(10);
        power += ((buf.at(11) << 8) + buf.at(12)) << 16;
        power *= 0.1;

        data = QString("功率:%1 W").arg(power);
        QLabel* lblPower = findChild<QLabel*>("lblPower", Qt::FindChildOption::FindChildrenRecursively);
        lblPower->setText(data);

        //取频率
        qDebug("%02x-%02x", buf.at(17), buf.at(18));
        float freq = ((unsigned char)buf.at(17) << 8) + (unsigned char)buf.at(18);

        freq *= 0.1;
        data = QString("频率:%1 Hz").arg(freq);
        QLabel* lblFreq = findChild<QLabel*>("lblFreq", Qt::FindChildOption::FindChildrenRecursively);
        lblFreq->setText(data);

        QLabel* serialState = findChild<QLabel*>("lblSerialState", Qt::FindChildOption::FindChildrenRecursively);
        QString statebuf = QString("正在采集 %1 次").arg(i);
        serialState->setText(statebuf);

        //update 图形
        //PaintFrame* frame = findChild<PaintFrame*>("frame", Qt::FindChildOption::FindChildrenRecursively);
        //frame->update(i, 140-(int)power, i, 140);
    }
    buf.clear();
}