Arduino Portenta H7 Part 5: UART

Arduino PRO Portenta H7
Arduino PRO Portenta H7

In embedded systems, industrial controllers rely on serial communications to share data.  In this industry-focused project, we will explore ways to configure this style of interface using the Arduino Pro Portenta H7 and two of its many built-in universal asyn­chronous receiver-transmitters (UARTs).

If you’re using the Portenta H7 for the first time, consider visiting my earlier projects or Arduino’s official sites, which explain how to get started easily.

Notice of Non-Affiliation and Disclaimer: As of the publication date, we are not affiliated with, associated with, authorized with, endorsed by, compensated by, or in any way officially connected with Arduino, Arm Holdings, RealTerm or Microsoft, or their owners, subsidiaries or affiliates.

The names Arduino, Portenta H7, Arm, Cortex, Core M7, Core M4, Microsoft, as well as related names, marks, emblems, and images are trademarks of their respective owners.

External Links: Links to external web pages have been provided as a convenience and for informational purposes only. Unboxing Tomorrow and Voxidyne Media bear no responsibility for the accuracy, legality or content of the external site or for that of subsequent links. Contact the external site for answers to questions regarding its content.

To recap, the Portena H7 is Arduino’s Internet of Things (IoT) and Industrial IoT platform.  With one Arm Cortex Core M7 (at 480MHz) and an Arm Cortex Core M4 core (at 240 MHz), it is able to achieve true hardware parallelism.  The M7 core is the main core, and the M4 will not operate unless the M7 allows it.  This lets the cores specialize in different tasks (a computing technique I wager will dominate the coming decade).

Besides being a relatively simple and popular format, the UART is prioritized for todays project for three main reasons:

  1. UARTs can operate command line interfaces (CLIs) digital products you’re developing.
  2. Linux can be operated over a serial interface.
  3. UARTs are common in industrial settings, especially wherever Modbus Remote Terminal Unit (Modbus RTU) is used .  Industrial controllers very often support RS-232 or RS-485 in some fashion, which are UART-driven interfaces.

Objectives

Today, we’ll transmit and receive UART messages using the input/output (I/O) pins of the Portena H7 itself.

  1. Test the UART to USB cable using the program: RealTerm
  2. Transmit message from the M7 core
  3. Transmit message from the M4 core
  4. Understand how the M7 and M4 cores use the Serial library differently
Figure 1: System-Level Diagram of Today’s Test

Material Requirements

  • Arduino Portenta H7
  • USB-C Cable
  • USB-Serial adapter
  • Used here: 3.3-volt USB to UART cable
  • Breakaway headers or 80-pin high density connectors
  • Circuit board or solderless breadboard
  • Recommended: Anti-Static Workstation
  • Optional: Oscilloscope
Figure 2: Schematic for Today’s UART Test

Software Requirements

  • Arduino IDE version 1.8.10 or later (version 1.8.13 used here)
  • Have Arduino Mbed OS Portenta Boards installed (version 2.0.0 was used here)
  • Virtual Terminal Software (RealTerm v 2.0.0.70 was used here)

Notice: Use 3.3-volt Logic!

Your Arduino Portenta H7 is a 3.3-volt device.  With the exception of USB, any interface you wire to it should also use 3.3 volt logic or you risk damaging your Portenta H7.

Standard 5-volt logic (TTL), RS-232, RS-422, RS-485 or other voltage formats will need to pass through a converter before it can work with your Portenta.­­  And I will have a few suggestions at the end of the video.

Circuit Layout

First, we need to determine which pins of the Portenta support the UART we want.

Visit the official Portenta H7 web page, and navigate to Platform –> Hardware.

