Four Serial UARTs and Programming Port - Portenta H7 and Breakout Board

This is for those that are having a hard time getting started with the serial ports and UARTs:

(Code below can test passing data between the ports at 1M baud)

I bought the Portenta-H7 and the Portenta-Breakout-Board hoping to be able to use four fast serial ports while also using the programming port separately. The H7 offers that.

My thanks to Jeremy Ellis' github information.

Most Excellent Portenta Dev URL

Code Below Modified From This

Modified code (I'm a little messy, but it works):

/* Portenta Serial UART

* Code modified from:
Thank you, Jeremy Ellis
https://github.com/hpssjellis/portenta-pro-community-solutions/blob/main/examples/dot1-portentaH7-examples/dot19-cores-uart-serial-com/dot198-uart-serialtransfer/dot198-uart-serialtransfer.ino

* Code modified from:
Thank you, Jeremy Ellis
//This, go there... ---> https://github.com/hpssjellis/portenta-pro-community-solutions

* ================================================================================
* 
* * UART Information for the PortentaH7 
* 
* UART myUART0(PA_0,  PI_9,  NC, NC);  // TX, RX, RTS, CTC  NOTE: NC means not connected
* UART myUART1(PA_9,  PA_10, NC, NC);   // pin D14 TX, pin D13 RX same as pre-defined Serial1
* UART myUART2(PG_14, PG_9,  NC, NC);
* UART myUART3(PJ_8,  PJ_9,  NC, NC);
* UART myUART6(PC_6,  PC_7, NC, NC);    // pin D5 TX, pin D4 RX
* UART myUART8(NC,    PA_8, NC, NC);    // pin D6 RX only can receive
* 
*/

//#include <Arduino.h>
//#include <Arduino_PortentaBreakout.h>
//#include "SerialTransfer.h"

//////////////////// Start All Core M7 Programing /////////////////////
#ifdef CORE_CM7 


//--------------------------------------------- NOTE ------------------------------------------------------
// I used the Portenta Breakout Board and soldered some jumpers on the four UART breakouts. 
// Everything worked.
//
// UART Test1 is a bidirectional test of UART0 and UART1
// UART Test2 is a bidirectional test of UART2 and UART3


//--assign Serial UART
//https://github.com/hpssjellis/portenta-pro-community-solutions <--- Most excellent URL
//Thank you, Jeremy Ellis.
//UART myUART0(PA_0,  PI_9,  NC, NC); // put this back to test with with myUART1 on M4 Test1 - worked 20230218  
UART myUART2(PG_14, PG_9,  NC, NC); // put this back to test with with myUART3 on M4 Test2 - worked 20230218  

int i=65; //(char)"A";

void setup() { 
  pinMode(LEDR, OUTPUT);   // LEDB = blue, LEDG or LED_BUILTIN = green, LEDR = red 
   bootM4();    
   Serial.begin(2000000);

   //myUART0.begin(1000000);   
   //myUART0.setTimeout(10);
   myUART2.begin(1000000);   
   myUART2.setTimeout(10);
}

void loop() {
  if (i > 90){i = 65;}           // ascii 65 =  letter A,   ascii 90 = letter Z
  //myUART0.write((char)i++);  // ascii code for numbers A to Z
  myUART2.write((char)i++);  // ascii code for numbers A to Z
  
  //if (myUART0.available()) {
  if (myUART2.available()) {
    digitalWrite(LEDR, !digitalRead(LEDR));     // switch on / off
    do { // Read all to clear buffer
      //Serial.write(myUART0.read());    // Read it and send it out Serial (USB)
      Serial.write(myUART2.read());    // Read it and send it out Serial (USB)
    //} while (myUART0.available());
    } while (myUART2.available());
  }
  Serial.write("\n");    // Read it and send it out Serial (USB)
  delay(500); 
}

#endif


//////////////////// End All Core M7 Programing /////////////////////

//////////////////// Start All Core M4 Programing /////////////////////

#ifdef CORE_CM4 

int  myCount=48;  //48 = ascii 0,    58 ascii 9
char c;

//--assign Serial UART
//https://github.com/hpssjellis/portenta-pro-community-solutions <--- Most excellent URL
//Thank you, Jeremy Ellis.
//UART myUART1(PA_9,  PA_10, NC, NC); // put this back to test with with myUART0 on M7 Test1 - worked 20230218
UART myUART3(PJ_8,  PJ_9,  NC, NC); // put this back to test with with myUART2 on M7 Test2 - worked 20230218  

void setup() { 
  pinMode(LEDB, OUTPUT);   // LEDB = blue, LEDG or LED_BUILTIN = green, LEDR = red 
  // Serial.begin(115200);  // no serial monitor on M4 core without RPC

  //Most excellent URL ---> https://github.com/hpssjellis/portenta-pro-community-solutions
  //myUART1.begin(1000000);   
  //myUART1.setTimeout(10);
  myUART3.begin(1000000);   
  myUART3.setTimeout(10);
}

void loop() {

  if (myCount >= 58){myCount = 48;}             // ascii 48 =  number 0,   ascii 58 = number 9
  char x = (char)myCount++;
  //myUART1.write(x); 
  //myUART1.write(c); 
  myUART3.write(x); 
  myUART3.write(c); 

  //if (myUART1.available()) {
  if (myUART3.available()) {
    digitalWrite(LEDB, !digitalRead(LEDB));     // switch on / off
    do { // Read all to clear buffer
      //c = myUART1.read(); // c
      c = myUART3.read(); // c
    //} while (myUART1.available());
    } while (myUART3.available());
  }

  delay(500); 
}

#endif

//////////////////// End All Core M4 Programing /////////////////////


1 Like

Working with the portenta, building off of Dot42_UART_M4_to_m7

Building off of the above conversation, I have an interest in passing 100 variables from the M4 core to the M7 core.

In my testing, It takes about 2.5 seconds between each set of data being printed on the screen (Arduino IDE 2.3.2)

These variables for now have been defined in an array and stored as type float. The float type is important considering the type of information I ultimately wish to send from the M4 to the M7 core.

Making a few assumptions that each byte is sent with a start and stop bit.

If I increase the baud rate of the UART, no data is displayed in the serial output.

Question 1: Why does it take 2.5 seconds vs the calculated nearly 5 seconds
Question 2: Why does increasing the baud rate disrupt data being received ?

/* 

Portenta Serial UART
similar code using Serial1  is at  a-i-core-serial-uart-tx-rx.ino
// Need to connect pin TX D14 and RX D13 together.
// Passing data between the cores both using UART1 works for simple transfers but does not work for 
// complex transfers, which need UART0 and UART1 which needs the breakout board.

UART myUART0(PA_0,  PI_9,  NC, NC); //TX, RX, RTS, CTS  NOTE: NC means not connected
UART myUART1(PA_9,  PA_10, NC, NC);
UART myUART2(PG_14, PG_9,  NC, NC);
UART myUART3(PJ_8,  PJ_9,  NC, NC);


   //  or
   // Serial
   // Serial0
   // Serial1   is myUART1
   // Serial2
   // Serial3

*/
#include <Arduino.h>

//////////////////// Start All Core M7 Programing /////////////////////
#ifdef CORE_CM7 

UART myUART1(PA_9,  PA_10, NC, NC);

float receivedArray[100];  // Buffer to store received floats
unsigned int byteIndex = 0;  // Index to keep track of received bytes
unsigned int floatIndex = 0;  // Index to keep track of the received floats
bool receiving = false;  // Flag to track if currently receiving data
byte tempBuffer[sizeof(float)];


void setup() { 
   bootM4();    
   Serial.begin(115200);
   myUART1.begin(9600);   

   while(!myUART1);
   while(!Serial);   // Wait for serial port to connect
   Serial.println("Portenta M7 is ready");
}

void loop() {

  while (myUART1.available()) {
        char receivedChar = myUART1.read();

        if (receivedChar == '<') {
            receiving = true;
            byteIndex = 0;
            floatIndex = 0;
        } else if (receivedChar == '>' && receiving) {
            if (floatIndex == 100) {
                Serial.println("Received 100 floats successfully!");
                for (int i = 0; i < 100; i++) {
                    Serial.print("Float ");
                    Serial.print(i);
                    Serial.print(": ");
                    Serial.println(receivedArray[i], 4);
                }
            }
            receiving = false;
        } else if (receiving) {
            tempBuffer[byteIndex++] = receivedChar;
            if (byteIndex == sizeof(float)) {
                if (floatIndex < 100) {
                    memcpy(&receivedArray[floatIndex++], tempBuffer, sizeof(float));
                    byteIndex = 0;
                }
            }
        }
    }
}

#endif


//////////////////// End All Core M7 Programing /////////////////////

//////////////////// Start All Core M4 Programing /////////////////////

#ifdef CORE_CM4 

UART myUART1(PA_9,  PA_10, NC, NC);

float floatArray[100];  // Array of 100 float variables


void setup() { 

    pinMode(LEDB, OUTPUT);   // LEDB = blue, LEDG or LED_BUILTIN = green, LEDR = red 
   // Serial.begin(115200);  // no serial monitor on M4 core without RPC
    myUART1.begin(9600);   

  
    // Initialize the float array
    for (int i = 0; i < 100; i++) {
        floatArray[i] = 1234 + i;  // Sample initialization
    }

}

void loop() {


    myUART1.write('<');  // Start marker
    for (int i = 0; i < 100; i++) {
        byte *byteArray = (byte *)&floatArray[i];
        for (int j = 0; j < sizeof(float); j++) {
            myUART1.write(byteArray[j]);  // Send each byte of the float
        }
    }
    myUART1.write('>');  // End marker

    digitalWrite(LEDB, !digitalRead(LEDB));  // Toggle LED to indicate transmission
    delay(250);  // Send every 500 ms    
}
#endif

//////////////////// End All Core M4 Programing /////////////////////

Looking forward to input on how I can move this data back and forth more quickly as well as learning more about the portenta.

I found that I couldn't move data fast enough over serial and found out how to transfer data using the shared memory:

From that link I posted posted in my previous response (above), I was able to make a program work with the memory sharing. Here's the thread where I mentioned getting the memory sharing working. Has example code down at the end.

I guess I kind of highjacked that thread. Oops.