CAN Open, the fast and furious way - Page 1
Forum section: electronics / general

author: Simon
author_rank: Unknown
timestamp: December 12, 2023, 02:33:53 pm
content: I've read a lot about CAN Open and it kind of baffles me. I have a micro controller and I am not sure if it has the memory to run the can open stack on it and I have little desire to spend months trying to fathom all this out so that I can transact in just 4 pieces of data.My understanding so far is that the master device will send out some initialization message. There is a sync message that needs sending every so often but I am unclear as to it's necessity. After that as long as I send a message with the right data in it i will get a response with each device having it's ID between 0 and 127 and there being 4 bits before that ID that depend on the message being sent. After that it's about the index and sub index in the message that define what the data is.Is this it? how do I turn it into working communication?

author: nctnico
author_rank: Super Contributor
timestamp: December 12, 2023, 02:43:32 pm
content: That is correct. I have implemented a simple form of CAN Open myself that just listens to the hearbeat messages and can write objects. In my case I need to send a CAN message to 0x600 orred with the device ID with a CAN data payload has the type (data length), index, sub-index and then up to 4 bytes of data (depending on the data length). This writes a value to a CANOpen object in a device.

author: Simon
author_rank: Unknown
timestamp: December 12, 2023, 02:52:54 pm
content: So I have from table 38 of CiA301:NMT: is what is sent to kick it all off? ID of 0SYNC: which I assume I send every so often from ID 128 (function code 1 of address 0)Time: slightly new on me, I guess the master sends this every so often with the time in the data?

author: nctnico
author_rank: Super Contributor
timestamp: December 12, 2023, 02:56:21 pm
content: I'd check the documentation for the device you are trying to talk to. Likely you don't need to implement a lot to make it work. My case was for a motor controller that just sends out keep-alive messages and listens to incoming CAN traffic. Nothing fancy.

author: Simon
author_rank: Unknown
timestamp: December 12, 2023, 03:28:15 pm
content: Yes this is a motor driver as well.

author: fenugrec
author_rank: Frequent Contributor
timestamp: December 12, 2023, 03:38:10 pm
content: Quote from: Simon on December 12, 2023, 02:52:54 pmAre you implementing a NMT master or slave node ?NMT includes a "state machine" (stopped, pre-op, operational) and the messages (sent by the master) to make each node transition to a given state. Some messages (e.g. PDO) are only allowed in the Operational state. This can be kept pretty simple depending on what you want to be compatible with.SYNC : unidirectional, sent by master, slaves may ignore. Depends what you're doing.heartbeat protocol : may be optional, also depends what you want to be compatible with.A "full" stack (I looked mainly atLely, well-maintained and appears quite thorough, andCANopenNode, also maintained and the main dev was responsive but at the time (2020) it was difficult to get to compile, I think it was around a fairly large set of breaking changes. Those were going to use way to much ROM on my puny stm32f0xx (IIRC a minimal stack was at least 12-16k flash), so I decided to implement a skeleton canopen implementation. If you plan on needing many SDO features, LSS, etc. I strongly recommend using a stack. Reinventing that wheel gets old fast; I was at the point where I needed multi-segment SDOs but project was binned just in time.To summarize : take a good look at what you really *need* to implement, and if it's a long list, or not clear in your mind how to implement the whole thing, think hard about using a full stack, and make sure your target has enough rom+ram.

author: Simon
author_rank: Unknown
timestamp: December 12, 2023, 03:53:17 pm
content: I need to be the master, so I am guessing I send out the NMT code to go operational and then start talking to the slave devices. Unfortunately the manual is a little over 5MB and the limit on here is 4MB so can't upload it.

author: Simon
author_rank: Unknown
timestamp: December 13, 2023, 01:44:18 pm
content: Right so watched a video, it seems to clear stuff up. SDO versus PDO. SDO communication is the master slave stuff where you ask for data in a specific index and get that back. PDO is where the producer just sends data out from one or more (max 4) ID's with data much like a J1939 transmission except that the data to be contained has to be somehow decided and agreed, well they did not go as for as that.https://www.csselectronics.com/pages/canopen-tutorial-simple-introAttaching my motor driver to a microcontroller development board so that it does not get lonely and snooping on it with kvaser can king I see transmissions from 0x181, 0x281 and 0x701, two PDO's and the heartbeat. So I have no idea what these two PDO's carry. At the moment all "0's" but for the odd flicker of one of them going to 0x80 on byte 1.I guess my next move is to transmit some stuff from my micro controller and see if I get a reaction.

author: radar_macgyver
author_rank: Frequent Contributor
timestamp: December 13, 2023, 04:34:11 pm
content: SDOs are more like register reads and writes over SPI or I2C in that you (as a bus master) can address an individual register to read or write. This can happen in any operational state. PDOs are more like autonomous messages that get sent asynchronously. One typically uses SDOs to configure slave devices to send PDOs in response to an event. This is done using the 'RPDO' and 'TPDO' objects. TPDOs can be thought of as 'slots' that are used to autonomously send messages, most stacks implement eight slots. The slots are really just a set of SDOs at 0x1800-1807 and 0x1A00-0x1A07. Each slot can have a trigger that causes the PDO to be sent, and a list of SDOs (aka registers) that get sent in response to the event (multiple registers can be sent in one PDO, up to the 8-byte payload limit of a CAN bus frame). Trigger events can include if the underlying SDO has changed, or the reception of a SYNC message. RPDOs are similar 'slots' that are used to receive information from some other node and store them into one or more SDOs. They are configured at 0x1400-0x1407 and 0x1600-0x1607. This means you'll need to set up a TPDO on the servo drive, and a corresponding RPDO on your master node. When using a third-party CANopen stack, one needs to tell the stack to listen for PDOs, typically in the form of a callback that's called in response to receiving a PDO. Slave devices do not send PDOs until they are changed to operational state via an NMT message.I've used the 'canfestival' library on Linux, with aPeak-CAN transceiver card(theUSB donglealso works). Device drivers for these are built into most modern kernels, so they're plug and play (shows up as network devices). Canfestival does not appear to be maintained actively, so I do need to rewrite my code some day. There is aCANopen monitorfor Linux that I have not used, this would be a step above CANKing in that it will decode the higher-level CANopen messages. Seems like there's also a neatPython libraryfor this (might be useful for testing).CANopen specifies theDS-402 profile, which most CANopen servo drives support. This is a set of SDOs that are common to all CANopen drives. Most drive manufacturers also add vendor-specific SDOs on top of the DS-402 spec.In my application, I have a CANopen servo drive that is configured to report load and motor position and speed via PDOs. PDOs are also used to send commands (current position and speed) from the host to the drive. I do both of these periodically by sending periodic bus-wide SYNC messages. The drive reports status messages less frequently (you can set up a PDO to be sent on every Nth SYNC message), but will also send them out when the status bits change. Status bits include things like overcurrent flags. You really only need to do this if you need high update rates (my application required 100 Hz update rates). If you don't need to have such high update rates, just using SDOs is a lot simpler, especially if you are implementing your own CANopen stack by sending raw CAN messages.

author: Simon
author_rank: Unknown
timestamp: December 13, 2023, 04:44:53 pm
content: Well, I have sent a data request (SDO) and got some back, but it does not make sense, it comes back with either an aborted SDO transfer or a segmented download with gibberish in the data

author: Simon
author_rank: Unknown
timestamp: December 21, 2023, 09:44:39 am
content: Well I have some communication working. However I often get the communication error response from the motor driver (server). I have some luck in the manufacturers specific area but any standadized profile area just sends back a message with a command byte (0) of 0x80 when I send an SDO message to it. I have tried starting the drive with the state machine but no luck and I can't get a message back that seems to be a valid response so I'm not even sure of the state I am in.

author: radar_macgyver
author_rank: Frequent Contributor
timestamp: December 22, 2023, 08:17:35 am
content: Hmm, my drive will respond to SDO reads and writes even in the stopped and pre-op states. Perhaps yours may not conform to DS-402? Since you have a Kvaser USB dongle, you could try to get some CANopen device explorer program (there are many commercial ones, some offer free trials) and snoop the traffic with CANking.

author: Simon
author_rank: Unknown
timestamp: December 22, 2023, 08:42:10 am
content: Well the manufacturer told me to change the working mode and send relevant parameters before enabling the drive in the control word (0x6040.00). They gave me a sequence to follow for starting up:QuoteTo me it made sense to an least probe the state of the drive before I do anything but a request to the status word at 0x6061.00 returns with a command byte of 0x80. This means according to wikipedia an aborted SDO transfer so I assume that i cannot trust any data contained. I start to wonder if they aborted means that this is the last transmission. Other sources list 0x80 as "error".

