编程语言
首页 > 编程语言> > 树莓派上的WiFi上的Python套接字

树莓派上的WiFi上的Python套接字

作者:互联网

我已经在python中编写了一个套接字.基本上有2个树莓派互相交谈,并使用套接字通过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)==如果GPIO.input(4)返回True,则结果为True.因此,您也可以跳过额外的比较(或者从另一个角度来看,为什么不编写(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()的调用.这将使您看到循环主体运行的频率.如果您发现时间差距,那么您就有第一个线索.

标签:sockets,raspberry-pi,tcp,networking,python
来源: https://codeday.me/bug/20191029/1962358.html