Pages: [1]   Go Down
Author Topic: Serial.available() vs. Serial.print()  (Read 10463 times)
0 Members and 1 Guest are viewing this topic.
Rochefort, France
Offline Offline
Jr. Member
**
Karma: 0
Posts: 73
Arduino is a king
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have two boards communicating serially through Xbees. On board #1 I have the following code:
Code:
int inByte = 0;         // incoming serial byte
int outputPin = 13;
void setup()
{
  // start serial port at 9600 bps:
  Serial.begin(9600);
  pinMode(outputPin, OUTPUT);
  }

void loop()
{
  if (Serial.available() > 0) {
    // get incoming byte:
    inByte = Serial.read();
    if (inByte == 'E') {
    digitalWrite(outputPin, HIGH);
    }else if (inByte == 'F') {
    digitalWrite(outputPin, LOW);
    }
   }else{
   Serial.print('H');
  delay(1000);
  Serial.print('L');
  delay(1000);            
  }
}
On board #2 I have the following code:
Code:
int inByte = 0;         // incoming serial byte
int outputPin = 13;
void setup()
{
  // start serial port at 9600 bps:
  Serial.begin(9600);
  pinMode(outputPin, OUTPUT);
  }

void loop()
{
  if (Serial.available() > 0) {
    // get incoming byte:
    inByte = Serial.read();
    if (inByte == 'H') {
    digitalWrite(outputPin, HIGH);
    }else if (inByte == 'L') {
    digitalWrite(outputPin, LOW);
    }
   }else{
   Serial.print('E');
  delay(2000);
  Serial.print('F');
  delay(2000);            
  }
}
The leds on pin 13 are blinking at the right frequency when delays are short, 100 - 200 msec. For values around 1 sec, as in the case above, only one led blinks - #1 - at about a 2000 msec pulse, #2 is constantly lit.
Maybe my aproach is not the best one to have a board both receiving and sending serial data?
Any suggestions?
Thanks!
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46026
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Serial data transmission is relatively slow, particularly at 9600 baud. Since the two Arduinos are directly connected, they can communicate MUCH faster than that. Try increasing the baud rate, to the maximum supported speed, 115200. That's 12 times as fast, so will take 1/12th as long.

Also, one of your Arduinos is waiting half as long as the other. The faster one will eventually overflow the serial buffer on the slower one.
« Last Edit: January 23, 2011, 09:12:14 am by PaulS » Logged

Rochefort, France
Offline Offline
Jr. Member
**
Karma: 0
Posts: 73
Arduino is a king
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Don't you think it could help to introduce a Serial.flush() somewhere to prevent the overflowing of the serial buffer on the slower Arduino?
I will try to increase the speed.
Thanks.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46026
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Don't you think it could help to introduce a Serial.flush() somewhere to prevent the overflowing of the serial buffer on the slower Arduino?
No, I don't. I figure that is the sender thinks the data is important enough to send that it is important enough to receive and process. Whatever needs to be done to ensure that that can happen should be done.

If the receiver can not be made fast enough, the sender and receiver need to implement handshaking, so that the sender doesn't send data until the receiver is ready to process it.

If that can't happen, there is no benefit to calling flush() to dump random amounts of data as opposed to dumping random amounts of data because the receive buffer is full.

I suspect that this is more than just theoretical work on your part. If you fill us in on what that larger picture looks like, perhaps we could be more helpful.
Logged

