1

I am working on a project that involves reading data from an Arduino Uno over serial port. In Arduino IDE, I observe that I am successfully printing values over the serial port in the following format:

  Serial.print(x, DEC);
  Serial.print(' ');
  Serial.print(y, DEC);
  Serial.print(' ');
  Serial.println(z, DEC);

e.g.:

2 4 -41

4 8 -32

10 5 -50

...etc.

Then, I have a program written in C using XCode to read these values as float data types. However, upon running the program in terminal, the program appears to be stuck (no values are read, and I must use ctrl+C to exit).

Any ideas what I might be doing wrong? Below is my code. As of now, I am just using a for loop to test whether I am actually reading in these values. Let me know if you need more information. Thanks for your help.

#include <stdio.h>
#include <ApplicationServices/ApplicationServices.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

// buffer for data
float buffer[100];

int main(int argc, const char* argv[])
{

    // open serial port
    int port;

    port = open("/dev/tty.usbmodem1411", O_RDONLY);
    if (port == -1)
    {
        printf("Unable to open serial port.");
    }

    // testing read of data

    fcntl(port, F_SETFL, FNDELAY);

    for (int i = 0; i < 10; i++)
    {

        read(port, buffer, 12);       
        printf("%.2f %.2f %.2f\n", buffer[3*i], buffer[3*i+1], buffer[3*i+2]);
    }

    // close serial port
    close(port);

    return 0;
}
rmaddy
  • 298,130
  • 40
  • 468
  • 517
Victor
  • 31
  • 6

1 Answers1

0

What are you attempting with

    read(port, buffer, 12);       
    printf("%.2f %.2f %.2f\n", buffer[3*i], buffer[3*i+1], buffer[3*i+2]);

??? buffer will contain string data, like following (not floating points):

{'2', ' ', '4', '0', ' ', '-', '4', '1', 0x0D, 0x0A, '4', ' ', '8'}
//0    1    2    2    3    4    5    6     7     8    9    10   11

Your first mistake is reading exactly 12 bytes - each line may have different number of bytes. Second mistake is trying to format a char as a float. Even printf may get invalid data as it expects 3 floats and you are supllying 3 chars.

So, you need to parse your input data! Some direction:

#include <stdio.h>

float input[3];

int main(int argc, const char* argv[]) {
    FILE *port;
    port=fopen("/dev/tty.usbmodem1411", "r"); //fopen instead, in order to use formatted I/O functions
    if (port==NULL) {
        printf("Unable to open serial port.");
        return 1; //MUST terminate execution here!
    }
    for (int i = 0; i < 10; i++) {
        fscanf(, "%f %f %f", &input[0], &input[1], &input[2]);
        printf("%.2f %.2f %.2f\n", input[0], input[1], input[2]);
    }
    fclose(port);
    return 0;

}
LS_ᴅᴇᴠ
  • 10,327
  • 1
  • 18
  • 44
  • Thanks LS_Dev. Why will buffer contain string data w/ commas? My understanding is that I'm sending data over serial port from Arduino without commas, hence floating points? Then, I store this data into buffer, which is just an array?. – Victor Dec 03 '13 at 13:12
  • `{ , , }` is just C representation of a byte array, like `2 40 -41??4 8` in ASCII or `32203430202D34310D0A342038` in hexadecimal. Over a serial connection bytes are exchanged - only bytes. The way you format then before sending or interpret on reading doesn't change their nature: just bytes. – LS_ᴅᴇᴠ Dec 03 '13 at 13:36
  • I understand now. I tried the new code, and it appears that I am having trouble opening the port. The program appears stuck when executing fopen. – Victor Dec 03 '13 at 14:13
  • Don't know what's the problem: try use `open` and `fdopen` instead of `fopen`. – LS_ᴅᴇᴠ Dec 03 '13 at 14:19
  • I read here (http://stackoverflow.com/a/1658517/3055752) that File* does not support O_NONBLOCK. In that case, how can I use read() while still parsing data correctly? – Victor Dec 04 '13 at 16:07
  • Let me clarify - My intentions are to read data whilst blocking; As of now, just opening the port with FILE* allows me to read data, but I also obtain a lot of zeros. – Victor Dec 04 '13 at 16:22