Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ports/esp8266: Software Serial (SoftUART) support. #7784

Open
wants to merge 15 commits into
base: master
Choose a base branch
from

Conversation

MrJake222
Copy link
Contributor

@MrJake222 MrJake222 commented Sep 13, 2021

Software serial communication for ESP-8266

class SoftUART - half-duplex serial communication

SoftUART implements the standard UART/USART half-duplex serial communications protocol.
Supported communication parameters are:

  • 8 data bits,
  • 1 stop bit,
  • No parity,
  • 1M-baud tested with nothing running in the background.

Initialization

from machine import SoftUART, Pin

uart = SoftUART(tx=Pin(2), rx=Pin(4))
uart.init(baudrate=9600, timeout=0)

Constructors

  • class machine.SoftUART(tx=Pin(Tx), rx=Pin(Rx))
    • Tx - pin used for data transmission
    • Rx - pin used for data reception

Methods

  • SoftUART.init(tx=Pin(Tx), rx=Pin(Rx), baudrate=9600, bits=8, parity=None, stop=1)
    Basically constructor without additional memory allocation.
    • Tx - pin used for data transmission
    • Rx - pin used for data reception
    • baudrate - data rate
    • bits - data bits (only 8 supported)
    • parity - data parity bit (only None supported)
    • stop - stop bits (only 1 supported)
  • SoftUART.deinit()
    Frees memory.
  • SoftUART.read(n)
  • SoftUART.readline()
    Unreliable.
  • SoftUART.readinto()
    Not tested.
  • SoftUART.write(buf)

Stream API

SoftUART supports stream API (select.select, select.poll, etc.)

Work done

Based on work of:

I did a clean-up, fixed code formatting, tried to stay as close as possible to machine.UART implementation. Examples.

dmascord and others added 14 commits September 13, 2021 16:13
Ensuring that timing is correct (to allow for 115200 baud).
Allows to work with 1200 baud or lower.
Used provided tools/codeformat.py.
Merge branch 'master' into esp8266-softuart
Now multiple instances of SoftUART possible.

softuart.c: Removed os_printf calls (they reset my ESP).
softuart.c: Moved validation to machine_softuart.c (as in regular UART).
machine_softuart.c: Tx/Rx can now only be defined via constructor
                    (as uart_id regular UART).
machine_softuart.c: Unsupported parameters now raise ValueErrors.
esp8266/examples: Added 2 examples for SoftUART (read, write).
@peterhinch
Copy link
Contributor

This sounds very useful. Has it been tested with uasyncio StreamReader and StreamWriter?

@MrJake222
Copy link
Contributor Author

MrJake222 commented Sep 14, 2021

No.

EDIT
I'm not sure if merging it right now is a good idea. The performance of the library itself is, well, undefined. Write blocks for entire byte (~1 ms). Read blocks in interrupt also for a whole byte.

Unfortunately I can't find any reference for how to use timers (God I wish It'd be as simple as avr). Anyone can help with some documentation about timers? This claims to use best practices but writing still blocks.

EDIT 2
But I see implementations of SoftSPI and SoftI2C are doing exactly the same.

@mmmdwyer
Copy link

For what it is worth, I tested it out in a rather non-strenuous task: Decoding packets from IKEA's Vindriktning air quality sensor. It's a burst of about 120 bytes every 30s or so at 9600bps. It's been working great! My full project requires SoftI2C and MQTT running at the same time, but @MrJake222 's binary release doesn't include SoftI2C and it'll take a bit longer before I'm up to building my own. But I look forward to seeing if it still works when multiple timing-sensitive stacks are running.

@jimmo
Copy link
Member

jimmo commented Sep 20, 2021

Thanks @MrJake222 ! This is definitely something we see a few requests for, and glad to hear from @mmmdwyer that it's working well.

We probably need to clarify the license situation for the softuart code and ensure that we're compliant. My understanding is that it's almost exactly based on https://github.com/plieningerweb/esp8266-software-uart which is MIT, so at the very least we need to include attribution and copyright headers. It might also be possible to use it as a submodule instead?

@MrJake222
Copy link
Contributor Author

It might also be possible to use it as a submodule instead?

What do you mean? Like, making it separate from machine module?

@jimmo
Copy link
Member

jimmo commented Sep 21, 2021

It might also be possible to use it as a submodule instead?

What do you mean? Like, making it separate from machine module?

A git submodule. Like the other libraries in the lib directory.

@MrJake222
Copy link
Contributor Author

Ahh like that... But which repository should it be linked to? plieningerweb one? Or mine for example?

@jimmo
Copy link
Member

jimmo commented Sep 21, 2021

Ahh like that... But which repository should it be linked to? plieningerweb one? Or mine for example?

In general, if this were a third-party library, then it should point to the upstream repo of that library. I think that's what plieningerweb is (unless you've made modifications?).

