Python Socket over wifi in raspberry pi

16,932

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.

Share:
16,932
Meet Desai
Author by

Meet Desai

Updated on June 08, 2022

Comments

  • Meet Desai
    Meet Desai almost 2 years

    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()
    
  • Meet Desai
    Meet Desai about 10 years
    Thanks you so much for the corrections. I will do them and get back to you in case if it solves my issue.
  • Meet Desai
    Meet Desai about 10 years
    Thanks a lot!! The s.recv(2) worked for me. Thank you very much.