#include "widget.h"
#include "ui_widget.h"

#define UART_WAIT_MS 50

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
//    启动时关闭按钮
    disable__();
    // 限制输入范围
    QLineEdit *edit_1R5 = ui -> write_1R5_lineEdit;
    QLineEdit *edit_4R5 = ui -> write_4R5_lineEdit;
    QLineEdit *edit_8R0 = ui -> write_8R0_lineEdit;
    QLineEdit *rssi = ui -> write_lineEdit;
    QLineEdit *coefficient = ui -> write_Coefficient_lineEdit;
    QLineEdit *edit_ns = ui -> write_distance_NS_lineEdit;
    QLineEdit *edit_we = ui -> write_distance_WE_lineEdit;
    // 创建正则表达式对象
    QRegExp rx_0_100("^([0-9]|[1-9][0-9]|100)$");
    QRegExp rx_x_xxxx("^([0-9])(\\.\\d{4})$");
    QRegExp rx__xx("^\\d+\\.\\d{2}$");
    // 创建 QRegExpValidator 对象
    QRegExpValidator *pReg_0_100 = new QRegExpValidator(rx_0_100, this);
    QRegExpValidator *pReg_x_xxxx = new QRegExpValidator(rx_x_xxxx, this);
    QRegExpValidator *pReg__xx = new QRegExpValidator(rx__xx, this);
    edit_1R5->setValidator(pReg_0_100);
    edit_4R5->setValidator(pReg_0_100);
    edit_8R0->setValidator(pReg_0_100);
    rssi->setValidator(pReg_0_100);
    coefficient->setValidator(pReg_x_xxxx);
    edit_ns->setValidator(pReg__xx);
    edit_we->setValidator(pReg__xx);

    error1_status_label[0] = ui -> error1_status_label;
    error1_status_label[1] = ui -> error2_status_label;
    error1_status_label[2] = ui -> error3_status_label;
    error1_status_label[3] = ui -> error4_status_label;
    error1_status_label[4] = ui -> error5_status_label;
    error1_status_label[5] = ui -> error6_status_label;
    error1_status_label[6] = ui -> error7_status_label;
    error1_status_label[7] = ui -> error8_status_label;
    error1_status_label[8] = ui -> error9_status_label;
    error1_status_label[9] = ui -> error10_status_label;
    error1_status_label[10] = ui -> error11_status_label;
    error1_status_label[11] = ui -> error12_status_label;
    error1_status_label[12] = ui -> error13_status_label;
    error1_status_label[13] = ui -> error14_status_label;
    error1_status_label[14] = ui -> error15_status_label;
    error1_status_label[15] = ui -> error16_status_label;

    // 启动时刷新串口
    QStringList serialNamePort;
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        serialNamePort << info.portName() + "|" + info.description();
    }
    ui -> SerialPort_comboBox -> clear();
    ui -> SerialPort_comboBox -> addItems(serialNamePort);

    Serial_port = new QSerialPort(this);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::closeEvent(QCloseEvent *event)
{
//    退出提醒弹窗
    QMessageBox *Close_msgBox = new QMessageBox(QMessageBox::Question, "提示", "是否退出", QMessageBox::Yes | QMessageBox::No, this, Qt::WindowStaysOnTopHint);
    Close_msgBox -> setDefaultButton(QMessageBox::No);
    Close_msgBox -> button(QMessageBox::No) -> setText(u8"不退出");
    Close_msgBox -> button(QMessageBox::Yes) -> setText(u8"退出");
    int val = Close_msgBox -> exec();
    if(val == QMessageBox::No)
    {
        event -> ignore();
    }
    if(val == QMessageBox::Yes)
    {
        event -> accept();
    }
}

void Widget::disable__()
{
    ui->groupBox->setEnabled(false);
    ui->groupBox_2->setEnabled(false);
    ui->groupBox_3->setEnabled(false);
    // 未打开串口时不让开页面
    ui->main_tabWidget->setTabEnabled(1, false);
    ui->main_tabWidget->setTabEnabled(2, false);


    ui->Password_lineEdit->setEnabled(false);
    ui->ID_lineEdit->setEnabled(false);
    ui->label_10->setEnabled(false);
    ui->label_11->setEnabled(false);
    ui->Trans_password_pushButton->setEnabled(false);
}

void Widget::able__()
{
    ui->groupBox->setEnabled(true);
    ui->groupBox_2->setEnabled(true);
    ui->groupBox_3->setEnabled(true);
    // 未打开串口时不让开页面
    ui->main_tabWidget->setTabEnabled(1, true);
    ui->main_tabWidget->setTabEnabled(2, true);
}

uint16_t Widget::modbusCrc16(const uint8_t *data, const int len)
{
    uint16_t crc = 0xFFFF;
    for (int pos = 0; pos < len; pos++) {
        crc ^= *data++;
        for (int i = 0; i < 8; i++) {
            if ((crc & 0x0001) > 0)
                crc = (crc >> 1) ^ 0xA001;
            else
                crc = crc >> 1;
        }
    }
    return (crc<<8&0xFF00)|(crc>>8&0x00FF);
}

