CyphalPicoBase/CAN - a node with Raspberry Pi Pico and MCP2515

Hardware

During the construction of the L3X-Z hexapod we had to develop several OpenCyphal nodes. One was the leg controller which is already described in the L3X-Z thread. The second type of node is the auxiliary controller which controls the less important task like the state of the emergency switch or the warning lights.
At first this controller was only some Arduino on a bread board like this:

and that:

But now this has emerged into a own board: The OpenCyphalPicoBase

It is based on a Raspberry Pi Pico which is mounted on the back and uses a MCP2515 CAN controller. Because of the difficult supply situation in 2022 I also used a THT footprint for the controller because these parts were sometimes better available. Additionally it has an I2C eeprom to store settings in a way that they are able to survive a firmware update.
As there were some pins left I implemented more functions than we actually needed for the L3X-Z. I supports the following functions:

  • measurement of bus voltage
  • internal temperature of RP2040
  • 4 digital inputs
  • 2 analog inputs
  • 2 digital outputs
  • 2 servo outputs
  • 1 connector for NeoPixel leds

This a photo of the mostly assembled board now:

The Raspberry Pi Pico can be stacked on headers on the bottom side to easily replace it in case of failure. It turned out that this is not necessary so it can be directly soldered on the board. Unfortunatelly I didn’t take enough care of the USB connector so it is difficult to solder and connect. I will fix this in a later release.

All the design data including schematic and KiCAD project file is available in my github repo:

Software

As this is a more generic board it is open to all kinds of software. For the L3X-Z hexapod we tried to implement a software which covers all inputs and outputs of the board and gives some lighting functions but not more.

This software is based on the Arduino framework and is also available on github:

This software relies heavily on the 107-Arduino-Cyphal library and tries to make use of all its functions. Unfortunatelly it is also bound to its restrictions. So no configurable subject-ids so far. The rest like Node Info, Execute Command and Register API should work.

This is the output of yakut monitor:

And these are the implemented registers:

{                                              
  "99": {
    "aux.updateinterval.analoginput0": 500,
    "aux.updateinterval.analoginput1": 500,
    "aux.updateinterval.input0": 500,
    "aux.updateinterval.input1": 500,
    "aux.updateinterval.input2": 500,
    "aux.updateinterval.input3": 500,
    "aux.updateinterval.inputvoltage": 3000,
    "aux.updateinterval.internaltemperature": 10000,
    "aux.updateinterval.light": 250,
    "uavcan.node.description": "L3X-Z AUX_CONTROLLER",
    "uavcan.node.id": 99,
    "uavcan.pub.analoginput0.id": 2008,
    "uavcan.pub.analoginput0.type": "uavcan.primitive.scalar.Integer16.1.0",
    "uavcan.pub.analoginput1.id": 2009,
    "uavcan.pub.analoginput1.type": "uavcan.primitive.scalar.Integer16.1.0",
    "uavcan.pub.input0.id": 2000,
    "uavcan.pub.input0.type": "uavcan.primitive.scalar.Bit.1.0",
    "uavcan.pub.input1.id": 2001,
    "uavcan.pub.input1.type": "uavcan.primitive.scalar.Bit.1.0",
    "uavcan.pub.input2.id": 2002,
    "uavcan.pub.input2.type": "uavcan.primitive.scalar.Bit.1.0",
    "uavcan.pub.input3.id": 2003,
    "uavcan.pub.input3.type": "uavcan.primitive.scalar.Bit.1.0",
    "uavcan.pub.inputvoltage.id": 1001,
    "uavcan.pub.inputvoltage.type": "uavcan.primitive.scalar.Real32.1.0",
    "uavcan.pub.internaltemperature.id": 1010,
    "uavcan.pub.internaltemperature.type": "uavcan.primitive.scalar.Real32.1.0",
    "uavcan.sub.led1.id": 1005,
    "uavcan.sub.led1.type": "uavcan.primitive.scalar.Bit.1.0",
    "uavcan.sub.lightmode.id": 2010,
    "uavcan.sub.lightmode.type": "uavcan.primitive.scalar.Integer8.1.0",
    "uavcan.sub.output0.id": 2004,
    "uavcan.sub.output0.type": "uavcan.primitive.scalar.Bit.1.0",
    "uavcan.sub.output1.id": 2005,
    "uavcan.sub.output1.type": "uavcan.primitive.scalar.Bit.1.0",
    "uavcan.sub.servo0.id": 2006,
    "uavcan.sub.servo0.type": "uavcan.primitive.scalar.Integer16.1.0",
    "uavcan.sub.servo1.id": 2007,
    "uavcan.sub.servo1.type": "uavcan.primitive.scalar.Integer16.1.0"
  }
}

further development

The next planned steps are:

  • implement storage of settings to eeprom
  • configurable subject-ids
  • rework pcb and make it smaller

If you have questions feel free to ask or post an issue on github.

2 Likes

I have two:

  1. Can one run MicroPython on this board to benefit from PyCyphal?

  2. Are there plans to support Ethernet for Cyphal/UDP, perhaps via Microchip ENC28J60 or similar, in a future hardware revision?

Let’s hope this critical piece of the protocol is supported sooner rather than later!

1 Like

This board is based on the Raspberry Pi Pico so it is definitely capable of running MicroPython. And there seems to be a driver for the MCP2515, so yes, it should be possible.

Unfortunatelly I’m not into Python so there won’t be any tests from my side. If you know anyone who is willing to try it I can send her or him one or two boards.

Nope, not really. This board is tailored to Cyphal/CAN.

A possibility might be to use the Raspberry Pi Pico W with the WiFi chip and run Cyphal/UDP over WiFi. But this is not on my roadmap.

Definitely. I would like to have a complete and working implementation of Cyphal on this board!

I would try it myself but at this moment there’s a blocker – PyCyphal is not yet out-of-the-box usable with MicroPython:

I don’t think it will take too much effort to render it compatible with MicroPython though. If anyone reading this is interested in this, we could use a hand.

1 Like

@pavel.kirienko I will do the redesign of the boards and as soons as the new ones arrive I will send you one.

1 Like

Providing a sneak-peek at the updated OpenCyphalPicoBase hardware enclosed in a 3D printed case :wink:

Intended purpose is auxiliary controller in L3X-Z during this year’s ENRICH Robotics Hackathon.

Are you getting any mileage out of the second core on the rp2040?

I’m on a collegiate design team (Baja SAE) that’s networking all of our onboard electronics through Cyphal/CAN, and one of our nodes is a rp2040 running standard IO on core0 and libcanard & Kevin O’Connor’s can2040 on core1.

Curious to hear what Cyphal on rp2040 insights you have.

1 Like

Hi Will :coffee: :wave:

Good hearing from you :wink: . And this is an excellent question!

The current firmware does not make use of the second core since all required tasks can be easily handled by one core without introducing any of those complications that usually tag along with multi-core software (race conditions, dead locks, …).

That being said we are evaluating extending the application to the second core if and when it makes sense. For example we also have this RP2040 / CAN-networked running 107-Arduino-Cyphal where the same SPI is used for talking with a MCP2515 and two AS5084 absolute position encoders. In this scenario it would not make sense splitting off the Cyphal/CAN part onto a separate core as they literally share the same SPI peripheral.

How’s your experience with the can2040 software CAN implementation? Also please feel free to share more information about your use-case and project :wink: .

Cheers, Alex

Hi Will,
using the second core for software CAN is a nice approach!
Until now we haven’t been so curious but used an external CAN controller (MCP2515 over SPI) instead.

Do you have any documentation and experiences on your design to share? I would really like to see that! We could consider to switch to software CAN if this works smoothly.

Hi Bernhard, I’m Zach, the main EE/systems guy on @Willmac16’s collegiate design team, the guy who picked the RP2040 for this purpose, and the guy who picked Cyphal/CAN over another protocol. I was planning on making a more detailed post on the forum about how we’re using the system once we’ve evaluated our implementation more thoroughly, but this is a good place to tease that :smile:.

I picked the RP2040 with the intention from the start of using core0 for the main “thread”, and core1 for all the CAN stuff. We’re using KevinOConnor’s can2040 library to facilitate the CAN 2.0B layer, but some of that library, as well as our Cyphal stack (a simple libcanard implementation) runs on core1, separate from whatever it’s main responsibilities are.

I evaluated the MCP2515 as an option but found that it was a lot more chip than we needed, it added a layer of complexity by adding system states that were not a part of the main MCU (I’m looking at you, multiple send and receive buffers, as well as hardware masks), and honestly most importantly was in a shaky spot of it’s lifecycle. I thought about other CAN controllers (and maybe even CAN-FD) but can2040 seemed almost like too good of a deal to pass up on. So, it’s what we’ve built our stack so far on, and we’ve had success with it to the extent that we’ve pushed it.

I will make a note, at Will’s request, that there are a few things missing from our implementation of Cyphal/CAN and can2040’s implementation of CAN 2.0B:

  1. Since can2040 doesn’t transmit error frames, and doesn’t handle switching between error states, it pretty much lives in an error passive state. This makes me a little uncomfortable, but in our application I don’t see it as a huge problem, and we can always add the functionality in the future.
  2. We have yet to test subscribing to Cyphal/CAN messages with CAN2040, but I don’t imagine this will be a problem given we can publish just fine.
  3. We haven’t field tested our implementation yet. This is not a huge deal IMO, as we honestly didn’t do that much work to glue the two together, and each library is independently verified by their respective communities.
  4. We’re living in the pico-sdk provided by Raspberry Pi. Again, not a huge issue I don’t think, but it’s definitely not as high level as Arduino.

