树莓派Python服务器未发送串行读写命令

0 投票
1 回答
823 浏览
提问于 2025-04-18 14:11

我有两台服务器(用Python写的),它们在处理树莓派上的串口通信时几乎是一样的。不过,一台能正常工作,另一台却不行,我找不到问题出在哪里。我连接了一个逻辑分析仪,发现第一台服务器在串口通信时能正确触发接收和发送信号,但第二台服务器却什么都不触发。

首先是第一台(能工作的)服务器,代码简化到只显示串口部分:

import socket
import sys
import RPi.GPIO as GPIO
from serial import Serial

#HOST = ' ' # Symbolic name meaning all available interfaces
PORT = 8888 # Arbitrary non-privleged port
ser = 0

#accepts a command as a string, parameters separated by white space
def processData( data ):
    print ( "cmd : " + data).strip()
    parseData = data.split(" ")
    cmdLength = len(parseData)
    cmd = parseData[0]

    if cmd == "digitalWritePin":
        pin = parseData[1]
        state = parseData[2]
        #GPIO.setup(pin, GPIO.OUT) # SHOULD HAVE ALREADY BEEN DONE W/ A CONFIG!!!
        if state == '1':
            GPIO.output(int(pin), True)
        elif state == "0":
            GPIO.output(int(pin), False)
    elif cmd == "serialConfig":
        baudRate = int(parseData[1])
        timeOut = int(parseData[2])
        global ser
        ser = Serial('/dev/ttyAMA0', baudRate, timeout=timeOut)
    elif cmd == "serialWrite":
        serialcmd = parseData[1]
        writeBuff = data.split("serialWrite")
        #print writeBuff[1].strip(" ")
        ser.write(writeBuff[1].strip(" "))
    elif cmd == "serialReadLine":
        print "serial read:"
        response = ser.readline()
        print response
        conn.sendall(response)
        print "read done"

    return

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
s.bind((HOST,PORT))
print 'Socket bind complete'

s.listen(10)    #parameter: backlog, controls number of connections that are 'queued'
print 'Socket now listening'

#Function f or handling connections. this will be used to create threads
def clientthread(conn):
    #sending message to connected client        
    try:
        while True:
            data = conn.recv(1024)
            if not data:
                break
            processData( data )

        #out of the loop
        conn.close()
    except socket.error , msg:
        print 'Recv failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]

while 1:
    #wait to accept a connection - blocking call
    conn, addr = s.accept()
    print 'Connected with ' + addr[0] + ':' + str(addr[1])

    #start new thread takes 1st argument as a function name to be run
    #second is the tuple of arguments to the function
    start_new_thread(clientthread,(conn,))

s.close

其中最重要的部分是:

    ser = Serial('/dev/ttyAMA0', baudRate, timeout=timeOut)

还有el/if块中的串口配置、读取和写入部分。

然后是第二台(不工作的)服务器:

import socket
import sys
from time import sleep
from serial import Serial
from thread import *
import binascii

#HOST = ' ' # Symbolic name meaning all available interfaces
HOST = '10.1.10.28'
PORT = 8889 # Arbitrary non-privleged port


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

try:
    s.bind((HOST,PORT))
except socket.error , msg:
    print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    sys.exit()

print 'Socket bind complete'

s.listen(10)    #parameter: backlog, controls number of connections that are 'queued'
print 'Socket now listening'

ser = Serial('/dev/ttyAMA0', baudrate = 115200, timeout= 10)
#ser.open #--- uncommenting this does not make a difference 

#Function f or handling connections. this will be used to create threads
def clientthread(conn):

    #infinite loop so the function does not terminate and thread does not end
    try:
        while True:
            print  "step 1"
            first = conn.recv(1)
            print  "step 2"
            if not first:
                break
            hextFirst = hex( ord(first) )
            print hextFirst
            if hextFirst == '0xff':
                print  "step 3"
                #ser.write(hextFirst)           #send 0xff (converted)
                ser.write(first)                #send 0xff (orignal)

                length = conn.recv(1)               #get length
                hextLength = hex( ord(length) )     #convert length
                intlength = ord(length)
                print "hextLength: " + hextLength
                print "step 4"
                #ser.write(hextLength)          #send length (converted)
                ser.write(length)               #send length (original)
                cmd = 0
                if ord(length) == 0:
                    cmd = conn.recv(13)
                else:
                    cmd = conn.recv(ord(length)-2)

                hextCmd = binascii.b2a_hex(cmd)

                print cmd
                print "hextCmd: " + hextCmd
                #ser.write(hextCmd)         #send cmd (converted)
                ser.write(cmd)              #send cmd (original)

                #sleep(1)
                response = ser.read(1)          #get response
                #hextResponse = hex(ord(response))

                print "serial resp: " + response
                conn.sendall(response)          #send response to LV
                print "step 5"
            print "step 6"
            sleep(10)

        #out of the loop
        conn.close()
    except socket.error , msg:
        print 'Recv failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]

try:
    while 1:
        #wait to accept a connection - blocking call
        conn, addr = s.accept()
        print 'Connected with ' + addr[0] + ':' + str(addr[1])

        #start new thread takes 1st argument as a function name to be run
        #second is the tuple of arguments to the function
        start_new_thread(clientthread,(conn,))

    s.close
except KeyboardInterrupt:
    ser.close
    s.close
    print "Exiting: Keyboard Interrupt"

我知道这段代码看起来很多,但你可以忽略大部分内容。我只是想知道在串口配置和写入部分出了什么问题。正如我最开始说的,问题在于逻辑分析仪没有检测到第二台服务器的任何串口通信,而第一台服务器却正常工作。

1 个回答

0

试着通过编辑 /boot/cmdline.txt 文件来释放 /dev/ttyAMA0 这个默认控制台。

原来的内容是:

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 ..

你需要把它改成:

dwc_otg.lpm_enable=0 console=tty1 .....

另外,还要从 /etc/inittab 文件中删除这一行:

T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

确保你以超级用户的身份运行程序,也就是在前面加上 sudo

撰写回答