Problem with serial communication

Hi, all,
I know there are already lots of posts about serial communication. I read some of them but they didn’t help solve my problem. I’m using a switch to control the transmitter to send different data.
This is part of the code of transmitter:

    if(...)
    Serial.write((byte)122);
    if(...)
    Serial.write((byte)123);

I used serial monitor to read the data sent by the transmitter, and I can get the correct ascii codes: “z” and “{”.
Part of the code for receiver:

void setup()
{
  Serial.begin(57600);
  pinMode(2,OUTPUT);
  pinMode(8,OUTPUT);
}
void loop()
{
  int inByte;
  inByte=Serial.read();
  if(inByte==122)//
  {
  digitalWrite(2,HIGH);
  delay(1000);
  digitalWrite(2,LOW);
  }
  if(inByte==123)
  {
    digitalWrite(8,HIGH);
    delay(1000);
    digitalWrite(8,LOW);
  }  
}

I measured the voltages of all the pins, pin2 kept HIGH and pin4 kept LOW no matter how I changed the positions of the switch. I also tried to use code like “if(inByte==‘z’)”, but it still didn’t work.
Is there any problem with my codes? Is it necessary to use “while(Serial.available()<1)”(hand shaking?)? I got some programs work without it.
Thanks in advance.

I used serial monitor to read the data sent by the transmitter

How did you do this? The Serial Monitor connects to the COM port you uploaded to the Arduino on. If the Arduino is still connected to the PC, then how did you connect the transmitter to it?

Part of the code for receiver:

What is connected to the TX and RX pins?

Sorry, I didn't explain well. I'm using two XBee s1, two Arduino Fio and a XBee adapter to do the test. In order to examine the data sent by the transmitter, I used the XBee adapter to receive the data first. The XBee adapter was connected to the PC using a FTDI cable. After making sure that the data sent by the transmitter were correct, I used the receiver (Arduino with XBee wireless module) to receive the data using the code posted.

I simplify the code, so that it would be easier to read. Transmitter:

int inByte=0;
int Br=7;//Brake
int inByteBr=0;
void setup()
{
  Serial.begin(57600);
  pinMode(Br,INPUT);
}
void loop()
{
  inByteBr=digitalRead(Br);
  if(inByteBr==HIGH)
  Serial.write((byte)122);
  if(inByteBr==LOW)
  Serial.write((byte)123);
  delay(10);
}

Receiver:

void setup()
{
  Serial.begin(57600);
  pinMode(2,OUTPUT);
  pinMode(8,OUTPUT);
}
void loop()
{
  int inByte;
  inByte=Serial.read();
  if(inByte==122)
  {
  digitalWrite(2,HIGH);
  delay(1000);
  digitalWrite(2,LOW);
  }
  if(inByte==123)
  {
   digitalWrite(8,HIGH);
   delay(1000);
   digitalWrite(8,LOW);
  }
}

The pin2 and pin8 are low all the time now. I used XBee adapter to receive the data sent by transmitter again, and I can still get the correct ascii characters. I think the XBee and arduino both work well, there should be something wrong with my codes.

If you are using a multimeter, are you watching the pins long enough (and at the right time) to see the outputs go HIGH?

If you are using a multimeter, are you watching the pins long enough (and at the right time) to see the outputs go HIGH?

I'm using a multimeter to watch the pins. I think I watched the pins long enough. They just never changed. I made a small change that I changed the data sent using 'A' and 'B' instead of (byte)122 and (byte)123. Transmitter:

if(inByteBr==HIGH)
Serial.write('A');
if(inByteBr==LOW)
Serial.write('B');
...

Receiver:

if(inByte=='A')
...
if(inByte=='B')
...

This time the codes worked! What's make the difference? I'm kind of confused.

Shouldn't that be

Serial.write(122,BYTE);

not

Serial.write((byte)122);

I used touch lcd on TX to control RGB leds on RX, this is how http://arduino.cc/forum/index.php/topic,114239.0.html on TX

Serial.println("P13"); // debug
Serial1.print(13,BYTE);  // Send Pin Number
Serial1.print(HIGH,BYTE);// Send Pin state ON

on RX

int cPin;  // Control Pin
int state; // Pin State, on | off

void setup()
{
  Serial.begin(9600);  // Start Serial
  pinMode(13,OUTPUT);  // Set Pin 13 led OUTPUT
}

void loop()
{
  if (Serial.available()>1) // wait for 2 bytes
  {
     cPin = Serial.read();  // First Byte is Pin Number
     state = Serial.read(); // 2nd Byte is Pin state on | off
     digitalWrite(cPin, state);  // Do it
  }
}

Thank you for replying. I tried Serial.write(122,BYTE), but the ide gave me such error information: "As of Arduino 1.0, the 'BYTE' keyword is no longer supported. Please use Serial.write() instead." In fact I got that idea from the post below. http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1293337259

Convert isn't really the correct term. Cast is. You need to cast the int to a byte in order to have Processing NOT convert the value to a string.

Code: myPort.write((byte)servoAval);

After reading your post, I changed my receiver code:

void setup()
{
  Serial.begin(57600);
  pinMode(2,OUTPUT);
  pinMode(8,OUTPUT);
}
void loop()
{
  int inByte;
  if(Serial.available()>1)
  {
  inByte=Serial.read();
  if(inByte==122)
  {
  digitalWrite(2,HIGH);
  delay(1000);
  digitalWrite(2,LOW);
  }
  if(inByte==123)
  {
   digitalWrite(8,HIGH);
   delay(1000);
   digitalWrite(8,LOW);
  }
  }
}

It's still the same. Pin2 and pin8 remain LOW.

It took me a while figure out too, but i found by using BYTE sent the actual value in my case pin number and not it's ascii value, i didn't realise the BYTE issue with IDE 1.0 as im still using IDE_0018 as it works for me without all the compatability issues, I'll have a good look at you code and see if i can help

Thank you!! As I said, I have some serial communication programs work without

if(Serial.available()>1

such kind of hand shaking (if it's the name) codes. I'm not sure whether they are necessary or not. The code worked if I sent 'A' instead of (byte)122. I think I'm still not quite clear about data format in serial communication.

aldaris: such kind of hand shaking(if it's the name) codes. I'm not sure whether they are necessary or not.

It's not called handshaking, it simply called making sure there is data in the buffer before reading the data. It's not necessary in every application, but there have been many a logic error that people here have because they didn't include it or implemented it incorrectly.

How to determine the value after Serial.available()? In P18F4550's case, he used

if (Serial.available()>1)

instead of

if (Serial.available()>0)

Couple of things,

  1. if you want a byte to be transmitted, use Serial.write(). Serial.print(122) will send 3 ascii characters: '1' then '2' then '2'. Serial.write() will send the binary value of the decimal "122". Serial.print("A") sent the binary value of 65. Change your transmit code to Serial.write(65) and you'll get the same results.

  2. Serial.available() returns the number of characters sitting in the receive buffer. Generally people wait for it to be greater than 0, unless they are waiting for more than 1 byte to arrive.

  3. You aren't required to use Serial.available() before Serial.read(). However, you should know that Serial.read() will return -1 if there's nothing in there. In a program like the original poster's where the value returned by Serial.read() is ran through if-statements (or a switch-statement), it doesn't really matter if you wait until a character arrives.

Thank you very much, James. I learn a lot.
One thing I have to apologize that after reading James’s post, I tried several different combinations:

122,123; 65, 66; ‘A’, ‘B’

None of them worked. The voltage levels on pin 2 and pin 8 seemed to be random, either high or low.

I said it would work with ‘A’, ‘B’ combination before, but it turned out that I was using ‘A’, ‘A’ combination instead. I tried ‘A’, ‘A’ combination again, and the voltage level on pin 2 and 8 were all changing. But the changing rate seemed faster than 1 second.

I used the XBee adapter to receive the data sent by the transmitter and checked the data in serial monitor. The characters were all correct and can change according to the positions of the switch.

Sorry again for the misleading. I will do more test. Thanks, guys.