CAN Gateway for UIROBOT UIM342 Motors
I'm working on a project that requires a stepper motor. Dane recommended one of UIROBOT's UIM342 family of all-in-one motors that include an encoder, driver, and motion controller.
For prototyping purposes, UIROBOT provides a Windows GUI application, StepEva3, for configuring and controlling their motors. But, Dane warned, it requires one of UIROBOT's first-party CAN gateways.
I already have a generic USB to CAN adapter that runs the open source slcan firmware. So, in order to spare myself the $70 expense of a new adapter, naturally I decided to spend 2 evenings developing a virtual gateway that allows StepEva3 to talk to motors using a wide range of third-party CAN adapters.
To start, I captured a network trace of StepEva3 trying to connect to a non-existent UIM2523 Ethernet-to-CAN gateway. It sent the packet aa008b00000000000000000000e8e4cc and then disconnected immediately. Following the product manual, I decoded this as a request for all devices to report their model numbers. I wrote a small server to send back a tentative reply. The next connection got a step further, now probing for my serial number.
I worked through the device discovery process, but progress stalled. The first evening devolved into hours of painful disassembly to diagnose why StepEva3 was stubbornly hanging up on my third packet—until I finally realized I had made a simple copy-paste error. (Another credit to large language models: "In your response to the GET CAN BITRATE command, you're using the wrong function code. You're using FC_MODEL (0x0B) instead of FC_PROTOCOL_PARAMETER (0x01).")
At last, StepEva3 was satisfied it was talking to a functional gateway:

I assumed the next step would be as easy as forwarding packets between my socket and the CAN interface provided by python-can. But instead of the UIMessage protocol used by the gateways, direct motor control over CAN involves a different protocol called SimpleCAN3.0, in which some message fields are smuggled through the CAN arbitration field.
Another hurdle was a mistake in the spec detailing how the 7-bit motor address is packed into this field. I knew the high and low bits were stored non-contiguously, but not where. To work it out, I re-assigned the motor to different addresses captured the resulting arbitration IDs, then searched across combinations of bitwise shifting and masking to find a function to extract the address successfully.
With the SimpleCAN3.0 implementation in place, not only could StepEva3 connect to my gateway, the messages translated back and forth allowed it to communicate with my motor.

I've published my Python code at uir-gateway, including the protocol implementations and the virtual gateway script.
Since it works well enough for my purposes, I have made the deliberate decision to put the pencil down and to stop working on this, although there are many improvements to make. At the outset of my project, I set a goal of staying focused on my principal objectives. Although I learned about CAN and succeeded in building this gateway, in the broader view it was an avoidable diversion.