ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-10-29 19:59:20  阅读:243  来源: 互联网

标签:sockets raspberry-pi tcp networking 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有