Python Socket over wifi in raspberry pi
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.
Meet Desai
Updated on June 08, 2022Comments
-
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 about 10 yearsThanks you so much for the corrections. I will do them and get back to you in case if it solves my issue.
-
Meet Desai about 10 yearsThanks a lot!! The s.recv(2) worked for me. Thank you very much.