Hi!
I need to connect GSM to ESP32 via serial communication. Some serial AT-commands sends answer too fast, some of them takes some time. If actions to write command to serial and read answer follows step by step some commands sends answer too be late. Sleep command can`t solve this problem cause various AT-commands requires different time to send answer and I was tested this method. No luck.
Is any IRQ to control availability to read answered data or any another method to make control data flow throu serial port?
Is there any Serial listener onboard?
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Is there any Serial listener onboard?
I suggest you look at the uasyncio stream mechanism which simplifies UART communication.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: Is there any Serial listener onboard?
Here is how I interact with a cellular modem via AT commands. Hope this helps!
Code: Select all
###################################################
##### IMPORTS AND REQUIREMENTS FOR SIMCOM.PY #####
###################################################
from machine import UART # ESP32 UART interface for connecting to SIM7000g.
from machine import Pin # ESP32 UART PIN definitions.
import time
import gc # Garbage Collection for keeping memory clean.
# Collect garbage after imports to keep things clean.
gc.collect()
####################################################################
##### SETUP AND CUSTOMIZATION FOR SIMCOM APN AND MQTT SETTINGS #####
####################################################################
# Cellular Network Setup
apn = 'your.cell.apn.goes.here' # Cellular network APN
# Power Pin and Control for Simcom 7000.
# Cell PIN power Machine pins. These control the power of the simcom chip.
cell_power = Pin(4, Pin.OUT) # PIN 4 on ESP32 controls power of Simcom.
cell_power.on() # Make sure PIN 4 is HIGH.
# Setting up UART to SIMCOM 7000 chip.
# Initialization at start.
simcom = UART(1, 9600) # init with given baudrate
simcom.init(baudrate=9600, bits=8, parity=None, stop=1, rx=26, tx=27) # init with given parameters check rx and tx.
def init():
simcom = UART(1, 9600) # init with given baudrate
simcom.init(baudrate=9600, bits=8, parity=None, stop=1, rx=26, tx=27) # init with given parameters check rx and tx.
def deinit():
simcom.deinit()
###########################################################################
##### MAIN FUNCTIONS RELATED TO SIMCOM MODEM VIA UART AND AT COMMANDS #####
###########################################################################
# AT commands for SIMCOM 7000 in relation to MFT - Basic functions.
# CMD line break for AT function - Need this for modem to accept commands. Equiv to 'enter' or 'submit' on a form.
CMD_LINEBREAK = b'\r\n'
# Write data through UART to Simcom
def send(data):
simcom.write(data) # Do the write.
# Encode the Commands and send.
def send_cmd(cmd):
send(cmd.encode('utf-8') + CMD_LINEBREAK) # Package the command and encode in UTF-8
# Watching for data from the Simcom modem over UART. This is the main function for handling data in and out of Simcom.
def watch(timeout=10, success=None, failure=None, echo_cmd=None):
t_start = time.time() # For timing how long the reply takes.
reply = list()
while True:
try:
if simcom.any(): # If there is data on UART 1 - connected to Simcom.
line = simcom.readline() # Read the line of data from UART.
echo = False # Start with the echo set to False
if echo_cmd:
echo = line.decode('utf-8').strip().endswith(echo_cmd) # Decode and strip the reply
if line != CMD_LINEBREAK and not echo: # Process the reply.
line = line.decode('utf-8').strip()
reply.append('\t' + line)
if success and line.startswith(success): # handle the reply according to 'if' situations.
return "Success", reply, time.time() - t_start
if failure and line.startswith(failure):
return "Error", reply, time.time() - t_start
if (time.time() - t_start) > timeout:
return "Timeout", reply, time.time() - t_start
time.sleep_ms(20)
except:
pass # Broad pass to keep program running. Often times it is OK with simcom.
# AT command function for communicating with Simcom
def AT(cmd="", timeout=10, success="OK", failure="+CME ERROR"):
cmd = 'AT' + cmd
# print("----------- ", cmd, " -----------")
send_cmd(cmd)
reply = watch(timeout=timeout, success=success, failure=failure, echo_cmd=cmd)
# print("{0} ({1:.2f}secs):".format(reply[0], reply[2]))
# print(*reply[1], sep='\n')
# print('')
return reply
Re: Is there any Serial listener onboard?
That is my tested variant. I used a class to collect all functions and to make one object to work with UART. Listener is listed below.
After any command needs "do listen" commands:
Code: Select all
def listener(self):
for attempt in range(12): # 12 secs to wait an answer
start = time.time() # Passing a second
while start == time.time():
pass
if self.any() == 0: # If no data received
yield str('next') # Send caller an instruction to continue
else:
break # else quit 'for' and return 'ready'
else:
return str('timeout') # If whole cycle finished then return 'timeout'
return str ('ready')
Code: Select all
(object).write()
Code: Select all
self.write(cmd)
result = ''
try :
while result in self.listener() is not 'ready':
pass
except StopIteration:
self.readBuffer = self.read()
if self.readBuffer.find(answer) > -1:
return True
else:
return False
else:
self.readBuffer = '+CME ERROR: Timeout'
return False