//串口刷新
void Widget::on_SerialPort_refresh_pushButton_clicked()
{
    QStringList serialNamePort;
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        serialNamePort << info.portName() + "|" + info.description();
    }
    ui -> SerialPort_comboBox -> clear();
    ui -> SerialPort_comboBox -> addItems(serialNamePort);
}

//打开关闭按钮状态
//1将打开按钮
//0将关闭按钮
int8_t open_button_status = 1;
void Widget::on_Open_Serial_pushButton_clicked()
{
    if(open_button_status == 1)
    {
        QSerialPort::BaudRate Baudrate = QSerialPort::Baud9600;
        QSerialPort::DataBits Databits = QSerialPort::Data8;
        QSerialPort::Parity Parity = QSerialPort::NoParity;
        QSerialPort::StopBits Stopbits = QSerialPort::OneStop;

        QComboBox *SerialPortbox = ui -> SerialPort_comboBox;
        QComboBox *Baudbox = ui -> BaudRate_comboBox;
        QComboBox *Databitsbox = ui -> DataBits_comboBox;
        QComboBox *Checkbitsbox = ui -> CheckBits_comboBox;
        QComboBox *Stopbitsbox = ui -> StopBits_comboBox;

        //波特率
        if(Baudbox -> currentText() == "4800"){
            Baudrate = QSerialPort::Baud4800;
        }
        else if(Baudbox -> currentText() == "9600"){
            Baudrate = QSerialPort::Baud9600;
        }
        else if(Baudbox -> currentText() == "19200"){
            Baudrate = QSerialPort::Baud19200;
        }
        else if(Baudbox -> currentText() == "38400"){
            Baudrate = QSerialPort::Baud38400;
        }
        else if(Baudbox -> currentText() == "57600"){
            Baudrate = QSerialPort::Baud57600;
        }
        else if(Baudbox -> currentText() == "115200"){
            Baudrate = QSerialPort::Baud115200;
        }
        else {
            QMessageBox::warning(this, "错误", "波特率未设置");
            return;
        }

        //数据位
        if(Databitsbox -> currentText() == "6"){
            Databits = QSerialPort::Data6;
        }
        else if(Databitsbox -> currentText() == "7"){
            Databits = QSerialPort::Data7;
        }
        else if(Databitsbox -> currentText() == "8"){
            Databits = QSerialPort::Data8;
        }
        else {
            QMessageBox::warning(this, "错误", "数据位未设置");
            return;
        }

        //校验位
        if(Checkbitsbox -> currentText() == "无"){
            Parity = QSerialPort::NoParity;
        }
        else if(Checkbitsbox -> currentText() == "奇"){
            Parity = QSerialPort::OddParity;
        }
        else if(Checkbitsbox -> currentText() == "偶"){
            Parity = QSerialPort::EvenParity;
        }
        else {
            QMessageBox::warning(this, "错误", "校验位未设置");
            return;
        }

       //停止位
        if(Stopbitsbox -> currentText() == "1"){
            Stopbits = QSerialPort::OneStop;
        }
        else if(Stopbitsbox -> currentText() == "1.5"){
            Stopbits = QSerialPort::OneAndHalfStop;
        }
        else if(Stopbitsbox -> currentText() == "2"){
            Stopbits = QSerialPort::TwoStop;
        }
        else {
            QMessageBox::warning(this, "错误", "停止位未设置");
            return;
        }

        //设置参数
        Serial_port -> setPort((const QSerialPortInfo)(SerialPortbox -> currentText().section('|', 0, 0)));
        Serial_port -> setBaudRate(Baudrate);
        Serial_port -> setDataBits(Databits);
        Serial_port -> setParity(Parity);
        Serial_port -> setStopBits(Stopbits);
        Serial_port -> setReadBufferSize(4096);
        if(Serial_port -> open(QIODevice::ReadWrite) == true){
            //        打开后将按钮变为关闭按钮,绿色指示标志
            ui -> Open_Serial_pushButton -> setText("关闭串口");
            ui -> serial_status_label -> setStyleSheet("QLabel { background-color :rgb(0, 144, 0); border-radius: 10px;}");
            //打开串口后禁止配置
            ui -> SerialPort_comboBox -> setEnabled(false);
            ui -> BaudRate_comboBox -> setEnabled(false);
            ui -> DataBits_comboBox -> setEnabled(false);
            ui -> CheckBits_comboBox -> setEnabled(false);
            ui -> StopBits_comboBox -> setEnabled(false);
            ui -> SerialPort_refresh_pushButton -> setEnabled(false);
            ui -> BaudRate_label -> setEnabled(false);
            ui -> DataBits_label -> setEnabled(false);
            ui -> CheckBits_label -> setEnabled(false);
            ui -> StopBits_label -> setEnabled(false);
//            串口打开后使能功能
            able__();

            open_button_status = !open_button_status;
        }
        else{
            QMessageBox::critical(this, "提示", "串口打开失败");
            return;
        }
    }
    else {
        //将按钮变为打开按钮,红色指示标志
        ui -> Open_Serial_pushButton ->setText("打开串口");
        ui -> serial_status_label -> setStyleSheet("QLabel { background-color :rgb(184, 0, 0); border-radius: 10px;}");
        Serial_port -> close();
        //关闭串口后允许配置
        ui -> SerialPort_comboBox -> setEnabled(true);
        ui -> BaudRate_comboBox -> setEnabled(true);
        ui -> DataBits_comboBox -> setEnabled(true);
        ui -> CheckBits_comboBox -> setEnabled(true);
        ui -> StopBits_comboBox -> setEnabled(true);
        ui -> SerialPort_refresh_pushButton -> setEnabled(true);
        ui -> BaudRate_label -> setEnabled(true);
        ui -> DataBits_label -> setEnabled(true);
        ui -> CheckBits_label -> setEnabled(true);
        ui -> StopBits_label -> setEnabled(true);
//            串口关闭后取消使能功能
        disable__();

        open_button_status = !open_button_status;
    }
}

