3

I have programmed a socket in python. Basically there are 2 raspberry pi's who talk to each other and send the gpio data over wifi using a socket. The code works perfectly fine at times but sometimes it either doesn't work or shows a lot of lag. What can the possible issue. Have I missed something. I am new to networking and python. Please help me!!

The Server code is

#!/usr/bin/python
import RPi.GPIO as GPIO
import socket
HOST='192.168.0.106'
PORT=5002
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr=s.accept()
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
print 'Connected by', addr
GPIO.setmode(GPIO.BCM)
GPIO.setup(04, GPIO.IN)
GPIO.setup(17, GPIO.IN)
GPIO.setup(27, GPIO.IN)
while True:
    if (GPIO.input(04)==True):
        if (GPIO.input(17)==False):
                if (GPIO.input(27)==False):
                        conn.send('0')
                elif(GPIO.input(27)==True):
                        conn.send('1')
        elif (GPIO.input(17)==True):
                if (GPIO.input(27)==False):
                        conn.send('2')
                elif (GPIO.input(27)==True):
                        conn.send('3')
    elif (GPIO.input(04)==False):
        conn.send('5')
s.close()

The client code is here

#!/usr/bin/python
import socket
import RPi.GPIO as GPIO
HOST='192.168.0.106'
PORT=5002
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
GPIO.setmode(GPIO.BCM)
GPIO.setup(02, GPIO.OUT)
GPIO.setup(03, GPIO.OUT)
GPIO.setup(11, GPIO.OUT)
GPIO.setup(10, GPIO.OUT)
while 1:
    data=s.recv(8096)
    if data=='0':
            print 'Forward'
            GPIO.output(02,True)
            GPIO.output(03, False)
            GPIO.output(11, False)
    elif data=='1':
            print 'Backward'
            GPIO.output(02, False)
            GPIO.output(03, True)
            GPIO.output(11, True)
            GPIO.output(10, False)
    elif data=='2':
            print 'Left'
            GPIO.output(02, False)
            GPIO.output(03, False)
            GPIO.output(11, False)
            GPIO.output(10, True)
    elif data=='3':
            print 'Right'
            GPIO.output(02, True)
            GPIO.output(03, False)
            GPIO.output(11, False)
            GPIO.output(10, False)
    elif data=='5':
            print 'Stop'
            GPIO.output(02, False)
            GPIO.output(03, False)
            GPIO.output(11, False)
            GPIO.output(10, False)
s.close()
4
  • What's a "lot" of lag? What do you expect to happen and what actually happens? Commented Mar 20, 2014 at 12:02
  • I want to transfer the gpio status over the socket in real time. The delay is not fixed everytime. Sometimes the program gets stuck, sometimes there is a lag which is variable and even packets are lost and sometimes the code works completely smooth. Not able to identify what is the exact problem here. Commented Mar 20, 2014 at 12:59
  • What counts as "smooth"? What counts as "lag"? Are you talking about a 10ms delay or a 10,000ms delay? Commented Mar 20, 2014 at 14:00
  • 10ms delay is fine..Sometimes the delay is almost too much. Even a minute sometimes. Sometimes it stops responding only. Not able to check what is wrong. Commented Mar 20, 2014 at 17:57

1 Answer 1

5

There are some things that are not idiomatic about your code. There are also some things that may make a difference to its behavior.

if (GPIO.input(04)==True):

You should write this statement like this instead:

if GPIO.input(4):

The parenthesis I removed are completely superfluous. They make no difference.

I also changed 04 to 4 because 04 is an octal literal. It makes no difference for this particular value because octal 4 and decimal 4 are the same value. It's confusing and surprising to use an octal here, though (if it were idiomatic to refer to GPIO pins using octal that might be a reason to use octal here, but as far as I know it isn't). Since your pin numbers that happen to be 8 or greater are not written using octal notation here I'm guessing this is unintentional.

I also removed the explicit comparison against True. You should almost never compare against True. GPIO.input(4) == True evaluates to True if GPIO.input(4) returns True. So you may as well skip the extra comparison (or from the other perspective, why don't you write if (GPIO.input(4) == True) == True:?).

Similar for a line like:

if (GPIO.input(27)==False):

You should write this instead:

if not GPIO.input(27):

You should almost never compare against False either.

Perhaps more seriously:

if (GPIO.input(27)==False):
    conn.send('0')
elif(GPIO.input(27)==True):
    conn.send('1')

I don't think it's critical to your application to sample this pin twice at this point in your program - but that's what you're doing. It's quite possible that the first GPIO.input(27) will return True and the second call will return False. In this case your program won't take either action - with who knows what consequences.

Instead you should write something like:

if GPIO.input(27):
    conn.send('1')
else:
    conn.send('0')

And perhaps most importantly

while 1:
    data=s.recv(8096)
    if data=='0':

This is a mis-use of the socket API. You asked for at most 8096 bytes and then you handled the result as if you had asked for at most 1 byte. It doesn't matter that the companion program always writes 1 byte at a time. TCP is allowed to merge those writes together.

Instead you should write:

while 1:
    data = s.recv(1)
    if data=='0':

Well, that's not really the ideal thing to write, but it's the smallest change to make the code do what you intend.

It's not clear that any of this is related to the problem you're experiencing but lacking your particular hardware I doubt anyone can actually reproduce that problem.

After fixing these issues with the code your next debugging step should be to narrow down where the delay first appears.

Perhaps the GPIO pins on the sending side are being interfered with and data stops coming out of them. Perhaps something in the GPIO library is misbehaving under some set of inputs. Perhaps the network stack on one of the raspberrypis is having issues - due to resource constraints or failing hardware or something else I can't guess - etc.

So instrument the sender so you can tell if it is sending data regularly or if the delays are introduced there. If it is sending data regularly then instrument the receiver to see if it is receiving data regularly. If it is then maybe you'll have narrowed down the problem to the GPIO library or pins on the receiving side.

The instrumentation can be very simple. For example, try putting a few prints along with calls to time.time() inside the loop. This will let you see how often the loop body runs. If you notice gaps in time then you've got your first clue.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks you so much for the corrections. I will do them and get back to you in case if it solves my issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.