Reading NULL character from Serial Port Linux C - c

I have read many questions and answers but didn't find any solution. May be my question is not right but I need some guidance. I am using serial port in Linux which is reading data from my Arduino device. Whenever I want to send data from Arduino to Linux, I first send two bytes which indicate the total bytes which will come from Arduino. I convert these two bytes to integer value and start reading data from Serial Port. Say, I want to send 300 bytes from Ardiuno to Linux, I will just write {1, 44} first and then convert this 1 and 44 byte into int by the following formula:
char data[] = {1, 44};
int to_read = data[0]
to_read = to_read << 8;
to_read = to_read | data[1];
return to_read;
this will give me 300 int value, this is working like charm. but problem comes when I have to read data less then 255. Say I want to read 100 bytes, then first two bytes will be {0, 100}. 0 is null character, serial port doesn't process it (I manually wrote 0s to serial port, it always give me 0 bytes written), and my all sequence goes wrong. So my question is can I read null characters from serial port OR someone please give me better solution..
thanks in Advance.

I got my problem solved. When working on bytes in C, don't confuse bytes (char) with string like I was treating bytes array (char data[]) and When I was trying to write these bytes on serial port with write method with length of strlen(data), I was only getting those bytes which were not null. strlen returns the length of data after seeing first null character that is \0, because of this I was not getting my desired output. What I did is that, If I want to write data char data[] = {0, 4} then I will do something like this:
char data[] = {0, 4};
write(serial_port_fd, data, 2);
told the write function to write 2 bytes. This will write 0 and 4, If I write something like this:
char data[] = {0, 4}
write(serial_port_fd, data, strlen(data));
this will write NOTHING.
One more thing, If you want to write non printable characters (which are from byte value 0 to 32) on Serial Port, then make sure that you have configured your Serial Port for raw input and ouput. Have a look on this guide:
http://www.cmrr.umn.edu/~strupp/serial.html#config

Related

Printing a bitstream data /TCP related

I am trying to make a communication between a Client and a Sever through TCP.
Let's say the client send 10 Hex numbers as bitstream to Sever. send(socketID, pSend, 20, 0); Where pSend = &ArrayClient; and unsigned short ArrayClient[] = { 0A, 0B, BA, B1...., FA }.
The sever receive the bytes stream with recv(acceptID, pRecv, 20, 0). How can I print out the content in my pointer pRecv correctly. As Sever I won't know how many bytes did the Client send, therefore I don't know how many to print.
Because the datas were sent as bitstream, not a string. I can not know the end of the message by finding \0 like working with string.
So is there a way that I can know how many bytes that I received as sever, or any way to print out the bitstream in my pRecv as Hex numbers.
I have tried pointer to a pointer and something similar like this:
while( ((unsigned int*)pRecv)[i] != 0){
printf("%X", ((unsigned int*)pRecv)[i]);
i++;
}
When dealing with TCP, there is no built-in way of separating messages, so your protocol needs to delimit the message boundaries in some known way.
A simple way of doing this is by first sending single byte denoting the length of the message, then sending that number of bytes.
For example, before sending the above message, do this:
char mlen = 20;
send(socketID, &mlen, 1, 0);

How to Send Hex string from uart to microcontroller and store it to integer for future "if" statement

