Is there any Serial listener onboard?

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
propeller
Posts: 9
Joined: Thu Jun 04, 2020 2:52 am

Is there any Serial listener onboard?

Post by propeller » Tue Jun 16, 2020 6:34 am

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?

User avatar
pythoncoder
Posts: 5145
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Is there any Serial listener onboard?

Post by pythoncoder » Wed Jun 17, 2020 6:43 am

I suggest you look at the uasyncio stream mechanism which simplifies UART communication.
Peter Hinch

kinno
Posts: 32
Joined: Mon Oct 21, 2019 2:06 pm

Re: Is there any Serial listener onboard?

Post by kinno » Wed Jun 17, 2020 10:53 am

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
    

propeller
Posts: 9
Joined: Thu Jun 04, 2020 2:52 am

Re: Is there any Serial listener onboard?

Post by propeller » Sun Jun 21, 2020 9:54 am

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.

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')
After any

Code: Select all

(object).write()
command needs "do listen" commands:

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

Post Reply