Arduino MEGA Serial Communication using TX2 and RX0

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 :-

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 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 :expressionless:

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.

 //while(Serial2.read());

You're aware that that is an infinite loop, except if, by some lucky chance you receive a zero?

@AWOL

That was really silly of me, however now I have changed it to

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.
  1. Writing the String "Hello World \n" to TX2.

That's this part:

  Serial2.print(F("HelloWorld\n"));
  1. Waiting till the entire string has been sent.
    That's this part:
  Serial2.flush();
  1. Clearing the Serial2 buffer.
    Where?

  2. Checking if something is available at RX0.
    That's this part:

  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.

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

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):-

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.

See reply #1.

@PaulS
Clearing the Serial2 buffer is this code:-

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 :-

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.

Link to IR LED DataSheet:-

Link to PhotoDiode(Receiver) DataSheet:-

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.

The attached file is the circuit that I have constructed.

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.

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.

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?

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!

PaulS:

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.

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.

  delayMicroseconds(1);

Why? Why not an hour or two?

You have no decoupling anywhere - not difficult to see why you don't need the IR receiver to pick up any light if
its comparator catches glitches from the supply rail - decouple all chips, especially comparators (they are extremely
sensitive). You may have to add a little capacitance on the comparator inputs to prevent false triggering too.

PaulS:
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.

I do know what flush does, however I was trying anything and everything to make it work, which by the way it still is not. Also, previously (before Arduino 1.0) flush was used to clear the buffer, so it was just a random try and nothing else.

PaulS:
Why? Why not an hour or two?

I had read somewhere that adding a delay provides stability to the code which deals with reading of ports. Just so you do NOT have to ask something like "Where on earth did you read such stuff...was it in your dreams??" I would like to give you a few links where the same has been mentioned:-
http://opensourcehardwarejunkies.com/tutorial-10-switch-case-statement-arduino-course-for-absolute-beginners/?utm_expid=43506286-0&utm_referrer=https%3A%2F%2Fwww.google.de%2F
http://www.fibidi.com/arduino-led-button/
If you check the comments on the delay statements on these two links, you will see what I meant.

An honest suggestion, I would appreciate it much more if you would try to help out with the problem rather than using that mocking tone. You sure may know much more than me as far as Arduino is concerned but that surely does not give you any rights to mock someone like that. The whole purpose of posting on this forum is to spread the knowledge that you already have and maybe even learn a thing or two in the process. If you do not know the answer to a question, in my honest opinion, it is a good idea not to comment on those aspects of the code which won't have any effect on the code execution at all and waste your and my time as well. Without these statments too the code in reply#7 should run fine as far as I know, I asked the question because I found some anomalies to my understanding, and not to be ridiculed that way. No offence meant.

MarkT:
You have no decoupling anywhere - not difficult to see why you don't need the IR receiver to pick up any light if
its comparator catches glitches from the supply rail - decouple all chips, especially comparators (they are extremely
sensitive). You may have to add a little capacitance on the comparator inputs to prevent false triggering too.

Thank you for your valuable suggestion, I will surely try it out and post my findings here again. Thanks again.

xenonforlife:
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.

You'd need to make it clearer what the connections were when you ran that code, because you're describing several arrangements in that post.

The behaviour you described originally matched up with what I would expect given that code and the hardware you described, assuming the IR link worked.

PeterH:
You'd need to make it clearer what the connections were when you ran that code, because you're describing several arrangements in that post.

The behaviour you described originally matched up with what I would expect given that code and the hardware you described, assuming the IR link worked.

The arrangement that I have corresponds to the one in the image that I have uploaded which is something like this:-
1.Tx2 is connected to the LED via an LED driver.
2. The receiver output (from the photodiode circuit via the differential amplifier to the comparator which gives us the final 5v/0v output) is connected to Rx1.
What I am trying to do here is transmit and receive serial data via an IR link. Ideally I should not be seeing Hello World at all as I am not receiving anything at all(My LED is not pointed to my photodiode).