Go Down

Topic: So confused by TX RX serial communication! (Read 2013 times) previous topic - next topic

SamuelCB

Hi everybody!

OK so lately I have been trying to learn about serial communication on the Arduino's TX and RX pins but I am just completely baffled! OK so I wanted to start as basic as possible and unfortunately I only have one Arduino (which may be part of the problem for all I know!). Anyways I decided to write a simple piece of code t send the number 19 out of the Arduino and then back into the Arduino by placing a jump cable from the TX pin to the RX pin on the same board. Therefore I uploaded the code below and opened the serial monitor!

Code: [Select]

int sent = 19;
int received = 0;

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

void loop()
{
  delay(2000);
  Serial.println(sent);
 
  if(Serial.available() > 0)
  {
    received = Serial.read();
    Serial.print("Received: ");
    Serial.print(received);
    Serial.println();
  }
}


At first I left the cable out and saw the following as expected:

19
19
19
19
19
19
19

However when I attached the cable I got this:

19
Received: 49
19
Received: 57
19
Received: 13
19
Received: 10
19
Received: 49
19
Received: 57
19
Received: 13
19
Received: 10
19
Received: 82

Now surly I should see, Received: 19, or at the very least if it is changing it to another language like ACSII, surly I would get the same number after received even if it is the wrong letter? Not just random ones?

Any explanation would be appreciated, thanks!

Tom Carpenter

#1
Aug 21, 2012, 02:16 am Last Edit: Aug 21, 2012, 02:18 am by Tom Carpenter Reason: 1
Every time this bit of code executes:
Code: [Select]
 if(Serial.available() > 0)
 {
   received = Serial.read();
   Serial.print("Received: ");
   Serial.print(received);
   Serial.println();

Your it will be printed out, and then loop back in and be read because TX and RX are connected.

I bet if you look up your numbers on an ascii table, they will represent the letters "Received".

You are also essentially sending 14 bytes for every one read which means you will quickly overrun the serial buffer and start loosing packets (think exponential growth in the number being sent).

You either need a second Serial port to talk to the Arduino serial monitor, or use something like an LED to verify the loop back.
Here is a possible (quickly written) example:
Code: [Select]
int sent = 19;
int received = 0;

void setup()
{
 Serial.begin(9600);
 pinMode(13,OUTPUT);
}

void loop()
{
 delay(2000);
 Serial.println(sent);
 
 if(Serial.available() > 0)
 {
   received = Serial.read();
   if (recieved == '1'){
     while(Serial.available == 0); //wait for the second byte
     recieved = Serial.read();
     if (recieved == '9'){
        //Recieved 19, so blink the light to show it was recieved successfully
       digitalWrite(13,HIGH);
       delay(1000);
       digitalWrite(13,LOW);
       delay(1000);    
     }
   }
 }
}
~Tom~

Tom Carpenter

Using the ascii table (well, from memory :P):

49
57
13
10

translates to:
1
9
<CR>
<LF>

in otherwords:
19<new line>
~Tom~

SamuelCB

Haha, thank you so much, for the first time I actually slightly understand the communication and the random number! And that code seems to work fine so thanks again! So am I correct in thinking that you cannot read what has been sent in the serial monitor because when you print the result that is then put in the serial buffer and send with the next load of data, therefor you used the LED for verification instead? Thanks again!!

PaulS

Quote
So am I correct in thinking that you cannot read what has been sent in the serial monitor because when you print the result that is then put in the serial buffer and send with the next load of data, therefor you used the LED for verification instead?

You can use a serial port to talk to ONE other device - either the Serial Monitor application OR the Arduino (as you are doing). Not both.

So, yes, that is why the LED was used, instead of trying to use the Serial Monitor.

NutDriverLefty


So am I correct in thinking that you cannot read what has been sent in the serial monitor ...


If you use "print" or "println" to put the value into the serial object, it's going to be converted to an ASCII string.  So using "print(19)" results in the serial object sending bytes (ASCII codes) 0x31 (49) and 0x39 (57) [plus '\r' (0x13) and '\n' (0x10) if you used println].  If you want to read back a binary value, you have to use the write() function rather than the print[ln]() function.  The write() function will send the raw bytes, without converting them to "human readable" ASCII output.  The write() function also will not append the \r\n (CR-LF) values that println() does.  If you use the print functions, the receiver has to convert back from ASCII to binary, if the binary is what the receiver cares about.

Go Up