Pages: [1]   Go Down
Author Topic: Serial read and write (RX,TX) equal endless loop  (Read 2524 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi

I'm really learning a lot reading the forum and I found many solutions to my problems, however I'm not able to find an answer to my latest problem. I would like to exchange data between raspberry pi and arduino so I have connected raspberry pi with arduino over serial RX/TX (UART) like this http://www.raspberrypi.org/phpBB3/viewtopic.php?f=37&t=22736 and this is the code I use.

Arduino code:
Code:
#include <stdlib.h>                                                             
byte num = 0;                                                                   
                                                                               
void setup ()                                                                   
{                                                                               
    Serial.begin (9600);                                                       
}                                                                               
                                                                               
void loop ()                                                                   
{                                                                               
    if ( Serial.available() > 0 )                                               
    {                                                                           
        num = Serial.read ();                                                   
                                                                               
        Serial.print( "RX: " );                                                 
        Serial.write(num);                                                     
        Serial.write(" ");                                                     
        Serial.println(num);                                                   
    }                                                                           

    delay(500);                                                                 
}

rPi Python code:
Code:
#!/usr/bin/python                                                               
                                                                               
# code from                                                                     
# http://shallowsky.com/blog/2011/Oct/16/                                       
                                                                               
import serial                                                                   
import time                                                                     
import select                                                                   
import sys                                                                     
                                                                               
serialport = serial.Serial("/dev/ttyAMA0", 9600, timeout=0.5)                   
                                                                               
while True:                                                                     
    # Check whether the user has typed anything (timeout of .2 sec):           
    inp, outp, err = select.select([sys.stdin, serialport], [], [], .2)         
                                                                               
    # If the user has typed anything, send it to the Arduino:                   
    if sys.stdin in inp :                                                       
        line = sys.stdin.readline()                                             
        serialport.write(line)                                                 
                                                                               
    # If the Arduino has printed anything, display it:                         
    if serialport in inp :                                                     
        line = serialport.readline().strip()                                   
        print "Arduino:", line

I connect all the wires, open serial monitor, run python script and all seems fine. Python waits for input, arduino is waiting for data on serial, but the moment I enter some character in python, arduino starts an endless loop of displaying its own printed characters.

// edited 10. mar 2013
In this example I entered "a" in python script and arduino returns "RX: a 97" but then it also thinks that string "RX: a 97" was sent to him over serial.
// end of edit
Code:
a
Arduino: RX: a 97
Arduino: RX: R 82
Arduino: RX: X 88
Arduino: RX: : 58
Arduino: RX:   32
Arduino: RX: a 97
Arduino: RX:   32
Arduino: RX: 9 57
Arduino: RX: 7 55
....

I know that Serial.print adds bytes to serial buffer, so i tried to clear the buffer at the end of the loop like this
Code:
delay(20);                                                               
while (Serial.read() != -1);
delay(500);

With this code it works almost as intended, but sometimes characters are not registered, I guess they get deleted when clearing the buffer. Maybe optimizing delays?

So I was wondering what would be the right/best way to receive data on arduino (only one character for example) and send a response over serial without having an effect on buffer or lost characters? Maybe disabling RX when transmitting over TX and vice-versa?

Thank you
« Last Edit: March 10, 2013, 04:21:46 am by bossek » Logged

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

Quote
I know that Serial.print adds bytes to serial buffer, so i tried to clear the buffer at the end of the loop like this
It adds bytes to the outgoing serial buffer, not the incoming serial buffer.

Without knowing what you entered, and seeing more of the Pi's output, all I can say is that the delays are useless, as is discarding serial data.

Why are you sending data TO the Arduino?
Logged

Rome, Italy
Offline Offline
Sr. Member
****
Karma: 20
Posts: 442
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, I tried your first script on a Mac with the standard USB connection and had different results. No endless loop (good), but on the other hand most characters sent by the Arduino were received by the python script, and only a few by the serial monitor (the two sets were complementary). If only the serial monitor or the python script are open the behavior is normal.

So I would say there was nothing wrong in your first attempt, and you should probably concentrate on configuration settings. Did you follow the other instructions given in the link (changes in inittab and console settings, connecting the ground)? I also wonder what are your results if you run only the serial monitor or the python script.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Without knowing what you entered, and seeing more of the Pi's output, all I can say is that the delays are useless, as is discarding serial data.
In the above example I entered "a" in python script and then it prints "Arduino: RX: a 97" but then arduino also thinks that string "RX: a 97" was sent to him over serial, since that is what he printed to serial. And the loop begins with python telling me "Arduino: RX: R 82", "Arduino: RX: X 88" and so on.

Why are you sending data TO the Arduino?
I need arduino to respond to raspberry pi instructions.

Hi, I tried your first script on a Mac with the standard USB connection and had different results. No endless loop (good), but on the other hand most characters sent by the Arduino were received by the python script, and only a few by the serial monitor (the two sets were complementary). If only the serial monitor or the python script are open the behavior is normal.
That seems normal, since Serial.read() removes the read byte from serial, as far as I know. So if you're running two serial monitors on the same computer, than its just a matter of who reads it first and deletes it so the second doesn't have anything to read.

In my case, I don't have arduino connected to raspberry pi with USB. They communicate over wires via GPIO RX/TX (pi) and RX/TX pins (on arduino). I have arduino connected to another computer with USB for uploading scripts and monitoring.

So I would say there was nothing wrong in your first attempt, and you should probably concentrate on configuration settings. Did you follow the other instructions given in the link (changes in inittab and console settings, connecting the ground)? I also wonder what are your results if you run only the serial monitor or the python script.
I've changed all the settings and connected the ground as described in linked post. It also doesn't change anything if I close down one serial monitor.

Thanks for the responses, you gave me think that it might not be the code. So I looked at the wiring (disclaimer: I'm better with software than with electrical circuits smiley ).

I changed the wiring just a little and only the raspberry pi to arduino part. So instead of transistor I used diode, for that small protection.
to:
Code:
pi(TX) >-------▶|-----|----[1k ohm]-------[ground]
                      |
                      |-----> ar(RX)

With this circuit it works as it should, no magic loops. So the initial problem solved.

However, I'm not completely sure what actually changed, why wouldn't it work properly with transistor and how should I fix it? If I change resistors or voltage in the circuit with transistor, it works even less, or am I missing something. One question answered two new appear smiley

Thank you
« Last Edit: March 10, 2013, 06:39:24 am by bossek » Logged

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

Quote
In the above example I entered "a" in python script and then it prints "Arduino: RX: a 97" but then arduino also thinks that string "RX: a 97" was sent to him over serial, since that is what he printed to serial. And the loop begins with python telling me "Arduino: RX: R 82", "Arduino: RX: X 88" and so on.
What the Arduino sent TO the serial port, and what it reads FROM the serial port are two different things. If the Arduino is seeing what it wrote to the serial port, the fault is on the Pi end.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What the Arduino sent TO the serial port, and what it reads FROM the serial port are two different things. If the Arduino is seeing what it wrote to the serial port, the fault is on the Pi end.

I understand they are two different things and thats what bugs me. From where is Arduino receiving his own response? I don't believe its pi fault. If he would receive it from pi, wouldn't it try to print "Arduino: RX: a 97" or something different and not just the string he sent "RX: a 97". Even if I remove all serialport.write() lines from python or even disconnect wire from pi(TX), this still happens, the moment arduino receives any byte to ar(RX) it starts the loop.

As I mentioned in my previous post, I got it working the way it should by removing transistor from the circuit and just connecting pi(TX) straight to ar(RX) with 1k ohm resistor. So I assume there is something wrong with the circuit I used (https://pbs.twimg.com/media/A7g86KCCQAAgwds.jpg). And now I'm wondering why this happens only when I add transistor to the circuit.

Regards
Logged

Rome, Italy
Offline Offline
Sr. Member
****
Karma: 20
Posts: 442
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I changed the wiring just a little and only the raspberry pi to arduino part. So instead of transistor I used diode, for that small protection.
to:
Code:
pi(TX) >-------▶|-----|----[1k ohm]-------[ground]
                      |
                      |-----> ar(RX)

With this circuit it works as it should, no magic loops. So the initial problem solved.

However, I'm not completely sure what actually changed, why wouldn't it work properly with transistor and how should I fix it? If I change resistors or voltage in the circuit with transistor, it works even less, or am I missing something. One question answered two new appear smiley

Thank you

Well it seems you are just cutting any signal from ar(RX) to pi(TX) -- which shouldn't have been there in the first place. I wonder what the 1k ohm to ground actually does. My impression is that your solution just masks the problem that produced the loopback effect.

Honestly, I'm not good at understanding circuits but the more I look at the original the less I understand what it was supposed to do. Take away the transistors and you have a voltage divider that protects the PI on the ar(TX) -> pi(RX) side (good) and also reduces the voltage on the pi(TX) -> ar(RX) side (why this?).

Now assume that the two GND are connected together, but they are just wires that you call GND without them actually being connected to the GND of either the PI or the Arduino, and you have created a loopback.

Then I'm confused by the transistors and the two 3.3V and 5V sources, but I guess they are not adding any useful effect.
Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have connected raspberry pi with arduino over serial RX/TX (UART) like this http://www.raspberrypi.org/phpBB3/viewtopic.php?f=37&t=22736

Did you also connect the grounds?
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Pages: [1]   Go Up
Jump to: