Go Down

Topic: Serial.read() reads characters put out by Serial.print() (Read 520 times) previous topic - next topic

ipd

I'm having an issue communicating between the computer and an Arduino Duemilanove via USB.

Here is a minimal example:

Code: [Select]

int val = 0;
unsigned long c = 0;

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

void loop() {
  if (Serial.available() > 0) {
    val = Serial.parseInt();
    c += val;
    Serial.print(c);
    Serial.print('\n');
    Serial.flush();
  }
}


What happens is that, during the next loop iteration, val contains the same character put out by print, duplicating the value of the adder/accumulator each time. If, however, I print a longer string (e.g., an additional iteration counter and val, together with some string), then the value read by parseInt is exactly what comes from the computer. What is going on?

EDIT: i'm new around here. I think I may have included this in the wrong subforum. Please, correct me if that's the case and/or move if to the right one if you can. Thanks!

Paul_KD7HB

You didn't understand the documentation;



In particular:

    Parsing stops when no characters have been read for a configurable time-out value, or a non-digit is read;

    If no valid digits were read when the time-out (see Serial.setTimeout()) occurs, 0 is returned;

So, more coding and logic to do,

Pau

Juraj


Robin2

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

ipd

did you set line ending in Serial Monitor?
I'm not communicating via the serial monitor. I'm using a process talking straight to /dev/ttyUSB0.

ipd

You didn't understand the documentation;


In particular:

    Parsing stops when no characters have been read for a configurable time-out value, or a non-digit is read;

    If no valid digits were read when the time-out (see Serial.setTimeout()) occurs, 0 is returned;

So, more coding and logic to do,

Pau
Pau, how does this explain the behaviour I am seeing?

Robin2

I'm not communicating via the serial monitor. I'm using a process talking straight to /dev/ttyUSB0.
Does that mean that you have control over the content of the messages being sent to the Arduino? If you do then have a look at the 3rd example in Serial Input Basics.

You can send data in a compatible format with code like this (or the equivalent in any other programming language)
Code: [Select]
Serial.print('<'); // start marker
Serial.print(value1);
Serial.print(','); // comma separator
Serial.print(value2);
Serial.println('>'); // end marker


...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Paul_KD7HB

Pau, how does this explain the behaviour I am seeing?
Guess you still have not read the documentation.


 val = Serial.parseInt();
    c += val;
    Serial.print(c);


Your code does not check for time-out on the Serial.parseInt().  The documentation says the function returns a 0 if time-out has occurred. You did not set a time-out nor did you check for a zero return, but when ahead and used the zero, anyway.

So c +=0 is still the same value in c.

Paul

ipd

The problem is that that's not the behaviour I am observing. If you read my question you'll see that the value I'm reading from parseInt is not a zero.

If I print 3 from the arduino, I'm getting a 3 in the next read. Which is very very weird. It has nothing to do with the timeout, as far as I understand.

That documentation does not explain this behaviour, as far as I understand.

Juraj

The problem is that that's not the behaviour I am observing. If you read my question you'll see that the value I'm reading from parseInt is not a zero.

If I print 3 from the arduino, I'm getting a 3 in the next read. Which is very very weird. It has nothing to do with the timeout, as far as I understand.

That documentation does not explain this behaviour, as far as I understand.
3 + 0 is 3

you have += there so c = c + val

ipd

I am not getting a "3" in c, I am getting it in val. I am getting it in the next read operation from the serial.

I understand how += works, but what I am saying is that, if I print a short text to the serial port, in the next iteration, parseInt actually gets that number I printed instead of the one coming from the computer via USB.

What I mean is that, if the computer puts a 3, and the arduino reads a 3, and the counter is a 3, and arduino puts a 3, and next the computer sends a 4, the arduino reads a 3 from the serial (which it put) and then the counter is a 6, and it puts out a 6, not a 7 (as I would have expected if the 4 had been parsed, or another 3, as I would have expected if nothing had been parsed).

Paul_KD7HB

YOU ARE NEVER PRINTING "val". you are only ever printing the sum of "c" and "val".

Paul

ipd

I AM SEEING A 3 FOLLOWED BY A 6. IF VAL WAS ACTUALLY 0, THEN C WOULD NOT INCREASE!

cattledog

Quote
I'm not communicating via the serial monitor. I'm using a process talking straight to /dev/ttyUSB0.
What you describe does not happen with the serial monitor sending data to the Arduino, so there must be something in your computer environment.

Quote
What I mean is that, if the computer puts a 3, and the arduino reads a 3, and the counter is a 3, and arduino puts a 3, and next the computer sends a 4, the arduino reads a 3 from the serial (which it put) and then the counter is a 6, and it puts out a 6, not a 7 (as I would have expected if the 4 had been parsed, or another 3, as I would have expected if nothing had been parsed).
It sounds as if there is some sort of echo setting if the computer is sending back what the Arduino sent to it.

If the Arduino sends a 3 to confirm what it received, and then the computer sends a 4, but the Arduino reads the 3, does it next read the 4, or does it read another echoed 3?

I think you will need to explain more about how the data is being sent to the Arduino.

Go Up