okay, im really beg for a help here, cause im hittin a rock bottom. ive spend weeks to do this and still not able to.
i have an avr, i will recive a string containing hex value in it from UART.
ex :
0x3cffaa31
i need to split it into
0x3c
0xff
0xaa
0x31
and store it into a variable so i can do if statement with it.
how can i achieve this, please help me. i already lookin here and there on the internet yet i still lost.
uint8_t Values[4]={0};
uint8_t Loc=0;
uint32_t Mask=0xFF; //32 bits UART Rx Buffer size
for(uint8_t i=0;i<=24;i+=8)
{
Values[Loc]=(((Mask<<i) & UartRxBuf) >> i);
Loc++;
}
Help me out if I'm interpreting this wrong, but it sounds like you need to;
split the incoming string from the UART into indidual 2-character strings, each one representing a byte of hex. If you will always have 4 bytes of data, in the format that you've shown, then this will be easy. e.g. you always know that the two characters of the first byte are at index 2 and 3 of the char[] holding your input string.
Convert each two-character string to an int, so you can use them for numerical calculations. Look at strtol, which is available in AVR libc, for this http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__stdlib_1gaf8ce3b8dae3d45c34c3b172de503f7b3.html
Make sure to specify base16 for strtol-- e.g.:
long converted = strtol(digits, NULL, 16);
(where digits is a char[] containing your two hex characters, null-terminated)
UPDATE- looks like strtol doesn't care if the string has a preceding 0x, so something like this would work to get the first hex value from the raw string:
const char *raw = "0x3cffaa31";
char digits[3];
long converted;
/* Copy two bytes from 'raw', starting from index 2,
* (so we can skip the '0x') to get the string "3c" */
strncpy(digits, raw + 2, 2);
/* Make sure the new string is null-terminated */
digits[2] = '\0';
/* Convert hex string to a long. Now you can use it
* in an if-statement */
converted = strtol(digits, NULL, 16);
I donot think this is an issue
If you are using uart in 8bit mode you will recieve only one byte data at a time .
Just increase the array index every time you recieve the data
for(i = 0; i<4; i++){
while(UART_recieve_not_completed);
arr[i] = UART_RX_BUFF;}
Hope this helps

linux - serial port programming ( ASCII to Byte )

I tried to receive data from serial port. However, those data is unrecognized to me. The root cause is because those are in ASCII. To decode the data, it needs to be the byte formate.
The buffer I've created is unsigned char [255] and I try to print out the data by using
while (STOP==FALSE) {
res = read(fd,buf,255);
buf[res]=0;
printf(":%x\n", buf[0]);
if (buf[0]=='z') STOP=TRUE;
}
Two questions here:
The data might is shorter than 255 in the real case. It might takes 20 - 30 arrays from 255. In this case, how can I print 20 arrays ?
The correct output should be 41542b ( AT+ ) as the head of the entire command since this is the AT command. So I expect the buf[0] should be 41 in the beginning. It is, however, I dont know why the second one is e0 while I expect to have 54 (T).
Thanks
Ascii is a text encoding in bytes. There's no difference in reading them, it's just a matter of how you interpret what you read. This is not your problem.
Your problem is you read up to 255 bytes at once and only ever print the first of them.
It's pointless to set buf[res] to 0 when you expect binary data (that possibly contains 0 bytes). That's just useful for terminating text strings.
Just use a loop over your buffer, e.g.
for (int i = 0; i < res; ++i)
{
printf("%x", buf[i]);
}

Error While Sending byte array serialy using Serial.write

