Saturday, January 26, 2013

Ready, set, optimize!

Alright, finally I had time to grab my solder iron and punish the naughty GSM shield for being such a greedy pig when it comes to efficiency in power consumption.

When we look more closely at the shield schematic, we can see that NETLIGHT and STATUS pins of SIM900 control the transistors which turn on and off the leds, powered from Arduinos +5V input via 300 ohm resistors R21 and R20. There's also the "shield powered" led that is always on when, as the name implies, the shield receives input power, regardless whether the GSM module is powered or not. Very wasteful when thinking about power efficiency, so I started with that first:


Actually I haven't ever done any operations on such a small SMD components before, so after unsoldering the R1 the end result was quite far from satisfactory: both copped pads under the resistor were ripped off because of too high temperature, excess force and prolonged heat exposure. Oh well, not that I need the "shield powered" LED anyway..

Before removing the R1 the power consumption of the SeeedStudio GSM shield was 12.2 mA (shield powered, but SIM900 not turned on) and 23.4 mA (SIM900 in sleep mode) when powered with external +5V lab supply (HP 6632B). After removal of R1 and thus disabling the LED, power consumption drops to 9.1 mA and 20.3 mA, respectively. This brings savings of 3.1 mA. Nice.

Wiser from this incident, I practiced desoldering a little bit with old PC motherboard and found a suitable removal procedure consisting of adding liquid flux, new solder and then removing everything with a solder wick. Then add little bit more solder to both ends of the resistor, heat one end with solder iron while lifting it with tweezers. Then repeat this with the other end and finally the resistor can be removed.

 I removed the R20 and R21 resistors and soldered a breadboard jump wire to bypass the LEDs. This time no solder pads were harmed and thus the procedure is reversible. The transistors Q3 and Q4 now connect our NETLIGHT and STATUS wires to ground when signaled by SIM900, making it posssible not only to put the GSM power and/or activity leds on the enclosure if needed, but also it's now easy to check the power status of the GSM module. Before this, the only way to see if the module is powered was to send AT commands and wait for the answer. Actually this was one of the things that annoyed me about this shield from the start. Luckily now only one digitalRead is needed.

It could have been possible to remove the transistor and tap into the NETLIGHT and STATUS pins of the SIM900 directly, but leaving them behind transistors is safer since the module uses lower voltage than rest of the device. It could have been possible to destroy the whole chip or at least the output pins with software by simply switching the pin mode on Atmega side to output and signaling +5V. Puff, there goes the magic smoke.

Since there isn't a nice way to attach strain relief to the jumper wires,  I used hot glue (again) to attach the proximal ends to the PCB to make sure all the vibration and shaking in the car doesn't cause the cables to come loose.

Now, after bypassing also the STATUS led and rewiring the NETLIGHT led (blinks once every 2800 ms, so not a concern in this case), I've managed to reduce the sleep mode consumption from 23.4 to 10.2 mA! Those LEDs really are gluttonious beasts! Then I tried inputting +12V onto the shield directly via its "low ground current, low-dropout voltage regulator", the MIC29302. Low ground current my ass. Increasing the voltage from +5V to +12V increases the quiescent current (=ground current) linearly from 10.2 mA back to 21.8 mA! And that is even without powering the GSM module! So, in this case it is better to use the 7805 to drop the voltage from +12V to +5V and distribute that to the GSM shield. If someone knows better alternatives, I'm all ears.

