Go Down

Topic: Arduino MEGA Serial Communication using TX2 and RX0 (Read 8636 times) previous topic - next topic

xenonforlife

Hi All,

I want to send and receive serial data to and from the same board. I have a IR transmitter connected to TX2 on my board and an IR Receiver to RX0. My code is as follows :-

Code: [Select]

void setup()
{
  Serial.begin(115200);
  //Serial1.begin(115200);
  Serial2.begin(115200);
 
}

void loop()
{
  Serial2.print(F("HelloWorld\n"));
  Serial2.flush();
  //while(Serial2.read());
  if(Serial.available())
  {
    while(Serial.available()>0)
    {
      char inByte = Serial.read();
      Serial.print(inByte);
    }
    Serial.print('\n');
    Serial.flush();
  }
  delayMicroseconds(1);
}


However even if my receiver is not receiving anything at all, I am seeing Hello World on my Serial Monitor. This is pointing me towards the conclusion that the serial buffer is being shared between all the ports, but that is kind of a puzzling conclusion. I tried to verify if my conclusion was true just by commenting out this while statement after
Code: [Select]
while(Serial2.read());. I believe this should clear the Serial2 buffer, but just as I expected, I do not get any monitor output at all. However the problem is my IR LED also stops glowing(checked with a digital camera) and it remains always on(it seems to be to the human eye because of the on/off speed) when I comment out that line again. Please help me understand the situation and if there is any way that I can achieve what I want to.

Hoping to hear from someone soon  :|

PaulS

Quote
This is pointing me towards the conclusion that the serial buffer is being shared between all the ports

It is not. There is a separate buffer for each port.

A schematic and some links to the IR devices you are using would be useful.
The art of getting good answers lies in asking good questions.

AWOL

Code: [Select]
//while(Serial2.read());
You're aware that that is an infinite loop, except if, by some lucky chance you receive a zero?

xenonforlife

@AWOL

That was really silly of me, however now I have changed it to
Code: [Select]

while(Serial2.available())
    Serial2.read();

Still I am seeing the same result. My monitor out is Hello World which keeps on repeating. This looks really weird to me, and I cannot understand what is  happening here. If I understand correctly, this is what I am doing:-
1. Writing the String "Hello World \n" to TX2.
2. Waiting till the entire string has been sent.
3. Clearing the Serial2 buffer.
4. Checking if something is available at RX0.
5. If something is available I am reading it and sending to the computer via TX0.
Am I wrong in my code somewhere? If so please point me out. I should not be able to see anything on the monitor at all till my receiver is receiving the signal that I am transmitting.



PaulS

Quote
1. Writing the String "Hello World \n" to TX2.

That's this part:
Code: [Select]
  Serial2.print(F("HelloWorld\n"));

2. Waiting till the entire string has been sent.
That's this part:
Code: [Select]
  Serial2.flush();

3. Clearing the Serial2 buffer.
Where?

4. Checking if something is available at RX0.
That's this part:
Code: [Select]
  if(Serial.available())
  {
    while(Serial.available()>0)
    {
      char inByte = Serial.read();
      Serial.print(inByte);
    }
    Serial.print('\n');
    Serial.flush();
  }


What doesn't make sense, though, is that you are reading from, and writing to, the same port. Is that the one that the Serial Monitor is connected to OR the one that the IR receiver is connected to? I'm confused.
The art of getting good answers lies in asking good questions.

xenonforlife

Another interesting observation:-
Serial monitor constantly shows an output Hello World until I point my receiver infront of the transmitter i.e in order to receive the data being transmitted. However I notice that the data received looks like
Code: [Select]

Hello World!

Hello World!

Hello World!

Hello World!

Hello World!

Hello World!

Hello World!

Hello World!

Hello World!

Hello World!

Hello World!

Hello World!


The above is my monitor output when the receiver is not receiving. When I place my transmitter infront of the receiver the monitor o/p is as follows (notice the change as soon as I align my transmitter and receiver):-

Code: [Select]
Hello World!

Hello World!

Hello World!

Hello World!

Hello World!

Hello World!

Hm¶ë º½É±??

HÿÿHÿÿ?þ
HÿÿHÿý?þ
HÿöÿHöð?ü
Höö@öù?ü
Hÿÿÿ@?


As can be seen the first character 'H' is always recieved properly while the rest are somehow getting garbled. So I have two questions here:-

1. Why is the code entering into the if(Serial2.available()) block when there is nothing on the Serial2 buffer when my reciever isnt receiving anything from the transmitter?
2. What can be the reason that data is getting corrupted except for the first character?

Someone please help, I am stuck on this since a really long time and no amount of googling is being able to help me.

PaulS

The art of getting good answers lies in asking good questions.

xenonforlife

@PaulS
Clearing the Serial2 buffer is this code:-

Code: [Select]

while(Serial2.available())
    Serial2.read();


