Software Serial with ESP32

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
nikten
Posts: 5
Joined: Wed Apr 08, 2020 9:16 am

Software Serial with ESP32

Post by nikten » Wed Apr 08, 2020 9:28 am

Hello,
i need four uart devices connected to my ESP32. My first purpose is to disable the UART0 from REPL, so i will have all the three UART available (But i don't know how to do that). However the problem of the fourth UART remains.
I tried the following command:

Code: Select all

uart3 = UART(3, 9600)                         # init with given baudrate
uart3.init(9600, bits=8, parity=None, stop=1, rx=26, tx=27) # init with given parameters
but of course it didn't work.
Is there any library that replicate the well known SoftwareSerial of the classic Arduino platform?

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

Re: Software Serial with ESP32

Post by jimmo » Wed Apr 08, 2020 2:11 pm

It's not currently possible to disable the UART from the REPL on ESP32.

Yes, you're right, the ESP32 only has three hardware UARTs (0, 1, 2).

Software UARTs are generally a terrible idea, it's very difficult to make them reliable (due to the timing), especially (counterintuitively) on more sophisticated microcontrollers because there's so much more going on that interferes with timing. It might be possible to do something with the RMT peripheral, but I'm not aware of anyone doing this?

What do you need all the UARTs for? Do you need to send and receive on all of them or just one direction? Could you use an external multiplexer?

nikten
Posts: 5
Joined: Wed Apr 08, 2020 9:16 am

Re: Software Serial with ESP32

Post by nikten » Wed Apr 08, 2020 2:36 pm

The project is for an electric bike. I put my microcontroller between the main controller and the display controller because i want to manage thei communication for different purposes, for example for decrease the maximum power of the motor. Other that, i need a GPS system that upload the current position of the bike.
Thus, i have:
-) UART0 for receiving and sending data with the main controller
-) UART1 for receiving and sending data with the display controller
-) UART2 for communicate with the SIM800L for GPRS and SMS services
-) UART3 (Software maybe) for communicate with ublox NEO-6M GPS

I wrote this project in Arduino code yet, and it works. But i'm really interested about micropython and i want to port this project here.

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Software Serial with ESP32

Post by Roberthh » Wed Apr 08, 2020 3:54 pm

As @jimmo said, software serial is not expected to work. Unlike the Arduino, the ESP32 has no guaranteed response time to interrupts, making receiving almost impossible, unless you can deal with really slow data rates, like <300 baud. Sending is possible in the actual port using the RMT hardware and the write_pulses() API. The corresponding read_pulses method is not yet implemented. If that helps: for sending, there is a short snippet below, which I used. It worked well with 9600 Baud. Should be fine for faster rates up to 38400 baud too.

Code: Select all

class RMT_UART:
    def __init__(self, gpio, *, status=None, restart=None, baudrate=BAUDRATE):
        self.rmt = RMT(0, pin=Pin(gpio), clock_div=80, idle=1)
        self.duration = 1000000 // baudrate  # tick duration 1us

    def send(self, msg):
        if type(msg) is str:
            msg = msg.encode()

        for byte in msg:
            data = [self.duration]  # start bit
            state = 0
            # create data bits
            for bit in range(8):
                if (byte & 1) == state:
                    data[-1] += self.duration
                else:
                    data.append(self.duration)
                    state = byte & 1
                byte >>= 1
            self.rmt.write_pulses(data, start=0)
            self.rmt.wait_done(timeout=self.duration * 9)  # Wait for the end
            sleep_us(self.duration * 2)  # Two stop bits

nikten
Posts: 5
Joined: Wed Apr 08, 2020 9:16 am

Re: Software Serial with ESP32

Post by nikten » Wed Apr 08, 2020 4:50 pm

Thank you very much for the code, however i mostly need to receive data and not to send.
My question is why SoftwareSerial should work with C++ (Arduino code) and shouldn't work with micropython? The fact is that it's working yet with the same ESP32 but with Arduino IDE (see ESPSoftwareSerial Arduino library : https://github.com/plerup/espsoftwareserial/)

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Software Serial with ESP32

Post by Roberthh » Wed Apr 08, 2020 6:36 pm

The reason why it is difficult to implement is the sometimes large interrupt latency. If an interrupt occurs, it may be handled sometimes within 10µs, sometimes as late as 900µs. That's about a full bit time at 9600 Baud. If nothing else is going on on the chip, that driver you referenced could work.

nikten
Posts: 5
Joined: Wed Apr 08, 2020 9:16 am

Re: Software Serial with ESP32

Post by nikten » Wed Apr 08, 2020 6:57 pm

Ok, i got it.
The problem is that the library is written in C and i don't know where to start. Do you know some function or class that (with interrupts) can work as an UART receiver?
Isn't more convenient to use time.sleep_us() instead of interrupts? So i can delay in the order of microseconds. But i feel i'm wrong.

User avatar
tve
Posts: 216
Joined: Wed Jan 01, 2020 10:12 pm
Location: Santa Barbara, CA
Contact:

Re: Software Serial with ESP32

Post by tve » Wed Apr 08, 2020 8:08 pm

A different option may be to time multiplex a uart between your SIM800L and the NEO-6M. For example, the neo-6m supports polling, so instead of having it send you nmea stanzas spontaneously you could change mode to poll it explicitly when you want the info.

I don't know about the SIM800, maybe there's a similar option. If not, maybe it supports RTS/CTS flow-control, so you can prevent it from sending to the esp32 when the uart is connected to to the NEO-6M. The flow control could also tell you when the esp32 needs to pay attention to it.

To multiplex you re-init the uart on the pins for the device you want to pay attention to now.

I haven't done the above myself, but thought I'd mention the option. In the long run, I suspect this would be more reliable than software-serial.

nikten
Posts: 5
Joined: Wed Apr 08, 2020 9:16 am

Re: Software Serial with ESP32

Post by nikten » Thu Apr 09, 2020 2:17 pm

Multiplexer is a good choice. However i think it's a good idea to implement this libary also in micropython.
Nonetheless, i decided to continue my project with Arduino script, and with another sim module (the SIM7000G) which has both LTE and GPS, and so i need one less UART port. SO without the need of ESPSoftwareSerial library.
Then, i noticed this repo https://github.com/dmascord/micropython that should be implement SoftUART in micropython. I'll test it soon.

User avatar
hcet14
Posts: 34
Joined: Sat Dec 19, 2020 12:59 am

Re: Software Serial with ESP32

Post by hcet14 » Sun Dec 27, 2020 11:36 am

Hi nikten, did you try?
I'm a beginner with this stuff and no programmer at all.

Post Reply