Since I’m determined to use the MKR-compatible header for today: I’ll use UART interface one (UART1)…

  • UART1_TX                 J1-33 (port: PA_9)
  • UART1_RX                 J1-35 (port: PA_10)
  • OUTPUT_LED             J2-59 (port: PA_8

Side note: If you can utilize the high-density connectors, you gain access to a total of 4 UARTs, plus the SerialMonitor.

UART to USB Conversion Test

First, verify the UART to USB conversion cable is working.

Locate the Ground (GND), TX and RX pins of your UART conversion device.  If you have additional wires left over marked 5V, 3.3V, CTS, or RTS, leave them unconnected.  If you do not know which pins are TX and RX, you will need to consult the product’s literature or use instrumentation to find out.

Plug the cable into your computer’s USB port.  In Windows, you easily tell if its working by looking for a new COM device in Device Manager, or by entering the following in the Windows Power Shell app…

[System.IO.Ports.SerialPort]::getportnames()

Waveform Test

Using RealTerm, you can verify the cable is transmitting by connecting an oscilloscope to the TX pin of the cable.  Any key you enter into Realterm’s main display will generate a corresponding waveform on the scope.

Testing the Arduino UART

Now it’s time to test the Arduino’s UART.

  1. Unplug the serial converter cable from the board and the computer.
  2. Exit the terminal program.
  3. Plug the Arduino into the board.
  4. And attach the Arduino to your computer USB port.
  5. Open the Arduino IDE.

Create a New Sketch

Create a new sketch called uart_m7_transmit.ino.

Add the following lines of code, and then upload it.

void setup() {
  Serial.begin(9600);        // Initialize the SerialUSB
  Serial1.begin(9600);       // Initialize UART1 and its pins
  Serial.println("Reset");   // Courtesy message
}

void loop() {
  Serial.println("Sending...");  // Print this to Arduino IDE
  Serial1.println("Hello");      // Print this to the physical pins
  delay(500);                    // Hold for 500 ms
}

Testing UART from Core M4

Now do a save as and rename to project uart_m4_transmit.ino.

I’ll change text so that we can be certain this is not the previous sketch.

void setup() {
  Serial.begin(9600);        // Initialize the SerialUSB
  Serial1.begin(9600);       // Initialize UART1 and its pins
  Serial.println("RESET");   // Courtesy message
}

void loop() {
  Serial.println("SENDING...");  // Print this to Arduino IDE
  Serial1.println("HELLO");      // Print this to the physical pins
  delay(500);                    // Hold for 500 ms
}

Select the M4 core and then upload…

When the code uploads, we can see from Serial Monitor that the old M7 code is still running and the M4 code (the ALL CAPS version) isn’t running at all.

To complete the project, do another save as and this time name the new sketch uart_m7_blink.

LED and UART

In the new sketch, enter the following.

void setup() {
  bootM4();                  // Enable the M4 core
  pinMode(PA_8, OUTPUT);     // Set port A8 as digital output
}

void loop() {
  digitalWrite(PA_8, HIGH);  // LED on
  delay(100);                // Hold 100 ms
  digitalWrite(PA_8, LOW);   // LED off
  delay(100);                // Hold 100 ms
}

Then upload to see the intended ALL CAPS text.

Side note: bootM4() was previously called LL_RCC_ForceCM4Boot().

At this point we can see the LED is blinking, and the UART is outputting messages.

Serial Behavior for Both Cores

But this is where things get a bit counter-intuitive…

On the M7 core, Serial will pipe messages to the SerialMonitor via the USB CDC interface, and Serial1 will connect to the physical pins associated with UART1.

On the M4, both Serial and Serial1 connect to UART, and neither Serial nor Serial1 connect to the SerialMonitor.  We can confirm this by seeing both Serial and Serial1 messages at UART1.

So how to can M4 communicate with the SerialMonitor?

Figure 3: Relaying Messages using Remote Procedure Calls

The Portena H7 has a feature called a remote procedure call (RPC).  RPCs let the two cores communicate with each other.  In this case, one solution would be for M7 to relay messages between M4 and the Serial Monitor.  RPCs are outside of today’s scope, but you can follow the proposal at Does M4 of the Portenta H7 have access to the serial monitor?

Linking the UARTs

Finally, the Arduino IDE does have a built-in example in the Examples à Communication category called “MultiSerial” that will link the two interfaces.  This will effectively let the Serial Monitor chat with the terminal program and vice versa if things are wired correctly.

I’ll leave this for you to try on your own, but I can confirm it worked when run from the M7 core.

Closing Thoughts on Industrial Interfaces

Finally, you may be wondering what’s the fastest possible UART speed (or baud)? 

Today’s project happened at 9600 baud which is considered quite slow, but RealTerm includes speed options as high as 921,600 baud.

Bear in mind: the max data rate you can send isn’t necessarily the fastest rate you can use.  Faster signals are more susceptible to transmission line effects and the wired interface will need to be more accommodating.

If you are using RS-485 (also called EIA-485) or RS-422 (EIA-422), one device I have featured in the past is the ISO3082DWR.  This is a galvanically isolated transmitter/receiver chip. 

References

[1]Arduino, “Arduino Pro,” Arduino, [Online]. Available: https://www.arduino.cc/pro/hardware/product/portenta-h7 . [Accessed 28 Apr. 2021].
[2]Arduino, “Portenta H7,” Arduino, 31 Oct. 2021. [Online]. Available: https://content.arduino.cc/assets/Pinout-PortentaH7_latest.pdf. [Accessed 28 Apr. 2021].
[3]Arduino, “Arduino Portenta H7 Product Reference Manual,” Arduino, 18 Dec. 2020. [Online]. Available: https://content.arduino.cc/assets/Datasheet-Portenta-H7.pdf. [Accessed 28 Apr. 2021].
[4]facchinm, “Portenta: CM4: route Serial to UART1,” 27 Oct. 2020. [Online]. Available: https://github.com/arduino/ArduinoCore-mbed/commit/58fee8b295474eee80e7b974096d6e8c7ffc0c41. [Accessed 231 Apr. 2021].

Important Notice: This article and its contents (the “Information”) belong to Unboxing-tomorrow.com and Voxidyne Media LLC. No license is granted for the use of it other than for information purposes. No license of any intellectual property rights is granted.  The Information is subject to change without notice. The Information supplied is believed to be accurate, but Voxidyne Media LLC assumes no responsibility for its accuracy or completeness, any error in or omission from it or for any use made of it.  Liability for loss or damage resulting from any reliance on the Information or use of it (including liability resulting from negligence or where Voxidyne Media LLC was aware of the possibility of such loss or damage arising) is excluded.