项目场景:
主要记录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;
}
二、上位机进行字符串拼接
博主水平有限,现在还不好解决