1
votes

I'm trying to write \ read from a serial device using a usb / rs 232 cable. I'm pretty sure that my code writes " #002s " (this is a control code) to the serial device, because

a) the serial port is open

b) the serial port is writable

c) the code successfully navigates "wait For Bytes Written (-1)"

d) when using a serial port sniffer the data is successfully written.

The issue I have is that I don't receive any data, and no data is being emitted from the other device. When using qt terminal writing the same " #002s " produces the correct response.

Any ideas?

many thanks.

    #include "test_serial.h"
#include "ui_test_serial.h"
#include <QtSerialPort/QtSerialPort>
#include <QDebug>

QSerialPort *serial;
Test_Serial::Test_Serial(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Test_Serial)
{
    ui->setupUi(this);

  serial = new QSerialPort(this);
  connect(serial,SIGNAL(readyRead()),this,SLOT(serialReceived()));
  serial->setPortName("COM1");
  serial->setBaudRate(QSerialPort::Baud9600);
  serial->setDataBits(QSerialPort::Data8);
  serial->setParity(QSerialPort::NoParity);
  serial->setStopBits(QSerialPort::OneStop);
  serial->setFlowControl(QSerialPort::NoFlowControl);
  serial->open(QIODevice::ReadWrite); 

  if (serial->isOpen() && serial->isWritable())
 {
  QByteArray input;

  input = "#";
  serial->write(input);
  serial->waitForBytesWritten(-1);
  input = "0";
  serial->write(input);
  serial->waitForBytesWritten(-1);
  input = "0";
  serial->write(input);
  serial->waitForBytesWritten(-1);
  input = "2";
  serial->write(input);
  serial->waitForBytesWritten(-1);
  input = "s";
  serial->write(input);
  serial->waitForBytesWritten(-1);
  input = "\r";
  serial->write(input);
  serial->waitForBytesWritten(-1);
  serial->flush();

  serial->waitForReadyRead(100);
  QByteArray output = serial->readAll();
  ui->label_2->setText(output);

}}


Test_Serial::~Test_Serial()
{
    delete ui;
    serial->close();
}

void Test_Serial::serialReceived()
{
    QByteArray output;
    output = serial->readAll();
    ui->label->setText("output");
}
2
techneaz thanks for the reply. Everything's working now turned out to be a timing problem.Jon CO

2 Answers

2
votes
  1. If you want to write " #002s ", Why not write at once? May be the serial device cant identify the control code when you write each character.

    void Test_Serial::writeDataToSerialPort()
    {
        QByteArray input = QString("#002s").toLocal8Bit();
        serial->write(input);
    }   
    
  2. And no need for this reading part .

        serial->waitForReadyRead(100);
        QByteArray output = serial->readAll();
        ui->label_2->setText(output);
    

    The Test_Serial::serialReceived will be called any way when you have the response from the serial device.

  3. And you can catch the error on opening the port by using the error signal from QSerialPort

    connect(serial,SIGNAL(error(QSerialPort::SerialPortError)),this,SLOT(serialPortError(QSerialPort::SerialPortError)));
    
    void Test_Serial::serialPortError(QSerialPort::SerialPortError error)
    {
        //Print error etc.
    }
    
0
votes

The issue ended up being that the readyread flag is only emitted if theirs data to read. However I was sending the data too quickly for the external device to receive it. This meant that some data was lost thus the device never recognised it as a valid command.

This meant that it was still waiting for the message to finish, hence the "IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_WAIT_ON_MASK) UP STATUS_CANCELLED COM1" error message upon closing the program. This also explains why their were no error messages with regards to writing data.

This also explains why the same program occasionally managed to read data, and at other times failed, (even without rebuilding the program, just re-running it.) When the data was read, the processor was more loaded, i.e. programs running in the background. This meant that the data was transmitted more slowly and thus the external device could recognise the commands and thus reply.