ESP8266 UART workaround

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
pytango
Posts: 1
Joined: Thu Oct 28, 2021 8:32 am

ESP8266 UART workaround

Post by pytango » Thu Oct 28, 2021 10:07 am

Hi Everyone!

I'm not strong in MicroPython and MCU programming so I'd like to get some suggestions and reviews from more experienced people how to work with another devices by UART and keep REPL. Or just maybe my experience bellow will help somebody.
I know that this question is very popular, but I haven't found the universal and completed solution.
In my case I'm setting communication between ESP8266 NodeMCU Lolin and GSM module SIM800L

Firstly I implemented first version of UART workaround based on detaching REPL from UART0 before read/write and reattach after, as it explained in MicroPython documentation for ESP8266.

Code: Select all

import uos
import machine

class UartEsp8266:
    """
    Class purposed to use UART with ESP8266 with REPL
    """
    UART_ID = 0  # We always use UART0 because UART1 is write only on ESP8266 MCU

    def __init__(self, **kwargs):
        self.uart = machine.UART(
            self.UART_ID
        )
        self.uart.init(
            **kwargs
        )

    def read(self):
        """
        Detach REPL from UART0, read and then reattach REPL to UART#0
        """
        self.__detach_repl()
        data = self.uart.read()
        self.__reattach_repl()
        return data

    def write(self, data):
        """
        Detach REPL from UART0, write bytes and then reattach REPL to UART0
        """
        self.__detach_repl()
        result = self.uart.write(data)
        self.__reattach_repl()
        return result

    def execute(self, cmd):
        """
        Detach REPL from UART0, write command,
        wait and read response and reattach REPL to UART0
        return command response
        """
        self.__detach_repl()
        _write_result = self.uart.write(cmd)
        # TODO: add check of _write_result
        response = self.uart.read()
        self.__reattach_repl()
        return response

    def __reattach_repl(self):
        """
        Reattach REPL to UART0
        """
        uos.dupterm(self.uart, 1)

    @staticmethod
    def __detach_repl():
        """
        Detach REPL from UART0
        """
        uos.dupterm(None, 1)
But then I realised that all debug messages which I want to send to REPL will be sent to UART device too. Am I right or not?

And the idea came into my mind. I thought that we can use UART0 RX to read data from UART device, but send data through UART1 TX. In this approach we can send clean data to connected peripheral device, without "garbage" from REPL.
So I implemented second UART workaround prototype. I'm not sure is it good approach or not? What cons?

Code: Select all

import uos
import machine

class UartEsp8266Hack:
    """
    Class purposed to use UART with ESP8266 with REPL.
    This implementation uses RX from UART0 and TX from UART1
    """
    UART_RX = 0 
    UART_TX = 1

    def __init__(self, **kwargs):
        self.uart_rx = machine.UART(
            self.UART_RX
        )
        self.uart_rx.init(
            **kwargs
        )
        self.uart_tx = machine.UART(
            self.UART_TX
        )
        self.uart_tx.init(
            **kwargs
        )

    def read(self):
        """
        Detach REPL from UART0, read and then reattach REPL to UART0
        """
        self.__detach_repl()
        data = self.uart_rx.read()
        self.__reattach_repl()
        return data

    def write(self, data):
        """
        Just write data to UART1
        """
        result = self.uart_tx.write(data)
        return result

    def execute(self, cmd):
        """
        Write command to UART1,
        detach REPL from UART0,
        read response and reattach REPL to UART0
        return command response
        """
        _write_result = self.uart_tx.write(cmd)
        # TODO: add check of _write_result
        response = self.read()
        return response

    def __reattach_repl(self):
        """
        Reattach REPL to UART0
        """
        uos.dupterm(self.uart_rx, 1)

    @staticmethod
    def __detach_repl():
        """
        Detach REPL from UART0
        """
        uos.dupterm(None, 1)
Thanks for your advices!

Post Reply