//读取按钮
void Widget::on_get_data_pushButton_clicked()
{
    QByteArray sent_comand;

    sent_comand.append(static_cast<uint8_t>(0x30));
    sent_comand.append(static_cast<uint8_t>(0x03));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x1E));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x0B));

    uint8_t sent_comand_u8[sent_comand.length()];
    for(int i = 0; i < sent_comand.length(); i++)
    {
        sent_comand_u8[i] = sent_comand[i];
    }

    uint16_t crc_16_val = modbusCrc16(sent_comand_u8, sent_comand.length());

    sent_comand.append(crc_16_val >> 8);
    sent_comand.append(crc_16_val);

    Serial_port->write(sent_comand);

    //连接信号与槽
    //断开所有其他的信号与槽连接
    disconnect(Serial_port, &QSerialPort::readyRead, nullptr, nullptr);
    connect(Serial_port, SIGNAL(readyRead()), this, SLOT(get_configdata()), Qt::UniqueConnection);
}

std::array<bool, 16> getBits(unsigned short num) {
    std::array<bool, 16> bits;
    for (int i = 15; i >= 0; --i) {
        bits[15 - i] = ((num >> i) & 1);
    }
    return bits;
}

void Widget::get_configdata()
{
    //    接收数据,一会再接收,以便接收超长数据
    QByteArray readed_data;
    while(Serial_port->waitForReadyRead(UART_WAIT_MS)==true);
    readed_data.append(Serial_port -> readAll());

    //防止干扰
    while(readed_data.length() > 1)
    {
        qDebug() << readed_data.length();
        qDebug() << readed_data;
        if(readed_data[0] != static_cast<char>(0x30) || readed_data[1] != static_cast<char>(0x03))
        {
            readed_data.remove(0, 1);
        }
        else
            break;
    }

    uint8_t read_comand_u8[readed_data.length()];
    for(int i = 0; i < readed_data.length(); i++)
    {
        read_comand_u8[i] = readed_data[i];
    }

    if(readed_data.length() >= 27)
    if(modbusCrc16(read_comand_u8, 25) >> 8 == read_comand_u8[25] && (modbusCrc16(read_comand_u8, 25) & 0x00FF) == read_comand_u8[26])
    {
        qDebug() << "CRC16校验成功";
        uint16_t config_1R5 = read_comand_u8[3] << 8 | read_comand_u8[4];
        uint16_t config_4R5 = read_comand_u8[5] << 8 | read_comand_u8[6];
        uint16_t config_8R0 = read_comand_u8[7] << 8 | read_comand_u8[8];
        uint16_t rssi = read_comand_u8[9] << 8 | read_comand_u8[10];
        uint16_t coefficient = read_comand_u8[11] <<8 | read_comand_u8[12];
        uint16_t ns_distance = read_comand_u8[13] << 8 | read_comand_u8[14];
        uint16_t we_distance = read_comand_u8[15] << 8 | read_comand_u8[16];
        uint16_t delay_time = read_comand_u8[17] << 8 | read_comand_u8[18];
        uint16_t errorlog = read_comand_u8[19] << 8 | read_comand_u8[20];
        uint16_t ns_c = read_comand_u8[21] << 8 | read_comand_u8[22];
        uint16_t we_c = read_comand_u8[23] << 8 | read_comand_u8[24];

        qDebug() << "config_1R5:" << config_1R5;
        qDebug() << "config_4R5:" << config_4R5;
        qDebug() << "config_8R0:" << config_8R0;
        qDebug() << "rssi:" << rssi;
        qDebug() << "coefficient:" << coefficient;
        qDebug() << "ns_distance:" << ns_distance;
        qDebug() << "we_distance:" << we_distance;
        qDebug() << "DelayTime:" << delay_time;
        qDebug() << "errorlog:" << errorlog;
        qDebug() << "ns_c:" << ns_c;
        qDebug() << "we_c:" << we_c;

        ui -> config_1R5_lineEdit -> setText(QString::number(config_1R5));
        ui -> config_4R5_lineEdit -> setText(QString::number(config_4R5));
        ui -> config_8R0_lineEdit -> setText(QString::number(config_8R0));
        ui -> RSSI_lineEdit -> setText(QString::number((float)rssi/100.0));
        ui -> Coefficient_lineEdit ->setText(QString::number((float)coefficient/10000.0));
        ui -> distance_NS_lineEdit -> setText(QString::number((float)ns_distance/500.0) + "mm");
        ui -> distance_WE_lineEdit -> setText(QString::number((float)we_distance/500.0) + "mm");
        ui -> Delay_Time_lineEdit -> setText(QString::number((float)delay_time) + "us");
        ui -> c_NS_lineEdit -> setText(QString::number((float)ns_c/10.0) + "m/s");
        ui -> c_WE_lineEdit -> setText(QString::number((float)we_c/10.0) + "m/s");

        std::array<bool, 16> bits = getBits(errorlog);
        for (int i = 15; i >= 0; --i)
        {
            qDebug() << bits[i];
            bits[i] ? error1_status_label[15 - i] -> setStyleSheet("QLabel { background-color :rgb(184, 0, 0); border-radius: 10px;}") \
            : error1_status_label[15 - i] -> setStyleSheet("QLabel { background-color :rgb(0, 144, 0); border-radius: 10px;}");
        }
        QMessageBox::information(this, "提示", "数据接受成功");
    }
    disconnect(Serial_port, &QSerialPort::readyRead, nullptr, nullptr);
}

