Serial connection between MPUs

Discussion in 'UDOO KEY' started by JMuller, Mar 5, 2023.

  1. JMuller

    JMuller UDOOer

    Joined:
    Feb 15, 2023
    Messages:
    5
    Likes Received:
    2
    I wanted to use standard serial communication to send a message from the ESP32
    to the 2040 to control the on-board LED.
    Several problems with UART ports and setup were resolved. I found that I cound not
    test the signals between the two devices since they are not exposed in hardware (
    IO 0 & 1 on the 2040 are not connected to the output pins like on the standard 2040 and
    on the ESP32 IO 19 & 22 connections are not provided).

    I also found the Udoo Key's MCU connections page incorrectly states "Keep in mind that RP GPIO0 is
    connected to ESP IO19 and, vice versa, GPIO1 is connected with IO22"
    .

    In reality the ESP32 IO 19 connects with the 2040 IO 1 and ESP 22 to IO 0. Standard TX to RX and
    RX to TX connections are used not as stated in the documentation.

    Here are the two programs that I wrote:
    ESP32 code:
    '''
    test UART connection between P2040 and
    and ESP32 for Udoo Key

    Send UART based command to RP2040 to flash its
    LED

    '''

    from machine import Pin, UART
    import time

    to2040 = 19
    from2040 = 22


    LEDy = Pin(33, Pin.OUT)
    LEDb = Pin(32, Pin.OUT)

    # NOTE you must use UART port 1, port 0 is REPL & 2 is external connector
    uart1 = UART(1, baudrate=9600, tx=to2040, rx=from2040)

    while 1:

    LEDy.value(1)
    uart1.write("1\n")
    time.sleep(.25)
    LEDy.value(0)
    uart1.write("0\n")
    time.sleep(.25)

    RP2040 code:
    '''
    test UART connection between P2040 and
    and ESP32 for Udoo Key

    Revieve command over UART to flash the RP2040
    internal LED

    '''

    from machine import Pin, UART
    import time

    LEDg = Pin(25, Pin.OUT)

    toESP32 = 0
    fromESP32 = 1

    # NOTE must use UART port 0, only that port connects with IO 0 & 1
    # also note the difference between the need to pass a Pin object vs
    # just the IO number
    uart0 = UART(0, baudrate=9600, tx=Pin(toESP32), rx=Pin(fromESP32))


    while 1:
    inp = uart0.readline()
    if inp != None:

    if inp == b'0':
    LEDg.value(0)
    elif inp == b'1':
    LEDg.value(1)
    else:
    print(inp)


    Instructions:
    Load Micropython on both devices. You may use Thony to load python on the rp2040 but for the ESP32
    download esp32-idf3-20210202-v1.14.bin from https://micropython.org/download/esp32/
    Use the estool.py to erase the 32's memory :
    esptool.py --chip esp32 --port COM9 erase_flash

    then flash Micropython to the ESP32:
    esptool.py --chip esp32 --port COM9 --baud 460800 write_flash -z 0x1000 esp32-idf3-20210202-v1.14.bin

    Verify you get the REPL on both MPUs (you may have to remove power before switching between MPUs.)

    Now load the first program on the ESP32 using Thony naming it main.py on that device.

    On the rp2040 use Thony to load the second program, then press the reset on the ESP32 to run the main.py code. The two LEDs should flash in Sync.
     
    Opi-Van-Kristovi likes this.
  2. Ramesh

    Ramesh New Member

    Joined:
    Mar 22, 2023
    Messages:
    1
    Likes Received:
    0
  3. Rebel_88

    Rebel_88 New Member

    Joined:
    May 1, 2023
    Messages:
    1
    Likes Received:
    0
    hello JMuller and all,
    I'm quite new to te rpi2040 world so I have used your rpi code to test the connection between esp32 and rpi, thank you very much.
    I would like to add a second serial transmission on USB side to show on PC screen that the LED was turned ON or OFF.
    I'm trying with print function but I can only write one Byte per transmission.
    I was not able to find a tutorial or a manual to understand this kind of serial transmission. could you please hepl me?
    Thank you.

    I'm using VSCode with espressif extention to build esp32 project in c/ c++ and Thonny to interface with rpi.
     
  4. Lealon

    Lealon New Member

    Joined:
    Apr 19, 2023
    Messages:
    1
    Likes Received:
    0
    I was not able to get this code working on the RP2040 side as published without adding a delay, approximately 3- Msec, in the while 1 loop. I added a sync output on the esp32 and RP2 side to measure the time difference between the LEDs on eaxh side. It vairied quite a bit from 8 msec to 25 msec. I finally added "timout=500" to the uart instantiation. and solved all the problems.
    Code:
    syncPin = Pin(3, Pin.OUT)
    
    # NOTE must use UART port 0, only that port connects with IO 0 & 1
    # also note the difference between the need to pass a Pin object vs
    # just the IO number
    uart0 = UART(0, baudrate=9600, tx=Pin(toESP32), rx=Pin(fromESP32),timeout=500)
    
    while True:
        inp = uart0.readline()
        #print(inp)
        if inp is not None:
            if inp == b'1\n':
                #LEDg.value(0)
                syncPin.value(1)
                LEDg.on()
                #print("  ONE1")
            elif inp == b'0\n':
                syncPin.value(0)
                LEDg.off()
                #print(" zero0")
        else:
            pass
            #time.sleep(0.03)
    
     
  5. Opi-Van-Kristovi

    Opi-Van-Kristovi New Member

    Joined:
    Aug 7, 2023
    Messages:
    7
    Likes Received:
    2
    I couldn't get this to work with Micropython, since I'm more familiar with Arduino IDE I tried to rewrite this example. And after many hours of cursing myself a ticket to hell, I finally succeeded! :)
    So here is the code in case someone is interested:
    Code for ESP32 (master):
    Code:
    const int rxPin = 22;    // UART0 rx-pin (connected to RP2040 tx-Pin)
    const int txPin = 19;    // UART0 tx-pin (connected to RP2040 rx-Pin)
    const int ledPin =  32;  //Blue on-board LED pin (yellow is pin 33)
    
    void setup() {
      //Setup the serial channel to RP2040 (Serial1 is UART0)
      //(Baudrate, Serial_mode, rx-pin, tx-pin)
      Serial1.begin(9600, SERIAL_8N1, rxPin, txPin);
      //Setup serial channel for monitor on PC via USB
      Serial.begin(115200);
      pinMode(ledPin, OUTPUT);
      Serial.println("Serial connections started");
    }
    
    void loop() {
      //Send serial command to RP2040 while turning the LED on/off
      Serial1.print(0);
      digitalWrite(ledPin, LOW);
      delay(500);
      Serial1.print(1);
      digitalWrite(ledPin, HIGH);
      delay(500);
    }
    Code for RP2040 (slave):
    Code:
    const int rxPin = 1;    //UART rx-pin (connected to ESP32 tx-pin)
    const int txPin = 0;    //UART tx-pin (connected to ESP32 rx-pin)
    const int ledPin =  25; //Green on-boar LED pin
    
    void setup() {
      //Configure the pins for UART1
      Serial1.setRX(rxPin);
      Serial1.setTX(txPin);
      //Start serial connections
      Serial1.begin(9600);
      Serial.begin(115200);
      pinMode(ledPin, OUTPUT);
      //Print to serial monitor via USB
      Serial.println("Serial connections started");
    }
    
    void loop() {
      if (Serial1.available()) {        //Check for available serial data
        char number = Serial1.read();   //read serial data into char variable
        //Turn on/off LED based upon received input
        if (number == '0'){
          digitalWrite(ledPin, LOW);
        }
        else if (number == '1'){
          digitalWrite(ledPin, HIGH);
        }
        //Notify and print received message to debug monitor if command is not recognized
        else {
          Serial.print("Unknown serial command: ");
          Serial.println(number);
        }
      }
    }
    After flashing these sketches to the mcu's and resetting them, the Blue and green LED should blink in sync.
    Make sure to disconnect the bootmode jumper from the ESP32 after flashing, otherwise it won't run.
    Also, before compiling the code for each mcu, make sure you have selected the right board in the "Tools" menu in your ArduinoIDE and check if the right COM port is connected and selected before uploading the code.
     

Share This Page