That's why I was asking where the code comes from. I think in this case it's a small enough that the submodule is unnecessary, but we need to sort out exactly where this code comes from and what the license is.

@MrJake222
Copy link
Contributor Author

MrJake222 commented Sep 21, 2021

I've linked the forum link. There you can see that at least 3 people have attempted to port this. I've only adapted dmascord version (which I think based on p-v-o-s one, which is based on the original one). I'll ask him to clarify this.

EDIT
As far as I can see the code across the repos linked is almost identical to upstream repository (so the license is MIT) and I can't tell you about modifications made because I've only really touched the API part.

@dmascord
Copy link

Hi guys,

The code licensed is as per original MIT. It has been adapted from the code bases mentioned above, hardly any of the work is actually my own code, all I did was just making it work as a micropython module with a recent micropython build.

I find the implementation quite stable at a variety of baud rates. I found some ports worked fine at 9600 and others at 115200, so combining what I could had it working at most baud rates, even higher than 115200.

Cheers,

Damien

@MrJake222
Copy link
Contributor Author

Same here, I've edited API a little bit, changed code style and commit message style to be compatible with this repo and that's about it.

@beyonlo
Copy link

beyonlo commented Oct 17, 2021

Hello. Great works!

This PR will works with ESP32 too?

Of course that I see the PR name as target ESP8266 ("ports/esp8266:"), but as ESP32 is from Espressif as well and a bit similar, I would like if will works.

Thank you.

@dmascord
Copy link

I tested an old version of the code, and it worked fine on ESP32, so it should be fine, but can't guarantee.

@MrJake222
Copy link
Contributor Author

I've removed ESP32 code as I was unable to test it.

@michelhe
Copy link

michelhe commented Nov 29, 2021

Hey @MrJake222 @jimmo , what needs to be done next in order to get this into upstream? :)

Can confirm that its working great for me with 9600 baud on this little project:
https://github.com/michelhe/pimp-my-marax/

@AlanBell
Copy link

This doesn't appear to implement the UART.any() method which should return the number of characters that can be read without blocking (the size of what is in the buffer) or simply 1 or 0 depending on whether there is anything to read.

@tomklapka
Copy link

Is there any idea when this could be merged ? It's very demanded especially on 8266 devices.

@ywz978020607
Copy link

ywz978020607 commented Jun 28, 2022

Hello. Great works!

This PR will works with ESP32 too?

Of course that I see the PR name as target ESP8266 ("ports/esp8266:"), but as ESP32 is from Espressif as well and a bit similar, I would like if will works.

Thank you.

esp32software serial mr has been submitted, i have used for a long time, but till now to submit, you can refer this. #8829

@ThinkTransit
Copy link
Sponsor Contributor

I've removed ESP32 code as I was unable to test it.

Great work.

Do you still have a copy of the esp32 code, I would be more than happy to test it out as I really need this feature!

@MrJake222
Copy link
Contributor Author

See original post for the links. See other repos. There should be some esp32 code.

@ThinkTransit
Copy link
Sponsor Contributor

See original post for the links. See other repos. There should be some esp32 code.

Thanks for the pointer, unfortunately I have struggled to integrate any of the linked code. I'm using an ESP32-S3 which requires idf V4.4 and I think this might be causing the problem. I'm getting a cryptic error I haven't come across before:

Bootloader binary size 0x4910 bytes. 0x36f0 bytes (43%) free. [5/249] Generating ../../genhdr/qstr.i.last FAILED: genhdr/qstr.i.last /home/patrick/esp/micropython/ports/esp32/build/genhdr/qstr.i.last

@garudaonekh
Copy link

@MrJake222 I tested your repos and it seems to work well so far to communicate with SIM800L.

But I have an issue with RXBufffer. when I read all SMS from SIM, some data is missed so I think it's related with rxbuffer. But there's no option to set RXBuffer in your SoftUART.

@MrJake222
Copy link
Contributor Author

But there's no option to set RXBuffer in your SoftUART.

You mean it's size?

@robtinkers
Copy link

I documented the process of building my own firmware with SoftUART and micropython-lib here:

https://gist.github.com/robtinkers/b653b045e3425903eff681d278e3823c

I hope this helps someone out!

tannewt pushed a commit to tannewt/circuitpython that referenced this pull request Mar 24, 2023
…n-main

Translations update from Hosted Weblate
@projectgus
Copy link
Contributor

This is an automated heads-up that we've just merged a Pull Request
that removes the STATIC macro from MicroPython's C API.

See #13763

A search suggests this PR might apply the STATIC macro to some C code. If it
does, then next time you rebase the PR (or merge from master) then you should
please replace all the STATIC keywords with static.

Although this is an automated message, feel free to @-reply to me directly if
you have any questions about this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet