edward0429 / arduino

Automatically exported from code.google.com/p/arduino
0 stars 0 forks source link

Add Serial.buffer() and Serial.bufferUntil() functions. #535

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
These should be along the lines of the Processing equivalents, triggering the 
corresponding serialEvent() functions when the particular character or number 
of characters is read.

Original issue reported on code.google.com by dmel...@gmail.com on 7 May 2011 at 5:10

GoogleCodeExporter commented 9 years ago
Christian, can you take a look at this?  It should basically delay calling the 
serialEvent() functions until the specified character (or number of characters) 
has appeared in the stream.

Original comment by dmel...@gmail.com on 5 Sep 2011 at 2:52

GoogleCodeExporter commented 9 years ago

This one is very challenging to do it right, here a partial solution

https://github.com/cmaglie/Arduino/commit/86ae0f9e8b16f319dbf306bbfa483409b94abe
3c

Methods:

- If you setup the serial port using Serial.buffer(10); the serialEvent 
function is called asyncronously, once every 10 byte received. If you receive 
20 bytes at once, the serialEvent is called twice, even if you read all 20 
bytes during the first call.
- The same applies for Serial.bufferUntil('\n'); => for every '\n' received, a 
call to serialEvent is performed, no matter if you read all the bytes or not.
- Default behaviour is Serial.buffer(1).

Notes:

- I've implemented it only on "Serial" i will do it on Serial1/2/3 after review 
and acceptance of the code.
- The interrupt service is a little bit more complex now, it has to handle the 
two cases of buffering.
- HardwareSerial class need access to 4 more global variables that interacts 
with the interrupt service routines.

Test for bufferUntil:
------------------------------------
void serialEvent() {
  while (Serial.available()) {
    char c = Serial.read();
    if (c==',')
      break;
    Serial.print(c);
  }
  Serial.println("<END");
}

void setup() {
  Serial.begin(9600);
  Serial.bufferUntil(',');
}

void loop() {
  delay(1000);
}
------------------------------------

Test for buffer():
------------------------------------
void serialEvent() {
  Serial.print((char)Serial.read());
  Serial.print((char)Serial.read());
  Serial.print((char)Serial.read());
  Serial.print((char)Serial.read());
  Serial.print((char)Serial.read());
  Serial.println("<END");
}

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

void loop() {
  delay(1000);
}
------------------------------------

Problems:
- With the defaults, serialEvent() is called for every byte received and this 
is very inefficient.
- If you use bufferUntil('a') but 'a' is not received before the buffer is 
full, the serial port is blocked.

I'll try to think a solution for these problems.

C

Original comment by c.mag...@bug.st on 8 Sep 2011 at 12:02

GoogleCodeExporter commented 9 years ago

Original comment by dmel...@gmail.com on 16 Dec 2011 at 10:08