//30->1E
void Widget::on_pushButton_clicked()
{
    QString text = ui -> write_1R5_lineEdit -> text();
    bool ok;
    double data = text.toDouble(&ok);
    qDebug() << data;
    uint16_t data_u16 = (uint16_t)data;

    QByteArray sent_comand;

    sent_comand.append(static_cast<uint8_t>(0x30));
    sent_comand.append(static_cast<uint8_t>(0x10));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x1E));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x01));
    sent_comand.append(static_cast<uint8_t>(0x02));
    sent_comand.append(static_cast<uint8_t>(data_u16 >> 8));
    sent_comand.append(static_cast<uint8_t>(data_u16 & 0x00FF));
    
    uint8_t sent_comand_u8[sent_comand.length()];
    for(int i = 0; i < sent_comand.length(); i++)
    {
        sent_comand_u8[i] = sent_comand[i];
    }

    uint16_t crc_16_val = modbusCrc16(sent_comand_u8, sent_comand.length());

    sent_comand.append(crc_16_val >> 8);
    sent_comand.append(crc_16_val);

    Serial_port->write(sent_comand);

    //连接信号与槽
    //断开所有其他的信号与槽连接
    disconnect(Serial_port, &QSerialPort::readyRead, nullptr, nullptr);
    connect(Serial_port, SIGNAL(readyRead()), this, SLOT(write_ack()), Qt::UniqueConnection);
}

//31->1F
void Widget::on_pushButton_2_clicked()
{
    QString text = ui -> write_4R5_lineEdit -> text();
    bool ok;
    double data = text.toDouble(&ok);
    qDebug() << data;
    uint16_t data_u16 = (uint16_t)data;

    QByteArray sent_comand;

    sent_comand.append(static_cast<uint8_t>(0x30));
    sent_comand.append(static_cast<uint8_t>(0x10));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x1F));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x01));
    sent_comand.append(static_cast<uint8_t>(0x02));
    sent_comand.append(static_cast<uint8_t>(data_u16 >> 8));
    sent_comand.append(static_cast<uint8_t>(data_u16 & 0x00FF));
    
    uint8_t sent_comand_u8[sent_comand.length()];
    for(int i = 0; i < sent_comand.length(); i++)
    {
        sent_comand_u8[i] = sent_comand[i];
    }

    uint16_t crc_16_val = modbusCrc16(sent_comand_u8, sent_comand.length());

    sent_comand.append(crc_16_val >> 8);
    sent_comand.append(crc_16_val);

    Serial_port->write(sent_comand);

    //连接信号与槽
    //断开所有其他的信号与槽连接
    disconnect(Serial_port, &QSerialPort::readyRead, nullptr, nullptr);
    connect(Serial_port, SIGNAL(readyRead()), this, SLOT(write_ack()), Qt::UniqueConnection);
}

//32->20
void Widget::on_pushButton_3_clicked()
{
    QString text = ui -> write_8R0_lineEdit -> text();
    bool ok;
    double data = text.toDouble(&ok);
    qDebug() << data;
    uint16_t data_u16 = (uint16_t)data;

    QByteArray sent_comand;

    sent_comand.append(static_cast<uint8_t>(0x30));
    sent_comand.append(static_cast<uint8_t>(0x10));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x20));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x01));
    sent_comand.append(static_cast<uint8_t>(0x02));
    sent_comand.append(static_cast<uint8_t>(data_u16 >> 8));
    sent_comand.append(static_cast<uint8_t>(data_u16 & 0x00FF));
    
    uint8_t sent_comand_u8[sent_comand.length()];
    for(int i = 0; i < sent_comand.length(); i++)
    {
        sent_comand_u8[i] = sent_comand[i];
    }

    uint16_t crc_16_val = modbusCrc16(sent_comand_u8, sent_comand.length());

    sent_comand.append(crc_16_val >> 8);
    sent_comand.append(crc_16_val);

    Serial_port->write(sent_comand);

    //连接信号与槽
    //断开所有其他的信号与槽连接
    disconnect(Serial_port, &QSerialPort::readyRead, nullptr, nullptr);
    connect(Serial_port, SIGNAL(readyRead()), this, SLOT(write_ack()), Qt::UniqueConnection);
}

