Cannot use UART0 for sensor communication

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
MuratUrsavas
Posts: 3
Joined: Thu Jul 07, 2022 6:22 am

Cannot use UART0 for sensor communication

Post by MuratUrsavas » Thu Jul 07, 2022 9:16 pm

Hi,

I'm trying to disable REPL on UART 0 on my NodeMCU V3 and use it for sensor communication, but cannot receive any characters as `UART.any()` always returns zero. I'm able to write to UART and send the data to the sensor side, but still can not read from it.

At one time, as I suspected, seen that the data is trapped in the buffer of REPL, even though it is disabled. That was revealed due to some kind of exception and I can't remember how that had happened.

I'm using stock boot.py but would like to paste here to clear any doubts.

boot.py:

Code: Select all

# This file is executed on every boot (including wake-boot from deepsleep)
#import esp
#esp.osdebug(None)
import uos, machine
#uos.dupterm(None, 1) # disable REPL on UART(0)
import gc
#import webrepl
#webrepl.start()
gc.collect()
main.py:

Code: Select all

import time
import machine
import esp
import uos
from sys import exit

is_led_on = True
led = machine.Pin(2, machine.Pin.OUT)        # Built-in LED

try:
    bypass_pin = machine.Pin(5, mode = machine.Pin.IN, pull = machine.Pin.PULL_UP)
except:
    exit()

if bypass_pin.value() == 0:
    print("Bypass activated. Quitting main.py...")
    for i in range(5):
        time.sleep(0.1)
        led.on()
        time.sleep(0.1)
        led.off()

    time.sleep(1)
    led.on()
    exit()


def finish_execution():
    print("Finishing app execution.")
    uos.dupterm(machine.UART(0, 115200), 1)         # Move REPL to its original place
    exit()

uos.dupterm(machine.UART(1, 115200), 1)     # Move REPL to UART1 to see the outputs
print("App started.")

class SerialDevice:
    """
    Serial device management class
    """

    def __init__(self):
        self.rx_buffer = bytearray(2048)
        self.rx_vector = 0
        self.waited_for_eof = False
        self.read_data_len = None

        try:
            self.port = machine.UART(0, 115200)
            self.port.init(115200, bits=8, parity=None, stop=1)
            print("Serial device serial port enabled.")
        except Exception as e:
            print("Cannot enable serial device port.")
            print(e)
            finish_execution()

    def receive_data(self) -> bool:
        print("UART Rx Check")
        try:
            self.read_data_len = None
            data_amount = self.port.any()
            if data_amount != 0:
                self.read_data_len = self.port.readinto(memoryview(self.rx_buffer)[self.rx_vector:], len(self.rx_buffer) - self.rx_vector)
        except OSError as e:
            print(("Serialport OsError ({error})").format(error=e.strerror))
            return False
        except Exception as e:
            print("Unhandled exception while reading port")
            print(e)
            return False

        if self.read_data_len is None:
            if self.rx_vector != 0:
                if self.waited_for_eof == True:
                    return True
                else:
                    self.waited_for_eof = True
                    return False
            else:
                return False

        self.rx_vector += self.read_data_len
        print(("Port data received ({read_data_amount})").format(read_data_amount=self.read_data_len))

        return False

    def clear_rx_buffer(self):
        self.rx_vector = 0

try:
    serial_dev = SerialDevice()
except Exception as e:
    print("Error: Serial device configuration error.")
    print(e)
    finish_execution()

while True:

    if serial_dev.receive_data():
        serial_dev.port.write(memoryview(serial_dev.rx_buffer)[:serial_dev.rx_vector])
        serial_dev.clear_rx_buffer()

    time.sleep(1)       # Extreme delay for debug purposes. Will be 0.1 for production.
To simplify reproduction, I've removed almost all unrelated logic and just added a simple echo to the same UART.

Thanks in advance for your any kind of help.

Cheers,
/// Murat

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Cannot use UART0 for sensor communication

Post by jimmo » Fri Jul 08, 2022 6:28 am

MuratUrsavas wrote:
Thu Jul 07, 2022 9:16 pm
I'm trying to disable REPL on UART 0 on my NodeMCU V3 and use it for sensor communication, but cannot receive any characters as `UART.any()` always returns zero. I'm able to write to UART and send the data to the sensor side, but still can not read from it.
Off the top of my head my guess would be that your NodeMCU board has the USB/UART adaptor connected to UART 0, and this is always holding the UART RX pin low.

MuratUrsavas
Posts: 3
Joined: Thu Jul 07, 2022 6:22 am

Re: Cannot use UART0 for sensor communication

Post by MuratUrsavas » Fri Jul 08, 2022 6:43 am

Thanks for your response @jimmo. Yes, I'm aware of that and just using the same channel (/dev/ttyUSB0) for my tests. So it's OK to use it for now. And I've verified the RX pin is acting correctly, showing the correct incoming characters electrically. So the actual problem is, somehow I can not reach the received characters in software.

The thing you've mentioned is a worry about the production. That could be my followup question. What's the best way to move it another location which would not be interfered by the installed USB - UART converter?

I'm also suspecting from REPL placement to UART1. As it actually only has TX line, RX line could be kept at the UART 0 RX location and since REPL is not active while my app is running, it could be kept in the buffer untouched. This is not something I've verified, though.

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Cannot use UART0 for sensor communication

Post by jimmo » Mon Jul 11, 2022 5:49 am

MuratUrsavas wrote:
Fri Jul 08, 2022 6:43 am
The thing you've mentioned is a worry about the production. That could be my followup question. What's the best way to move it another location which would not be interfered by the installed USB - UART converter?
The ESP8266 UART is pretty limited. You can either have it on pins 1 & 3 or 15 & 13.
Like you say there is only one UART (the second only has TX available).

As long as you have your USB/UART converter connected to pins 1 & 3, you will be unable to use those pins for anything else.

MuratUrsavas
Posts: 3
Joined: Thu Jul 07, 2022 6:22 am

Re: Cannot use UART0 for sensor communication

Post by MuratUrsavas » Thu Jul 14, 2022 7:29 am

Somehow I've been stuck even with moving the UART0 to its second location (Pins 13, 15). So I should be doing something fundamentally wrong. Wondering what that is.

Post Reply