UART and Raspberry Pi Pico (RP2040)

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
Cristian_Padova
Posts: 1
Joined: Wed Jan 27, 2021 4:45 pm

UART and Raspberry Pi Pico (RP2040)

Post by Cristian_Padova » Wed Jan 27, 2021 4:54 pm

Hi, how can I set the timeout in the UART connection (MicroPython v1.13-290-g556ae7914 on 2021-01-21)?

my code:

Code: Select all

comm = machine.UART(1,9600)
comm.init(9600, bits=8, parity=None, stop=1, timeout=2000)

But:
Traceback (most recent call last):
File "<stdin>", line 49, in <module>
AttributeError: 'UART' object has no attribute 'init'

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

Re: UART and Raspberry Pi Pico (RP2040)

Post by Roberthh » Wed Jan 27, 2021 5:06 pm

There is not init() method in the source code. You have to set the parameters in the constructor call. Which is ok, since constructor and init() are a common source of confusion.

Besides that, timeout seems not to be included in the parameters.

Vaibhavik
Posts: 3
Joined: Fri Feb 19, 2021 5:11 am

Re: UART and Raspberry Pi Pico (RP2040)

Post by Vaibhavik » Fri Feb 19, 2021 5:48 am

Hello sir, Encountered the same problem with the UART communication with the sensor.

Below is the code :
sensor code
import mhz14a
from time import sleep_ms

CO2_Sensor = mhz14a.MHZ14A(uartNum=1, rxPin=18, txPin=19)
attempts = 0
ppm=0
while attempts < 3:
ppm = CO2Sensor.readCO2()
if ppm > 0:
print("CO2 value is: " + str(ppm) + " ppm")
break
else:
sleep_ms(500)


sensor library

from machine import UART
from time import sleep_ms, ticks_ms, ticks_diff, sleep_us

class MHZ14A():
packet = [0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79]

def __init__(self, uartNum=1, txPin=18, rxPin=19):
"""initializes communication with CO2 sensor"""
self.uart = UART(uartNum, 9600)
self.uart.init(parity=None, stop=1, bits=8, rx=rxPin, tx=txPin)
# wait a minimum amount of time before trying to read the sensor
sleep_ms(250)

def readCO2(self):
"""reads CO2 concentration from MH-Z14a sensors and returns ppm value"""
packet = [0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79]
try:
# flush serial
while self.uart.any() > 0:
self.uart.read(self.uart.any())
self.uart.write(bytearray(packet))
start = ticks_ms()
while self.uart.any() < 9:
if ticks_diff(ticks_ms(), start) > 5000:
print("Timeout reading CO2 sensor")
return -4
res = self.uart.read(9)
if res is not None and len(res)==9:
checksum = 0xff & (~(res[1]+res[2]+res[3]+res[4]+res[5]+res[6]+res[7])+1)
if res[8] == checksum:
res = bytearray(res)
ppm = (res[2]<<8)|res[3]
return ppm
else:
print("CO2 sensor reading checksum failed. Result was: ", res)
return -1
else:
print("CO2 sensor did not return data")
return -2
except Exception as e:
print("Exception reading sensor:")
print(str(e))
return -3

File "<stdin>", line 4, in <module>
File "mhz14a.py", line 10, in __init__
AttributeError: 'UART' object has no attribute 'init'

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

Re: UART and Raspberry Pi Pico (RP2040)

Post by Roberthh » Fri Feb 19, 2021 7:07 am

As above, the init() method was dropped in the rp2 port. Instead of:

self.uart = UART(uartNum, 9600)
self.uart.init(parity=None, stop=1, bits=8, rx=rxPin, tx=txPin)

you can write in all ports:

self.uart = UART(uartNum, 9600, parity=None, stop=1, bits=8, rx=rxPin, tx=txPin)

That's because init is performed with the instantiation call.

Vaibhavik
Posts: 3
Joined: Fri Feb 19, 2021 5:11 am

Re: UART and Raspberry Pi Pico (RP2040)

Post by Vaibhavik » Fri Feb 19, 2021 8:40 am

Hello sir , Thankyou for your prompt reply , being a complete newbee in micropython , getting another error in the following code , request you to please have a glimpse at the same.

Thanks again!


import mhz14a
from machine import UART
from time import sleep_ms
CO2Sensor = UART(uartNum=1,rxPin=19, txPin=18,)
attempts = 0
ppm=0
while attempts < 3:
ppm = CO2Sensor.readCO2()
if ppm > 0:
print("CO2 value is: " + str(ppm) + " ppm")
break
else:
sleep_ms(500)

File "<stdin>", line 4, in <module>
TypeError: 'id' argument required

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

Re: UART and Raspberry Pi Pico (RP2040)

Post by Roberthh » Fri Feb 19, 2021 9:47 am

This line is wrong:

CO2Sensor = UART(uartNum=1,rxPin=19, txPin=18,)

It should be
from machine import UART, Pin
CO2Sensor = UART(1, rx=Pin(19), tx=Pin(18))

Vaibhavik
Posts: 3
Joined: Fri Feb 19, 2021 5:11 am

Re: UART and Raspberry Pi Pico (RP2040)

Post by Vaibhavik » Tue Feb 23, 2021 7:29 am

Still not able to get CO2 readings on the terminal sir. Would you please review the code and the library?


Code: Select all

import mhz14a
from machine import UART,Pin
from time import sleep_ms
CO2Sensor = UART(1,tx=Pin(18),rx=Pin(19))
attempts = 0
ppm=0
while attempts < 3:
    ppm = CO2Sensor.readCO2()
    if ppm > 0:
        print("CO2 value is: " + str(ppm) + " ppm")
        break
    else:
        sleep_ms(500)



from machine import UART , Pin
from time import sleep_ms, ticks_ms, ticks_diff, sleep_us

class MHZ14A():
    packet = [0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79]

    def __init__(self, uartNum=1, tx=Pin(18), rx=Pin(19)):
        """initializes communication with CO2 sensor"""
        self.uart = UART(1, 9600, parity=None, stop=1, bits=8, rx=Pin(19), tx=Pin(18))
        # wait a minimum amount of time before trying to read the sensor
        sleep_ms(250)

    def readCO2(self):
        """reads CO2 concentration from MH-Z14a sensors and returns ppm value"""
        packet = [0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79]
        try:
            # flush serial
            while self.uart.any() > 0:
                self.uart.read(self.uart.any())
            self.uart.write(bytearray(packet))
            start = ticks_ms()
            while self.uart.any() < 9:
                if ticks_diff(ticks_ms(), start) > 5000:
                    print("Timeout reading CO2 sensor")
                    return -4
            res = self.uart.read(9)
            if res is not None and len(res)==9:
                checksum = 0xff & (~(res[1]+res[2]+res[3]+res[4]+res[5]+res[6]+res[7])+1)
                if res[8] == checksum:
                    res = bytearray(res)
                    ppm = (res[2]<<8)|res[3]
                    return ppm
                else:
                    print("CO2 sensor reading checksum failed. Result was: ", res)
                    return -1
            else:
                print("CO2 sensor did not return data")
                return -2
        except Exception as e:
            print("Exception reading sensor:")
            print(str(e))
            return -3
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
ValueError: bad TX pin

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

Re: UART and Raspberry Pi Pico (RP2040)

Post by Roberthh » Tue Feb 23, 2021 7:35 am

Looking again at the Pinout, th epins for uart are wrong. For UART1 you have to use pins 8 (tx) and 9 (rx) or pin 4(tx) and pin 5(rx)

Post Reply