Send Hex data to a serial port? - c++

I have a GPS connected to USB0 and I can read everything perfectly but now I am trying to write data to it. It works with sending and receiving Hexadecimal data. I tried to send data to the GPS. Let's say I want to send 0xB6 0x62 to the port how could I do it in C++. I used this but I don't know weatehr I am right or wrong could someone help me
int main()
{
unsigned char bytestosend[2] = {0xB5, 0x62};
write(fd,&bytestosend,2);
}
of course I open the port to the file descriptor fd.

basically, what you're doing is right given your GPS reads actually hexadecimal bytes. But it may as well read string encoded hexadecimal values, so be sure of that. So from what you tell, I'd say you're writing to it correctly.
And you don't say how you open the serial port, but be careful to use termios and set the connection up correctly, or you may get issues. You shall not just open the port like a standard file. If you haven't done it yet, have a good read of this!

Related

Parsing NMEA sentences from serial

I want to use TinyGPS++ on an Arduino to parse NMEA data and display information on an OLED display. But, instead of using software serial and the TX/RX pins, the NMEA data will be received by USB.
I followed the examples from TinyGPS++, but i encountered two problems:
1)
Only the first 64 characters are received by the Arduino, when i send one NMEA sentence over the serial monitor (Windows, Arduino 1.6.9). How can I overcome this restriction? I help myself by deleting a couple of decimal places, but this is not the preferred way to go.
2)
In the TinyGPS++ BasicExample a sample NMEA string is defined in the read-only memory:
// A sample NMEA stream.
const char *gpsStream =
"$GPRMC,045103.0,A,3014.0,N,09748.0,W,36.88,65.02,030913,,,A*7C\r\n"
"$GPGGA,045104.0,3014.0,N,09749.0,W,1,09,1.2,211.6,M,-22.5,M,,*62\r\n"
"$GPRMC,045200.0,A,3014.0,N,09748.0,W,36.88,65.02,030913,,,A*77\r\n"
"$GPGGA,045201.0,3014.0,N,09749.0,W,1,09,1.2,211.6,M,-22.5,M,,*6C\r\n"
"$GPRMC,045251.0,A,3014.0,N,09748.0,W,36.88,65.02,030913,,,A*7D\r\n"
"$GPGGA,045252.0,3014.0,N,09749.0,W,1,09,1.2,211.6,M,-22.5,M,,*6F\r\n";
and parsed by
while (*gpsStream) {
Serial.print(*gpsStream);
gps.encode(*gpsStream++);
}
I receive my NMEA (unfortunately only one line) this way:
if (Serial.available()) {
while (Serial.available() > 0) {
if(index < 80)
{
inChar = Serial.read();
inData[index] = inChar;
index++;
inData[index] = '\0';
}
}
}
and try to parse it by:
index = 0;
while (index < 80) {
gps.encode(inData[index]);
Serial.print(inData[index]);
index++;
}
But this does not work as desired. Checking if the location isValid() always returns not to be true.
Unfortunately, i have several possible sources for this undesired behavior.
The too short sentences (unlikely)
Incorrect way of reading the data over serial.
I only submit one line.
Something else.
I am not that experienced with neither NMEA, nor the serial data communication, and i have only little experience with Arduino/C. Can you point me into a direction how to solve for this (these) problems?
Basically, you do not need to accumulate NMEA characters. Just feed them to the GPS library as you receive them. You don't provide the entire loop, but it is very common to have a problem there, too.
After struggling with several GPS libraries and their examples, I eventually wrote NeoGPS. It is faster and smaller than all other libraries, it validates the checksum, and the examples are structured correctly. Unlike other libraries, NeoGPS does not store GPS values as floating-point values, so it is able to retain the full accuracy of your GPS device.
If you'd like to try it, be sure to follow the Installation instructions. The NMEA.ino example will emit one line of info (CSV format) for each batch of GPS sentences that you send, ending with the default RMC sentence. Be sure to modify it to use the Serial object instead of gps_port, or simply define it that way:
#define gps_port Serial
It will also show the number of characters that have been parsed, how many good sentences have been received, and how many sentences had checksum errors. That could help with debugging if you are not generating the checksum correctly. This site is useful, too.
Those CSV lines will be sent back over the USB port (to the PC), but you can easily change it to send specific fields to the OLED (see NMEAloc.ino).
Although it is possible to develop something on a PC and then port it to an embedded environment like the Arduino, you have to be careful about (1) linear program structure and (2) ignoring resource limits (program size, MCU speed and RAM). There are a number of quirks with the Arduino environment that usually make it frustrating to port a "sketch" to/from a PC. :P

Send and Receive QStrings String through the Raspberry Pi serial port c++

