Bit Position / Bitfield in CANBUS Export in PMU24

The new CRC check feature in the latest PMU software (ref: Creating Checksum Byte on PMU24 ) is great, but I am struggling to export fields to specific bit positions. I am trying to create this export message to a motor controller:

Below is the canx output (after I import the DBC), which has the fidelity of specifying the byteOffset, bitCount, and bitPosition, which aligns with expectations.

[As a side note, I was hoping to use the XML as a means to configure the export, which might avoid any UI limitations, but I did not see an option to import an export canx—the add function only imports an import canx. Right?]

Per section 5 of the CRC manual, I understand that, “If a custom channel uses a bit length that is not a multiple of 8, all channels that follow the custom channel are placed immediately after its data, without byte alignment.” However, the user interface does not seem to allow me to enter more channels to fill out the complete message if the total message is less than 64 bits. So for the message that I am trying to create, I tried to simply add channels to account for the bitPosition. Here is what I think the configuration might look like if I use the UI, which clearly stops before the 64th bit (even if I use 16 bits in channel 0 to span 0,1):

Maybe this is covered in the manuals somewhere and I missed it (if so, happy to be pointed to the specific location for me to dig in and understand better. Anyone have any thoughts? This is not related to the CRC functionality (AFAIK), so I am guessing that this is covered elsewhere already and my ignorance is showing…

Thanks in advance!!

This is a limitation of our export system.

You can, however, work around this.
You must combine all the data you want to send into 8- or 16-bit values.

For bit shifting, you can use multiplication (*2^n).
To shift the number by one bit to the left, you multiply by 2.
Shift by two is multiplication by 4, and shift by 3 is multiplication by 8.
To combine data, first shift the data to the correct positions, then add the shifted data.

Let’s take byte 4, for example.
There are two values: green and grey.

Green value is a single bit and needs to be at bit position 2.
We multiply the green value by 4, which shifts it two bits to the left.
Let’s name it “green_b2”.

Grey value has two bits and must be at bit position 6.
We multiply the grey value by 64 (2^6), which shifts it six bits to the left.
Let’s name it “grey_b6”.

And to finish:
Byte4 = grey_b6 + green_b2

Now you have a single, 8-bit value that contains two channels, and can be sent as byte 4 of that frame.

As Marek wrote, you can create your own bitfield using operations on numbers.

Below you can find examples similar to Marek’s description, but using “choose” and “lookup” operations to save on the total number of operations.

You can do it this way using 2 operations, or (light green * 4) + (blueGrey * 64), but that consumes 2 more operations.(so 4 operations more for CANBus export from this case)

Please check the example below, where you have your entire frame.
bitfieldExample.pmu (3.3 KB)

Thanks, both. That was a big help, and I appreciate the details and example. I managed to get it working as described by both Marek and Maciej, although it took me some time to really understand Maciej’s (clever) method. Does saving operations (e.g., 4 operations is reduced to 2 operations) result in a performance improvement or is it simply more elegant? It seems like it would improve performance because the choose and lookup functions are more like a “lookup table,” if I follow the logic of the operators correctly.

Now for another question: the blue gray in byte 4 is a counter. It counts 0,1,2,3 and repeats. The message is 100Hz/10ms, so it seems like I could implement a similar style counter as described here: Can I make reactive CANBUS Export cycling timers? but unsure if that is the best method because any misalignment or out of tolerance in timing could result in a skipped number, which could result in a failure by the receiving motor controller. The OP of the reference article simply needed an incremental number, so slightly different than my situation.

It looks like the new CRC field supports such counters, but there can only be one CRC field per message, if my experimentation is correct.

It has 2 pros and 1 con:
Pros: performance and lower resource usage (more operations will be available for future things on the PMU as your project grows).
Con: what you pointed out – without a description of how it works (sorry, I should have written it when I was writing that post), it is not very intuitive.

Regarding the counter, every CANbus Export element has its own counter, so you don’t need to create a counter in the project tree.

x_export1 has its own channel – x_export1.txCounter – which is, I guess, exactly what you need. So just replace n_blueGrey in n_byte4 with the txCounter channel.

1 Like

Thanks for both explanations. And apologies for missing the TX counter description in the CRC how-to manual! Page 3 provides a good description of the functionality for those that have the same question in the future.

1 Like

Quick clarification on the lookup function: should it allow negative numbers in all Values/fields?

I attempted using lookup2 with a negative number in choice 2, but it saves as a positive or absolute value of the number. This does not happen with lookup3, lookup4, or lookup5 in Value[2], Value[3], and Value[4]. For example, when input:

Saves as (for any arbitrary channel in my project):

That is, with the absolute value in Value[0] and Value[1]. Is this expected behavior or a result of a limiting setting somewhere?

Note: This did not seem worthy of a new topic, but I can re-post if appropriate.

Thank you for reporting this. This is not correct behavior. It will be fixed in the next PMU version.

Is this a stopper for your PMU project?

Thanks, and happy to help contribute. The field is critical to my project, but (1) there may be an alternative, more optimal approach, (2) I think I have a workaround using lookup3, and (3) I can wait for the next release.

My usage: I use the lookup2 values to read a linear switch that sets the motor rotation desired. The lookup2 values set a multiplier of either *1 for positive motor rotation or *-1 for negative motor rotation. My formula is (MotorTorque) x (Lookup2 value), which is then sent in a CANBUS message to the motor. The result of the formula produces a positive rotation when multiplied by 1 and a negative rotation when multiplied by -1. The MotorTorque value is determined by a separate linear analog input.

To summarize the initial implementation that found the bug:

First index = 2
Value[2] = 1 (positive rotation)
Value[3] = -1 (negative rotation) ← Bug: does not allow negative value

As an alternative approach, I will use lookup3, which I confirm works:

First index = 0
Value[1] = 0 (zero rotation)
Value[2] = 1 (positive rotation)
Value[3] = -1 (negative rotation)

1 Like