//33->21
void Widget::on_pushButton_4_clicked()
{
    QString text = ui -> write_lineEdit -> text();
    bool ok;
    double data = text.toDouble(&ok);
    qDebug() << data;
    uint16_t data_u16 = (uint16_t)data;

    QByteArray sent_comand;

    sent_comand.append(static_cast<uint8_t>(0x30));
    sent_comand.append(static_cast<uint8_t>(0x10));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x21));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x01));
    sent_comand.append(static_cast<uint8_t>(0x02));
    sent_comand.append(static_cast<uint8_t>(data_u16 >> 8));
    sent_comand.append(static_cast<uint8_t>(data_u16 & 0x00FF));
    
    uint8_t sent_comand_u8[sent_comand.length()];
    for(int i = 0; i < sent_comand.length(); i++)
    {
        sent_comand_u8[i] = sent_comand[i];
    }

    uint16_t crc_16_val = modbusCrc16(sent_comand_u8, sent_comand.length());

    sent_comand.append(crc_16_val >> 8);
    sent_comand.append(crc_16_val);

    Serial_port->write(sent_comand);

    //连接信号与槽
    //断开所有其他的信号与槽连接
    disconnect(Serial_port, &QSerialPort::readyRead, nullptr, nullptr);
    connect(Serial_port, SIGNAL(readyRead()), this, SLOT(write_ack()), Qt::UniqueConnection);
}

//34->22
void Widget::on_pushButton_5_clicked()
{
    QString text = ui -> write_Coefficient_lineEdit -> text();
    bool ok;
    double data = text.toDouble(&ok);
    data *= 10000;
    qDebug() << data;
    uint16_t data_u16 = (uint16_t)data;

    QByteArray sent_comand;

    sent_comand.append(static_cast<uint8_t>(0x30));
    sent_comand.append(static_cast<uint8_t>(0x10));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x22));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x01));
    sent_comand.append(static_cast<uint8_t>(0x02));
    sent_comand.append(static_cast<uint8_t>(data_u16 >> 8));
    sent_comand.append(static_cast<uint8_t>(data_u16 & 0x00FF));
    
    uint8_t sent_comand_u8[sent_comand.length()];
    for(int i = 0; i < sent_comand.length(); i++)
    {
        sent_comand_u8[i] = sent_comand[i];
    }

    uint16_t crc_16_val = modbusCrc16(sent_comand_u8, sent_comand.length());

    sent_comand.append(crc_16_val >> 8);
    sent_comand.append(crc_16_val);

    Serial_port->write(sent_comand);

    //连接信号与槽
    //断开所有其他的信号与槽连接
    disconnect(Serial_port, &QSerialPort::readyRead, nullptr, nullptr);
    connect(Serial_port, SIGNAL(readyRead()), this, SLOT(write_ack()), Qt::UniqueConnection);
}

//35->23
void Widget::on_pushButton_6_clicked()
{
    QString text = ui -> write_distance_NS_lineEdit -> text();
    bool ok;
    double data = text.toDouble(&ok);
    data *= 500;
    qDebug() << data;
    uint16_t data_u16 = (uint16_t)data;

    QByteArray sent_comand;

    sent_comand.append(static_cast<uint8_t>(0x30));
    sent_comand.append(static_cast<uint8_t>(0x10));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x23));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x01));
    sent_comand.append(static_cast<uint8_t>(0x02));
    sent_comand.append(static_cast<uint8_t>(data_u16 >> 8));
    sent_comand.append(static_cast<uint8_t>(data_u16 & 0x00FF));
    
    uint8_t sent_comand_u8[sent_comand.length()];
    for(int i = 0; i < sent_comand.length(); i++)
    {
        sent_comand_u8[i] = sent_comand[i];
    }

    uint16_t crc_16_val = modbusCrc16(sent_comand_u8, sent_comand.length());

    sent_comand.append(crc_16_val >> 8);
    sent_comand.append(crc_16_val);

    Serial_port->write(sent_comand);

    //连接信号与槽
    //断开所有其他的信号与槽连接
    disconnect(Serial_port, &QSerialPort::readyRead, nullptr, nullptr);
    connect(Serial_port, SIGNAL(readyRead()), this, SLOT(write_ack()), Qt::UniqueConnection);
}