I am trying to write a string command to the serial port of my Raspberry Pi 2 B without success. I followed this http://www.raspberry-projects.com/pi/programming-in-c/uart-serial-port/using-the-uart, but I need to send and receive QStrings (or arrays of bytes). Are there specific c++ functions that send and receive strings through the RPi Serial Port?
Could someone share some sample code?
Many thanks in advance!
Andrea
If you look at the QString docs you will see a number of methods that convert QString to other types. QString is just a wrapper around a character string.
To get at the underlying char buffer you can do something like this:
std::string stdStr = qString.toStdString();
char* buffer = stdStr.c_str();
Make sure that stdStr stays in scope as long as you wish to use buffer otherwise you will end up using a pointer that points to deallocated memory.

Sending numeric Array via UDP using winsock vc++

RESOLVED: Problem was primarily with the simulink blockset that was reading in the UDP packet rather than data transmission.
I am trying to send a 20 byte numerical array out of a c++ program by using winsock. The issue I am running into is data packaging, in the end I want each number in the array to go out as its own byte so that my simulink model that is receiving these values does not need an additional processing script.
My array contains 14 boolean values (0|1) and then 6 values that range from -100 to 100. These are reporting the status of a controller input. for example the array would look like
int array msgint[20] = [1,0,1,0,0,1,1,0,0,0,0,0,0,0,50,80,-90,40,90,-20];
I have tried using typecasting and sending multiple strings but all just appear to rearrange the gibberish I am getting or cause a socket error. Currently my sendto function looks like
sendto(sd,message,80,0,(struct sockadd *) &server,server_length)
I know this line works as the packet makes it through it just does not appear as I would like it to. In the send to, message is the formatted string I am trying to create to properly send all of contents of the array. Currently is is arbitrary and has little significance I have it in for debugging purposes essentially.
you are starting at the wrong point. Network communications should start with the design of the wire protocol.
How will you represent something on the wire. Binary or text. Most 'modern' protocols use text (json or xml). A few years ago binary was hot (asn1/ber/der). I suggest json
Then how will you wrap up the payload. Do you need to say 'here is a set of xxxs. now here is a set of yyyys'. I dont know what you are doing so its hard to say what you need
If you want to send 20 bytes, and you know that every integer value in your array will be in the [-100, +100] range, you should not use the int type, which usually contains either 32-bit or 64-bit values on modern platforms.
You might instead want to use the char type, which usually represents a 8-bit value.
For even more certainty, if you can use C++11 features, you should use the <cstdint> header, which defines the int8_t type, guaranteed to be a signed 8-bit type. See http://en.cppreference.com/w/cpp/types/integer.
Your array should look like:
#include <cstdint>
std::int8_t msgint[20] = {1,0,1,0,0,1,1,0,0,0,0,0,0,0,50,80,-90,40,90,-20};
or
char msgint[20] = {1,0,1,0,0,1,1,0,0,0,0,0,0,0,50,80,-90,40,90,-20};
and your sendto will be:
sendto(sd,msgint,20,0,(struct sockadd *) &server,server_length);
"in the end I want each number in the array to go out as its own byte"
Then change your array to
char msgint[20] = ...

Socket Read \n at the End From Java Client

Using below code I reading data from socket. On the other side the Java client sending string data. But while reading the data an additional \n appears at the end of the string. Can anyone explain why this happen.
Code:
unsigned char buf[100];
rd=read(newsockfd,buf,100);
char cmd[30];
sprintf(cmd,"%s",buf);
Result:
buf->"DATA\n"
cmd->"DATA\n"
From the client if I sent "DATA" then I am getting "DATA\n" at the server side. Can anyone explain the reason for this ? and how can I extract the exact data I sent.
My guess here would be that the newline comes from the Java client itself.
Probably the client is using a function like sendLine(String) or something that adds a newline to the string passed to it before sending it on the network. I don't know Java but this seems very likely.
In java you can say (as other people has pointed) socket.writeLine("Data") which appends a "\n" at the end.
One thing I've noticed though, in the code you wrote, there is a possibly error you could get, if the sender sends you more than 100 chars you would get a memory error.
unsigned char buf[100];
rd=read(newsockfd,buf,1024);
Here you say you want to read up to 1024 chars/bytes but the buffer is declared as [100], be careful!

Linux C++ write string to COM port, read back response?

I am trying to write to the /dev/ttyACM0 port. In the command line shell I can write the string ":35\n" to the sensor I have plugged in to that port, and via putty listening on the port I can see it responds and gives me the data I am asking for (compass data).
I want to write a driver in C++ that writes this string to that port and reads in the response returned. I have looked online but have been unsuccessful in writing this. I feel like it should be an easy task. I wouldn't think writing to the ttyACM port would be any different than writing to a ttyCOM or ttyS port. Can anyone give me an example of this? I wouldn't think it'd be more than 5 lines of code.
Thank you for any help.
As requested, five lines of code:
#include <fstream>
std::fstream file("/dev/ttyACM0");
file << ":35" << std::endl; // endl does flush, which may be important
std::string response;
file >> response;