Unable to send and receive images between 2 Raspberry connected to Zigbee via UART.
-
I have 2 Raspberry Pi4 connected to Zigbee via UART, I wrote the program to receive and send between the two devices. My program can send and receive character data very accurately, but when I send data from a photo, the program never receives enough data. I tried a PC connected to Zigbee and sent pictures to Pi via RealTerm, on Pi I received photos. What is the problem here? Or does anyone have another way to send photos between 2 Raspberry connected to Zigbee via UART? Thanks very much.
Program send data:#include "ui_serial.h" #include <QDebug> #include <QBuffer> #include <QPixmap> #include <QFile> serial::serial(QWidget *parent) : QMainWindow(parent), ui(new Ui::serial) { ui->setupUi(this); serialPort = new QSerialPort(this); serialPort->setPortName("ttyAMA0"); serialPort->setBaudRate(QSerialPort::Baud115200); serialPort->setDataBits(QSerialPort::Data8); serialPort->setStopBits(QSerialPort::OneStop); serialPort->setFlowControl(QSerialPort::NoFlowControl); serialPort->open(QIODevice::ReadWrite); if (serialPort->isOpen() == true){ qDebug() <<"Port Opened...."; connect(serialPort, SIGNAL(readyRead()), this, SLOT(on_readdata())); } } void serial::on_pushButton_2_clicked() { QFile* imageFile = new QFile("/home/pi/Desktop/image.jpg"); imageFile->open(QIODevice::ReadOnly); QByteArray ba = imageFile->readAll(); imageFile->close(); delete imageFile; if(serialPort->isOpen()==true){ serialPort->write(ba); qDebug()<<ba.size()<<"size_send:"; } }
Data receiving program:
#include "ui_serial.h" #include <QDebug> #include <QBuffer> #include <QPixmap> #include <QFile> #include <QMessageBox> serial::serial(QWidget *parent) : QMainWindow(parent), ui(new Ui::serial) { ui->setupUi(this); serialPort = new QSerialPort(this); serialPort->setPortName("ttyAMA0"); serialPort->setBaudRate(QSerialPort::Baud115200); serialPort->setDataBits(QSerialPort::Data8); serialPort->setStopBits(QSerialPort::OneStop); serialPort->setFlowControl(QSerialPort::NoFlowControl); serialPort->open(QIODevice::ReadWrite); if (serialPort->isOpen() == true){ qDebug() <<"Port Opened...."; connect(serialPort, SIGNAL(readyRead()), this, SLOT(on_readdata())); } } void serial::on_readdata() { QByteArray ba; while (serialPort->waitForReadyRead(1000)){ ba.append(serialPort->readAll()); } qDebug()<<ba.size()<<"sizeeeee:"; QFile newDoc("/home/pi/Desktop/imagexx.jpg"); if(newDoc.open(QIODevice::WriteOnly)){ newDoc.write(ba); } newDoc.close(); }
-
I have 2 Raspberry Pi4 connected to Zigbee via UART, I wrote the program to receive and send between the two devices. My program can send and receive character data very accurately, but when I send data from a photo, the program never receives enough data. I tried a PC connected to Zigbee and sent pictures to Pi via RealTerm, on Pi I received photos. What is the problem here? Or does anyone have another way to send photos between 2 Raspberry connected to Zigbee via UART? Thanks very much.
Program send data:#include "ui_serial.h" #include <QDebug> #include <QBuffer> #include <QPixmap> #include <QFile> serial::serial(QWidget *parent) : QMainWindow(parent), ui(new Ui::serial) { ui->setupUi(this); serialPort = new QSerialPort(this); serialPort->setPortName("ttyAMA0"); serialPort->setBaudRate(QSerialPort::Baud115200); serialPort->setDataBits(QSerialPort::Data8); serialPort->setStopBits(QSerialPort::OneStop); serialPort->setFlowControl(QSerialPort::NoFlowControl); serialPort->open(QIODevice::ReadWrite); if (serialPort->isOpen() == true){ qDebug() <<"Port Opened...."; connect(serialPort, SIGNAL(readyRead()), this, SLOT(on_readdata())); } } void serial::on_pushButton_2_clicked() { QFile* imageFile = new QFile("/home/pi/Desktop/image.jpg"); imageFile->open(QIODevice::ReadOnly); QByteArray ba = imageFile->readAll(); imageFile->close(); delete imageFile; if(serialPort->isOpen()==true){ serialPort->write(ba); qDebug()<<ba.size()<<"size_send:"; } }
Data receiving program:
#include "ui_serial.h" #include <QDebug> #include <QBuffer> #include <QPixmap> #include <QFile> #include <QMessageBox> serial::serial(QWidget *parent) : QMainWindow(parent), ui(new Ui::serial) { ui->setupUi(this); serialPort = new QSerialPort(this); serialPort->setPortName("ttyAMA0"); serialPort->setBaudRate(QSerialPort::Baud115200); serialPort->setDataBits(QSerialPort::Data8); serialPort->setStopBits(QSerialPort::OneStop); serialPort->setFlowControl(QSerialPort::NoFlowControl); serialPort->open(QIODevice::ReadWrite); if (serialPort->isOpen() == true){ qDebug() <<"Port Opened...."; connect(serialPort, SIGNAL(readyRead()), this, SLOT(on_readdata())); } } void serial::on_readdata() { QByteArray ba; while (serialPort->waitForReadyRead(1000)){ ba.append(serialPort->readAll()); } qDebug()<<ba.size()<<"sizeeeee:"; QFile newDoc("/home/pi/Desktop/imagexx.jpg"); if(newDoc.open(QIODevice::WriteOnly)){ newDoc.write(ba); } newDoc.close(); }
@Rika said in Unable to send and receive images between 2 Raspberry connected to Zigbee via UART.:
while (serialPort->waitForReadyRead(1000)){
ba.append(serialPort->readAll());
}How do you actually know when the whole picture was received?
You need a protocol. For example you could first send an int containing the image size and then send the actual image. This way the receiver would know how many bytes to receive. -
@Rika said in Unable to send and receive images between 2 Raspberry connected to Zigbee via UART.:
while (serialPort->waitForReadyRead(1000)){
ba.append(serialPort->readAll());
}How do you actually know when the whole picture was received?
You need a protocol. For example you could first send an int containing the image size and then send the actual image. This way the receiver would know how many bytes to receive. -
@jsulm Thank you for replying. I tried sending images from a PC (using Realterm to send pictures), on my Pi 4, I ran the receiving program and got the images. Could the error be in the sending program?
@Rika
Hi
There is no real error as such. it's just that data will come as multiple read and
the current code will then save only the last seen data piece as imagexx.jpg
and the image will always appear broken.
Overlooked waitForReadyRead in slotThat is why @jsulm want you to include the size of the image so we can know we got all data.
-
@Rika
Hi
There is no real error as such. it's just that data will come as multiple read and
the current code will then save only the last seen data piece as imagexx.jpg
and the image will always appear broken.
Overlooked waitForReadyRead in slotThat is why @jsulm want you to include the size of the image so we can know we got all data.
@mrjj said in Unable to send and receive images between 2 Raspberry connected to Zigbee via UART.:
There is no real error as such. it's just that data will come as multiple read and
the current code will then save only the last seen data piece as imagexx.jpgAre you sure?
QByteArray ba; while (serialPort->waitForReadyRead(1000)){ ba.append(serialPort->readAll()); }
-
@mrjj said in Unable to send and receive images between 2 Raspberry connected to Zigbee via UART.:
There is no real error as such. it's just that data will come as multiple read and
the current code will then save only the last seen data piece as imagexx.jpgAre you sure?
QByteArray ba; while (serialPort->waitForReadyRead(1000)){ ba.append(serialPort->readAll()); }
-
@jsulm
Hi
Àhh on first ready signal, it will call the slot and the
waitForReadyRead + loop will then read all remaining data.
Ok that should actually do it.
( if really never breaks the while loop) -
@mrjj Yes, possible that the timeout kicks in and terminates the loop before everything was received.
-
@jsulm Thank you for replying. I tried sending images from a PC (using Realterm to send pictures), on my Pi 4, I ran the receiving program and got the images. Could the error be in the sending program?
@Rika I suggest you implement the receiving part in a proper way: without mixing asynchronous and synchronous ways to read data. Remove the loop from serial::on_readdata(). Put QByteArray ba as member variable in the class. Accumulate data in ba untill you got all data.
-
-
@Rika Please read https://doc.qt.io/qt-5/qserialport.html#waitForReadyRead "This function blocks until new data is available for reading and the readyRead() signal has been emitted" and my previous post (no need for waitForReadyRead and the loop).
-
@Rika I suggest you implement the receiving part in a proper way: without mixing asynchronous and synchronous ways to read data. Remove the loop from serial::on_readdata(). Put QByteArray ba as member variable in the class. Accumulate data in ba untill you got all data.
-
@jsulm You mean this?
void serial::on_readdata() { QByteArray ba(serialPort->readAll()); qDebug()<<ba.size()<<"sizeeeee:"; QFile newDoc("/home/pi/Desktop/imagexx.jpg"); if(newDoc.open(QIODevice::WriteOnly)){ newDoc.write(ba); } newDoc.close(); }
-
@Rika No, not like this. Please read my post above "Put QByteArray ba as member variable in the class. Accumulate data in ba untill you got all data."
-
void serial::on_readdata() { ba.apend(serialPort->readAll()); qDebug()<<ba.size()<<"sizeeeee:"; if (ba.size() == imageSize) { QFile newDoc("/home/pi/Desktop/imagexx.jpg"); if(newDoc.open(QIODevice::WriteOnly)){ newDoc.write(ba); } newDoc.close(); } }
-
void serial::on_readdata() { ba.apend(serialPort->readAll()); qDebug()<<ba.size()<<"sizeeeee:"; if (ba.size() == imageSize) { QFile newDoc("/home/pi/Desktop/imagexx.jpg"); if(newDoc.open(QIODevice::WriteOnly)){ newDoc.write(ba); } newDoc.close(); } }
-
@mrjj No, the last time was 241. My old way it also received only 241 bytes, so I was thinking of the possibility of an error sent by the program.
@Rika said in Unable to send and receive images between 2 Raspberry connected to Zigbee via UART.:
No, the last time was 241.
So you do get mutiple
qDebug()<<ba.size()<<"sizeeeee:";
messages ? -
@Rika said in Unable to send and receive images between 2 Raspberry connected to Zigbee via UART.:
No, the last time was 241.
So you do get mutiple
qDebug()<<ba.size()<<"sizeeeee:";
messages ?