//36->24
void Widget::on_pushButton_7_clicked()
{
    QString text = ui -> write_distance_WE_lineEdit -> text();
    bool ok;
    double data = text.toDouble(&ok);
    data *= 500;
    qDebug() << data;
    uint16_t data_u16 = (uint16_t)data;

    QByteArray sent_comand;

    sent_comand.append(static_cast<uint8_t>(0x30));
    sent_comand.append(static_cast<uint8_t>(0x10));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x24));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x01));
    sent_comand.append(static_cast<uint8_t>(0x02));
    sent_comand.append(static_cast<uint8_t>(data_u16 >> 8));
    sent_comand.append(static_cast<uint8_t>(data_u16 & 0x00FF));
    
    uint8_t sent_comand_u8[sent_comand.length()];
    for(int i = 0; i < sent_comand.length(); i++)
    {
        sent_comand_u8[i] = sent_comand[i];
    }

    uint16_t crc_16_val = modbusCrc16(sent_comand_u8, sent_comand.length());

    sent_comand.append(crc_16_val >> 8);
    sent_comand.append(crc_16_val);

    Serial_port->write(sent_comand);

    //连接信号与槽
    //断开所有其他的信号与槽连接
    disconnect(Serial_port, &QSerialPort::readyRead, nullptr, nullptr);
    connect(Serial_port, SIGNAL(readyRead()), this, SLOT(write_ack()), Qt::UniqueConnection);
}

void Widget::on_Get_ID_pushButton_clicked()
{
    QByteArray sent_comand;
    sent_comand.append(static_cast<uint8_t>(0x30));
    sent_comand.append(static_cast<uint8_t>(0x03));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x38));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x04));
    sent_comand.append(static_cast<uint8_t>(0xC1));
    sent_comand.append(static_cast<uint8_t>(0xE5));

    Serial_port->write(sent_comand);

    //连接信号与槽
    //断开所有其他的信号与槽连接
    disconnect(Serial_port, &QSerialPort::readyRead, nullptr, nullptr);
    connect(Serial_port, SIGNAL(readyRead()), this, SLOT(getIdData()), Qt::UniqueConnection);
}

uint32_t PassWord[2] = {0};
uint32_t key[] = {0x509770ff, 0x29c6b369, 0x4da2c125, 0x0};//ID中间32位
void Widget::getIdData()
{
    uint32_t ID_1;
    uint32_t ID_2;
    //    接收数据,一会再接收,以便接收超长数据
    QByteArray readed_data;
    while(Serial_port->waitForReadyRead(UART_WAIT_MS)==true);
    readed_data.append(Serial_port -> readAll());

    //防止干扰
    while(readed_data.length() > 1)
    {
        qDebug() << readed_data.length();
        qDebug() << readed_data;
        if(readed_data[0] != static_cast<char>(0x30) || readed_data[1] != static_cast<char>(0x03))
        {
            readed_data.remove(0, 1);
        }
        else
            break;
    }

    uint8_t read_comand_u8[readed_data.length()];
    for(int i = 0; i < readed_data.length(); i++)
    {
        read_comand_u8[i] = readed_data[i];
    }
    if(readed_data.length() >= 13)
    if(modbusCrc16(read_comand_u8, 11) >> 8 == read_comand_u8[11] && (modbusCrc16(read_comand_u8, 11) & 0x00FF) == read_comand_u8[12])
    {
        ui->ID_lineEdit->clear();
        ID_1 = read_comand_u8[3] << 24 | read_comand_u8[4] << 16 | read_comand_u8[5] << 8 | read_comand_u8[6];
        QString ID_1_Str = QString::number(ID_1, 16).toUpper().rightJustified(2, '0').prepend("0x");
        ID_2 = read_comand_u8[7] << 24 | read_comand_u8[8] << 16 | read_comand_u8[9] << 8 | read_comand_u8[10];
        QString ID_2_Str = QString::number(ID_2, 16).toUpper().rightJustified(2, '0').prepend("0x");
        ui->ID_lineEdit->setText(ID_1_Str + " " + ID_2_Str);
        qDebug("%x %x",ID_1, ID_2);

        key[3] = ID_1;
        PassWord[0] = ID_1;
        PassWord[1] = ID_2;

        tea_encrypt(PassWord, key);

        ui->Password_lineEdit->clear();
        QString PW_1_Str = QString::number(PassWord[0], 16).toUpper().rightJustified(2, '0').prepend("0x");
        QString PW_2_Str = QString::number(PassWord[1], 16).toUpper().rightJustified(2, '0').prepend("0x");
        qDebug("%x %x",PassWord[0], PassWord[1]);
        ui->Password_lineEdit->setText(PW_1_Str + " " + PW_2_Str);
    }
    disconnect(Serial_port, &QSerialPort::readyRead, nullptr, nullptr);

//    点亮控件
    ui->Password_lineEdit->setEnabled(true);
    ui->ID_lineEdit->setEnabled(true);
    ui->label_10->setEnabled(true);
    ui->label_11->setEnabled(true);
    ui->Trans_password_pushButton->setEnabled(true);
}

void Widget::tea_encrypt(uint32_t *v, uint32_t *k)
{
    uint32_t v0 = v[0], v1 = v[1], sum = 0, i;           // 初始化v0, v1, sum
    uint32_t delta = 0x9e3779b9;                          // 初始化delta
    uint32_t k1 = k[1], k3 = k[3], k0 = k[0], k2 = k[2];   // 初始化密钥k
    for (i = 0; i < 32; i++) {                            // 执行32轮加密
        sum += delta;
        v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
        v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
    }
    v[0] = v0;                                            // 返回加密结果
    v[1] = v1;
}