author: SpacedCowboy
author_rank: Frequent Contributor
timestamp: December 22, 2023, 04:26:00 pm
content: I've just sent off a PCB to JLCPCB which has an RP2040 on it, and a couple of USB-A connectors (upon which the "aquabus" protocol runs modbus over a CAN protocol)...The CAN protocol is going to be implementedusing a PIO, leaving me just the modbus implementation to handle (and I doubt I'll have to implement much more than the basic read/write stuff). Component costs are minimal, so I thought I'd try the implement-it-in-software approachMy first time using JLCPCB for assembly. From the point of issuing gerbers and uploading XLS files for pick-and-place etc. it took 8 days to deliver a set of 5 assembled boards to my house in California. For $95 all in...If you're curious, the I2C header is for an OLED display, and the open section is the pinout for one of those $2-3 SPI<->Ethernet Wiznet controllers from AliExpress. The only other pin-header is something I put on every fist-prototype board to help with the smoke-test - an isolation between the voltage regulator and the power rails...

author: Simon
author_rank: Unknown
timestamp: December 22, 2023, 06:22:41 pm
content: CAN bus in not CAN Open. I don't know how the hardware is handled on a RP Pico, it sounds like you can deal with the IO pins in real time, however to run CAN bus at 1 MHz that means polling the pins at up to 16 MHz which I suppose is doable if a single core is concentrating on the pin and running all of the controller functionality but now you have a 133MHz CPU doing what a CAN controller just does. Horses for courses I guess but the world seems to be full of people that want to coerce the wrong thing to do the job. I suppose some bright spark will do it on a single board computer one day and use a 2GHz core dedicated to that function.

author: SpacedCowboy
author_rank: Frequent Contributor
timestamp: December 22, 2023, 07:28:20 pm
content: A few points:The GPIO pins (in combination with the PIO core) can bit-banga 250-odd MHz DVI bitstreamin software.... I think 16MHz is well within scope. I note that the author of the CAN code says it works at 1MHz bus-speedThe purpose of the 'can-spy' is to see just how well it does cope with CAN, because if it does cope well, then it means a whole slew of other modules can use the cheapest high-performance ARM chip I know of without external support hardware, which will add upThe PIO (note: this is not the GPIO) core on the chip isspecificallydesigned to implement protocols in software and offload the processor. This is, in fact,exactlywhat the chip is designed for, your comments of "bright sparks" notwithstanding.More of an aside: I've never seen an RP2040 have problems clocking in at even twice the 133MHz official figure.With that said, please feel free to completely ignore the post and use whichever CAN implementation you prefer - I just happened to have made the PCB and the thread at the top of the list caught my eye. I don't know your requirements just like you don't know mine, so peace and Merry Xmas.

author: langwadt
author_rank: Super Contributor
timestamp: December 22, 2023, 07:30:48 pm
content: Quote from: Simon on December 22, 2023, 06:22:41 pmthe RP Pico has the PIO statemachines to do exactly such things

author: Simon
author_rank: Unknown
timestamp: December 22, 2023, 08:22:53 pm
content: Quote from: SpacedCowboy on December 22, 2023, 07:28:20 pmYou are doing CAN bus, so am I, neither of us are doing CAN Open.

author: Simon
author_rank: Unknown
timestamp: December 28, 2023, 09:16:17 am
content: Well I think I will probably give up on trying to run these motor drivers from a microcontroller, if anything because we are going to be out of time. It could be that a physical IO pin needs pulling one way or anther to unlock the motor driver. The next stage is to move to a SBC system for our HMI so I will probably put the controls into there and run a CAN open master node from the HMI. Both CANopenNode and Lely CANopen seem to be installable under Linux although Lely wants to run from it's own package manager and seems to be C++.

author: Simon
author_rank: Unknown
timestamp: January 20, 2024, 11:35:01 am
content: well I did a little more digging and discovered that the SDO error response contains an error code. 0x06090011, this means sub index not found, this is rather troubling as I was trying to get the contents of the status word 0x6041.0 which does not have a sub index so the default 0 applies.

author: Simon
author_rank: Unknown
timestamp: January 22, 2024, 10:49:08 am
content: Well it turns out that the supplier did not supply a controller that is DS402 compliant, it was for some CAN bus communication and control via a built in PLC. Now that they have sent me the correct firmware, I get a response to my message requesting object 6041.0