串行 AT 命令在 python 脚本中不起作用,但在 Minicom 中起作用
Posted
技术标签:
【中文标题】串行 AT 命令在 python 脚本中不起作用,但在 Minicom 中起作用【英文标题】:Serial AT commands not working in python script but working in Minicom 【发布时间】:2020-02-27 13:34:45 【问题描述】:我正在尝试对 GPRS/GNSS/... Raspberry PI HAT 进行编程。 使用 Minicom 发送命令可以正常工作。 使用 Python 脚本发送命令适用于大多数命令,但并非适用于所有命令。 收到使用 Python 脚本命令,但返回错误。 我尝试了很多初始化序列,所有这些都在 Minicom 中工作,但在 Python 脚本中却没有。 每两次执行一次 AT+CSTT="APNNAME" 有效 并且 AT+CIICR 从未在脚本中工作过。 我重新启动了板子,结果是一样的。 董事会回答我,但用“+PDP:DEACT”和“ERROR”
代码如下:
#!/usr/bin/env python
from serial import *
import time
import io
import sys
import RPi.GPIO as GPIO
# --- Use GPIO PINs to boot the Board
def toggle_board_onoff():
GPIO.setmode(GPIO.BCM)
GPIO.setup(4,GPIO.OUT)
GPIO.output(4,GPIO.HIGH)
GPIO.output(4,GPIO.LOW)
time.sleep(3)
GPIO.output(4,GPIO.HIGH)
# --- Send AT command to the board. (sio ~ serial port, cmd=command, wait=time to wait after execution before read the result)
def send_cmd(sio, cmd, wait=0):
# - Write section
sio.flush()
sio.write(unicode(cmd))
sio.flush()
print("CMD-> '" + str(cmd) + "'")
# - Wait section
if wait > 0:
print("[ DEBUG ] <" + cmd.rstrip() + "> executed, will wait " + str(wait) + " sec")
time.sleep(wait)
print("[ DEBUG ] Wait for " + str(wait) + " sec [ DONE ]")
# - Read section
ligne = sio.readline()
print(ligne)
# - Expect 'OK' answer
while(ligne.rstrip() != "OK"):
if(ligne.rstrip() == "ERROR"):
return -1
#sys.exit(1)
ligne = sio.readline()
print("[" + ligne + "]")
# - Split screen for next AT command
print("----------------------------------")
# --- Commands to execute in order to bring the network UP
def init_gprs_network_short(sio):
com4=b"AT+CSTT='FREE'\n"
com5=b'AT+CIICR\n'
if(send_cmd(sio, com4,3) == -1):
return -1
if(send_cmd(sio, com5,3) == -1):
return -1
# --- Serial communication with the board
def serial_init():
# - This function might be called in a loop for debug (auto reboot if error on network auth)
# -------------- Reboot section ---------------
time.sleep(2)
print("Board reBoot [ ... ]")
print("Off...")
toggle_board_onoff()
time.sleep(8)
print("On...")
toggle_board_onoff()
print("Board reBoot [ OK ]")
#print("Board is warming [ ... ]")
#time.sleep(5)
#print("Board is warming [ OK ]")
# ---------------------------------------------
with Serial(port="/dev/ttyS0", baudrate=115200, timeout=1, writeTimeout=1) as port_serie:
if port_serie.isOpen():
sio = io.TextIOWrapper(io.BufferedRWPair(port_serie, port_serie))
# - Let the board show boot msg (SMS ok, Call ok etc)
for i in range(0,4):
print("Boot msg iter [" + str(i) + "]")
time.sleep(0.5)
ligne = sio.readline()
print(ligne)
# - Try to bring the network UP...
network_active = init_gprs_network_short(sio)
if network_active == -1:
return network_active
#while True:
# ligne = sio.readline()
# print(ligne == unicode("ligne\n"))
# print(ligne) i
return -1
def main():
# - Boot the board
print("Board Boot [ ... ]")
toggle_board_onoff()
print("Board Boot [ OK ]")
board_connected_gprs = serial_init()
# - While we got errors when trying to bring the network UP...
while(board_connected_gprs == -1):
board_connected_gprs = serial_init()
main()
这里是执行内容:
Board Boot [ ... ]
serial_at_gprs_2.py:11: RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.
GPIO.setup(4,GPIO.OUT)
Board Boot [ OK ]
Board reBoot [ ... ]
Off...
On...
Board reBoot [ OK ]
Boot msg iter [0]
Boot msg iter [1]
Boot msg iter [2]
Boot msg iter [3]
CMD-> 'AT+CSTT='FREE'
'
[ DEBUG ] <AT+CSTT='FREE'> executed, will wait 3 sec
[ DEBUG ] Wait for 3 sec [ DONE ]
AT+CSTT='FREE'
[OK
]
----------------------------------
CMD-> 'AT+CIICR
'
[ DEBUG ] <AT+CIICR> executed, will wait 3 sec
[ DEBUG ] Wait for 3 sec [ DONE ]
AT+CIICR
[+PDP: DEACT
]
[
]
[ERROR
]
Board reBoot [ ... ]
Off...
问题不是来自电路板的接缝,因为它在 Minicom 中运行良好。 我一开始以为是编码问题,但是当董事会回答我时,命令读得很好......
您有什么想法可以帮助我解决这个问题吗? 如果您需要有关配置或其他任何信息的更多信息,请告诉我。
董事会: https://www.waveshare.com/wiki/GSM/GPRS/GNSS_HAT
SIM868_GNSS_Application Note_V1.00: https://www.waveshare.com/w/upload/3/3d/SIM868_GNSS_Application_Note_V1.00.pdf
非常感谢!
【问题讨论】:
你试过在命令后发送“\r\n”吗? 这能回答你的问题吗? Console does not show the entire answar from serial port 在发送第二个命令之前,请阅读输出以查看是否收到其他任何内容。 我在最后尝试了 "\r\n": com4=b"AT+CSTT='FREE'\r\n" 但我在多次执行中得到了相同的结果.. 我在 send_cmd() 的顶部添加了:ligne = sio.readline() 和 print(ligne) 但没有什么特别的显示... 【参考方案1】:-
使用 AT+CIPSHUT
使用\r\n(CR和LF,可以看这里的区别>Difference between CR LF, LF and CR line break types?)
以下这些步骤对我有用。 在我的代码上使用(UART 连接波特率=9600)
import sys, time
from machine import UART
sim800 = UART(1, baudrate=9600, tx=Pin(8), rx=Pin(9)) ##this pinout for raspberry pi pico
# [...] something about my code that is not the question point
#try to connect AT+CSTT in APN mode
sim800.write('AT+CSTT="host","username","password"\r\n') ## this is to connect into APN
time.sleep(.5)
if 'ERROR' in str(sim800.read()):
print('error to connect 1, trying again...')
sim800.write('AT+CIPSTATUS\r\n') ## this is to check the status, probably it will be 'IP START' or 'PDP: DEAC'
time.sleep(.5)
if 'IP INITIAL' not in str(sim800.read()):
sim800.write('AT+CIPSHUT\r\n') ## after this command the cipstatus will change to IP INITIAL
time.sleep(.5)
# now we can connect to apn using AT+CSTT
sim800.write('AT+CSTT="host","username","password"\r\n')
time.sleep(.5)
if 'ERROR' in str(sim800.read()):
print('error to connect 2. closing')
sys.exit()
将其调整为您的代码,如下所示:
[...]
com6 = b'AT+CIPSTATUS\r\n'
com7 = b'AT+CIPSHUT\r\n'
if('IP INITIAL' not in send_cmd(sio, com6,3)):
send_cmd(sio, com7,3)
[...]
【讨论】:
以上是关于串行 AT 命令在 python 脚本中不起作用,但在 Minicom 中起作用的主要内容,如果未能解决你的问题,请参考以下文章
NPM 脚本 - 配置变量和命令替换在 package.json 中不起作用