CAN SDO interfacing problems

Post Reply
davefiddes
Posts: 211
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 14 times
Been thanked: 35 times

CAN SDO interfacing problems

Post by davefiddes »

As part of my Tesla M3 firmware project I really need to be able to configure and monitor the inverter entirely through the CAN bus. I haven't seen any software to do anything like this for the STM32 openinverter boards. It seems that the ESP8266 web interface and serial interface works for most people. I have set out to build a simple command line tool that would use the CAN SDO interface to get and set parameters/values but run on a PC and be useful for both projects.

There is a reasonably mature python library called canopen that looked like it might be a good base. Unfortunately I've run into a bit of a problem with the implementation of CANopen SDO in openinverter. It seems that the upload/download semantics have been inverted from the standard implementation. For example, a simple fetch of the "boost" parameter would look something like:

Code: Select all

    network = canopen.Network()
    network.connect(bustype='socketcan', channel='can0', bitrate=500000)
    network.check()

    # Add a node with corresponding Object Dictionaries
    dict = canopen.ObjectDictionary()
    dict.add_object(canopen.objectdictionary.Variable('boost', 0x2000, 0x0))
    node = canopen.BaseNode402(1, dict)
    network.add_node(node)
    
    # "Upload" a value from the remote node
    print("remotevalue:", node.sdo.upload(0x2000, 0))
This generates a CAN request that looks like:

Code: Select all

40 00 20 00 00 00 00 00
From the openinverter documentation I would expect this request to look like:

Code: Select all

22 00 20 00 00 00 00 00
Trying to set a parameter with:

Code: Select all

node.sdo.download(0x2000, 1, b'\x80\x0C\x00\x00')
generates:

Code: Select all

23 00 20 01 80 0c 00 00
whereas openinverter would expect:

Code: Select all

40 00 20 01 80 0C 00 00
It seems that everything is backwards, upload is download and download is upload. The CANopen terminology is odd to me so I can understand how this happened.

I've cross checked the python canopen library with Wireshark's CANopen dissector and the open source canopen-stack firmware stack and I believe it is doing the right thing. It should be possible to use the "CiA 301 - CANopen application layer and communication profile" spec but it's a pretty impenetrable industry spec and I found it difficult to follow. :x

Not sure what to do here. Main options seem to be:
- Leave openinverter as-is, fork and heavily modify the python canopen library (it does a lot of useful stuff) and create a new Wireshark dissector
- Fix openinverter to implement the standard so as to use existing tools but break all existing users (are there any?)

I'm leaning towards the first but it is a ton of non-standard work. CANopen is an over-complicated hot mess and I'm not sure it makes sense to use it as a guide for the other command-and-control requests needed to replace the serial commands. Thoughts?
Pete9008
Posts: 1801
Joined: Sun Apr 03, 2022 1:57 pm
Has thanked: 102 times
Been thanked: 347 times

Re: CAN SDO interfacing problems

Post by Pete9008 »

Would like to help but afraid I know nothing about this subject :(

Only thought that occurs is that upload and download appear reversed from the master and slave perspective, could both openInverter and the python library be implementing the same end (or doesn't it work that way)?
User avatar
johu
Site Admin
Posts: 5684
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 960 times
Contact:

Re: CAN SDO interfacing problems

Post by johu »

If in doubt change openinverter. I don't think it's used by many yet and I got the semantics from a 2nd order source
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
davefiddes
Posts: 211
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 14 times
Been thanked: 35 times

Re: CAN SDO interfacing problems

Post by davefiddes »

OK. I'll go down that path. Will double check that I've got the semantics right and put together a PR for you to have a look at.
davefiddes
Posts: 211
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 14 times
Been thanked: 35 times

Re: CAN SDO interfacing problems

Post by davefiddes »

On closer inspection the implementation in openinverter was definitely wrong and didn't match any spec and also had a recent bug that prevented it reading/writing of parameter values by unique ID. PR (https://github.com/jsphuebner/libopeninv/pull/6) raised to fix this. I'll now be able to have a go at putting together a command line tool to manage inverter parameters over CAN. I'll start a new thread for that when I have something that's worth sharing.

Edit: For the record the CiA 301 spec wasn't nearly as bad as I made out above on a second reading. The client/server vs. upload/download semantics are very poorly defined though.
User avatar
johu
Site Admin
Posts: 5684
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 960 times
Contact:

Re: CAN SDO interfacing problems

Post by johu »

Thanks for fixing, merged it to float branch and will merge to master later
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
Bigpie
Posts: 1585
Joined: Wed Apr 10, 2019 8:11 pm
Location: South Yorkshire, UK
Has thanked: 74 times
Been thanked: 299 times

Re: CAN SDO interfacing problems

Post by Bigpie »

Is the wiki information on this up to date? I'm wanting to disable braking regen when battery is 0 degrees of below or -30% otherwise. Not sure if 0x40 is the write command anymore

Code: Select all


static void SendRegenMessage(bool enabled) {
   uint8_t canData[] = { 0x40, 0x20, 0x01, 0x26, 0xFF, 0xFF, 0xFF, 0xE2 };

   if (!enabled) {
      canData[4] = 0x0;
      canData[5] = 0x0;
      canData[6] = 0x0;
      canData[7] = 0x0;
   }
   can->Send(0x601, (uint32_t*)canData);
}
VW Beetle 2003
Outlander front generator
Prius Gen 3 inverter (EVBMW logic board)
Outlander charger
3x Golf GTE batteries
Chademo Charging
Outlander water heater
User avatar
johu
Site Admin
Posts: 5684
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 960 times
Contact:

Re: CAN SDO interfacing problems

Post by johu »

That has indeed changed, 0x23 is now the write command. I updated the wiki https://openinverter.org/wiki/CAN_commu ... rs_via_SDO
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
davefiddes
Posts: 211
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 14 times
Been thanked: 35 times

Re: CAN SDO interfacing problems

Post by davefiddes »

The wiki is out of date. CAN SDO support is in a bit of a state across stm32-sine and stm32-vcu branches which makes it hard to document.

Assuming you are running stm32-sine v5.24.R or later. To configure "brakeregen" (unique id = 38) you are best to use the SDO index 0x2100. To get -30% you need to convert to fixed point by mulitplying by 32 which gives you -960 or 0xFFFFFC40. Values are in little-endian format so you have to swap the bytes around according to the word size (16-bit index, 32-bit data value). The message should look like:

0x23 0x00 0x21 0x26 0x40 0xFC 0xFF 0xFF

This seems to work for me.
User avatar
johu
Site Admin
Posts: 5684
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 960 times
Contact:

Re: CAN SDO interfacing problems

Post by johu »

davefiddes wrote: Sat Dec 10, 2022 11:59 am The wiki is out of date. CAN SDO support is in a bit of a state across stm32-sine and stm32-vcu branches which makes it hard to document.
Wiki is updated. Indeed the SDO changes haven't made it into the libOI can_new_structure branch yet so not into ZombieVerter either

UPDATE: merged to can_new_structure
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
davefiddes
Posts: 211
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 14 times
Been thanked: 35 times

Re: CAN SDO interfacing problems

Post by davefiddes »

Thanks and apologies for not getting to it sooner given that I broke it. :(
Post Reply