How can i write the serial port incoming data into text file (.txt) - c++

How I can write the serial port incoming data into text file(.txt).. The data write should have one hour interval time.
Following this the serial read data code:
void MainWindow::readData()
{
QByteArray data = serial->readAll();
QDataStream stream(data);
double value;
stream>>value;
console->putData(data);
qDebug()<<value;
}
I have tried this way but failed
void Write(QString Filename)
{
QFile mFile(Filename);
if(!mFile.open(QFile::WriteOnly | QFile::Text))
{
qDebug() << "Could not open file for writing";
return;
}
QTextStream out(&mFile);
out << data;
mFile.flush();
mFile.close();
}

I suggest you to use QByteArray for receiving and use signal readyRead() to call receive function when data is received.
QSerialPort *serialPort= new QSerialPort();
connect(serialPort, &QSerialPort::readyRead, this, &MainWindow::receiveData_WriteToFile);
This function read data and write it in file.
void MainWindow::receiveData_WriteToFile()
{
if (serialPort->isOpen())
{
QByteArray DataReceived;
QFile LogFile("D:/data.txt");
if(!LogFile.open(QFile::Append | QFile::Text))
{
//Can't Open Log File.
}
if(serialPort->bytesAvailable())
{
DataReceived = serialPort->readAll();//All Data Received Successfully.
if(DataReceived.size() > 0)
{
if(LogFile.isOpen())
{
QTextStream in(&LogFile);
in << DataReceived;
}
LogFile.close();
}
else
{
//Fail To Receive Data.
}
}
LogFile.close();
}
}
readyRead() : This signal is emitted once every time new data is available for reading from the device's current read channel. It will only be emitted again once new data is available, such as when a new payload of network data has arrived on your network socket, or when a new block of data has been appended to your device.
output file:
This is a sample project for your question on github download here.

Related

how to transfer QImage from QLocalServer to QLocalSocket

I have two mac apps that communicate with each other using QLocalSocket.
Able to send the received QString but not able to send the received QImage Below is my code.
SERVER SIDE CODE
QImage image(":/asset/logo_active.png");
QByteArray ba;
qDebug() << image.sizeInBytes() <<image.size();
ba.append((char *)image.bits(),image.sizeInBytes());
qDebug() <<ba.size(); //262144
this->mSocket->write(ba);
if(!this->mSocket->waitForBytesWritten(-1))
{
qDebug() << "writen Bytes error " << this->mSocket->errorString();
}
this->mSocket->flush();
CLIENT SIDE CODE
connect(mLocalSocket,&QLocalSocket::readyRead, [&]() {
QByteArray ba;
ba = mLocalSocket->readAll();
qDebug() << "size is" << ba.size(); // size is 0
QImage image((uchar *)ba.data(),1024,768,QImage::Format_RGB32);
ui->labelStream->setPixmap(QPixmap::fromImage(img));
});
at sender 262144 is the byte-array size
but at the receiver, byte-array size is 0
Do let me know if I am missing anything.
Thanks In Advance
Finally I got the solutions I used QDataStream below is the code example.
SERVER SIDE CODE:
QDataStream T(mSocket);
T.setVersion(QDataStream::Qt_5_7);
QByteArray ba;
ba.append((char *)img.bits(),img.sizeInBytes());
T << ba;
mSocket->flush();
CLIENT SIDE CODE
QByteArray jsonData;
QDataStream socketStream(mLocalSocket);
socketStream.setVersion(QDataStream::Qt_5_7);
for (;;) {
socketStream.startTransaction();
socketStream >> jsonData;
if (socketStream.commitTransaction()) {
QImage image((uchar *)jsonData.data(),640,480,QImage::Format_RGB888);
ui->labelStream->setPixmap(QPixmap::fromImage(image));
}else {
// the read failed, the socket goes automatically back to the state it was in before the transaction started
// we just exit the loop and wait for more data to become available
break;
}
}
Thanks, Everyone for your support also Stackoverflow.

read tcpsocket by qt

hi i want to receive data from FPGA by Ethernet with qt. i can write data to fpga but unfortunately i cant receive data. after writing x"c000" to fpga it should send data but my code doesn't woked.
i write this code for receive data but i cant please help me.
QByteArray ba2;
ba2.resize(2);
ba2[0] = 0x00;
ba2[1] = 0xc0;
Client ob;
ob.connectToHost();
ob.writeData(ba2);
QByteArray Client:: readback(QByteArray data)
{
qDebug() << socket->readAll();
return data;
}
void Client::connectToHost()
{
socket->connectToHost("192.168.100.17", 1134);
}
void Client::close()
{
socket->close();
}
Client::Client(QObject *parent) : QObject(parent)
{
socket = new QTcpSocket();
connect(socket, SIGNAL(readyRead()), this, SLOT(readback(QByteArray data)));
}
Try it asynch:
auto t = make_unique<QTcpSocket>();
QObject::connect(t.data(),&QTcpSocket::connected,[&t](){
QDataStream writer(t.data());
writer << static_cast<quint16>(0xc000);
});
QObject::connect(t.data(),&QTcpSocket::readyRead,[&t](){
qDebug() << t->readAll();
});

Why QTcpSocket doesn't write ? I need to flush it to make it send my data