All in all, the ChiliCAN now consumes 14.3 mA when all the chips are sleeping (i.e., when there's no CAN traffic and no calls are being made). That constitutes maybe 90% of the time. When the heater is on (or otherwise CAN bus is active), the consumption wanders between 30 and 55 mA. During phone calls it lies around 100-200 mA having maximum peaks of 1.5 A, but those are quite short bursts, having almost nil effect on battery life. If we assume average consumption of 17.2 mA, it would take almost 4 months for ChiliCAN to deplete my 95 Ah car battery to 50% charge. I could live with those numbers :)

Saturday, January 19, 2013

Soft chippy, warm chippy, little chunk of RAM. Happy chippy, sleepy chippy, purr purr purr..

Like Sheldon Cooper, also the ChiliCAN needs a good night's sleep. I've been tinkering power optimization features and I must say the results so far are pretty good!

Here's the list of tricks that I've found by reading the datasheets and various articles on the web related to Arduino power saving:

  • MCP2551 CAN transceiver can be put to sleep via the Rs-pin. Just control it via one of the Atmega328 output pins via 10k resistor (+5V in sleep mode, 0V awake), and we can save around 4 milliamps.
  • Atmega328p has various power saving modes, and I wanted to use the most aggressive one (SLEEP_MODE_PWR_DOWN), which reduces the power consumption to less than few hundred microamps! It can then wake up with an interrupt generated by either the CAN controller or the GSM module.
  • MCP2515 CAN controller has a sleep mode as well, enabled with SPI command. Before that we must enable the CANINTE.WAKIE interrupt signaling and connect the interrupt pin to INT0/1 on Atmega328p. Then, when a new CAN frame is received, interrupt is generated and the CPU can also kicked out of his silicon bed. Warning: The first CAN frame is always discarded and does not end up into the receive buffer (I think the sleep mode of both the transceiver and controller cause this). However in my setup it doesn't concern me, since the signal from key fob light button is not in the first CAN frame in the burst of messages sent to the bus when button is pressed and the car wakes up from its slumber. Another pitfall can be found in the wake up routine of MCP2515: If we want to wake up the controller (for example when the interrupt is generated by GSM module and not the controller), then it must be done by generating the CANINTF.WAKIF interrupt by ourself, and NOT the operation mode switch by SPI interface. The latter DOES NOT WORK! This is kind of weird, since the SPI interface is specified to be active even when in sleep mode. Reading its registers seems to work, but chancing the CANCTRL has no effect. Anyway, putting the controller to sleep gives us savings of around 3-4 mA.
  • Ditch the AEM and consequentially, be able to get rid of the grounding relay as well. Naturally, this has no effect on sleep mode power savings directly, but since the relay is a power hog (~ 50mA when switched on!), getting rid of it enables us to use smaller and more efficient voltage regulator (those usually have also lower maximum output current). 
  • Switch from 7805 to LM2936Z-5. The 7805 has in my tests shown quiescent current (waste current generated by the regulator even without any load) of more than 4 mA, where as the LM2936 is much more efficient, having quiescent current measured only in tens or hundreds of microamps, depending on the load. Unfortunately its maximum output current is 50 mA which is way too low if we want to use the GSM module as well.  
So, putting all the chips to sleep and using other aforementioned power saving tricks, I managed to get the sleep mode consumption down to 400 MICROamps! :) Now I don't have to worry anymore about accidentally emptying the car battery!  