My IR receiver is connected to the RX0 pin. My serial monitor is connected to TX0 and RX0 (Serial) ports. I can actually read and write to from the same serial connection because it offers  me two ports Rx0 and Tx0 for receiving and transmitting respectively. That is the basic requirement of two way communication isn't it. If I would just have been able to use a Serial connection for either transmitting or receiving then we would not have been able to use any of the other Arduino boards like Uno or Duemilanove for two way serial communication as unlike the Mega they have just one RX pin and one TX pin which can be accessed with the Serial class methods.
In any case I have also tried different combinations of the ports to recieve and transmit but no success. For example I connected the IR LED to TX2, the IR Sensor to RX1 and then checked for data availability on Serial1. If available I read it and transmitted the data to Serial Monitor. This also gives me the exact same result. The code for the above modification is as follows :-
Code: [Select]

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  Serial2.begin(115200);
 
}

void loop()
{
  Serial2.print(F("HelloWorld\n"));
  Serial2.flush();
  while(Serial2.available())
          Serial2.read();
  if(Serial1.available())
  {
    while(Serial1.available()>0)
    {
      char inByte = Serial1.read();
      Serial.print(inByte);
    }
    Serial.print('\n');
    Serial1.flush();
  }
  delayMicroseconds(1);
}

I hope now my problem is a bit clear.

xenonforlife

Link to IR LED DataSheet:-
https://www.sparkfun.com/datasheets/Components/LED/YSL-R531FR2C-F1.pdf

Link to PhotoDiode(Receiver) DataSheet:-
http://www.ti.com/lit/ds/symlink/opt101.pdf

I do not know how to put the schematic here, sorry I am new to the forum. Anyhow I will try take a picture and myrk my elements on the picture. Maybe that could help a bit. I will attach the picture soon.

xenonforlife

The attached file is the circuit that I have constructed.

PeterH

The Serial object represents the hardware UART that connects to RX0 and TX0 and the USB serial channel and hence the Serial monitor in the Arduino IDE.

Your sketch writes "Hello World" to TX2 which will result in it being passed via IR to your receiver and returns on RX0, which is the receive pin for the Serial port. You sketch reads input from the Serial port and echoes it back out the same port so it will be sent to the serial monitor. In other words, your sketch is doing just when you'd expect in that situation.

It's not a good idea to use RX0 and TX0 to connect to any other devices when you are using the USB connection, because it will result in the same pins being driven simultaneously by the USB port and the external devices you connected. Depending on the electrical characteristics of the device it might work, or it might not, but in any case it's not a good idea. If you have multiple UARTs available then reserve the Serial object (TX0/RX0) for use by the USB serial channel and use the other ports Serial1 etc for connecting to your other devices.

xenonforlife


The Serial object represents the hardware UART that connects to RX0 and TX0 and the USB serial channel and hence the Serial monitor in the Arduino IDE.

Your sketch writes "Hello World" to TX2 which will result in it being passed via IR to your receiver and returns on RX0, which is the receive pin for the Serial port. You sketch reads input from the Serial port and echoes it back out the same port so it will be sent to the serial monitor. In other words, your sketch is doing just when you'd expect in that situation.

It's not a good idea to use RX0 and TX0 to connect to any other devices when you are using the USB connection, because it will result in the same pins being driven simultaneously by the USB port and the external devices you connected. Depending on the electrical characteristics of the device it might work, or it might not, but in any case it's not a good idea. If you have multiple UARTs available then reserve the Serial object (TX0/RX0) for use by the USB serial channel and use the other ports Serial1 etc for connecting to your other devices.


Thanks for your reply. But I am not sure I understand correctly. Does this mean that I cannot use Serial1, Serial2 etc for serial communication using the onboard UART? It should right? I agree with your suggestion of keeping the Rx0 and Tx0 free to communicate just with the computer via USB, but in that case too, the code in reply #7 should have worked. If serial ports Serial1, Serial2 cannot use the UART hardware on the board, how else can they be used serially? This is what is confusing me, dont the libraries containing the code for Serial, Serial1, Serial2 all use UART for communication?

PaulS

Quote
Does this mean that I cannot use Serial1, Serial2 etc for serial communication using the onboard UART?

No, it doesn't. What it means is that a given serial port talks to ONE thing - either the Serial Monitor application on the PC OR (!and) the IR receiver. Pick ONE!
The art of getting good answers lies in asking good questions.

xenonforlife


Quote
Does this mean that I cannot use Serial1, Serial2 etc for serial communication using the onboard UART?

No, it doesn't. What it means is that a given serial port talks to ONE thing - either the Serial Monitor application on the PC OR (!and) the IR receiver. Pick ONE!

Exactly..that was my understanding too...in that case could you please look at the code I had placed in reply# 7 and tell me if what I have done is theoretically and logically correct..because I have the issue with that code too.
Thanks a lot for your help.

PaulS

Code: [Select]
if(Serial1.available())
 {
   while(Serial1.available()>0)
   {
     char inByte = Serial1.read();
     Serial.print(inByte);
   }
   Serial.print('\n');
   Serial1.flush();
 }

I'm sorry, but you don't seem to have a clue what flush() does. You haven't sent any data on Serial1. There is no reason to block until nothing has been shifted out.

Code: [Select]
 delayMicroseconds(1);
Why? Why not an hour or two?
The art of getting good answers lies in asking good questions.

Go Up