Monday, January 14, 2013

Reverse engineering AEM: Part deux

Today I had the appointment with Volvo Service for AEM reprogramming, and it was quite a quick operation. After 20 minutes a hefty sum of 80 euros in my wallet was magically converted into bits and bytes to give breath of life to the module. And alive it was.

The wizards of the garage were quite amused to see the test setup: AEM was dangling freely in the trunk, its movement restricted only by the AEM cord.  I hadn't bothered to drill any holes to vehicle chassis since I had plans to ditch the module anyway after some testing and  reverse engineering. As a makeshift remote control signaler, I used a dongle consisting of rs-232 connector with two of its pins connected. When connected to a remote control box cable (substituting the control box itself, since it's not ready yet), the AEM control pin #3 is shorted to ground and the heater is supposed to engage automatically. Against all the odds everything worked out in the first time, and in just few seconds the sweet smell of burning diesel was reaching my olfactory nerves. Yay!

When hooked up to CAN logger, we can see the AEM broadcast idle with CAN id 01a00006:

01 a0 00 06 : 00 00 00 00 00 04 03 00
01 a0 00 06 : 00 00 00 00 00 00 03 00
01 a0 00 06 : 00 00 00 00 00 06 03 00


After bit of testing its functionality with VIDA, I managed to pinpoint the most important data locations:

  1. data byte: Always 0x00 ?
  2. data byte: Always 0x00 ?
  3. data byte: Always 0x00 ?
  4. data byte: Always 0x00 ? 
  5. data byte: Always 0x00 ?
  6. data byte:  High nibble: radio mute signal: 4=initiated by telephone, 8=initiated by parking assistance Low nibble: alternates in idle between 0/4/6. Meaning unknown.
  7. data byte:  High nibble: call start (remote parking heater enable): 0=off, 6=start, 4=stop, 2=on.              Low nibble: operating mode(?): When powered, one message with 0x00, then several messages with 0x01 until it receives a CAN frame sent by any other Volvo CAN module. After that, the low nibble is always 0x3.
  8. data byte:  Parking assistance proximity sensor: ranges from 0x7f (2 meters) to 0x10 (0 meters). 0x00 is off.  This sends signal to audio module to play a buzzer/beep signal on the speakers on various intervals depending on the proximity distance.

We can also request various parameters from AEM via diagnostic messages (in the same way as explained in previous blog posts). The module responds with diagnostic CAN id of 0x00810001 and its module id is 0x52.

AEM voltage:
00 0f ff fe cd 52 a6 1a 01 01 00 00

00 81 00 01 cd 52 e6 1a 01 5f 00 00 // 11.88V
00 81 00 01 cd 52 e6 1a 01 60 00 00 // 12V
00 81 00 01 cd 52 e6 1a 01 61 00 00 // 12.13V

Callstart supply
00 0f ff fe cd 52 a6 5f 21 01 00 00 
00 81 00 01 cd 52 e6 5f 21 02 00 00 // not-active

Callstart active
00 0f ff fe cd 52 a6 5f 20 01 00 00 
00 81 00 01 cd 52 e6 5f 20 01 00 00  // no
00 81 00 01 cd 52 e6 5f 20 00 00 00  // yes