void Widget::on_Trans_password_pushButton_clicked()
{
    QByteArray sent_comand;

    sent_comand.append(static_cast<uint8_t>(0x30));
    sent_comand.append(static_cast<uint8_t>(0x10));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x3C));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x04));
    sent_comand.append(static_cast<uint8_t>(0x08));
    sent_comand.append(static_cast<uint8_t>(PassWord[0] >> 24));
    sent_comand.append(static_cast<uint8_t>(PassWord[0] >> 16));
    sent_comand.append(static_cast<uint8_t>(PassWord[0] >> 8));
    sent_comand.append(static_cast<uint8_t>(PassWord[0] >> 0));
    sent_comand.append(static_cast<uint8_t>(PassWord[1] >> 24));
    sent_comand.append(static_cast<uint8_t>(PassWord[1] >> 16));
    sent_comand.append(static_cast<uint8_t>(PassWord[1] >> 8));
    sent_comand.append(static_cast<uint8_t>(PassWord[1] >> 0));

    uint8_t sent_comand_u8[sent_comand.length()];
    for(int i = 0; i < sent_comand.length(); i++)
    {
        sent_comand_u8[i] = sent_comand[i];
    }

    uint16_t crc_16_val = modbusCrc16(sent_comand_u8, sent_comand.length());

    sent_comand.append(crc_16_val >> 8);
    sent_comand.append(crc_16_val);

    Serial_port->write(sent_comand);

    //连接信号与槽
    //断开所有其他的信号与槽连接
    disconnect(Serial_port, &QSerialPort::readyRead, nullptr, nullptr);
    connect(Serial_port, SIGNAL(readyRead()), this, SLOT(write_ack()), Qt::UniqueConnection);
}

void Widget::on_pushButton_8_clicked()
{
    QByteArray sent_comand;
    sent_comand.append(static_cast<uint8_t>(0x30));
    sent_comand.append(static_cast<uint8_t>(0x10));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x1A));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x01));
    sent_comand.append(static_cast<uint8_t>(0x02));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x01));
    sent_comand.append(static_cast<uint8_t>(0x3C));
    sent_comand.append(static_cast<uint8_t>(0x3B));
    Serial_port->write(sent_comand);
}

void Widget::write_ack()
{
    //    接收数据,一会再接收,以便接收超长数据
    QByteArray readed_data;
    while(Serial_port->waitForReadyRead(UART_WAIT_MS)==true);
    readed_data.append(Serial_port -> readAll());

    //防止干扰
    while(readed_data.length() > 1)
    {
        qDebug() << readed_data.length();
        qDebug() << readed_data;
        if(readed_data[0] != static_cast<char>(0x30) || readed_data[1] != static_cast<char>(0x10))
        {
            readed_data.remove(0, 1);
        }
        else
            break;
    }

    uint8_t read_comand_u8[readed_data.length()];
    for(int i = 0; i < readed_data.length(); i++)
    {
        read_comand_u8[i] = readed_data[i];
    }

    if(modbusCrc16(read_comand_u8, readed_data.length()-2) >> 8 == read_comand_u8[readed_data.length()-2] && (modbusCrc16(read_comand_u8, readed_data.length()-2) & 0x00FF) == read_comand_u8[readed_data.length()-1])
    {
        QMessageBox::information(this, "提示", "数据下发成功");
    }
    disconnect(Serial_port, &QSerialPort::readyRead, nullptr, nullptr);
}

//37 ->25
void Widget::on_pushButton_9_clicked()
{
    QString text = ui -> write_delay_time_lineEdit -> text();
    bool ok;
    double data = text.toDouble(&ok);
    qDebug() << data;
    uint16_t data_u16 = (uint16_t)data;

    QByteArray sent_comand;

    sent_comand.append(static_cast<uint8_t>(0x30));
    sent_comand.append(static_cast<uint8_t>(0x10));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x25));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x01));
    sent_comand.append(static_cast<uint8_t>(0x02));
    sent_comand.append(static_cast<uint8_t>(data_u16 >> 8));
    sent_comand.append(static_cast<uint8_t>(data_u16 & 0x00FF));

    uint8_t sent_comand_u8[sent_comand.length()];
    for(int i = 0; i < sent_comand.length(); i++)
    {
        sent_comand_u8[i] = sent_comand[i];
    }

    uint16_t crc_16_val = modbusCrc16(sent_comand_u8, sent_comand.length());

    sent_comand.append(crc_16_val >> 8);
    sent_comand.append(crc_16_val);

    Serial_port->write(sent_comand);

    //连接信号与槽
    //断开所有其他的信号与槽连接
    disconnect(Serial_port, &QSerialPort::readyRead, nullptr, nullptr);
    connect(Serial_port, SIGNAL(readyRead()), this, SLOT(write_ack()), Qt::UniqueConnection);
}

void Widget::on_read_config_file_pushButton_clicked()
{
    //清空名字
    ui -> configFile_comboBox -> clear();
    ui -> configFile_comboBox ->addItem("请选择配置文件");

    //创建QSetting对象,指定INI文件的路径和格式
    QSettings settings("config/config.ini", QSettings::IniFormat);

    //获取所有节名
    QStringList sections = settings.childGroups();
    foreach (const QString &section, sections)
    {
        //当前节名称添加进下拉菜单
        ui -> configFile_comboBox -> addItem(section);

        qDebug() << "Section" << section;
    }
}


