How to read long value sent by Arduino in C I have a quick question regarding this code below in Arduino:

Serial.print("0");
Serial.print(5);
Serial.print("0");
Serial.print(1);
Serial.print("0");
Serial.print(5);
Serial.print("0");
Serial.print(1);
Serial.print("0");
Serial.println(5);


In C code, currently I'm receiving the message using this method below:

int serialport_read_until(int fd, char* buf, char until, int buf_max, int timeout)
{
    char b[1];  // read expects an array, so we give it a 1-byte array
    int i=0;
    do { 
        int n = read(fd, b, 1);  // read a char at a time
        if( n==-1) return -1;    // couldn't read
        if( n==0 ) {
            usleep( 1 * 1000 );  // wait 1 msec try again
            timeout--;
            if( timeout==0 ) return -2;
            continue;
        }
        buf[i] = b[0]; 
        i++;
    } while( b[0] != until &amp;&amp; i+1 &lt; buf_max &amp;&amp; timeout&gt;0 );

    buf[i] = 0;  // null terminate the string
    return 0;
}


In C i defined:

char message[13];
uint32_t num;
char until = '\n';

serialport_read_until(fd, message, newLine, sizeof message, 20000);
// the 20000 is timeout in millisec
// this method stores the data in serial buffer into message array

printf("message is %d\n", num);


I am expecting a raw value of 0501050105 first.
Then I convert this raw string into 501050105 using:

sscanf(message, "%d", &amp;num);


Currently it works fine, but I strongly believe it is not the correct way to do it (or rather not the optimized way to do it).

In addition, when i use serialport_read_until() method above, even though i specify the char until as '\n', the method terminates after reading '\r' (leaving the \n in the serial buffer), and the '\n' is only captured in the next method call.

Q1: Am i reading the \r\n wrongly from the println (I saw in Arduino documentation that println prints \r\n)? What resulted in C 'cutting off' the message when it detected a \r from Arduino even though I specifically set to kill it only when \n is received?

Q2: Instead of printing a string to me and converting it back to integer in C, is there a way for Arduino to send me a long value directly instead? eg 501050105 or 51515. how should I rewrite the serial print or method? And how do i capture that integer correctly in C? If i'm not wrong if a raw integer is print out from Arduino, it converts it into ASCII code. I'm still very new to C and Arduino and hope some guidelines to be given so I can improve on the current coding.

Thank you very much.
char b[1];  // read expects an array, so we give it a 1-byte array


No, it expects a pointer to a destination to store the data. You don't need a 1-entry array - you can simplify your code with:

char b;
...
int n = read(fd, &amp;b, 1);  // read a char at a time
...
buf[i] = b;
... etc ...



  Currently it works fine, but I strongly believe it is not the correct way to do it (or rather not the optimized way to do it).


C has the function strtoul() which is far more efficient that sscanf.

uint32_t val = strtoul(buf, NULL, 10);


The 10 is the base to convert from, so you could convert hexadecimal (base 16), octal (base 8), etc using it.


  Q1: Am i reading the \r\n wrongly from the println (I saw in Arduino documentation that println prints \r\n)? What resulted in C 'cutting off' the message when it detected a \r from Arduino even though I specifically set to kill it only when \n is received?


You're defining the variable until to contain \n, yet passing the variable newLine to your function. Maybe that has something to do with it?


  Q2: Instead of printing a string to me and converting it back to integer in C, is there a way for Arduino to send me a long value directly instead? eg 501050105 or 51515. how should I rewrite the serial print or method? And how do i capture that integer correctly in C? If i'm not wrong if a raw integer is print out from Arduino, it converts it into ASCII code. I'm still very new to C and Arduino and hope some guidelines to be given so I can improve on the current coding.


You can send a 32-bit value using just 4 bytes. However it's not reliable without implementing a whole protocol around those 4 bytes which, for just 4 bytes, is a bit of a waste. Simplest just to stick to ASCII encoding your data.