Motor2040 UART connection does not work

Hi Everyone,

I just got my Motor2040 and I am trying to get it to communicate with other Pico via UART. My Motor2040 board cannot send or listen to the message. Could anyone help me to see if my setting is wrong or if something is wrong with my Motor2040 board?

What I have tried so far:

My code worked when I tested Pico vs Pico. So I guess the issue is not here.
I tested the Motor 2040 RX and TX pin by connecting them to a button, one by one. Both of them can get responses from the button.
I flashed Pimoroni firmware, but it did not work. Then I flashed the official Pico firmware, it did not work either.
It sounds dumb but I tried to swap RX and TX wire, and it did not work.

My wire:

Motor2040 RX → Pico GPIO0
Motor2040 TX → Pico GPIO1
Motor2040 GND → Pico GND

My code:

Motor 2040:

from machine import Pin,UART
from time import sleep
uart = UART(0,9600)
count = 0
while True:
    message = "hello " + str(count)
    print(message)
    count = count + 1
    uart.write(bytes(message + '\n','utf-8'))
    sleep(1)

Pico:

from machine import Pin,UART
uart = UART(0,9600)
while True:
    if uart.any():
        command = uart.read().decode('utf-8')
        print(command)

Thank you!

Edit: The answer is I need to specify the PIN used for TX and RX on Motor 2040

uart = UART(0,9600, tx=Pin(16), rx=Pin(17))

If I read the schematic correctly, the motor 2040 uses GPIO 16 and 17 for UART.
GPIO 16 TX and GPIO 17 RX. Not 0 and 1
motor2040.sch (shopify.com)

Raspberry Pi Pico GPIO Pinout

Hi @alphanumeric ,

You are correct that on Motor2040, the GPIOs are 16 and 17. However, the Pico uses GPIO 0 and 1 as TX and RX. So my wiring is still correct, isn’t it?

I just tried to use Pico GPIO 16 and 17, it did not work either

Motor2040 RX → Pico GPIO0
Motor2040 TX → Pico GPIO1
Motor2040 GND → Pico GND

Best

Your wiring is correct. But I think you need to set up the use of those pins in your motor 2040 code.

Hi @alphanumeric ,

Could you give me more information on how to do it correctly? What lines in my code above need to be corrected?

The thing is, I tested my code using Pico vs Pico and it worked. Also, I don’t think I need to specify any GPIO PIN when using UART. All I need to check is channel 0 or channel 1. In this case, Motor 2040 only has 1 channel UART0.

Best.

Hi @alphanumeric,

Thank you for your help. It works now. As you said, I need to specify the pins in

uart = UART(0,9600, tx=Pin(16), rx=Pin(17))

I think the problem is when I used Pico, I only used 3 PINs (TX, RX, GND), and the other UART PINs were free. So the Pico knew where to read/send data. But in Motor 2040, the other UART PINs are used for controlling motors or other things, so the board is confused. Hope someone from Pimoroni team could confirm this.

Again, thanks for your help.

Best

1 Like

I “think” the way it works is, if you don’t specify any pins, it defaults to using 0 and 1.
You were wired up to 16 and 17, but software wise, it was trying to use 0 and 1.

Manually pointing it to the correct pins fixed it. That was good sleuthing figuring out what line of code to edit. I was thinking it was that line, based on the following

i2c has a similar issue, depending on what Pack etc your using.

from pimoroni_i2c import PimoroniI2C

PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5}
PINS_PICO_EXPLORER = {"sda": 20, "scl": 21}

i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN)

I use i2c = PimoroniI2C(sda=(4), scl=(5)) in my code as those are the pins I most often use.

So far I haven’t done anything UART wise on a PICO.

I see. It is interesting to know about specifying PINs for i2c. I have never tried to connect more than 1 i2c device at a time.

However, I dont think there are default UART PINs. I did try to connect Pico 0, 1 to another Pico 17, 16. And my code worked without specifying PINs. That is why I thought something wrong with my Motor 2040.

You can have multiple i2c devices on the same bus, as long as no two devices have the same address. I have done it many many times on a PICO and Pi. Light sensors, environmental sensors, Real Time Clock, etc. It’s why some Pimoroni breakouts have an address select jumper on the back. It lets you use two of that breakout at the same time.
On a Pi your limited to the default pins for i2c1. On a PICO, i2c0 can be set to several different sets of pins. same deal for SPI and UART.

SPI is the same deal, as long as each device uses a different chip select pin. I’ve run two Display packs on a PICO with special wiring and special code. And three displays on a Pi on SPI 1

Just haven’t dabbled in UART as of yet.

EDIT: I’ve been at it a while and still get very confused by how some of it works, Pi and PICO.

1 Like

I am trying to do something similar. Im trying to get the Inventor2040w to connect to wifi and get mqtt msgs to then drive the Motor2040
The inventor does everything correctly, but the Motor2040 using UART 0 on pins 16,17 causes the MOTOR A to start running.
uart = UART(0,9600, tx=Pin(16), rx=Pin(17))

Does this mean that there is no way to use a UART the same time as using the Motor2040 to drive MotorA (as well as the other 3) ?

Basically is there a way to get the right side of the connection to work?
Wifi-Mqtt msg->Inventor2040W → UART connected to UART->Motor2040->Drive 4 Motors with Encoders

I have a similar setup and it works perfectly. I use the bluetooth HC-06 to connect to Motor2040 via UART pins to control my car using my phone. I also use the library from Pimoroni to control the motor.

I think you should check your code. Make sure the uart is declared only once and with the correct pins. I remember when I did not declare the uart pins, the light of motor A was always turned on. And with the correct pins declared, the light of motor A was only turned on when it moved.

Ive simplified this the most that i can. This is a test code, that will cause the MotorA to run nonstop.
from machine import UART,Pin
from time import sleep

uart = UART(0,9600, tx=Pin(16), rx=Pin(17))

while True:
sleep(2)
uart.write(‘this is motor2040’)
sleep(0.1)
str0=uart.read(22)
print("uart0: ",str(str0))

Either i am not getting the pins right or there is something unusual about my board.
Could someone please try this with a motor plugged into MotorA. Also what is the purpose of uart.init()

Could you share the code that you use to read from the HC-06?

Could you try this? Just a simple way to print out all message from UART.

from machine import Pin,UART

uart = UART(0,9600, tx=Pin(16), rx=Pin(17))
            
while True:
    if uart.any():
        command = uart.readline()
        print(command)

Thanks, the answer is pins 16,17 that got everything to work on the motor2040 side
And I also found that 0,1 work with the inventor on Uart 0
So now i have the inventor connected to wifi and it can relay motor commands to the motor240. Between the 2 boards, lots of things to enhance a robot with small footprint
The inventor brings much more than wifi. I now have servos, audio, neopixels,ADC and I2c

2 Likes

This is really good news. I was wanting a way to do/try this with an Interstate 75.