CAN to MQTT Gateway with Arduino
CAN to MQTT Gateway working on the Arduino Portnta Machine Control and Arduino Portenta H7 (WiP)
An Arduino Portnta Machine Control arrived at my desk, and like a child, getting a new toy, it's time to play with it a bit. Will this the usual boring lab entry where it works in the end? I guess from the Dead End sign on the project, no.
But first, let's talk a little bit about the Hardware. Based on an Arduino Portenta H7, this looks from the hardware side interesting and also a bit strange. The Arduino Portenta it is powered by an STM32H747XI, offering an asymmetric dual-core, in one MCU. The two cores are one Cortex-M4 with 240MHz max clock and a Corex-M7 with 480MHz max clock. The STM32 gives access to a rich set of peripherals. Two CAN-FD, a lot of SPI and UARTs offer a lot of connectivity. Added with native Ethernet within the STM32H747 and an integrated Ethernet PHY onboard as well as a Cypress Infineon Wi-Fi and Bluetooth Module, what else do we wish? The STM32 includes an MPI-DSI interface, that will be feed from the internal display controller. With the 8 MByte SD-RAM and 16 MByte Flash also mounted on the board, that could be very interesting in terms of graphics.
But how to connect a display? MPI-DIS ones may be tricky? Don't worry, there is a USB-C connector and an MPI-DSI to Displayport bridge. This allows to connect a USB-C dock with video output to be connected and have the image that the STM32 can produce directly transferred to a Monitor. And with 720p (1280*720 pixel) resolution as supported maximum, this offers some interesting opportunities. Specially considering that we can use the LVGL library for graphics. And as we have two MCU cores, you can dedicate one entirely to visuals while the other core can do your real-time applications. But the video output is not today's topic.
With the CAN-FD controller and Ethernet connectivity, why not do some test with CAN? A CAN to LAN Gateway with transport to a MQTT-Server, should be a matter of some hours to get that working?! In the end, we are talking about an Arduino product with (hopefully) proper software support. But why CAN to MQTT? CAN is used in many applications, and besides the industrial use, one you may wonder, is in model railways. Being able to capture CAN-Frames and analyze them later also allows adding some AI on a remote location to search for strange data pattern.
For the Arduino Portenta H7 you need the Board-Support to be installed. This can be done in the Arduino IDE, if you like to use it. The Version 2.x as an editor and IDE has improved over the Verson 1.x, so you may give it a try. Still not the best editor in class, but at lest an improvement. After you have installed the Board-Support, we need to grab some libraries:
Arduino Portenta Machine Control
PubSubClient
EthernetWebServer
This means we have for the Arduio Portenta Machine Control now the required hardware support installed. Also, we have a Web server, Web socket server and MQTT-client at hand. That should be all we need. As a basic concept, we want to pass CAN-messages like this:
Should not be that hard. Also, as we now have a Web socket server, adding a Webpage that will connect to it and display CAN-messages in real-time (almost) should be no problem. The web server is a port from the one the ESP32 uses. Long story short, there were some API incompatibilities, and reading files from the flash attached to the Arduino Portenta didn't work. That's it for the web server. It is still in the code and active, serving a static 404 page.
The MQTT connection will open the topics "/gateway/can/gw0/can_in/" and publish any received message there. It will subscribe to "/gateway/can/gw0/can_out/" to listen for any message that someone wants to transmit to the CAN-bus. Data is exchanged via JSON and looks like this:
But first, let's talk a little bit about the Hardware. Based on an Arduino Portenta H7, this looks from the hardware side interesting and also a bit strange. The Arduino Portenta it is powered by an STM32H747XI, offering an asymmetric dual-core, in one MCU. The two cores are one Cortex-M4 with 240MHz max clock and a Corex-M7 with 480MHz max clock. The STM32 gives access to a rich set of peripherals. Two CAN-FD, a lot of SPI and UARTs offer a lot of connectivity. Added with native Ethernet within the STM32H747 and an integrated Ethernet PHY onboard as well as a Cypress Infineon Wi-Fi and Bluetooth Module, what else do we wish? The STM32 includes an MPI-DSI interface, that will be feed from the internal display controller. With the 8 MByte SD-RAM and 16 MByte Flash also mounted on the board, that could be very interesting in terms of graphics.
But how to connect a display? MPI-DIS ones may be tricky? Don't worry, there is a USB-C connector and an MPI-DSI to Displayport bridge. This allows to connect a USB-C dock with video output to be connected and have the image that the STM32 can produce directly transferred to a Monitor. And with 720p (1280*720 pixel) resolution as supported maximum, this offers some interesting opportunities. Specially considering that we can use the LVGL library for graphics. And as we have two MCU cores, you can dedicate one entirely to visuals while the other core can do your real-time applications. But the video output is not today's topic.
With the CAN-FD controller and Ethernet connectivity, why not do some test with CAN? A CAN to LAN Gateway with transport to a MQTT-Server, should be a matter of some hours to get that working?! In the end, we are talking about an Arduino product with (hopefully) proper software support. But why CAN to MQTT? CAN is used in many applications, and besides the industrial use, one you may wonder, is in model railways. Being able to capture CAN-Frames and analyze them later also allows adding some AI on a remote location to search for strange data pattern.
For the Arduino Portenta H7 you need the Board-Support to be installed. This can be done in the Arduino IDE, if you like to use it. The Version 2.x as an editor and IDE has improved over the Verson 1.x, so you may give it a try. Still not the best editor in class, but at lest an improvement. After you have installed the Board-Support, we need to grab some libraries:
Arduino Portenta Machine Control
PubSubClient
EthernetWebServer
This means we have for the Arduio Portenta Machine Control now the required hardware support installed. Also, we have a Web server, Web socket server and MQTT-client at hand. That should be all we need. As a basic concept, we want to pass CAN-messages like this:
Should not be that hard. Also, as we now have a Web socket server, adding a Webpage that will connect to it and display CAN-messages in real-time (almost) should be no problem. The web server is a port from the one the ESP32 uses. Long story short, there were some API incompatibilities, and reading files from the flash attached to the Arduino Portenta didn't work. That's it for the web server. It is still in the code and active, serving a static 404 page.
The MQTT connection will open the topics "/gateway/can/gw0/can_in/" and publish any received message there. It will subscribe to "/gateway/can/gw0/can_out/" to listen for any message that someone wants to transmit to the CAN-bus. Data is exchanged via JSON and looks like this:
{ "src": "mqtt", "type": "can", "extid": false, "canid": 2047, "lenght": 4, "data": [ 0, 0, 255, 255, 0, 0, 0, 0 ] }
For the configuration, in the first lines of the sketch you can set your CAN-Bitrate and the address of the MQTT-Server. You can upload the sketch and it should start forwarding messages. But why is this Dead End? With the hardware and the price, just using it as a simple CAN to LAN gateway will be a total waste. That can be done a lot cheaper and with parts where the web server will work as intended. Nevertheless the code is attached down below if you want to have a look. It is far from perfect and not even ready for publication, so you be warned.
Discussion (0 comments)