Can I make reactive CANBUS Export cycling timers?

I’m trying to interface with an OEM drive Selector (from a Range Rover Sport), and I know to do this, I need to send it a canbus message which has multiple cycling values in it. There is one byte in the message which cycles through 16 values, then repeats. That byte will cycle through a different list of 16 values if the drive selector is in another mode, (for example, Drive or Reverse)

I’d like to set up a table of 16 values that my channel will cycle through, and make it cycle through a different table of values if the drive selector is in a different state (as defined by a CANBUS input channel).

Can I do this? How?

Use choose function if value 1 choose given channel or value 2 choose another and so on so on .

I am confused.

Are you trying to read data from a gear selector?
Or are you trying to emulate a gear selector with PMU?

Your description seems to suggest that one byte has a counter and selector position. If the counter is going through 16 different values, that would mean it has 4 bits. I think there are 4 bits for the counter and 4 bits for the selector position.

If you decode the full byte, it will look like cycling through 16 values, and the values will be different depending on the position. However, underneath, you can probably separate them into a 4-bit counter and 4-bit selector position and treat them separately.

It would make decoding it much more straightforward, and it’s often done like this.

I’m not looking to decode the 16 values, just send them in sequence when my vehicle is in a certain drive state. Each drive state has a different sequence of 16 values.

If I do this, the drive selector I am using will not throw a fault, since it is getting the propietary messages it expects from the OEM controller.

You didn’t understand my description.

I think the byte is constructed something like this:
obraz

If that’s the case, you can make one counter from 0 to 15, which is 4 bits in the byte. Drive state would be a constant value that is the other bits in the byte.

This makes it much simpler to implement in PMU than doing multiple counters that count differently depending on another thing.

Thanks for explaining mkuklis, i know what you mean but there’s a bit more to it than that.

When in Park, (which we receive via another canbus message from the Drive Selector), the OEM controller will return these cycling messages:


and I want the PMU24 to emulate that, and send these same cycling messages to the Drive Selector when the Drive selector is in Park. (note, byte 5 is the sequence of values I want to pull from a table. I don’t beleive there is a pattern to them, unless you can see one?)

When in reverse, I need the PMU24 to send these cycling messages:

When in neutral, I need the PMU24 to send these cycling messages:

When in Drive, I need the PMU24 to send these cycling messages:

When in SPORT, I need the PMU24 to send these cycling messages:

If I don’t send these messages at the right time in the right way, the drive selector locks up and does not function.

I’ve got this working this with a seperate microcontroller acting as the OEM controller, and interpreting the drive mode from the Drive Selector, so I think I may keep that bit of hardware as an interface that can go between the Drive selector and the VCU and PMU24. Then I’ll define a new canbus message that the PMU24 can more easily handle.

If you think there is a way I can handle these messages with the PMU24, that would mean I don’t need a microcontroller interface and would defintely be very beneficial.

Cheers,

this is compound ( multplexed) where byte 6 is multiplexor you would need ot use chose and send corrrect value for given multiplexor ( multiplexor is byte that counts up and define what value need ot be send Byte 6 in your case)

The counter is 4-bit.
It counts from 0x0 to 0xF.

I didn’t find any pattern for the other byte.
It looks like CRC, but I couldn’t find the correct calculation.

What is the frequency of frames that PMU has to send?

The controller would be sending messages on ID 0x1B0 and 0x0D0, at a 7.3 ms cycle time, but i’ve sent them at a lower frequency (15ms) and that still worked fine.

How would you structure the functions to handle this message in the PMU software? Or do you agree that this is better to be handled by a seperate controller, like i’ve done on my test bench?

could you share the CAN messages from the selector for each mode? this could help to see if the 16 values generated use some key value from this.

Are you using a lookup table with the separate controller or just sending the 16 messages when it matches a value from the selector?

I see what you’re meaning shyam, perhaps byte 4 of 0x1F0 from the drive selector is converted into byte 5 of 0x1B0 from the controller, using a key?

What has me sceptical of that though is that the controller sends the 0x1B0 message twice as regularly as the drive selector, it’s not a call and response situation, but perhaps the timing is not important, just that the correct sequence of messages are sent in the correct state.

The controller also needs to send this static message:
0x0D0 [FROM CONTROLLER] Data: E4 00 0E 53 E2 6D 55 8D
That could be related a key of some sort, I’m not sure.

Drive Selector Message:

0x1F0 [FROM SELECTOR]
Byte 7: C0 when in park

Byte 7: C4 when in Reverse

Byte 7: C8 when in Neutral

Byte 7: CC when in Drive

Byte 7: DC when in Sport

My bench test currently uses a lookup table, correct. It detects which state (PRNDS) the drive selector is in and sends the cycling messages back that matches that state.

I managed to implement this in PMU.

n_gearSelectorPosition - placeholder for the channel with gear selector position value. Use the actual channel with that value.
n_counter_2ms - counter that increases by one every 2 ms and starts over after 32767.
f_counter2Max - true if the n_counter_2ms is at max value.
n_pulse_8ms - generates a pulse every 8 ms.
n_counter_8ms - counter that increases by one every 8 ms and starts over after 32767.
f_counter8Max - true if the n_counter_8ms is at max value.
n_counter8_mod16 - counter that increases by one every 8 ms and starts over after 15.
t_canGearCRC - table with the current “CRC” value (in decimal form) that should be sent over CAN. One axis of the table has the counter value from 0 to 15. The other axis has the current gear selector position, which changes the sequence of values to send.

I filled one row of the table for the park position.
You would have to fill in other rows for different positions.
You can use the n_pulse_8ms as the trigger for frame transmission.
You can use the n_counter8_mod16 counter for byte 7.

Project tree:

Numbers and functions:






Table:

3 Likes

Thanks @mkuklis_ECUMASTER !
This worked! I expanded and used tables for the other bytes in the message, this is what my final project tree looks like:

1 Like

Small optimization suggestion.

You don’t have to copy the CAN input with gear selector position to a number.
I created the number to have something to put on the axis.
You can directly put the CAN input channel “c_gearSelectorPosition” as the table axis.
You save one number function that way.

I will update my answer.

1 Like