uint16_t config_1R5_value;
uint16_t config_4R5_value;
uint16_t config_8R0_value;
uint16_t rssi_value;
uint16_t coeff_value;
uint16_t distance_NS_value;
uint16_t distance_WE_value;
uint16_t delay_value;
void Widget::on_configFile_comboBox_highlighted(const QString &arg1)
{
    //没东西提前返回
    if(arg1 == "请选择配置文件")
    {
        return;
    }
    //创建QSetting对象,指定INI文件的路径和格式
    QSettings settings("config/config.ini", QSettings::IniFormat);

    //读取配置
    config_1R5_value  = settings.value(arg1 + "/value1R5").toInt();
    config_4R5_value  = settings.value(arg1 + "/value4R5").toInt();
    config_8R0_value  = settings.value(arg1 + "/value8R0").toInt();
    rssi_value        = settings.value(arg1 + "/rssiValue").toInt();
    coeff_value       = settings.value(arg1 + "/coefficientValue").toInt();
    distance_NS_value = settings.value(arg1 + "/diatanceNS").toInt();
    distance_WE_value = settings.value(arg1 + "/diatanceWE").toInt();
    delay_value       = settings.value(arg1 + "/delayUsValue").toInt();

    qDebug() << config_1R5_value;
    qDebug() << config_4R5_value;
    qDebug() << config_8R0_value;
    qDebug() << rssi_value;
    qDebug() << coeff_value;
    qDebug() << distance_NS_value;
    qDebug() << distance_WE_value;
    qDebug() << delay_value;

    //展示配置
    ui -> write_1R5_lineEdit_2          -> setText("0." + QString::number(config_1R5_value));
    ui -> write_4R5_lineEdit_2          -> setText("0." + QString::number(config_4R5_value));
    ui -> write_8R0_lineEdit_2          -> setText("0." + QString::number(config_8R0_value));
    ui -> write_lineEdit_2              -> setText("0." + QString::number(rssi_value));
    ui -> write_Coefficient_lineEdit_2  -> setText(QString::number(float(coeff_value)/10000));
    ui -> write_distance_NS_lineEdit_2  -> setText(QString::number(float(distance_NS_value)/500) + " mm");
    ui -> write_distance_WE_lineEdit_2  -> setText(QString::number(float(distance_WE_value)/500) + " mm");
    ui -> write_delay_time_lineEdit_2   -> setText(QString::number(delay_value) + " us");
}

void Widget::on_pushButton_10_clicked()
{
    QByteArray sent_comand;

    sent_comand.append(static_cast<uint8_t>(0x30));
    sent_comand.append(static_cast<uint8_t>(0x10));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x1E));
    sent_comand.append(static_cast<uint8_t>(0x00));
    sent_comand.append(static_cast<uint8_t>(0x08));
    sent_comand.append(static_cast<uint8_t>(0x10));
    sent_comand.append(static_cast<uint8_t>(config_1R5_value >> 8));
    sent_comand.append(static_cast<uint8_t>(config_1R5_value & 0x00FF));
    sent_comand.append(static_cast<uint8_t>(config_4R5_value >> 8));
    sent_comand.append(static_cast<uint8_t>(config_4R5_value & 0x00FF));
    sent_comand.append(static_cast<uint8_t>(config_8R0_value >> 8));
    sent_comand.append(static_cast<uint8_t>(config_8R0_value & 0x00FF));
    sent_comand.append(static_cast<uint8_t>(rssi_value >> 8));
    sent_comand.append(static_cast<uint8_t>(rssi_value & 0x00FF));
    sent_comand.append(static_cast<uint8_t>(coeff_value >> 8));
    sent_comand.append(static_cast<uint8_t>(coeff_value & 0x00FF));
    sent_comand.append(static_cast<uint8_t>(distance_NS_value >> 8));
    sent_comand.append(static_cast<uint8_t>(distance_NS_value & 0x00FF));
    sent_comand.append(static_cast<uint8_t>(distance_WE_value >> 8));
    sent_comand.append(static_cast<uint8_t>(distance_WE_value & 0x00FF));
    sent_comand.append(static_cast<uint8_t>(delay_value >> 8));
    sent_comand.append(static_cast<uint8_t>(delay_value & 0x00FF));

    uint8_t sent_comand_u8[sent_comand.length()];
    for(int i = 0; i < sent_comand.length(); i++)
    {
        sent_comand_u8[i] = sent_comand[i];
    }

    uint16_t crc_16_val = modbusCrc16(sent_comand_u8, sent_comand.length());

    sent_comand.append(crc_16_val >> 8);
    sent_comand.append(crc_16_val);

    Serial_port->write(sent_comand);

    //连接信号与槽
    //断开所有其他的信号与槽连接
    disconnect(Serial_port, &QSerialPort::readyRead, nullptr, nullptr);
    connect(Serial_port, SIGNAL(readyRead()), this, SLOT(write_ack()), Qt::UniqueConnection);
}