Relay: electrical preheater (note: this isn't our remote control relay, but a different heater functionality).
00 0f ff fe cd 52 a6 5f 10 01 00 00 
00 81 00 01 cd 52 e6 5f 10 02 00 00  // not active

And activation functionality for testing (used in our reverse engineering):

Callstart enable:
00 0f ff fe cc 52 b2 02 01 00 00 00 <- enable
00 81 00 01 cb 52 f2 02 00 00 00 00 <- ACK
01 a0 00 06 00 00 00 00 00 04 63 00 <- AEM: start the heater
01 a0 00 06 00 00 00 00 00 04 23 00 <- AEM: keep the heater enabled
01 a0 00 06 00 00 00 00 00 00 23 00 
01 a0 00 06 00 00 00 00 00 06 23 00 

...

Parking sensor buzzer : simulates proximity from 2m to 0m
00 0f ff fe cb 52 b2 01 00 00 00 00 
00 81 00 01 cb 52 f2 01 00 00 00 00 
01 a0 00 06 00 00 00 00 00 04 03 7f  <- AEM sensor: 2 meters
01 a0 00 06 00 00 00 00 00 00 03 7f 
01 a0 00 06 00 00 00 00 00 04 03 7c 
01 a0 00 06 00 00 00 00 00 04 03 79 
....
01 a0 00 06 00 00 00 00 00 04 03 10  <- AEM sensor: 0 meters


The disable command  seems to be the same for all the different activation test functions:
00 0f ff fe ca 52 a0 00 00 00 00 00 
00 81 00 01 ca 52 e0 00 00 00 00 00 

Remind you that these messages are the result of  testing of AEM with VIDA on my lab workbench and I haven't made sure if these values have any real effect in the car. If you have your own CAN transceiver and you are  in need of a, say radio mute functionality, but don't want to shell out money for the AEM, it might be worth a try to replicate these messages. Enabling these functionalities normally requires reprogramming the AEM or CEM or both, but for some reason it seems to be possible to turn on some options (for example the audio mute) with diagnostic messages, so maybe it's not the AEM that needs reprogramming any more, but the modules that need to interpret those messages (AUM & CEM in this case).

Anyway, if you hook up your own CAN module to mimic AEM, in best case scenario you might not need AEM at all, but just the CEM reprogramming. Though it might be interesting  to see if  someone manages to convince Volvo service to modify the CarConfig to include AEM even though it's not really physically there :)

"- So you want us to install the application #9499904 to enable AEM in your car?
"-Affirmitive."
"-But according to the ECU scan, there is no AEM installed."

"-That's correct."

"- Sigh... Also you want to have the #8690151 remote heater start application as well as the #8637215 parking assistance application?"
"-You got that right."
"-But sir, he AEM has to be installed in order to use those functions!"
"-I'm perfectly aware of that."
"-..?"


UPDATE: Starting the heater by emulating AEM does work!

7 comments:

  1. You have done very great work, especially with your open source project sardine and your sleep code on arduino and mcp2515. Thanks for the all time well documented work, carry on :) .

    Planning to release a diy solution in my country on canbus extending :) as well. If it gets positive resonance i think it could be a use for the whole Volvo can bus community.

    But have one question on the logic about getting the battery voltage.

    The diagnostic request should be:
    Cmd: 00 0f ff fe | cd 40 a6 1a 02 01 00 00
    Reply 00 80 00 03 | cd 40 e6 1a 02 60 00 00

    60 in Hex should represent 12V no problem at all.
    So 5F in Hex is 1011111 in binary.
    The first signs in binary are 1011 and in dez conversation are 11 right? So there is 111 in binary left for fraction. How do you get to 88 when the voltage should be 11,88V.

    Best regards:
    Lukas (working on V70II)

    ReplyDelete
  2. Hi Lukas!
    and thanks for the kind words.

    The voltage calculation is just simple binary arithmetic. Actually not even bitwise logic is needed. First, 5F (hex) = 95 (dec). Now since the lowest 3 bits are the decimal fraction, then 95 / 8 = 11.875 rounded to 11.88. I just cast the original number to floating point and then do the division. Alternatively, you can think of the division of the decimal part like this: 0111 (bin) / 1000 (bin) = 0.875 (in case you want to keep the integer and fractional parts separate, but there should be no need for it)

    Your project sounds interesting! Looking forward to seeing what you come up with!


    Br,
    Olaf

    ReplyDelete
  3. Wow. Last year I actually googled around if anyone had any projects to control Volvo's Ardic via CAN-bus.
    I wish I had found this blog earlier, I already bought the AEM module. Not sure though it would be worth my time unless someone had a drop-in replacement ready. ;)

    Keep up the good work!

    ReplyDelete
    Replies
    1. Guys,

      just made some tests on the "test polygon" here. It is just CEM with CPM connected, no other modules. CEM is from car without any heater configured (i.e. VIDA does not see it thus no CPM diagnostics is allowed).

      However sending any of these to this CEM:

      -> 40 B1 5F 3B 01 01 80 heater stop
      -> 40 B1 5F 3B 01 01 81 heater start
      -> 40 B1 5F 3B 01 01 84 heater diagnostic start
      -> 40 B1 5F 3B 01 01 83 heater vispstart (whatever it means?)
      -> 40 B1 5F 3B 01 01 85 rest heat start (only water pump active)
      -> 40 B1 5F 3B 01 01 86 operate fuel pump
      -> 40 B1 5F 3B 01 01 87 one activation of fuel pump

      will start the (diesel) heater SW P/N: 08697009 HW P/N: 03731003 over any CEM that I have (both gasoline S80 2000 or gasoline XC70 2.4T 2004).

      Thus no need to have AEM.

      Pavel

      Delete
  4. Guys,
    Its a great blog. I am curious to know, if there is information about CAN protocol followed - between
    main ECU and sensors like NOX.

    Regards,
    -Rajan

    ReplyDelete
  5. Hey I was looking at your sardine arduino project. I was wondering if you think it could work with a toyota prius's obd port? I'm basically trying to learn how to make new key fobs for my car. Toyota wants over 600 dollars for a single key. I could go to a locksmith but I'm also a software engineer and I think it would be fun to do this with an arduino. You mentioned your program as is does not connect to the obd port under the steering wheel. Why was that exactly? I wonder if that's only a problem with certain models of cars?

    ReplyDelete