Rochefort, France
Offline Offline
Jr. Member
**
Karma: 0
Posts: 73
Arduino is a king
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I set the speed on both Xbees and Arduinos to 115200, there was no change: I could see on the serial monitors (I have the boards hooked up to two different PCs) both sequences of EFEFEF and HLHLHL generated at apparently the right frequencies but only the led on board #1 pulses. If I change the delays on board #2 from 2000 to 500, then it is the led #2 which is blinking. This confirms what you said before:
Quote
The faster one will eventually overflow the serial buffer on the slower one.
.
Now my question is: how to manage not to get this buffer to be overflown?
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 238
Posts: 24317
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Now my question is: how to manage not to get this buffer to be overflown?
1) Make sure you read data out faster than it is written in.
2) Implement handshaking. (which is another way of saying 1)  )
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Rochefort, France
Offline Offline
Jr. Member
**
Karma: 0
Posts: 73
Arduino is a king
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Alright, here is what I am looking for.
A mobile automata carries an Arduino board #1 with an Xbee module and a PCB with an embedded Atmega. The Atmega drives the motors and controls different sensors, among them an ultrasonic transmitter which is turned on when the Arduino #1 receives an 'A'  and off when it is a 'B' .
Code:
if (Serial.available()) {
    valUS = Serial.read();
    if (valUS == 'A') {
      digitalWrite(outputPin, HIGH);
    }
    if (valUS == 'B') {
      digitalWrite(outputPin, LOW);
    }
  }
Connected to the PC there is another Arduino board (#2) also with an Xbee, it computes from the ultrasonic receiver signals the time-of-flight th1, i.e., it trigers the US transmitter with an 'A' and then computes the time before receiving an US pulse with a while():
Code:
Serial.print('A');
  t = micros();
  while (val1 == LOW){
    val1 = digitalRead(inUS1);
    th1 = micros() - t;
}
    Serial.print(th1);
  Serial.print(10, BYTE);
    Serial.print('B');  
  Serial.print(10, BYTE);
This works fine.
Now, I would like the mobile to be able to send a signal to the PC when it encounters an obstacle. So, I would like to add on the Arduino #1 something like this:
Code:
valMoteur1 = digitalRead(inPin9);
  if(valMoteur1 == HIGH) {
    Serial.print('H');
  }else if(valMoteur1 == LOW){
    Serial.print('I');
  }
and the Arduino #2 will receive these 'H' and 'L' and use them to pass 1 and -1 to the PC:
Code:
if (Serial.available()) {
    valRF = Serial.read();
    if (valRF == 'H') {
     Serial.println('E');
     Serial.print(1);
     Serial.print(10, BYTE);
    }
    if (valRF == 'L') {
     Serial.println('E');
     Serial.print(-1);
     Serial.print(10, BYTE);
    }
Unfortunately this doesn't work!
As I said in my previous posts I am unable to get both Arduinos to send and receive serial data.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46026
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
A mobile automata carries an Arduino board #1 with an Xbee module
This is the first mention of another device in the serial data path. It is quite likely that all of your issues involve the XBees, not the serial communication.

Which XBees do you have?

If you replace the two XBees with a pair of wires, connecting TX to RX and vice versa (as well as grounds), do you have the same problem?
Logged

Rochefort, France
Offline Offline
Jr. Member
**
Karma: 0
Posts: 73
Arduino is a king
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry, you didn't realize I was using Xbees, Although I mentioned it in my first post:
Quote
I have two boards communicating serially through Xbees.
The Xbees I use are the 802.15.4.
I tried to replace them with cables, as suggested by PaulS, to no avail!
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46026
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The Xbees I use are the 802.15.4
I missed that you were using XBees in the first post. All XBees transmit using the 802.15.4 protocol. There are series 1 and series 2.5 XBees that are used for different purposes. Which do you have?

It doesn't really matter if direction connection does not solve the problem.

Rereading what you want to do, I think I see the problem. You are trying to have the XBees AND the PC communicate with the Arduino using the hardware serial port. It looks like you want to send data to the serial port, from the Arduino, and have the serial port know whether to send the message to the XBee or the PC. That won't work. The serial port is a dumb device. Both the XBee and the PC can be connected to the serial port, and both will see the same incoming and outgoing data.

However, it really looks like you should be using the hardware serial port to talk to the PC and NewSoftSerial to talk to the XBee on another pair of pins. If you are using a shield (probably not with a homemade PCB), that could prove difficult.
Logged

Pages: [1]   Go Up
Jump to: