[英]Python Socket over wifi in raspberry pi
我已經在python中編寫了一個套接字。 基本上有2個覆盆子pi彼此交談並使用套接字通過wifi發送gpio數據。 代碼有時完美無缺,但有時它或者不起作用或顯示很多延遲。 什么可能的問題。 我錯過了什么。 我是網絡和python的新手。 請幫我!!
服務器代碼是
#!/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()
客戶端代碼在這里
#!/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()
有些事情與您的代碼不相關。 還有一些事情可能會對其行為產生影響。
if (GPIO.input(04)==True):
你應該這樣寫這樣的語句:
if GPIO.input(4):
我刪除的括號完全是多余的。 他們沒有任何區別。
我也將04
更改為4
因為04
是八進制文字。 這個特定值沒有區別,因為八進制4和十進制4是相同的值。 然而,在這里使用八進制是令人困惑和驚訝的(如果使用八進制來引用GPIO引腳是慣用的,這可能是在這里使用八進制的原因,但據我所知它不是)。 由於您的引腳號碼恰好是8或更大,因此不會使用八進制表示法寫入,我猜這是無意的。
我還刪除了與True
的顯式比較。 你幾乎不應該與True
比較。 GPIO.input(4) == True
的計算結果為True
,如果GPIO.input(4)
返回True
。 所以你也可以跳過額外的比較(或者從另一個角度來看,為什么不編寫if (GPIO.input(4) == True) == True:
)。
類似於以下行:
if (GPIO.input(27)==False):
你應該寫這個:
if not GPIO.input(27):
你幾乎不應該與False
比較。
也許更嚴重的是:
if (GPIO.input(27)==False):
conn.send('0')
elif(GPIO.input(27)==True):
conn.send('1')
我不認為你的應用程序在你的程序中對此引腳進行兩次采樣並不重要 - 但這就是你正在做的事情。 很可能第一個GPIO.input(27)
將返回True
,第二個調用將返回False
。 在這種情況下,您的程序不會采取任何行動 - 誰知道后果。
相反,你應該寫一些像:
if GPIO.input(27):
conn.send('1')
else:
conn.send('0')
也許最重要的是
while 1:
data=s.recv(8096)
if data=='0':
這是套接字API的誤用。 您最多要求8096個字節,然后處理結果,就像您最多要求1個字節一樣。 伴隨程序總是一次寫入1個字節並不重要。 允許TCP將這些寫入合並在一起。
相反,你應該寫:
while 1:
data = s.recv(1)
if data=='0':
好吧,這不是寫作的理想選擇,但這是使代碼按照您的意圖執行的最小變化。
目前尚不清楚這與您遇到的問題有關但缺乏您的特定硬件我懷疑任何人都可以實際重現該問題。
在使用代碼解決這些問題后,您的下一個調試步驟應該是縮小首次出現延遲的位置。
也許發送端的GPIO引腳受到干擾,數據不再出現。 也許GPIO庫中的某些內容在某些輸入下是行為不端的。 也許其中一個raspberrypis上的網絡堆棧存在問題 - 由於資源限制或硬件故障或其他我無法猜測的事情 - 等等。
因此,請對發件人進行檢測,以便了解它是否定期發送數據或是否在此處引入延遲。 如果它定期發送數據,則檢查接收器是否定期接收數據。 如果是,那么你可能已經將問題縮小到GPIO庫或接收端的引腳。
儀器可以非常簡單。 例如,嘗試將幾個打印與調用time.time()
放在循環中。 這將讓您了解循環體運行的頻率。 如果你發現時間差,那么你就得到了第一條線索。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.