每一个包都加一个包头,里面包括数据类型(图片/温湿度),节点号(哪一个模块的数据),数据包的序号,数据包有效长度等信息,辅助解析串口数据。
每一个包分两两部分读取,包头+有效数据。
从包头获取有效数据长度,让串口只读取有效长度的字节数即可得到一个完整的数据包。在切换为包头读取状态!!!!
void MainWindow::serialRead()
{
int cnt_tmp;
static unsigned int seq_old = 0;
static unsigned int pkt_cnt = 0;
QByteArray tmp_data;
//char ACK[1] = {1};
if(serial.bytesAvailable() >= 1)
{
switch(serial_state)
{
case READ_HDR:
cnt_need = HDR_LEN - cnt_read;
tmp_data = serial.read(cnt_need);
if(tmp_data.isEmpty())
return ;
cnt_tmp = tmp_data.length();
// //qDebug()<<"0:"<<cnt_tmp;
cnt_read += cnt_tmp;
read_data += tmp_data;
if(HDR_LEN == cnt_read)
{
cnt_read = 0;
cnt_need = 0;
serial_state = READ_DATA;
node_type = bytesToInt(read_data.mid(0,1));
node_id = bytesToInt(read_data.mid(1,1));
data_need = bytesToInt(read_data.mid(7,1));
seqnb = bytesToInt(read_data.mid(6,1))*256 + bytesToInt(read_data.mid(5,1));
if(seqnb == seq_old)
{
FAIL_FLAG = true;
qDebug()<<"seqnb err..********************************";
}
else if(seqnb - seq_old > 1)
{
FAIL_FLAG = false;
int need_pkt = seqnb - seq_old;
QByteArray errData(64*(need_pkt-1),0);
//qDebug()<<"diushide: "<<64*(need_pkt-1);
my_stream += errData;
dst.write(my_stream);
my_stream.clear();
pkt_cnt = 0;
}
else {
FAIL_FLAG = false;
}
seq_old = seqnb;
//操作头部数据
QString str_display;
QString str = read_data.toHex().data();
str = str.toUpper();
str_display.clear();
for(int i = 0;i < str.length();i+= 2)
{
QString st = str.mid(i,2);
str_display += st;
str_display += " ";
}
//显示数据
ui->textEdit->insertPlainText(str_display);
read_data.clear();
}
break;
case READ_DATA:
if(node_type == 1)
{
cnt_need = data_need - cnt_read;
// //qDebug()<<"2:"<<cnt_need;
tmp_data = serial.read(cnt_need);
if(tmp_data.isEmpty())
return ;
cnt_tmp = tmp_data.length();
cnt_read += cnt_tmp;
read_data += tmp_data;
//qDebug()<<"3:"<<cnt_read;
cnt += cnt_tmp;
if(data_need == cnt_read)
{
cnt_read = 0;
cnt_need = 0;
serial_state = READ_HDR;
//if(photo_state == END && strcmp("end\r\n",str_tmp) == 0)
//if(strcmp("end",str_tmp) == 0)
if(read_data.contains("end"))
{
dst.close();
qDebug()<<"end";
qDebug()<<cnt;
read_data.clear();
my_stream.clear();
photo_state = BEGIN;
//serial.write(ACK);
data_need = 0;
cnt = 0;
return ;
}
//if(photo_state == BEGIN && strcmp("begin\r\n",str_tmp) == 0)
//if(strcmp("begin\r\n",str_tmp) == 0)
if(read_data.contains("begin"))
{
QDateTime time = QDateTime::currentDateTime();//获取系统现在的时间
//设置显示格式,注意QFile的文件名不能有:(冒号)等特殊字符
QString str = time.toString("yyyy-MM-dd-hh-mm-ss");
str += ".jpg";
qDebug()<<str;
dst.setFileName(str);//将时间作为文件名
//QDir::currentPath()
bool isOK = dst.open(QIODevice::WriteOnly|QIODevice::Append);
if(isOK == false)
{
qDebug()<<"dst.open err";
this->close();
}
//my_stream.setDevice(&dst);
read_data.clear();
photo_state = READING;
//serial.write(ACK);
data_need = 0;
return ;
}
//if(photo_state == READING)
{
if(FAIL_FLAG == true)
{
//serial.write(ACK);
read_data.clear();
data_need = 0;
return;
}
// //qDebug()<<"==========>"<<seqnb;
pkt_cnt++;
my_stream += read_data;
if(data_need < REAL_LEN)
{
photo_state = END;
dst.write(my_stream);
my_stream.clear();
pkt_cnt = 0;
}
if(pkt_cnt == 32)
{
pkt_cnt = 0;
dst.write(my_stream);
my_stream.clear();
}
//serial.write(ACK);
read_data.clear();
data_need = 0;
}
}
}
break;
default:
break;
}
}
}