Now, the measurements above are done without the Seeedstudio GSM module, because it is completely another beast: 
  • The SIM900 GSM chip itself doesn't consume that much in sleep, its specified to be around  1-1.5 mA, but then again it has a peak current consumption of 2 amps during network registration and other wireless activity, which makes it little bit difficult to find suitable but efficient power supply. 
  • The GSM shield has its own power regulator MIC29302BU. It is a low voltage drop regulator that can use Arduinos +5V and will provide 4.1 volts (adjustable) for the rest of the GSM shield to use. It is also able to handle the peak currents required by SIM900. Unfortunately it has a quiescent current of around 8 mA when idle, which is not that good.
  • The shield has a "input power on" LED as well as an actual "power on" LED that is lit when SIM900 is turned on. I'm not sure of their forward voltage drop, so it's hard to guess their current consumption. It's maybe around 2.7 mA + 9 mA when fed with input +5V, if assuming voltage drop of 2.3 V (green SMD led). Also there's a orange GSM activity led, but it's on only intermittently (one blink every 2-3 seconds).
  • The total consumption of the shield when the SIM900 is not even powered  is 12.6 mA! 
  • When powered and in sleep mode, the consumption increases to 23.6 mA, having bursts of 36.2 mA every 3 seconds. 
  • The total consumption of the whole device (7805 as the regulator, since LM2936 doesn't output enough juice for the GPS shield) when all the chips are in sleep mode is 27.4 mA (bursts of up to 40 mA every 3 seconds). 
It's quite clear that the SeeedStudio GPRS shield v1.4 is not designed for low power consumption in mind, otherwise it would have included a more efficient power regulator and a way to either disable the LEDs or give a way to control them for example with PWM. Since the MIC29302 is intended for automotive applications and has maximum input voltage of +60V, it should  be safe to power the whole device with this regulator. However while Atmega328p and MCP2515 can operate with 4.1V, the MCP2551 CAN controller needs at least 4.5V, which is then too much for the SIM900. So, another regulator is anyway needed.  

What about LM2936 for the main board and then power the shield with car battery directly? I looked at the LED configuration in the GSM shield schematics and found out that the LEDs are powered straight from the VIN (i.e. before the regulator), and if we give the shield input voltage of +12V without changing also the resistors, LED consumption would rise to tens of milliamps (probably burning them, if not at idle, but at least when the car alternator is running..)  So in this case little bit of resoldering would be needed anyway. 



Wednesday, January 16, 2013

Debugging in -25C...

Howdy!

The name of this post kind of says it all. Sitting in the car with a laptop and tapping on the keyboard while exhaling visible moisture which might make me look like a living steam engine. Trying to fix relentlessly the few remaining bugs, hoping that the laptop battery would last long enough, even though part of me wishes that the laptop would generate more heat.  At least the parking heater works!

For the past few days I've been building the remote heater starter and finally ChiliCAN v0.1 was born! It resembles little bit those implementations that I wrote about in the first post, but don't let the version number confuse you. This one speaks CAN and has multiple additional functions in addition to it's raison d'ĂȘtre: flipping on the relay and making the car a warm haven amidst the hostile environment that the Northern Finland is now at this time of the year.


Let's see what the little controller box has eaten: 
Ok,  it's not going to win any beauty contests, but it does what it's supposed to do.


The schematic is quite similar to what Arduino and the CAN shield would be when combined together. On the left is a separate USB breakout board, since it is not needed unless there is a need for debugging, giving manual test commands via the COM port or re-flashing the firmware. So the list of components is quite familiar: Atmega328p, MCP2515 CAN controller, MCP2551 can transceiver. A relay for grounding the AEM control pin (gives better isolation than grounding it directly via a transistor). The 7805 constant +5V voltage regulator + few passive components. Under the ribbon cable is also a SPI header for easy access to debugging with oscilloscope or maybe BusPirate (actually I ordered it a while back, but haven't yet tested it).

There's a extra 5A car fuse, isolated and kept in place with a hot glue, but now it's kind of deprecated since I have a main fuse outside the case for extra safety. Also the connectors are insulated with hot glue, and that with the IP65 protected case should give ample protection against moisture.  I still have to spray the board with a coating of protective lacquer, but that's only after extensive testing.

Then there's the female headers, resembling little bit the headers in Arduino board. And what's with the antenna?



Yup! That's the Arduino GPRS shield based on the SIM900 chip. I didn't have guts to start dismantling it, so I installed the Arduino type headers and laid the shield on top of the main board. I didn't want to use the built-in SMA-connector on the right side of the shield since that would cause both placement problems as well as increase my worries of poor insulation. So I used a left over WiFi SMA->U.FL extension wire from the Asus Maximus V Formula motheboard that I recently installed. I didn't have any use for desktop WiFi, so why not put the nice cable to use. Actually quite many of the parts here are left-overs or parts that have been recycled from old devices. There was also a long WiFi antenna included with the mother board, but I decided to use the one shipped with the GPRS shield.  

Sadly after preliminary testing I had to conclude that the Arduino+GRPS shield+CAN shield combination isn't going to work so nicely for two reasons. Separately they work quite fine, but all the combined code requires more memory than the measly 2Kb that theAtmega328p has to offer. This resulted in numerous random crashes, weird behaviour or just lack of functioning. This problem could be solved with optimization tricks, such as better memory utilization by removing unnecessarily large parameters and variables, and moving some parts out of SRAM to flash memory etc. 

However the much bigger problem would emerge when looking at the power consumption. Even when the sleep mode was enabled (in which text messages and calls could still be received) , the total amount of juice sucked by the device was around 80-90 mA. Although the sleep functionality of Atmega and CAN controller are not yet utilized by my code, the portion of power consumption by the SIM900 is almost half of the total even though it is in sleep mode ! Maybe I'm doing something wrong here, since according to the specs the GPRS module should consume only around 1-2 mA when dozing. 

For now as a heater start signal I will be using the yellow light button on the wireless key fob. Luckily the parking spot for my Volvo is almost right below my apartment window, so it is in the wireless range of the key fob and I will be able to use it to start the heater from the warmth of my house :) 

Pressing the light button 4 times (turning the car interior and exterior lights on-off-on-off in a time period of 10 seconds will start the heater. Turning it off is done in the same manner. I can also check the heater status with the fob: When pressing the light button  (regardless whether the sequence ends up in starting to heater or not), the car headlights are blinked 1-4 times. One blink means heater is off, two blinks: heater is either starting or stopping, three blinks: heater is on, four blinks: there is an error condition.



Here's the device ready for testing! Leftmost green led is for status. Next (yellow) is CAN traffic indicator (actually it doesn't blink for every CAN frame, since then it would just stay lit when connected to the car because of the huge amount of CAN traffic going on all the time. Instead, it blinks only when sending messages or receiving ones that have some inherent importance to us.).The third LED is a heater status indicator and fourth one is an error LED. I might later print labels and other stuff on the case with silk screen technique.


Here is the wiring harness for extending the AEM connector, nicely sleeved for making it look less like a botch job for what it really is. I tried for quite many hours to find suitable male/female connectors compatible with the 4-pin one that AEM and its harness has, but without any result. So I ended up having 4 separate connectors, one for each AEM pin. 

Then there are two DB9 standard CAN connectors. Leftmost has 12V connected to its pin #9 and is meant for connecting the ChiliCAN, and the right one is an extra debugging/tracing/logging CAN cable carrying only CAN-L, CAN-H and ground wires. Then there's extra fuse housing and the screw terminal to put the wires together. That + numerous cable ties give pretty good strain relief. 

I have to remind you that this is still going to be temporary installation as I may not even keep the AEM beyond the first few days of testing, so this not-so-elaborate setup will have to do for now.  Ok, so maybe I'm going to keep these in place until when outside temperatures are easier to count in celcius degrees than Kelvins.


Here's the final setup. Installing these separate dangling wires to AEM connector with  "relative safety" requires either that the negative wire from the car battery is detached or at least that the AEM fuse is removed. Also good electrical insulation tape is necessary. Did I mention botch job?

Later I might bypass the AEM connector altogether and connect the ChiliCAN directly to the Rear Electronic Module (REM) where the AEM wiring is originated.


Inspired by the stuff the guys at the Swedish Volvo forum have been doing, I too decided to add menu feature to the ChiliCAN. The menu can be accessed by keeping the cruise zero button pressed for two seconds.  The +/- buttons are used in navigating and another zero button press makes a selection. The return button exits the menu.

Using cruise buttons doesn't interfere with the normal cruise functionality unless we have turned it on before entering the menu. And even then the cruise buttons work normally and are not hijacked in any way.  Another, more familiar way of using the DIM menu would have been with SWM control stalk, but then we would have been forced to hijack the control stalk and I'm not sure if that can be done via CAN bus.

Heater can be turned on and off via the menu. Here it's status is shown (off / on / starting / stopping / error). It's handy to see the battery voltage without having to go crawl under the hood (or in case of S80, the trunk) with a multi meter. The various bits of information are queried by the ChiliCAN from CEM via diagnostic messages.


 It can be quite informative to see the coolant temperature here, since it gives rough estimation of how cold the engine is and whether you should start the heater. This makes it much easier to do rough guesses of how long should you keep the heater on to get the cabin and the engine comfortable. And of course, this isn't limited to the diesel/petrol parking heater, but could be used in conjunction with any additional heaters. When my Ardic broke down a while back, I got an electrical block heater (coolant heater) installed, but I wasn't (and still I'm not) quite sure how effective it is in hard metrics. With ChiliCAN I can now easily be able to see how well (or badly)  it really works.

One feature to tinker in the future would be the enabling of the water pump in Ardic in conjuction with the electrical coolant heater. That would give more even spread of the heat, since the block heater doesn't have its own water pump and is just heating one part of the coolant circulation, hoping that the difference in thecoolant temperature itself moves the liquid around a bit.



 Here we can see the GSM module status. Code isn't included in the firmware yet, since the memory optimization hasn't been done yet.


There is still quite a lot of things to do, but priority is now in lowering the energy consumption. After that, I might start thinking about having features little bit like what Volvo has to offer in their newest models: Volvo On Call mobile app :)

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!

Monday, January 7, 2013

Dissection of AEM

Hello all!

As I wrote in earlier post, I had enough of banging head against the wall (or in this case, steering wheel) and after numerous failures regarding controlling the Ardic via CAN bus, I decided to go with the flow and ordered the Accessory Electronic Module (AEM) that simplifies that task quite a bit. All one needs is to connect one of the control pins to ground, after which AEM asks CEM to turn on the heater. In theory, I might be able to emulate the functionality of AEM in this matter, however there's no going around purchasing the AEM anyway, since both the module and CEM need to be programmed at Volvo Service to enable this functionality. Only after they are programmed, I'm (hopefully) able to reverse engineer the AEM messaging and emulate it with my own device, making the AEM useless. Whereas without programming, CEM doesn't understand what AEM is saying, and AEM doesn't know what to say. Sounds like a date between a bimbo and a geek.

It's been few weeks since I ordered the AEM, and all this time it has been lingering somewhere in the limbo of finnish post services. Last time something like that happened was one year ago when I ordered bunch of electronics from DealExtreme. Turns out it had been waiting for me for three weeks at the nearest post office 200m away - nobody just bothered to scan it when it arrived! Anyway, finally today I received the module, and of course, I had to pry it open!


Heater (and other functionalities) are controlled by this multi-pin connector. Pin 1: +12V output. Pin 2: Ground. Pin 3: Parking heater enable signal (connect to ground to enable). 4-pin connector is the AEM connector explained in earlier post: Pin 1 (lower left): +12V input. Pin 2 (upper left): ground. Pin 3: (lower right): CAN high signal, Pin 4 (upper right): CAN low signal.


The main cover can be opened by releasing the clips, so at this stage we can continue the dissection without a fear of voiding the warranty.

Let's see what it has eaten:

The PCB is covered with lacquer resembling substance, presumably to protect it from moisture and corrosion. However this makes some of the IC markings unreadable.

Starting for top left corner:
1st row: left: ?. middle: BTS611L1 (smart two channel high side power switch)
2nd row: TLE 4279 (5V low drop voltage regulator)
3rd row: Left: ? Right: ?
4th row: middle: Infineon TLE 6236G (smart octal low side switch)  Right: ?
5th row: 2 x CD4010BQ (CMOS hex buffer)

I didn't feel like removing the metal shield, since that would quite likely leave marks suspicious enough to void the warranty. I might do that later though after AEM has made itself useless :)

Now, some testing:

As you can see, it consumes around 30mA when idle. Not bad, at least now I have some kind of reference to use what kind of power consumption is acceptable.  

I tried  to communicate with it via manual diagnostic commands as well as VIDA, but it didn't react in any way, nor did it send any CAN frames when powered on. Just for a fun I grounded the Pin 3 to create a parking heater enable signal, but nothing happened, just as expected for a device without any programming.

For a moment I thought it might be damanged (either DOA or broken by my endless curiosity) since it just lied there silently, but then I realized it still might be ACKing all CAN bus messages since SardineCAN was sending CAN frames succesfully. In that case it wouldn't be completely dead and might be just lacking suitable firmware. To test this hypothesis I removed the AEM from the bus and immediately SardineCAN went haywire since now there wasn't any device on the network that acknowledges the messages it sends. My assumption is then that the AEM is delivered as tabula rasa condition and it lacks all the functionality except the most basic CAN protocol stuff, such as ACKing messages on the bus. I suppose it doesn't even know it's CAN address yet. How cute.

Next stop: Volvo Service