Overall, I see it as a really slick solution, and I’m really glad I have a @Willmac16 to implement all my crazy architecture and systems ideas in software so I can worry about circuits and PCB design. We have a few other neat Cyphal nodes that you’ll hopefully hear about eventually, including but not limited to…

  • an EKF based Cyphal AHRS for the car (9-axis IMU + GPS)
  • a ton of different little sensor nodes (thermocouple, odometry, suspension travel, etc)
  • a non-invasive fuel level sensing solution
  • a custom BMS/hot swappable battery
  • a cool F1 style steering wheel

So basically, we’re fully onboard, and are looking to jam Cyphal pretty much wherever we can (no pun intended). I’m especially looking forward to Cyphal/UDP becoming more mature, as I’ve been looking for an excuse to play with single pair ethernet…

Let either of us know if you have any questions, and I’ll try to get some demo code de-secret-ized so we can better show off our implementation.

-ZB

3 Likes

Hi Zach :coffee: :wave:

Thank you for taking out the time to take this detailed description :wink: . I’m sure @generationmake will be jumping in with additional questions. At least I can already see his finger itching to possibly get rid of the MCP2515. EOL isn’t a problem imho, but getting the part is indeed quite tricky these days.

To be perfectly honest, my preferred long-term solution is to replace RP2040 with an MCU that sports an integrated CAN module (I’m looking at you SAMC21 :grin: ).

You should definitely write-up a separate blog article about your learnings and I’m looking forward to see a host of new Cyphal-enabled devices. Keep jamming Cyphal in there :grin: :bowing_man: .

Cheers, Alex

2 Likes

I think we managed to get the software running and support all basic and necessary features of Cyphal and make the device as configurable as intended by Cyphal. For the time being we stayed with MCP2515. But in the next weeks we will give the software-CAN of the Raspberry Pi Pico a try.

The software can be found here:

I will write a longer post but this will take a few days.

2 Likes

Hi everyone :coffee: :wave: .

The first manufactured batch of the OpenCyphalPicoBase open hardware reference design by @generationmake and with a fully Cyphal-compliant open firmware written by myself - have arrived today.

This battletested design has already proven itself in the field when utilized as a general auxiliary controller, a pressure sensor or a radiation sensor.

Pending documentation interested parties will be able to purchase this board as a Cyphal evaluation module or as a Cyphal-node base building block shortly.

Pre-orders can be made via :email: (sales@lxrobotics.com) or DM :wink: :bowing_man: .

3 Likes

Here are some pictures w/ the OpenCyphalPicoBase in its fancy yellow 3D printed enclosure four your kind perusal! (keeping the hype alive :grin: :bowing_man: ).

(Yellow and Black make for a good combination imho :angel: ).

2 Likes

Black and yellow
Black and yellow
Yeah, uh-huh, you know what it is

1 Like

Following up on the request by @pavel.kirienko this board/project is renamed to CyphalPicoBase/CAN.

1 Like

Hi @all
I want to give a short update on the project.
The hardware hasn’t changed for several months now and there haven’t been any major issues. So I assume this device is somehow stable.

Here is an overview of the current design with all the interfaces:

All ressources can be found on github: GitHub - generationmake/CyphalPicoBase-CAN: Board for the Raspberry Pi Pico to connect via CAN using OpenCyphal and UCANPHY Micro

The main controller is a Raspberry Pi Pico and is mounted on the bottom side.

The design is a general purpose node for a Cyphal/CAN network and utilizes the UCANPHY micro connector (JST GH). It can be powered by the CAN bus but a local 5V supply is also possible.

There exists also a default firmware: GitHub - 107-systems/CyphalPicoBase-CAN-firmware: Firmware for the OpenCyphalPicoBase board.

This firmware allows to control the following functions:

  • digital inputs
  • digital outputs
  • analog inputs
  • Neopixel output (basic functions)
  • servo output
  • internal temperature sensor
  • measurement of bus voltage
  • internal LED

The serial connector and the I2C connector are not supported by this firmware.

This firmware follows the cyphal spec and in the initial state or after factory reset no functions are enaled. By using the register interface the user can decide and configure which functions are needed and set the appropriate subject ids. These settings are stored in an onboard eeprom. All registers are described on the github page.

Since this should be a general device different firmwares are possible. Propably based on our default firmware.

I will post several alternative projects and firmwares based on this design in the next couple of weeks.

Bernhard

3 Likes