How to correctly set QextSerialPort for Windows - serial-port

I'm regularly using QextSerialPort for Serial Communication on Linux (Ubuntu); I'd like to transfer my code to Windows, but it seems to be a problem related to the QExtSerialPort library use.
Here's my function:
void ts400::EsuPortSetupDNI()
{
this->EsuPort = new QextSerialSleeperThread::msleep(TIME_STEP);Port("/dev/ttyS0", QextSerialPort::EventDriven); // Serial Port
EsuPort->flush();
EsuPort->setBaudRate((BaudRateType)BAUD4800);
EsuPort->setFlowControl((FlowType)FLOW_OFF);
EsuPort->setParity((ParityType)PAR_NONE);
EsuPort->setDataBits((DataBitsType)DATA_8);
EsuPort->setStopBits((StopBitsType)STOP_1);
if (EsuPort->open(QIODevice::ReadWrite) == true)
{
connect(EsuPort, SIGNAL(readyRead()), this, SLOT(onReadyReadDNI()));
ui->EsuReturnLabel->setText("Ready to receive serial data");
EsuPortFlag = SET;
}
else
ui->EsuIdentlineEdit->setText("SERIAL NOT PRESENT!");
}
I tried to replace the first line:
this->EsuPort = new QextSerialSleeperThread::msleep(TIME_STEP);Port("/dev/ttyS0", QextSerialPort::EventDriven); // Serial Port
with one , in my opinion, for Windows:
this->EsuPort = new QextSerialPort("COM1", QextSerialPort::EventDriven); // COM1
Compiling, result are a lot of errors; seems to be related to Linux use...
Any idea?

Related

How to send data from USB device to DJI SDK?

So this might be a bit basic of a question, but I don't have much experience on the hardware side of things. I am using DJI Android Mobile SDK to communicate with a M600 flight controller and have a FTDI CU/TTY device I am trying to send info back and forth.
This successfully works to send "Hello World" to my USB device:
//sends data to onboard sdk device
final byte[] helloWorld = "HelloWorld".getBytes();
mFlightController.sendDataToOnboardSDKDevice(helloWorld, new CommonCallbacks.CompletionCallback() {
#Override
public void onResult(DJIError djiError) {
if (djiError != null) {
showToast(djiError.getDescription());
WriteFileAppendAsync writeAppend = new WriteFileAppendAsync();
writeAppend.execute(djiError.getDescription(), "sendOnboardErrorFile.txt");
} else {
showToast("Hopefully Hello World");
WriteFileAppendAsync writeAppend = new WriteFileAppendAsync();
writeAppend.execute(helloWorld.toString(), "sendOnboardSuccessFile.txt");
}
}
});
I can see this when I run either of the following in terminal:
screen /dev/cu.usbserial-BLAHBLAH 38400
screen /dev/tty.usbserial-BLAHBLAH 38400
A bunch of gibberish/ hieroglyphics show up and then the text "Hello World" pops up every time I click a button that triggers the above DJI code.
Now, I want to get the flips side of this working i.e. send something back from the USB to the DJI sdk using the following:
if (mFlightController.isOnboardSDKDeviceAvailable()) {
showToast("Set Onboard SDk Callback");
mFlightController.setOnboardSDKDeviceDataCallback(new FlightController.OnboardSDKDeviceDataCallback() {
#Override
public void onReceive(byte[] bytes) {
WriteFileAppendAsync writeAppend = new WriteFileAppendAsync();
writeAppend.execute(bytes.toString(), "onboardCallbackFile.txt");
}
});
}
The trouble is I never seem to get anything in response.
As per this question, I made sure I have read write permission on the USB device:
chmod o+rw /dev/ttyS1
And I have tried all sorts of echo and cat commands (I don't know which one is read and write). They either say device is busy, or if not, they seem to open a port of communication (the terminal blinks indefinitely), but nothing sends to my device.
Commands I've tried:
echo 'HelloTest' > /dev/cu.usbserial-BLAHBLAH
Nothing special happens, goes to next terminal line
echo 'HelloTest' > /dev/tty.usbserial-BLAHBLAH
Terminal returns HelloTest
echo 'HelloTest' < /dev/tty.usbserial-BLAHBLAH
cursor blinks indefinitely
echo 'HelloTest' < /dev/cu.usbserial-BLAHBLAH
Terminal returns HelloTest
cat < /dev/cu.usbserial-BLAHBLAH
cat -v < /dev/tty.usbserial-BLAHBLAH
cat -v > /dev/tty.usbserial-BLAHBLAH
cat -v > /dev/cu.usbserial-BLAHBLAH
No such file or directory (I guess I need 2 terminals running for this?)
Questions
Does this have to do with Baud rate? I have set that up in DJI Assistant. What is the difference between TTY and CU and Echo and Cat? I have tried all sorts of combinations. I am able to use the screen command with both cu and tty. Finally, what is a simple hello world I can send back to the sdk to see that I am actually receiving data from my usb device? I would think echo would success, but I'm not receiving anything.
Edit
I almost feel like I need to use something like usb-serial-for-android; however, I'm not actually connecting the usb device to my android device. Instead, I am connecting to the DJI RC Controller, which connects to Lightbridge/ M600, which connects through the API port with my usb device.
I came across this issue a while back as well using the Matrice M100 with the ROS onboardSDK.
if (mFlightController.isOnboardSDKDeviceAvailable()) {
showToast("Set Onboard SDk Callback");
mFlightController.setOnboardSDKDeviceDataCallback(new FlightController.OnboardSDKDeviceDataCallback() {
#Override
public void onReceive(byte[] bytes) {
WriteFileAppendAsync writeAppend = new WriteFileAppendAsync();
writeAppend.execute(bytes.toString(), "onboardCallbackFile.txt");
}
});
}
Where are you calling this?. Here's how I solved my issue: I wrote a function:
private void addCallback()
{
mFlightController.setOnboardSDKDeviceDataCallback(new
FlightController.OnboardSDKDeviceDataCallback() {
#Override
public void onReceive(byte[] bytes) {
// Do stuff with the data here..
}
});
}
Then in my onResume method I did something like:
#Override
public void onResume() {
Log.e(TAG, "onResume");
super.onResume();
if (mFlightController != null) {
addCallback();
}
}
It's not the most elegant way but it seemed to do the trick for me. You can find my solution here. It's been a while since I worked on it though!
If you have an FTDI device then you need an FTDI driver. :)
Did you install something like this by chance? https://www.ftdichip.com/FTDrivers.htm
Serial port emulation through USB requires virtual serial port software to function.
I believe you need to understand the DJI OpenProtocol to make this work. The "bunch of gibberish" is in fact the problem here. That gibberish is the protocol that DJI drones use to properly relay communications.
In order to send from "Onboard" to "Mobile" with the latest code you need the 0xFE CMD_Set Id as a header to your data:
https://developer.dji.com/onboard-sdk/documentation/protocol-doc/open-protocol.html
So, either, figure out the proper format to your data or buy a cheap PC and install the OSDK.

