0

I have the following program that tries to read data from an arduino using the serial port, the thing is it mostly doesn't read anything, except sometimes it reads a piece of what I'm sending. The arduino code its just writing a single letter in a loop.

#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>

int main() {
    int serialfd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
    if (serialfd == -1)
        perror("Error opening the serial port");
    else
        fcntl(serialfd, F_SETFL, 0);

    fprintf(stdout, "Device is open, attempting read \n");

    fcntl(serialfd, F_SETFL, 0);
    char buf[11] = {0};
    read(serialfd, buf, 10);
    fprintf(stdout, "Buffer: %s", buf);
    close(serialfd);
    return 0;
}

for example the output is like this

Device is open, attempting read 
Buffer: AAAAAAAAAAA⏎

If I try to run it again (several times) I just get the 0'd buffer

Device is open, attempting read 
Buffer: ⏎                
aram
  • 1,415
  • 13
  • 27
  • You did not say *which* single character you are repeatedly sending. On the assumption you do have the matching BAUD rate (no mention) and you are sending `'A'` then after receiving 11 of them, the input buffer is full and has no zero-termination of `'\0'` and so you are passing a not_string to `fprintf` and it is inevitable some crap will therefore be output. But please [read this](http://stackoverflow.com/questions/34943745/why-fcntlfd-f-setfl-0-use-in-serial-port-programming) about `F_SETFL`. – Weather Vane Dec 22 '16 at 19:03
  • @WeatherVane I'm writing the 'A' from the arduino, I have no idea how to set the baudrate with file descriptors. – aram Dec 22 '16 at 21:04
  • 1
    After opening a serial terminal device, you have to configure the terminal attributes before you can read or write. Study [Setting Terminal Modes Properly](http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_12.html#SEC237) and [Serial Programming Guide for POSIX Operating Systems](http://www.cmrr.umn.edu/~strupp/serial.html) For sample code see http://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c/38318768#38318768 and http://stackoverflow.com/questions/12437593/how-to-read-a-binary-data-over-serial-terminal-in-c-program/12457195#12457195 – sawdust Dec 22 '16 at 22:31
  • @WeatherVane Also the F_SETFL was took from the serial programming guide, I want the call to block. Is that? or am I missing something- – aram Dec 23 '16 at 12:50

2 Answers2

2

It sounds like a configuration issue, most likely the baudrate is not properly set. Also, as mentioned in the question's comments, you might be getting a full buffer with no '\0' character at the end, thus fprintf does not behave properly.

Here I'll explain how to set the baudrate but you can use the wikibooks link I've put further down the answer to set other settings, also make sure to check the buffer.

Put simply on the arduino I like to use 115200 as my baudrate. There are a few more that are usually supported on other devices but this value does just fine so I'll use that for my example.

On the arduino this is most likely going to be the only thing you will have to configure (and if fact, it's the only thing I set when I want to use the serial port to talk to my computer).

Serial.begin(115200);

Then according to this wikibook you can set your baudrate via settings in the termios structure, as in the wikibook example I'll call it attribs.

struct termios attribs;

/* get the current settings */
tcgetattr(serialfd, &attribs);

/* set the baudrate */
cfsetospeed(&attribs, B115200); /* outut baudrate */
cfsetispeed(&attribs, B115200); /* input baudrate */

/* if there is need for it, set other settings here */

/* eventually apply everything for your serialfd descriptor */
tcsetattr(serialfd, TCSANOW, &attribs);

So yes technically you could have different speeds for input than for output but the arduino's UART only has one such setting and does not support different speeds for input/ouput, so you need to set it for both on the computer to the same value.

Community
  • 1
  • 1
frostblue
  • 176
  • 2
  • 14
  • This didn't fix it at all I'm getting the same results as if I wasnt setting the baud rate. – aram Dec 23 '16 at 12:35
  • Have you checked the contents of your buffer, see if it was NULL terminated ? – frostblue Dec 23 '16 at 12:44
  • Yes I was just reading 10 bytes so the 11th is null terminated. Now it 'kinda works'. Its reading most of the times but sometimes I still get garbage. Do you know why that could be? In a tight loop I'm reading the A correctly. If I execute the program several times sometimes I get random characters. – aram Dec 23 '16 at 12:49
  • What if you flush the buffer before doing anything? If it is properly reading when you loop fast, then that's one more reason to believe the issue is the buffer – frostblue Dec 23 '16 at 13:22
0

If you just need to receive binary data on PC side and maybe react to some certain values and send something back to Arduino and log data for example,

then you can use some more advanced RS232 terminal program such as http://docklight.de/

It does have much more option and scripting to basically make ant data processing, but I did not use scripting on it yet.

But in few minutes you can have data read and answering in ASCII or binary format.

Of course for some database connectivity or more you will need custom program, but to test operation during debugging stage docklight is great tool.

Vladimir
  • 11
  • 2