I wanted to use the UART as well to get some information from a GPS module. But
is it even possible to use UART for communicating with another module? UART(1) does not make any sense, so I can only use UART(0). The problem with UART(0) is that when I connect the GPS module, it will simply print all the data to the console. How can I use the read method instead?
That's what I get on WebREPL (I don't even have to create the UART object); PuTTy not working with UART in use:
- gps.png (45.26 KiB) Viewed 9708 times
Update: Couldn't get it work so I used
software serial provided by some really nice guy (watch
here!). If you want to use SoftUART have a look at
this firmware modification, which includes a SoftUART class in the machine module. If you don't want to build the firmware yourself, here is a compiled version that works for me:
firmware-softuart.bin
Code: Select all
import machine
su = machine.SoftUART(machine.Pin(13), machine.Pin(12), baudrate=9600) # first is TX, second RX
while True:
print(su.readline()) # usage similar to machine.UART
Update 2:
Got UART0 working now. You cannot use PuTTy/ampy when using UART0 for another device. You will first have to setup everything (wlan and WebREPL if required later). You can put your code (where you read from uart0) in main.py or in another file (that has to be run from WebREPL then), but you cannot use the standard output (I think). That's why I connected a small oled display for output. My working test code (using a NEO 6M GSM module connected via RX/TX and a 128x64 OLED display (you will need ssd1306.py from Adafruit as well) connect via SCL/SDA):
Code: Select all
# main.py
import machine, utime
import ssd1306
class Display:
def __init__(self, width=128, height=64, scl=5, sda=4):
self._width = width
self._height = height
self.oled = ssd1306.SSD1306_I2C(self._width, self._height,
machine.I2C(-1, machine.Pin(scl), machine.Pin(sda)))
self.clear()
def clear(self):
self.oled.fill(0)
self.oled.show()
def println(self, msg: str):
self.oled.scroll(0, -8)
self.oled.framebuf.fill_rect(0, self._height-8, self._width, 8, 0) # clear last line
self.oled.text(msg, 0, self._height-8)
self.oled.show()
class GPSModule:
def __init__(self):
self.module = machine.UART(0, 9600)
self.module.init(9600)
def next(self):
ret = self.module.read(1)#.decode()
return b'\x00' if ret is None else ret
def main():
display = Display()
display.println("#### START! ####")
gps = GPSModule()
while True:
try:
display.println(str(ord(gps.next())))
except Exception as ex:
display.println("ERR: %s" % repr(ex))
utime.sleep(1)
display.println(" %s" % ex.args[0])
break
except KeyboardInterrupt:
display.println("ERR: INTERRUPTED")
break
except:
display.println("ERR!")
break
if __name__ == "__main__":
main()
Update 3: Another problem happens when the module connected on UART0 sends b'\x03' which means
CTRL+C, you will get an
KeyboardInterrupt then. I saw that there may be a function to disable keyboard interrupts (micropython.kbd_intr(-1)), but in my version (1.8.6) I had to disable keyboard interrupts manually (see
here). My module is able to send 0x03 without any interrupts. And the best thing is: You will still be able to connect via WebREPL (if activated before using import webrepl_setup) and you'll see the keys pressed immediately on the screen (but not in WebREPL). You're also able to send an interrupt (CTRL+C) there which will still cause an KeyboardInterrupt.