write and read data to terminal from serial port without connecting any hardware devices to serialport

actually i have Qt code. so i need to send data of packets from serial port to terminal and display the data in terminal and also from terminal i need to read data and display it in Qt window page. main problem is, for serial communication to terminal, does we really require serial port should connect to some hardware devices and also.. can we write and read data to terminal without connecting any serial port to hardware devices.
the code from Transceiver layer to serial port
Transceiver::Transceiver(QObject *parent)
:
QObject(parent),
mSerial(new QSerialPort(this))
{
mSerial->setPortName(QString("COM1"));
qint32 baudRate = 9600;
mSerial->setBaudRate(baudRate);
mSerial->setDataBits(QSerialPort::Data8);
mSerial->setParity(QSerialPort::NoParity);
mSerial->setStopBits(QSerialPort::OneStop);
connect
(
mSerial,
&QSerialPort::readyRead,
[ this ]()
{
QByteArray data = mSerial->readAll();
OnDataReceived( data );
qDebug()<<data;
}
);
}
Transceiver::~Transceiver()
{
mSerial->close();
}
void
Transceiver::Send_Data(const QByteArray & inDataStream )
{
qDebug()<<"Data_in_Transceiver_layer :"<<inDataStream;
mSerial->write(inDataStream);
}
bool
Transceiver::OpenConnection()
{
mSerial->open(QIODevice::ReadWrite);
QSerialPort::SerialPortError error = m`enter code here`Serial->error();
return error == QSerialPort::NoError;
// connect(mSerial, SIGNAL(readyRead()), this, SLOT(read_data()));
}
when i run this it shows
QIODevice::write (QSerialPort): device not open

Processing serial port error

I'm trying to get my arduino to communicate with a processing program. Every time I do it I get this error:
"Error opening serial port /dev/tty.usbmodem1441: Port busy". My arduino is using the same port.
Here is my processing code:
import processing.serial.*;
Serial myPort;
String val;
void setup()
{
String portName = Serial.list()[5];
myPort = new Serial(this, portName, 9600);
}
void draw()
{
if ( myPort.available() > 0) {
val = myPort.readStringUntil('\n');
}
println(val);
}
I got it from https://learn.sparkfun.com/tutorials/connecting-arduino-to-processing and I didn't change anything.
If you have the Arduino serial monitor open, attempting to connect to the serial line with Processing will create a conflict, resulting in that error. Simply close the serial monitor and try starting the sketch again. (Maybe reset Arduino too by clicking Reset button near AREF)
You cant use same port for two diffrent purpose at a same time.
check if that is the case. If thats not the case then try restarting arduino and pc both.
also make sure you are connected to the right port.
ls -l /dev/tty.* should return all connected dvices if you are in unix system
if you are in window, may be its under device mager(its been long time i used window)
Just close the "Serial Monitor" in Arduino and everything will work fine

Flow Controll Settings for Serial Communication between Java RXTX and Arduino

I have a simple sketch on my Seeeduino Mega 1.22 which just displays the serial input on a LCD Display. Using lynx term and the arduino serial monitor works fine: sent input is being displayed. The trouble starts when I want to start serial communication between my Java programm, running in Eclipse on a Win7 x64 machine, and the Seeeduino. I'm using the RXTX x64 build. The programm is intended to send and receive some string.getBytes() via the open port. Receiving on the Java side works, but receiving on the Arduino side fails.
It seems that the problem is the proper Flow Control setting. I saw that some people had the same issue like here Issues receving in RXTX
But this solution does not work for me. If I set the FlowControl to None, than I get only a block icon on the display, indicating, that the serial connection has been established, but nothing else. If I set the FlowControl to RCTS_IN | RCTS_OUT, then I get the string bytes only on the display when I close the established connection.
Why is the data only send when I close the connection (Flushing the out stream did not help as well) ? What am I doing wrong with the Flow Controll settings?
This is the modified connect() method I'm using.
void connect(String portName) throws Exception {
CommPortIdentifier portIdentifier = CommPortIdentifier
.getPortIdentifier(portName);
if (portIdentifier.isCurrentlyOwned()) {
System.out.println("Error: Port is currently in use");
} else {
CommPort commPort = portIdentifier.open(this.getClass().getName(),
2000);
if (commPort instanceof SerialPort) {
SerialPort serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(115200, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
try {
serialPort.setFlowControlMode(
// SerialPort.FLOWCONTROL_NONE);
// OR
// If CTS/RTS is needed
//serialPort.setFlowControlMode(
SerialPort.FLOWCONTROL_RTSCTS_IN |
SerialPort.FLOWCONTROL_RTSCTS_OUT);
} catch (UnsupportedCommOperationException ex) {
System.err.println(ex.getMessage());
}
serialPort.setRTS(true);
in = serialPort.getInputStream();
out = serialPort.getOutputStream();
(new Thread(new SerialWriter(out))).start();
serialPort.addEventListener(new SerialReader(in, this));
serialPort.notifyOnDataAvailable(true);
} else {
System.out.println("Error: Only serial ports are to use!");
}
}
}
Thanks in advance for your time
Solved it. It was not the buffer, as many suggested it. The problem was, that the Seeeduinos RST Switch on the board was set to automatic. Setting it to manual, solved the problem.
No Flow-Controll needed.

gnu.io.PortInUseException: Unknown Application?

void connect ( String portName ) throws Exception
{
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
if ( portIdentifier.isCurrentlyOwned() )
{
System.out.println("Error: Port is currently in use");
}
else
{
System.out.println(portIdentifier.getCurrentOwner());
CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);
if ( commPort instanceof SerialPort )
{
SerialPort serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(115200,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();
(new Thread(new SerialReader(in))).start();
(new Thread(new SerialWriter(out))).start();
}
else
{
System.out.println("Error: Only serial ports are handled by this example.");
}
}
}
is giving
gnu.io.PortInUseException: Unknown Application
at gnu.io.CommPortIdentifier.open(CommPortIdentifier.java:354)
i am using RXTX with Java in windows 7 home 64-bit.
Check that /var/lock folder exist on your machine.
mkdir /var/lock
chmod go+rwx /var/lock
Reboot the system / disable the port.
Actual problem is when the program runs port is opened and it didn't close after the program terminates.
it works.
I ran into this problem because the port was actually in use. A previous instance of javaw.exe appeared in the Windows task manager, it hogged the port.
The reason why that previous java process hung was a hardware issue: When plugging the USB-2-serial converter that I happened to use into a USB-2 port, all worked fine. When plugged into a USB-3 port, RXTX CommPortIdentifier code would hang, and then subsequent instances of Java received the PortInUseException.
I used Process Explorer to find a process with the handle \Device\PCISerial0 and closed the handle. If your com ports aren't on a PCI card, the name might be different.
For Windows
Open Task Manager
under Eclipse (or your ide) find Java application.
Right click on it -> End Task
May be useful, I solved such problem by remove gateway from service and stop it , gateway is instance of SerialModemGateway.
Service.getInstance().stopService();
Service.getInstance().removeGateway(gateway);
gateway.stopGateway();

Resources