Error While Sending byte array serialy using Serial.write.
byte buf[] = {125, 126, 127, 2000, 5000};
int i = Serial.write(buf, sizeof(buf));
for(int i = 0; i < (sizeof(buf) / sizeof(buf[0])); i++)
{
Serial.println(buf[i]);
}
output :
}~??125
126
127
208
136
Any while for Unknown charcters at start. I am using Arduino 1.0.5 version
They are not Unknow characters, that's what you printed with:
int i = Serial.write(buf, sizeof(buf));
Just check an ASCII table buf[0] = 125 = '{'
With write() you are writing raw data without any kind of format. Your first byte is the value 125, in binary 01111101. This byte correspond to the character { if it is intepreted as char. Your serial communication interprets the incoming byte as char, so it prints '{`.
If you want to print 125 as string on a serial communication, you have to send buf[] = {49, 50, 53}. Or you have to convert your interget into a string.
what's also wrong is that you are using the byte type with values higher than 255. Try changing to int16_t.
Characters at the start is the ASCII representation of the buff numbers you send. The arduino serial monitor monitors all the activities, and it prints out also your .write commands. .writeln which you do later, gets printed additionally after the original .write.
So what you see, is the ASCII representation of arduino sending your commands.
PS:
The numbers 2000 and 5000 don't fit into the byte, so the last two bytes that you send are probably corrupted.

How do I send an array of integers over TCP in C?

I'm lead to believe that write() can only send data buffers of byte (i.e. signed char), so how do I send an array of long integers using the C write() function in the sys/socket.h library?
Obviously I can't just cast or convert long to char, as any numbers over 127 would be malformed.
I took a look at the question, how to decompose integer array to a byte array (pixel codings), but couldn't understand it - please could someone dumb it down a little if this is what I'm looking for?
Follow up question:
Why do I get weird results when reading an array of integers from a TCP socket?
the prototype for write is:
ssize_t write(int fd, const void *buf, size_t count);
so while it writes in units of bytes, it can take a pointer of any type. Passing an int* will be no problem at all.
EDIT:
I would however, recomend that you also send the amount of integers you plan to send first so the reciever knows how much to read. Something like this (error checking omitted for brevity):
int x[10] = { ... };
int count = 10;
write(sock, &count, sizeof(count));
write(sock, x, sizeof(x));
NOTE: if the array is from dynamic memory (like you malloced it), you cannot use sizeof on it. In this case count would be equal to: sizeof(int) * element_count
EDIT:
As Brian Mitchell noted, you will likely need to be careful of endian issues as well. This is the case when sending any multibyte value (as in the count I recommended as well as each element of the array). This is done with the: htons/htonl and ntohs/ntohl functions.
Write can do what you want it to, but there's some things to be aware of:
1: You may get a partial write that's not on an int boundary, so you have to be prepared to handle that situation
2: If the code needs to be portable, you should convert your array to a specific endianess, or encode the endianess in the message.
The simplest way to send a single int (assuming 4-byte ints) is :
int tmp = htonl(myInt);
write(socket, &tmp, 4);
where htonl is a function that converts the int to network byte order. (Similarly,. when you read from the socket, the function ntohl can be used to convert back to host byte order.)
For an array of ints, you would first want to send the count of array members as an int (in network byte order), then send the int values.
Yes, you can just cast a pointer to your buffer to a pointer to char, and call write() with that. Casting a pointer to a different type in C doesn't affect the contents of the memory being pointed to -- all it does is indicate the programmer's intention that the contents of memory at that address be interpreted in a different way.
Just make sure that you supply write() with the correct size in bytes of your array -- that would be the number of elements times sizeof (long) in your case.
It would be better to have serialize/de-serialize functionality in your client /server program.
Whenever you want to send data, serialize the data into a byte buffer and send it over TCP with byte count.
When receiving data, de-serialize the data from buffer to your own interpretation .
You can interpret byte buffer in any form as you like. It can contain basic data type, objects etc.
Just make sure to take care of endianess and also alignment stuff.
Declare a character array. In each location of the array, store integer numbers, not characters.
Then you just send that.
For example:
char tcp[100];
tcp[0] = 0;
tcp[1] = 0xA;
tcp[2] = 0xB;
tcp[3] = 0xC;
.
.
// Send the character array
write(sock, tcp, sizeof(tcp));
I think what you need to come up with here is a protocol.
Suppose your integer array is:
100, 99, 98, 97
Instead of writing the ints directly to the buffer, I would "serialize" the array by turning it into a string representation. The string might be:
"100,99,98,97"
That's what would be sent over the wire. On the receiving end, you'd split the string by the commas and build the array back up.
This is more standardised, is human readable, and means people don't have to think about hi/lo byte orders and other silly things.
// Sarcasm
If you were working in .NET or Java, you'd probably encode it in XML, like this:
<ArrayOfInt><Int>100</Int><Int>99</Int><Int>98</Int><Int>97</Int></ArrayOfInt>
:)

Resources