串口接收不定长数据的各种不合格版本
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include <QApplication>
#include <QTime>
#include <QDateTime>
#include <QIODevice>
#include <QDir>
#include <QImage>
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
extern FILE * fopen(const char * path,const char * mode);
extern int fclose( FILE *fp );
extern size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;
extern size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
#ifdef __cplusplus
}
#endif /* __cplusplus */
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
cnt_read = 0;
cnt_need = 0;
photo_state = BEGIN;
serial_state = READ_HDR;
data_need = 0;
node_id = 0;
node_type = 0;
cnt = 0;
seqnb = 0;
ui->setupUi(this);
initSeialPort();
}
MainWindow::~MainWindow()
{
serial.close();
delete ui;
}
void MainWindow::on_serialSelect_currentIndexChanged(const QString &arg1)
{
QSerialPortInfo info;
QList<QSerialPortInfo> infos = QSerialPortInfo::availablePorts();
int i = 0;
foreach (info, infos) {
if(info.portName() == arg1) break;
i++;
}
if(i != infos.size ()){//can find
ui->label->setText("[已开启]");
serial.close();
serial.setPort(info);
serial.open(QIODevice::ReadWrite); //读写打开
serial.setBaudRate(QSerialPort::Baud115200); //波特率
serial.setDataBits(QSerialPort::Data8); //数据位
serial.setParity(QSerialPort::NoParity); //无奇偶校验
serial.setStopBits(QSerialPort::OneStop); //停止位
serial.setFlowControl(QSerialPort::NoFlowControl); //无控制
}
else
{
serial.close();
ui->label->setText("[出错]");
}
}
#if 1
void MainWindow::serialRead()
{
QByteArray temp = serial.readAll();
if(!temp.isEmpty())
{
my_stream.append(temp);
if(my_stream.contains("end"))
{
qDebug()<<my_stream.length();
QByteArray array=my_stream.left(my_stream.indexOf("end"));
//QImage image;
//bool flag=image.loadFromData((const uchar *)array.data(),array.size());
if (1)
{
QDateTime time = QDateTime::currentDateTime();//获取系统现在的时间
//设置显示格式,注意QFile的文件名不能有:(冒号)等特殊字符
QString str = time.toString("yyyy-MM-dd-hh-mm-ss");
str += ".jpg";
qDebug()<<str;
//image.save(str);
dst.setFileName(str);//将时间作为文件名
//QDir::currentPath()
bool isOK = dst.open(QIODevice::WriteOnly|QIODevice::Append);
if(isOK == false)
{
qDebug()<<"dst.open err";
this->close();
}
dst.write(array);
dst.close();
//QPixmap pixmap=QPixmap::fromImage(image);
//ui->labelImage->setPixmap(pixmap);
}
my_stream.clear();
//my_stream = my_stream.right(my_stream.length()-my_stream.indexOf("end")-3);
}
}
}
#endif
#if 0
bytesToInt(QByteArray bytes) {
int addr = bytes[0] & 0x000000FF;
addr |= ((bytes[1] << 8) & 0x0000FF00);
addr |= ((bytes[2] << 16) & 0x00FF0000);
addr |= ((bytes[3] << 24) & 0xFF000000);
return addr;
}
void MainWindow::serialRead()
{
int cnt_tmp;
static unsigned int seq_old = 0;
//static unsigned int seq_new = 0;
static unsigned int pkt_cnt = 0;
bool FAIL_FLAG = false;
QByteArray tmp_data;
char ACK[1] = {1};
if(serial.bytesAvailable() >= 8)
{
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;
seq_old = seqnb;
//qDebug()<<"1:"<<data_need;
//操作头部数据
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;
//操作有效数据
my_stream.append(read_data);
if(my_stream.contains("end"))
{
qDebug()<<my_stream.length();
QByteArray array=my_stream.left(my_stream.indexOf("end"));
//QImage image;
//bool flag=image.loadFromData((const uchar *)array.data(),array.size());
if (1)
{
QDateTime time = QDateTime::currentDateTime();//获取系统现在的时间
//设置显示格式,注意QFile的文件名不能有:(冒号)等特殊字符
QString str = time.toString("yyyy-MM-dd-hh-mm-ss");
str += ".jpg";
qDebug()<<str;
//image.save(str);
dst.setFileName(str);//将时间作为文件名
//QDir::currentPath()
bool isOK = dst.open(QIODevice::WriteOnly|QIODevice::Append);
if(isOK == false)
{
qDebug()<<"dst.open err";
this->close();
}
dst.write(array);
dst.close();
//QPixmap pixmap=QPixmap::fromImage(image);
//ui->labelImage->setPixmap(pixmap);
}
my_stream.clear();
//my_stream = my_stream.right(my_stream.length()-my_stream.indexOf("end")-3);
}
#if 0
//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);
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);
return ;
}
//if(photo_state == READING)
{
if(FAIL_FLAG == true)
{
serial.write(ACK);
read_data.clear();
return;
}
qDebug()<<"==========>"<<seqnb;
pkt_cnt++;
my_stream += read_data;
if(data_need < REAL_LEN)
{
photo_state = END;
dst.write(my_stream);
my_stream.clear();
}
if(pkt_cnt == 32)
{
pkt_cnt = 0;
dst.write(my_stream);
my_stream.clear();
}
//dst.write(read_data);
//my_stream<<read_data;
serial.write(ACK);
read_data.clear();
}
data_need = 0;
#endif
#if 0
switch(photo_state)
{
//判断是不是一张新的图片
//如果是beigin开头,新建文件
case BEGIN:
if(strcmp("begin\r\n",str_tmp) == 0)
{
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);
return ;
}
break;
//如果不是begin开头,将数据插入原来打开文件的末尾
case READING:
dst.write(read_data);
//my_stream.clear();
if(data_need < REAL_LEN)
photo_state = END;
//my_stream<<read_data;
serial.write(ACK);
read_data.clear();
break;
//判断图片是否传送完毕--接收到的是否是end
case END:
if(strcmp("end\r\n",str_tmp) == 0)
{
dst.close();
qDebug()<<"end";
qDebug()<<cnt;
read_data.clear();
photo_state = BEGIN;
serial.write(ACK);
return ;
}
break;
}
data_need = 0;
#endif
}
}
break;
default:
break;
}
}
}
#endif
#if 0
#define MAX_BUF 80
#define SRC "D:/1.jpg"
#define DST "D:/2.jpg"
void MainWindow::serialRead()
{
static unsigned int length = 0;
if(serial.bytesAvailable() >=13 )
{
//读串口数据
QByteArray serial_data = serial.read(72);
char *str_tmp=serial_data.data();
unsigned int low = (unsigned int)str_tmp[5];
unsigned int high = (unsigned int)str_tmp[6];
unsigned int seqnb = high*256+low;
qDebug()<<serial_data.length()<<seqnb;
//判断图片是否传送完毕--接收到的是否是end
if(strcmp("end\r\n",str_tmp+8) == 0)
{
dst.close();
qDebug()<<"end";
qDebug()<<length;
return ;
}
//判断是不是一张新的图片
//如果是beigin开头,新建文件
if(strcmp("begin\r\n",str_tmp+8) == 0)
{
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();
}
return ;
}
//如果不是begin开头,将数据插入原来打开文件的末尾
dst.write(serial_data);
length += (serial_data.length()-8);
//将数据格式化
QString str_display;
QString str = serial_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);
}
}
#endif
#if 0
void MainWindow::serialRead()
{
QByteArray tmp_buf = serial.readAll();
static QByteArray buf;
static FILE* dst = NULL;
static bool OPEN_FLAG = false;
static int flag = 0;
static int cnt_update = 0;
static int all_cnt = 0;
static int tmp_cnt = 0;
int off_cnt = 0;
QByteArray remain_buf;
char *remain_str=NULL;
if(cnt_update == 0)
{
all_cnt = *(tmp_buf.data());
qDebug()<<"cnt_update == 0:\t"<<all_cnt<<endl;
cnt_update = 2;
}
//qDebug()<<"tmp_buf:"<<tmp_buf<<endl;
#if 0
remain_str = tmp_buf.data()+2;
qDebug()<<"remain_str:"<<remain_str<<endl;
remain_buf = QByteArray(remain_str);
qDebug()<<"remain_buf:"<<remain_buf<<endl;
tmp_buf.resize(tmp_buf.size()-2);
qDebug()<<"new tmp_buf:"<<tmp_buf<<endl;
#endif
#if 1
tmp_cnt += tmp_buf.size();
//qDebug()<<"tmp_buf.size:"<<tmp_buf.size()<<endl;
//qDebug()<<"tmp_cnt:"<<tmp_cnt<<endl;
if(tmp_cnt < all_cnt)
{
buf += tmp_buf;
qDebug()<<"tmp_cnt <<<<<<<<<<<<<<<<<<<< all_cnt\t"<<endl;//(tmp_buf)<<"\ttmp_size:"<<tmp_buf.size()<<"\ttmpcnt:"<<tmp_cnt<<endl;
//qDebug()<<"buf:"<<buf<<endl;
return ;
}else if (tmp_cnt > all_cnt){
off_cnt = tmp_cnt - all_cnt;
remain_str = tmp_buf.data()+(tmp_buf.size()-off_cnt);
remain_buf = QByteArray(remain_str);
//qDebug()<<"tmp_buf:"<<tmp_buf<<endl;
//qDebug()<<"remain_buf:"<<remain_buf<<endl;
tmp_buf.resize(tmp_buf.size()-off_cnt);
//qDebug()<<"tmp_cnt >>>>>>>>>>> all_cnt"<<endl;//(tmp_buf)<<"\ttmp_size:"<<tmp_buf.size()<<"\ttmpcnt:"<<tmp_cnt<<endl;
buf += tmp_buf;
//qDebug()<<"buf:"<<buf<<endl;
cnt_update = 1;
}
else
{
buf += tmp_buf;
//qDebug()<<"tmp_cnt================ all_cnt"<<endl;//(tmp_buf)<<"\ttmp_size:"<<tmp_buf.size()<<"\ttmpcnt:"<<tmp_cnt<<endl;
//qDebug()<<"buf:"<<buf<<endl;
cnt_update = 0;
}
//ui->textEdit->append(buf);
#if 1
if((all_cnt == 7)&&
(strcmp((buf.data()+1),"begin")==0)
)
{
dst = fopen(DST,"wb+");
OPEN_FLAG = true;
flag = 1;
}
else if((all_cnt == 5)&&
(strcmp((buf.data()+1),"end")==0)
)
{
fclose(dst);
OPEN_FLAG = false;
flag = 2;
}else{
dst = fopen(DST,"ab+");
OPEN_FLAG = true;
flag = 3;
}
if(NULL == dst)
{
qDebug()<<"dst"<<" error!\n";
OPEN_FLAG = false;
}
if( (OPEN_FLAG == true) &&
( flag == 3)
)
{
char * str = buf.data();
//qDebug()<<all_cnt<<endl;
fwrite(&(str[1]),1,all_cnt-1,dst);
}
fclose(dst);
#endif
//qDebug()<<buf<<(int)all_cnt<<endl;
ui->textEdit->append(buf);
tmp_cnt = 0;
//qDebug()<<all_cnt<<endl;
buf.clear();
all_cnt = 0;
if(cnt_update == 1)
{
all_cnt = *(remain_buf.data());
cnt_update = 2;
qDebug()<<"cnt_update == 1:\t"<<all_cnt<<endl;
buf += remain_buf;
tmp_cnt += remain_buf.size();
//qDebug()<<"tmp_cnt:"<<tmp_cnt<<endl;
}
#endif
}
#endif
void MainWindow::on_sendButton_clicked()
{
if(ui->lineEdit->text().isEmpty())
return;
serial.write(ui->lineEdit->text().toLatin1());
}
void MainWindow::sendPhoto()
{
#if 0
FILE* src = NULL;
FILE* dst = NULL;
unsigned char tmp_cnt = 0;
char buf[MAX_BUF+1]={0};
src = fopen(SRC,"rb");
if(NULL == src)
{
qDebug()<<"src"<<" error!\n";
}
dst = fopen(DST,"wb+");
if(NULL == dst)
{
qDebug()<<"dst"<<" error!\n";
}
while((tmp_cnt = fread(&(buf[1]),1,MAX_BUF,src)) >= MAX_BUF)
{
fwrite(&(buf[1]),1,MAX_BUF,dst);
//write(fd,buf,MAX_BUF);
buf[0] = tmp_cnt+1;
qDebug()<<buf[0]<<endl;
serial.write(buf,buf[0]);
QTime reachTime = QTime::currentTime().addMSecs(100);
while(QTime::currentTime() < reachTime)
{
QCoreApplication::processEvents(QEventLoop::AllEvents,100);
}
}
fwrite(&(buf[1]),1,tmp_cnt,dst);
//write(fd,buf,tmp_cnt);
buf[0] = tmp_cnt+1;
serial.write(buf,buf[0]);
fclose(src);
fclose(dst);
#endif
}
void MainWindow::initSeialPort()
{
connect(&serial,SIGNAL(readyRead()),this,SLOT(serialRead())); //连接槽
//get name for choose
QList<QSerialPortInfo> infos = QSerialPortInfo::availablePorts();
if(infos.isEmpty())
{
ui->serialSelect->addItem("无效");
return;
}
ui->serialSelect->addItem("串口");
foreach (QSerialPortInfo info, infos) {
ui->serialSelect->addItem(info.portName());
}
}
void MainWindow::on_sendPhoto_button_clicked()
{
//sendPhoto();
}