Jump to content

Volvo power steering pump CAN on a Link G4X P&P


Venomancer

Recommended Posts

Hello. I have a Link G4X P&P for Evo I-III and I would like to control my Volvo Electric Power Steering Pump via CAN. 
Does anyone have the ability to help me out? I found some info about the can codes that operate the pump, but I'm not smart enough to know what they mean and how to make it work in the PC Link Software.

Here is a link to the article: https://rusefi.com/forum/viewtopic.php?p=45441#p45441

Here are the LUA codes:

 

-- "alive" message from pump
  canRxAdd(0x1B200002)
   
  local pumpAlive = Timer.new()
   
  function onCanRx(bus, id, dlc, data)
  if id == 0x1B200002 then
  pumpAlive:reset()
  end
  end
   
  local data_0x1ae0092c = { 0x00, 0x00, 0x22, 0xe0, 0x41, 0x90, 0x00, 0x00 }
  local data_0x02104136 = { 0xbb, 0x00, 0x3f, 0xff, 0x06, 0xe0, 0x00, 0x00 }
   
  local slowCounter = 0
  local slowRoll = 0
   
  local slowRollTable = { 0x00, 0x40, 0x80, 0xC0 }
   
  -- car stopped is 0
  -- car "moving fast" is 6000 (whatever that means?)
  local speedVal = 1000
   
  function onTick()
  if pumpAlive:getElapsedSeconds() < 1 then
  -- Ignition on frame: sends every 30th speed frame
  if slowCounter == 0 then
  -- cycle through 0, 40, 80, c0
  slowRoll = (slowRoll + 1) & 3
  data_0x1ae0092c[1] = slowRollTable[slowRoll + 1]
   
  txCan(1, 0x1ae0092c, 1, data_0x1ae0092c)
   
  slowCounter = 30
  end
   
  slowCounter = slowCounter - 1
   
  data_0x02104136[7] = (speedVal >> 8) & 0xFF
  data_0x02104136[8] = speedVal & 0xFF
   
  -- pump speed frame
  txCan(1, 0x02104136, 1, data_0x02104136)
  end
  end
   
  setTickRate(71)



Also, I know that MAXX ECU has cracked the code to make this pump works on their CAN and there is some info about this on the exact same threat on this forum: 
maxxecu sends IDs 2104136 and 1ae0092c to the pump

2104136 is ~71.4hz
1ae0092c is ~2.38hz

exact 30:1 ratio

pump responds at 11.84hz, which is 1/6 the rate of 2104136

I will be very thankful if anyone has the ability to help me out with this!

Cheers!

Link to comment
Share on other sites

From my own research, the pump is really expecting two things.

A keep alive and a input for pwm. 

The keep alive seems to be on ID 1AE0092c (Extended)

The PWM from the ECU is on ID 2104136 (Extended)

Here is some Arduino code that controls it. The coder also sells a stand alone controller as well which looks nice. 
https://github.com/NMSTEC/Volvo_EPS_FREE/blob/main/src/main.cpp

https://www.nmstec.ca/product/psc/

Adam might have a way to have a custom stream but the rolling keep alive might be a head scratcher (for me at least) interested to see how this pans out.

Link to comment
Share on other sites

3 hours ago, wastegate said:

From my own research, the pump is really expecting two things.

A keep alive and a input for pwm. 

The keep alive seems to be on ID 1AE0092c (Extended)

The PWM from the ECU is on ID 2104136 (Extended)

Here is some Arduino code that controls it. The coder also sells a stand alone controller as well which looks nice. 
https://github.com/NMSTEC/Volvo_EPS_FREE/blob/main/src/main.cpp

https://www.nmstec.ca/product/psc/

Adam might have a way to have a custom stream but the rolling keep alive might be a head scratcher (for me at least) interested to see how this pans out.

Thank you for the reply. I don't understand any of this... The pump is currently switched on via AUX 3 with the condition of the engine running. Not sure about that Keep Alive you're talking about, but I would like to be able to control the the pump via CAN, so it can be on 100% when VS is below 40kph and to be 0% when over 200kmh or something like that.

Link to comment
Share on other sites

From what I can tell, based purely on what I've looked into, the pump will "default" to 70% with no CAN input.

The keepalive is a heart beat signal from the ecu, so effectively turning on the PWM of the pump itself, enabling it to be controlled 0-100%. 
If the keep alive signal is not there, it will default to 70%.

Once the keep alive is active, the PWM can be changed. 
It "might" be as simple as giving the keep alive the rpm parameter, so as long as the engine is running, it has that keep alive signal, but then it might not and might be expecting a certain counter.. You just need to know what bytes within that frame need to change. I'm very novice on code and not quite making out the C++ of the Arduino code but should be pretty easy for a coder to say what bytes need changing etc from that code example. 

Link to comment
Share on other sites

Come on guys is there really no one here who is capable of doing this? I'm willing to pay you if that is whats stopping you from helping out.

It seems as if there are several controllers online that can control the pump via GPS speed signal, however, I would like to do so via the Link. Didn't spend that much money on it if it can't control one pump... 

It's really a shame :( 

Link to comment
Share on other sites

15 minutes ago, Adamw said:

It will likely be possible.  I will take a look when I have a spare half hour but I mostly look after the forum in my own time and im reasonably busy with other stuff right now. You can bump the thread to remind me if I haven't replied here within say about a week.  

Thank you, Adam. As I said, I will gladly pay for your time if you decide.

Link to comment
Share on other sites

Can't do 2104136 at ~71.4hz and 1ae0092c at ~2.38hz, closest you can get on that with custom CAN would be 50Hz and 2Hz.

1ae0092c is a hex number and is '450890028' in decimal format, this will be an extended Id
I assume 2104136 is also a hex number based on the above code, this will be '34619702' in decimal format and will also be an extended CAN Id.

To get the fixed values in the streams use any runtime and give it a multiplier of 0 and an offset that matches the fixed offset as shown below for the 0x1ae0092c ID:
local data_0x1ae0092c = { 0x00, 0x00, 0x22, 0xe0, 0x41, 0x90, 0x00, 0x00 }
image.png.0cdd0d2e4df3c4fd1cce8d7c3f6d4ca3.png
Note that I've done it as 2 16bit numbers instead of 4 8 bit numbers, 0x22, 0xe0 = 0x22e0 = 8298.
image.png.cb5edc91501b66b471ca139a1960c31a.png

The following code says that the 2nd byte (assuming 0 list indexing in the above code) in the 0x1ae0092c id message changes each sent message.

slowRoll = (slowRoll + 1) & 3
data_0x1ae0092c[1] = slowRollTable[slowRoll + 1]

The first message will have '((0 + 1) &(bitwise AND) 3) + 1 = 1+1 = 2' in that byte
The second will have '((1 + 1) & 3) + 1 = 2+1 = 3'
The third will have '((2 + 1) & 3) + 1 = 3+1 = 4'
The fourth will have '((3 + 1) & 3) + 1 = 0+1 = 1'
The fifth will have '((0 + 1) & 3) + 1 = 1+1 = 2' which means the cycle has repeated.

The best way I can think of to replicate this given that you can't do a specific message counter in custom CAN is to use a timer with a max time that won't run out in any drive, the max value of 16,000,000 wouldn't be a bad choice, set the activation to always on and polarity to reset when inactive. Then use a math block setup as below:

image.png.eb8d7c5b9ffecf37c9b0ae9bf0891556.png
Note I haven't tested this setup but the thinking behind it is multiply time by 2 so that you are effectively incrementing every half second (this matches the 2Hz message transmit rate), the '%4' is a modulus operation which should give values of 0, 1, 2, 3 and then adding one will make this value move between 1,2,3 and 4 every half second, then add the math block to byte 1 of the 0x1ae0092c message.

Note: I'm pretty sure the modulus operation isn't working in the current release firmware so you might need to wait for the next firmware release for that bit to work.

 

For the 0x2104136 use the same trick as above for the fixed values (data_0x02104136 = { 0xbb, 0x00, 0x3f, 0xff, 0x06, 0xe0, 0x00, 0x00 }).

and then just put a CAN Aux duty cycle in bytes 7 and 8 (width of 16, Least Significant (LS) byte first and control that CAN Aux duty using a gp pwm output.
 

Link to comment
Share on other sites

10 hours ago, Vaughan said:

Can't do 2104136 at ~71.4hz and 1ae0092c at ~2.38hz, closest you can get on that with custom CAN would be 50Hz and 2Hz.

1ae0092c is a hex number and is '450890028' in decimal format, this will be an extended Id
I assume 2104136 is also a hex number based on the above code, this will be '34619702' in decimal format and will also be an extended CAN Id.

To get the fixed values in the streams use any runtime and give it a multiplier of 0 and an offset that matches the fixed offset as shown below for the 0x1ae0092c ID:
local data_0x1ae0092c = { 0x00, 0x00, 0x22, 0xe0, 0x41, 0x90, 0x00, 0x00 }
image.png.0cdd0d2e4df3c4fd1cce8d7c3f6d4ca3.png
Note that I've done it as 2 16bit numbers instead of 4 8 bit numbers, 0x22, 0xe0 = 0x22e0 = 8298.
image.png.cb5edc91501b66b471ca139a1960c31a.png

The following code says that the 2nd byte (assuming 0 list indexing in the above code) in the 0x1ae0092c id message changes each sent message.

slowRoll = (slowRoll + 1) & 3
data_0x1ae0092c[1] = slowRollTable[slowRoll + 1]

The first message will have '((0 + 1) &(bitwise AND) 3) + 1 = 1+1 = 2' in that byte
The second will have '((1 + 1) & 3) + 1 = 2+1 = 3'
The third will have '((2 + 1) & 3) + 1 = 3+1 = 4'
The fourth will have '((3 + 1) & 3) + 1 = 0+1 = 1'
The fifth will have '((0 + 1) & 3) + 1 = 1+1 = 2' which means the cycle has repeated.

The best way I can think of to replicate this given that you can't do a specific message counter in custom CAN is to use a timer with a max time that won't run out in any drive, the max value of 16,000,000 wouldn't be a bad choice, set the activation to always on and polarity to reset when inactive. Then use a math block setup as below:

image.png.eb8d7c5b9ffecf37c9b0ae9bf0891556.png
Note I haven't tested this setup but the thinking behind it is multiply time by 2 so that you are effectively incrementing every half second (this matches the 2Hz message transmit rate), the '%4' is a modulus operation which should give values of 0, 1, 2, 3 and then adding one will make this value move between 1,2,3 and 4 every half second, then add the math block to byte 1 of the 0x1ae0092c message.

Note: I'm pretty sure the modulus operation isn't working in the current release firmware so you might need to wait for the next firmware release for that bit to work.

 

For the 0x2104136 use the same trick as above for the fixed values (data_0x02104136 = { 0xbb, 0x00, 0x3f, 0xff, 0x06, 0xe0, 0x00, 0x00 }).

and then just put a CAN Aux duty cycle in bytes 7 and 8 (width of 16, Least Significant (LS) byte first and control that CAN Aux duty using a gp pwm output.
 

Oh, man! Thank you for this info! 
I will have to read that some more times unless I'm able to assimilate it and understand all the bits. 

Can I send you the Map so you can do it properly? I will be glad to pay you if you would like me to.

Link to comment
Share on other sites

On 7/31/2023 at 12:39 AM, wastegate said:

This is easier for me to understand than the Lua code originally quoted above.  

It looks like they actually wait to receive an "im awake" message from the steering? (0x1B200002) before sending the speed and counter messages.  That might be a bit tricky to do in the Link user streams.  That may not be needed though, especially since its only being transmitted at 2Hz you would think the steering ecu should be booted up by then.  So we can give it a try without waiting for the Im awake message.  The counter is quite easy, it is just 0x00,0x40, 0x80, 0xC0, which is really just 0/1/2/3 in the 2 most significant bits.  

@Venomancer Can you attach a copy of your tune and tell me what CAN port the steering is wired to and I will set up a couple of streams.  

  

Link to comment
Share on other sites

13 minutes ago, Adamw said:

This is easier for me to understand than the Lua code originally quoted above.  

It looks like they actually wait to receive an "im awake" message from the steering? (0x1B200002) before sending the speed and counter messages.  That might be a bit tricky to do in the Link user streams.  That may not be needed though, especially since its only being transmitted at 2Hz you would think the steering ecu should be booted up by then.  So we can give it a try without waiting for the Im awake message.  The counter is quite easy, it is just 0x00,0x40, 0x80, 0xC0, which is really just 0/1/2/3 in the 2 most significant bits.  

@Venomancer Can you attach a copy of your tune and tell me what CAN port the steering is wired to and I will set up a couple of streams.  

  

Hey Adam! Here is a file of my MAP. Thank you very much! 
The CAN port is Number 2.

3000gt current.pclx

Edited by Venomancer
Forgot an important detail
Link to comment
Share on other sites

Ok, give this a try.  Assist level is varied with GP PWM 1,  0% in this table gives minimum assist level (CAN speed = 6000), 100% DC gives maximum assist level (zero speed).  For testing I have set up this table to be controlled by TPS so you can just press the throttle to see if the assist level changes.  

3000gt Volvo EPAS CAN.pclx

Link to comment
Share on other sites

2 hours ago, Adamw said:

Ok, give this a try.  Assist level is varied with GP PWM 1,  0% in this table gives minimum assist level (CAN speed = 6000), 100% DC gives maximum assist level (zero speed).  For testing I have set up this table to be controlled by TPS so you can just press the throttle to see if the assist level changes.  

3000gt Volvo EPAS CAN.pclx 460.66 kB · 0 downloads

Thank you so much! I will try it now and report back.

Link to comment
Share on other sites

@Adamw It works! When I press the throttle the pump raises its RPM and when I let go, it lowers it. It seems that it cannot go to 0 RPM tho, maybe I should just switch it off with a condition if the wheel speed is over 200km/h.  

Thanks once again!!! I have changed the TPS on the GP PWM graph with Wheel speed, hopefully, it will work that way.

I have one question about the streams, I see that you have used an %Ethanol in there, hopefully, this won't cause trouble when I install a flex fuel sensor to measure the ethanol %. Sorry for my ignorance, I'm just new to all of this and not sure if it is related somehow.

3000gt Volvo EPAS CAN.pclx

Link to comment
Share on other sites

I used ethanol as its the first parameter in the list.  It is just being used to generate a constant, since we are multiplying it by zero then adding an offset it will always output a constant no matter what the actual %ethanol is reading.  

 

7 hours ago, Venomancer said:

When I press the throttle the pump raises its RPM and when I let go, it lowers it. It seems that it cannot go to 0 RPM tho, maybe I should just switch it off with a condition if the wheel speed is over 200km/h.  

They are not meant to turn off, the assist level controls the flow rate of the hydraulic fluid through the system.

 

7 hours ago, Venomancer said:

I have changed the TPS on the GP PWM graph with Wheel speed, hopefully, it will work that way.

Yes, that is the intent, you can put whatever axes you like on there.  Typically wheelspeed Vs a multipostion adjustment knob on the dash.

Link to comment
Share on other sites

  • 1 month later...
On 8/1/2023 at 4:24 AM, Venomancer said:

Come on guys is there really no one here who is capable of doing this? I'm willing to pay you if that is whats stopping you from helping out.

It seems as if there are several controllers online that can control the pump via GPS speed signal, however, I would like to do so via the Link. Didn't spend that much money on it if it can't control one pump... 

It's really a shame :( 

Try asking the creator for help :) He might even suggest to avoid volvo pumps!

Link to comment
Share on other sites

On 8/3/2023 at 6:00 AM, Adamw said:

This is easier for me to understand than the Lua code originally quoted above.  

It looks like they actually wait to receive an "im awake" message from the steering? (0x1B200002) before sending the speed and counter messages.  That might be a bit tricky to do in the Link user streams.  That may not be needed though, especially since its only being transmitted at 2Hz you would think the steering ecu should be booted up by then.  So we can give it a try without waiting for the Im awake message.  The counter is quite easy, it is just 0x00,0x40, 0x80, 0xC0, which is really just 0/1/2/3 in the 2 most significant bits.  

@Venomancer Can you attach a copy of your tune and tell me what CAN port the steering is wired to and I will set up a couple of streams.  

  

Your assumption is correct, there is no need to wait for pump to respond, I just don't like spamming can data until its needed. On my controller I actually check for the correct pump to respond, and have timeouts in case it stops talking.

Technically you don't have to have SPECIFIC timeframes to send the canbus data, just I tried matching to what OEM did. If I recall KAM can be sent every 250ms, while the VSS needs to be sent at most 100ms. Or other way around, I can't remember. 

Recommend you guys use Mopar pumps, volvo is unreliable weak sauce stuff.

Link to comment
Share on other sites

  • 3 weeks later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...