[SOLVED] Wierd serial behavior with C

Hey everyone, I'm not a complete noob, but I am when it comes to serial programming. So, here is my simple C function that will get a value from serial:

int arduinoValue(int fd, int length){
    char valBuf[length];
    char b[1];
    int k = 0;

    for(k = 0; k <= length; k++){ 
        int n = read(fd, b,1);
        if(n == -1) exit(1);
        valBuf[k] = b[0];
    }
    valBuf[k] = '\0';
    tcflush(fd,TCIOFLUSH);

    int retval = atoi(valBuf);
    return retval;
}

And this DOES work. Mostly. For instance, If i run this 5 times, 3 of those times Ill get the right value, other times it seems the bits are getting mashed. For instance, my potentiometer is set to "586". Here are 5 runs of my function:
$ 586
$ 586
$ 58686
$ 5
$ 586

Is there away to get a more consistent reading? I've tried, as you see above, to force it to read a fixed number of bits. Any help would be awesome. BTW, I've looked around for about an hour and couldn't find anything. And yes, I did see the link about interfacing with C via the arduino site, his code is sketchy and never worked. So, this does work, its just a bit sketchy itself. Thanks for reading and hopefully this leads to a solid arduino/serial interface for C.

--ac

What does this statement do:

tcflush(fd,TCIOFLUSH);

Are you sure you are not flushing stuff away, that you should keep ?

Having the Arduino code would also be helpfull.

You need to make the Arduino send an end-of-packet marker after the data that you send.

Then, you need to have the C application read serial data until it sees that end of packet marker. Only then should it use the data that it has read, and reset for the next packet.

Thanks for all of the tips guys. The end of packet marker makes a lot of sense. But, if I'm not mistaken, would the CR-LF be a suitable end of packet marker? I'll attempt that first. Also, as per request, here is the basic arduino code I am using to get values from serial.

int sensorPin = A0;
int sensorValue = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  sensorValue = analogRead(sensorPin);
  Serial.println(sensorValue);
}

Also, tcflush(fd,TCIOFLUSH) makes it so the data is near real time. Without that, I believe the data is filling a buffer. So when I read from the port, I'm reading from a buffer == not what I wanted. I want as close to real time data I can get.

I want as close to real time data I can get.

Then you are wasting a lot og time converting the integer to a string and converting the string back to an integer. Use the lowByte() and highByte() functions to extract the two bytes that make up the integer into byte variables, then use Serial.write() to send binary data. Reassemble the integer on the receiving end.

Thanks for the help, that definitely fixed it. It makes a lot more sense to do it that way. I'll post the code soon when I get it nice and sorted out.

ac_slater:
Thanks for the help, that definitely fixed it. It makes a lot more sense to do it that way. I'll post the code soon when I get it nice and sorted out.

I will wait for your code because I have exactly the same problem as your :slight_smile: