[QT串口上位机BUG解决]json解析数据bug以及接收数据问题

文章讲述了在QT串口上位机中遇到的JSON数据因超过32字节而被分割导致无法解析的问题。解决方案包括在单片机端控制发送数据量不超过32字节,或者在上位机端进行字符串拼接。作者提供了STM32F103zet6通过I2C与INA226通信的示例代码,并讨论了可能的数据丢失和显示问题。
摘要由CSDN通过智能技术生成

项目场景:

主要记录QT入门第三步串口上位机的使用json格式发送电压,电流和解析出现的bug


问题描述

主要是串口每次只能打印32个字节的数据,如果多了就会把数据放到缓冲区,这导致要二次打印,使json格式不连续,就构不成json格式,如下图。这样就不能解析出json数据了。
在这里插入图片描述


原因分析:

主要原因就是QT上位机数据最对打印32位,这导致json格式不完整,这样就不能解析了。


解决方案:

这里我有两个办法分别是对应的数据采集端(单片机)一次只发送32位数据。第二个是上位机进行字符串拼接

一、是数据采集端(单片机mcu)来解决

我采集电压电流是通过Stm32F103zet6在通过I2C与INA226通信,下面是数据采集端(单片机mcu)程序,

这里的解决办法是设置一个标志位,该标志位用取反函数让其有两种状态,0和1.
然后我在用if判断不同状态发送不同的json格式数据,并且保证发送的数据长度必须
小于32个8位数据。

#include "stm32f10x.h"                  // Device header
#include "delay.h"
#include "USART.h"
#include "stdio.h"
#include "Wire.h"
#include "AHT10.h"
#include "SW3526.h"
#include "INA226.h"
//本案例是以一个AHT10温湿度传感器来显示I2C协议!
float Temp;
float Humi;
float ADC_Voltage;
u8 USART_FLAGS;
int main(void){
	USART_Begin(115200);
		//AHT10_Reset();
	//AHT10_Init();
	INA226_Init();
  //SW3526_Init();
	//printf("INA226_ID=0x%x\r\n",INA226_Get_Addr(0xFF)>>8);	

	while(1){
		//AHT10_Read_Data(&Temp,&Humi);
	  
		//SW3526_Init();
		//I2CS_ACK();
		//I2CS_ACK();
		//SW3526_Send_8_Reg(0x3A,0x01);
		//ADC_Voltage=SW3526_Read_8_Reg(0x3B)<<4|SW3526_Read_8_Reg(0x3C);
		//SW3526_Send_8_Reg(0x3A,0x01);
		//ADC_Voltage=SW3526_Read_8_Reg(0x30)*16*10;
		//SW3526_Fast_charge_protocol();
		//SW3526_Buck_ON_OFF(1);
		//SW3526_Fast_charge_protocol();
		//SW3526_Send_8_Reg(0x05,0x00);
		//printf("输出协议=%d\r\n",SW3526_Read_8_Reg(0x06));
		//printf("V=%.2f\r\n",SW3526_Buck_OUTPUT_Voltage()/1000);
		//Delay_ms(500);
		//printf("Temp=%.2f\r\nHumi=%.2f\r\n",Temp,Humi);
		
		USART_FLAGS=~USART_FLAGS;
		if(USART_FLAGS==0){
			printf("{\"current\":%d,\"voltage\":%d}",(int)(INA226_Get_Current_dat()),(int)(INA226_Get_Voltage_dat()));
			Delay_ms(400);
		}else{
			printf("{\"power\":%d}",(int)INA226_Get_Power_dat());
			Delay_ms(10);
		}
	  //printf("Voltage=%.4fV\r\n",INA226_Get_Voltage_dat()/1000);
	  //printf("CURRENT=%.2fmA\r\n",INA226_Get_Current_dat());
		
	 // printf("CURRENT=%.4fW\r\n",INA226_Get_Power_dat());		
	}
}


但是这里会出现一个问题当串口发送另外一个数据时电流,电压会短暂显示0,这里我们可以缩短单片机发送功率的数据延时来减少上位机的电流。电压出现0的问题。或者是修改上位机代码,如图二。
在这里插入图片描述第二种发方法是修改上位机的写入lcd_Number的数据,因为单片机是分时发送数据,当发送power的数据时,电流、电压的json解析失败,那存放电流,电压的数据肯定为 0
这时我们用一个if判断,当读取的电压、电流 == 0时,就不将值写入到lcd_Number。这样就完美的解决了这个问题
下面是QT串口上位机的串口接收数据代码的修改

QByteArray Widget::DateRead()  //接收数据
{



    QByteArray temp=serialPort->readAll();


    QString str=ui->recelives->toPlainText();
    str=QString::fromLocal8Bit(temp);
    ui->recelives->appendPlainText(str);



    //解析 JSON格式
   // QString json_str="{\"current\":15,\"voltage\":29,\"yan\":29}";
    QString receive =QString::fromLocal8Bit(temp.constData());
    qDebug() << receive ;
    qDebug() << receive.length();
    QJsonDocument doc=QJsonDocument::fromJson(receive.toUtf8());
    QJsonObject obj=doc.object();

    QJsonValue Current =obj.value("current");
    QJsonValue Voltage =obj.value("voltage");

    QString Current_cp;
    Current_cp.sprintf("%d",Current.toInt());
    QString Voltage_cp;
    Voltage_cp.sprintf("%d",Voltage.toInt());
    //qDebug() << Current_cp ;
   // qDebug() << Voltage_cp ;
    //ui->current_dat->display(Current.toInt());
   // ui->voltage_dat->dosplayVoltage.toInt()();
    if(Current.toInt()!=0 && Voltage.toInt()!=0){
    ui->current_dat->display(Current_cp);
    ui->voltage_dat->display(Voltage_cp);
    }
    temp.clear();
    return temp;
}

二、上位机进行字符串拼接

博主水平有限,现在还不好解决

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

单片有机机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值