I read in the documentation that to send a packet with QTcpSocket I can just use the write method.
But when I do it, my server doesn't receive it. I need to call flush or waitForByteWritten to send it.
TCPClient::TCPClient(Client *babel , const std::string &hostname, unsigned short port, QObject *parent) : QObject(parent), client(babel), hostName(hostname), port(port), is_connected(false)
{
this->tcpSocket = new QTcpSocket(this);
connect(this->tcpSocket, SIGNAL(readyRead()),this, SLOT(readMessage()));
connect(this->tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
connect(this->tcpSocket, SIGNAL(connected()), this, SLOT(connectReady()));
connect(this->tcpSocket, SIGNAL(disconnected()), this, SLOT(disconnectedReady()));
}
TCPClient::~TCPClient()
{
}
bool TCPClient::initiateService()
{
this->tcpSocket->connectToHost(this->hostName.c_str(), this->port);
this->tcpSocket->waitForConnected(5000);
}
void TCPClient::connectReady()
{
this->is_connected = true;
}
void TCPClient::disconnectedReady()
{
}
bool TCPClient::sendBabelPacket(Protocol::BabelPacket &packet)
{
if(this->tcpSocket->state() == QAbstractSocket::ConnectedState && is_connected)
{
std::cout << "writing ... size : " << sizeof(Protocol::BabelPacket) + packet.dataLength<<std::endl;
this->tcpSocket->write((const char *)&packet, sizeof(Protocol::BabelPacket) + packet.dataLength);
//this->tcpSocket->flush();
return true;
}
else
{
std::cout << "socket close" << std::endl;
return false;
}
}
void TCPClient::shutDown()
{
this->tcpSocket->abort();
}
void TCPClient::displayError(QAbstractSocket::SocketError socketError)
{
}
void TCPClient::readMessage()
{
char buffer[sizeof(Protocol::BabelPacket)];
this->tcpSocket->read(buffer, sizeof(Protocol::BabelPacket));
}
When I call write, it returns the right amount of bytes.
I use this class in a GUI context, in the same thread.
QTcpSocket is a buffered device, so data is not written directly, but into internal buffer. Documentation states:
Note: TCP sockets cannot be opened in QIODevice::Unbuffered mode.
Because of it you should call flush or waitForBytesWritten to be sure something is transferred.
There is the difference between them. flush writes as much as possible from the internal write buffer to the underlying network socket, without blocking. waitForBytesWritten blocks until at least one byte has been written on the socket and the bytesWritten() signal has been emitted.

How to read data from the serial port in QT?

I am creating a script in QT for reading the format packages (AA), (BB), etc from serial port. I open the serial port, but when I go to check inside the QByteArray values, comes back that I could not read any value.
This is my code
...
QSerialPort *serialPort = new QSerialPort();
serialPort->setPortName("ttyUSB0");
serialPort->setParity(QSerialPort::NoParity);
serialPort->setBaudRate(QSerialPort::Baud9600, QSerialPort::AllDirections);
serialPort->setStopBits(QSerialPort::OneStop);
serialPort->setFlowControl(QSerialPort::NoFlowControl);
serialPort->open(QIODevice::ReadOnly);
if (serialPort->isOpen()) {
qDebug() << "Serial port is open...";
QByteArray datas = serialPort->readAll();
if (datas.size() == 0) {
qDebug() << "Arrived data: 0";
} else {
for (int i = 0; i < datas.size(); i++){
if (datas.at(i)) {
qDebug() << datas[i];
}
}
}
} else {
qDebug() << "OPEN ERROR: " << serialPort->errorString();
}
serialPort->close();
qDebug() << "...serial port is closed!";
return 0;
...
You called readAll() immediately after open(). It probably took the computer a few nanoseconds to get from one to the other.
At 9600 baud, each byte of data takes slightly more than one millisecond to transfer. It would be absolutely impossible for any data to have arrived in that short an interval, so that's why you got no data.
Serial ports don't begin buffering incoming data until you open them (how could they, what baud rate and other settings would be used for receiving and buffering when no program has the port open?)
Use either a blocking read function of some sort (such as readLine()) or an event loop that reacts to data when it arrives.

Qt getting network requests with QNetworkReply that download data to temp file

I am having some issues reading an online file. I'm trying to read what is in the file after it gets downloaded to a temporary file. Here is my code:
void MainWindow::fileIsReady( QNetworkReply * reply)
{
QTemporaryFile tmpFile;
tmpFile.write(reply->readAll());
QByteArray asdf = reply->readAll();
qDebug() (QString("%1").arg(asdf.length())); // returns 0
if (tmpFile.open())
{
qDebug << "attempting to read file";
QTextStream stream(&tmpFile);
QString value = stream.readAll();
qDebug << value; // value is returning nothing
}
else
{
qDebug() << "failed to open internet file";
}
}
// in MainWindow constructor (MainWindow::MainWindow)...
QNetworkAccessManager * manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(fileIsReady(QNetworkReply*)) );
manager->get(QNetworkRequest(QUrl("https://www.website.com/stuff/file.exe.md5")));
I'm going to be using this to compare two md5 strings.
There are several issues in your code:
You need to open tmpFile before writing to it.
reply->readAll() will return data only once. Further calls will return empty array. Once you received data using readAll, it's your responsibility to store it in a variable if you need it later.
After you wrote someting to file, the file pointer is at its end. You cannot read anything from it because there is no data there. You can use seek to move pointer to the beginning of the file and read its content.
There is no point in reading from file just after you wrote data to it. You can use QTextStream on QNetworkReply directly to read text from it. (Maybe this was just for debugging, I don't know.)
It's hard to believe that you need to create a temporary file just to calculate md5. There are simplier ways to do that.
So turns out I was dumb and forgot to open the reply first. Also, it was unnecessary for me to create a temp file. Here is my solution::
void MainWindow::fileIsReady( QNetworkReply * reply)
{
if (reply->error() == QNetworkReply::NoError)
{
if (reply->open(QIODevice::ReadOnly))
{
QByteArray asdf = reply->readAll();
qDebug() << (QString("asdf %1").arg(asdf.length()));
qDebug() << (QString(asdf));
}
else
{
qDebug << "cant open reply";
}
}
}