Thursday, 25 January 2018

Calling All P2s

So what is a P2 Volvo you say? Well I did some research and here's the data.

Volvo used the P2 (Platform 2) across a number of models and years.
Here's an overview (all images thanks to WikiPedia or their owner).

S80 1999-2006, Type 184
The classical flagship luxury sedan

V70 2001-2007, Type 285
The sedan but made practical as a family wagen

XC70 2001-2007, Type 295
A raised V70, with AWD, and some tough-looking body parts

S60 2001-2009, Type 384
The smaller compacter sedan

XC90 2003-2014, Type 275
The rugged 5- or 7-seater AWD SUV, like an XC70 but taller all around.
I think this is the best looking of all the P2 vehicles

Another XC90 facelift model, out in the environment it was born for


The fundamentals of my software work on all of these vehicles, however the bus addresses sometimes do change from model year to model year. But don't let that stop you!

So if you own one of the above vehicles, keep following this blog....

Wednesday, 24 January 2018

Success Feels Good! (Part 2)

So following my weekend success (read about it here), I had a day of rest and recovery (Monday) and came home from work on Tuesday inspired and energized to start the next step.

Read before you Write
So what would be the next step? Let's review what I have done so far:

  1. Build and test interface
  2. Write and test my code
  3. Successfully read data from the vehicle and run logic on the data to activate an LED / buzzer on my Arduino breadboard

If you read carefully you will see that up to now I have only been reading the vehicle.

The next step is to write to the vehicle: send it a command to do something, and check that the command was properly executed.

If you do Write, Write Carefully
But you don't send it any sort of random data. You need to know what device you want to write to, know it's address, know the command, and be confident that the command is not dangerous. Ask yourself these questions:

  1. What are you instructing the vehicle to do? 
  2. What will be the expected outcome?
  3. Will it likely have any bad side effects?

For example, I do NOT want to send a random command to the SRS system that may activate the airbags! Neither do I want to send a command to stress any electrical component such as drive an electric motor beyond it's designed limits.

So you do very much need to prepare yourself with knowledge (there is a fair amount on the Internet, start looking) and it is always good to have experience (nothing beats hours in the saddle when learning to ride).

So that's what I did on Tuesday night: after careful study and consideration, I prepared some commands and executed them in the vehicle.

All I wanted to do was light a lamp, and sound a gong. That is a safe area to play in.

And by the end of the night I had achieved:

  • Control of all the lamps on the instrument cluster: low oil, charge lamp, indicator lamps, high-beam, park brake, ABS, general warning lamp, etc. etc. etc.
  • Control of the gong - turning it on and off
  • Knowledge of when the gong in the DIM is active and how it works in response to the commands I send it. It does remain active after the ignition is turned off and the key removed from the ignition for approximately 60 seconds, enough for me.

I also caused an SRS AIRBAG SERVICE URGENT fault and had to clear that with VIDA. Being forewarned is being forearmed as they say, I had VIDA by my side ready to go and deal with any problems when they happen. And that problem did happen.

I now have the knowledge on how to sound the gong and illuminate the yellow warning triangle - which is exactly what I need for my Lights On Ding app.

Time now to start building those commands into my code and test the Arduino... keeping in mind that I am working in a live environment in a fully functional car, and I don't have any intention of damaging anything....

Onwards and upwards!

Tuesday, 23 January 2018

Success Feels Good! (Part 1)

So if you have read up to here you have been following my journey in and around my MY2009 Volvo XC90 car, my Arduino, my (appalling) coding skills, and seen some of the highs I achieved and the lows that I faced.

On the weekend just passed I actually had some great successes in that I had my first Arduino code properly doing what it should.
If you were there you would have heard me whoop for joy, throw my hands up in the air and do a little victory dance behind my car. Lucky the garage door was closed....

My First Volvo App: Lights On Ding

I identified this app as my first app to get something going.
You have to walk before you can run. Start small, grow big.
A concrete goal. Not too complex.

The Goal
Sound the vehicle gong, light the yellow warning triangle on the instrument cluster (the DIM), and ideally also show some text such as LIGHTS! when I have the ignition key out, and the drivers door open, and the lights on to PARK. 
Reason: sometimes I set my lamps to PARK in the garage to turn off my headlamps, and then forget they are on, lock the car and go upstairs.
And then my neighbor comes to visit to tell me my lights are on.
And I'd like to use the gong, the text display and the yellow triangle to make my app look as "original Volvo" as possible. Right down to using the same language. My car speaks German :)

The Method
Breaking down the project into component steps I need to:

  • Decode the CAN bus data
  • Identify the key-in and key-out-of-ignition data 
  • Identify the door-open data, and identify the driver's door open
  • Identify the light-switch-set-to-PARK data
  • Intermediate Goal 1: Print all data to the Arduino serial port to verify the logic on the connected laptop
  • Add logic to AND all of the conditions together
  • Sound a piezo buzzer on my breadboard when all conditions are met, and/or....
  • Light an LED on my breadboard when all conditions are met
  • Make the light flash/buzzer pulse without using Arduino delays()
  • Intermediate Goal 2: have the Arduino sounding the piezo buzzer as a Lamps On warning
If you look at my chosen steps I am deliberately only listening (reading) the CAN bus, I am NOT yet sending any data to the vehicle. It's called playing it safe, learning as you go, gathering experience, walking before you can run, etc etc etc.

So how did I go up to this point?
Basically very well. I had a rainy weekend ahead of me and nothing to hold me back out of the garage, so I decided to throw myself into a weekend of data discovery and practical experience.
Identifying the data was not too hard. I found some using my Excel method, but afterwards I got CanHacker to work and used that to find the other data bytes. And a lot more too!

By the end of the Saturday, I had identified all the data I needed.

Tip: Use a Battery Charger when Playing With Your Car. I have a CTEK intelligent battery charger, only 5A, but enough to offset hopefully a large chunk of the power consumption when the ignition key is out or in PosI. Not enough for PosII, but I don't plan to have the ignition in PosII for too long. Oh, and did I tell you CTEK chargers are also Swedish?

Anyway, back to the normal program. Adding the buzzer and LED to the breadboard was easy enough, 2 different Arduino output pins. I have enough bits and pieces lying around to add around 200 LEDs and a couple of buzzers. Enough for what I needed.
However I quickly disconnected the buzzer, as a bug in my code meant the piezo buzzer was on all the time, and the piezo screech was driving me mad. 
Learning moment: LEDs are your friends, they are nice and silent :).

I also learnt that the difficult part of my work was debugging the running code on the live vehicle: it's cold in the garage, and operating the laptop on the vehicle cargo area floor is simple nowhere near as comfortable as my desk in my house. So how could I program and test the code in my house without being in the cold garage all the time? It is Winter after all.

I could go to the wreckers and buy some modules and hook them up on my workbench and run everything here - but that costs time and money, and I was hungry for a result.

So I wrote some auto-vehicle-detect code. Very simple: the Arduino runs and loops using a dummy CAN bus frame until it detects a real CAN bus frame, and then it switches off the dummy data. This allows me to run and debug without being in the car. And I just write what I need in my dummy data to test whatever I am testing.

By late rainy Sunday afternoon I had stable, working code that ran connected to the car, doing what I wanted, albeit at this stage still using the LED and the (now connected) piezo buzzer.

I call that a great success!

Walk before you run, remember?


(PS: look out for part 2, it's coming, it's good...)








Monday, 22 January 2018

Crash and Burn

Doing stuff like sniffing your CAN bus and trying to get your head around new hardware, new software, new IDE, and new code does generate its casualties.

In the last week since I have started (yes, only a week) I have...

  • Destroyed a genuine Arduino Uno through static charge / voltage spikes which killed the regulator (shorted it) and put 12V on the 5V rail, and killed other devices on the board. Also crashed my connected laptop big-time, but the laptop survived the 12V spike on the 5V USB port.... phew. I had a spare Arduino, and have since ordered 3 more, which arrived on the weekend.
    I now have 4 x Ardunio Unos (all happy clones).
  • Crashed my vehicle's CAN bus by connecting a Ardunio configured for 500kbps to the 125kbps bus. The car's bus shut down. I thought I'd killed the CAN bus shield. I don't have a spare. Maybe even damaged a CAN bus device in the car. But disconnecting the power from the shield brought the car bus back, and analysis of the code revealed the error. Phew. Thank goodness for robust industrial hardened vehicle electronics. Phew.
    Also checked with VIDA afterwards, no error codes logged in the car. Yay.
  • Killed my Arduino compilation. Through my hunt for good example code, I installed many different libraries relating to the CAN bus. Some of these libraries conflicted with each other.
    Learning moment: when you have a successful build that works, take a few moments and document which libraries it is using. You can also avoid conflicts by keeping the .ino files and the library files of the example you are trying all within the same folder, and then the compiler uses those files.
  • Gotten totally fed up with trying to analyse CAN bus data in Excel. You can do it but it is long and tedious. Everyone talks about using CanHacker, and I struggled to find a Arduino sketch that would compile without error for use with CanHacker (closely associated with the last point - multiple libraries produces multiple conflicts).
    But I succeeded! And ended up in the garage at midnight, logging and decoding CAN bus messages...
  • Except then my own sketch no longer compiled. That took another hour or so to hunt down.
At the end of all this I did get somewhere. Where? Watch out for the next blog post....

Sunday, 21 January 2018

Identify Yourself!

So of course playing on a databus is no fun without knowing who is there.

You need to know the unique addresses of all the devices.
They are like the names of your friends - the name or the address is their identity, and with the address known you will get to know the device well, in fact you will learn them off by heart.
Just like many humans, the Volvo P2 devices have 3 x identities. in fact sometimes more.
Let's go through them, remembering always that I am talking about a P2 MY2009 XC90:

1. The static ECU id
Every module in the car is assigned 1 of up to 256 possible single byte static very important ids, from 0x00 to 0xFF. Well actually, 0x00 would never be assigned, so that's 255 ids. These are used by the diagnostic device such as VIDA to address the module directly. See my last blog post for where to find these ids in VIDA - they are hidden in plain sight.
These ids are static because the diagnostic system needs to know who it wants to talk to regardless as to what car is connected.
As an example, we'll use the friendly and very clever CEM (Central Electronics Module).
The CEM has the module id of 0x40 on the low-speed CAN bus and also 0x50 on the high-speed CAN bus - yeah, then CEM is rather special.
However, these are not the frame ids (or message ids) used on the CAN bus.

2. The high-priority message id
On the CAN bus every message has a message id. These are the ids that you see in every CAN bus monitoring tool
When a module, like the CEM, responds to a diagnostic message, it does so using a special CAN bus diagnostic message id, also known as a diagnostic id. This diagnostic id has a higher priority that the normal CAN bus messages, so that it can jump to the front of the queue.
The CEM has a diagnostic message id of 0x00800003.
The response includes an acknowledgement of the request, and the data requested. Interestingly, these messages also contain the ECU address of the device sending the message. We'll study response formats later.... maybe.

3. The normal message id
On the CAN bus each device sends a message with a unique message id. As the message id also determines the priority of the message, the developers (or their tools) very carefully assign these message ids based on the message content and it's priority, not based on the device sending the message. Thus a CEM can, and does, send multiple messages with different message ids. Actually, once you start to think of the CAN bus id as a message id, and not a unique device id, you start to understand the way the CAN bus works a lot easier.
In a Volvo, due to the software used by Volvo designers when designing the bus as a realtime bus system, the message ids vary across model years (MYs) and thus may not be the same in a 2004 XC90 versus a 2009 XC90.
But luckily some messages retain their ids across time and this makes our job a little bit easier.
Also some messages have similar, but not identical, ids, also helping us to understand them.
As an example of message ids, the SWM (Steering Wheel Module) sends data in a few different messages, with one message for the audio buttons, one for the cruise control buttons, and I also believe one for the control stalks.

Finding all the message ids is quite tedious. There should be a clever way, and I'm thinking about that.
But currently, I'm doing the slow, hard, log the bus and figure out who is what by using freqeuency analysis and studying the data content. It's a bit like Neo seeing the matrix....

Tuesday, 16 January 2018

All about Dominance, and being Hidden in Plain Sight

All about Dominance
When VIDA - or any other diagnostic tool - talks to the car, VIDA has it's own CAN bus address 0x000FFFFE. This address is reserved for diagnostic devices, and due to the 0x000 at the start of the address, has the highest priority of all addresses on the bus. It's like being in the Gold Member club, you always get seat 1A with the best service and the best views. And the diagnostic message will always get through.
Tip: Get used to the address 0x000FFFFE - you'll be seeing it a lot.

So why does this address have a higher priority? It's because bit 0 is dominant.
Read the Wiki article on the CAN bus and you will see that 0s have priority.
So ids starting with 0x0000 have priority over 0x000, and 0x000 has priority over 0x00, and 0x00 beats 0x0, etc etc etc.
So you see there is no equality on the bus. 0s win, 1s lose. That's the way it is. Martin Luther King would turn over in his grave if he knew.

Hidden in Plain Sight
So given the nature of CAN bus addressing, where the sender address is known but the recipient address is not specified, meaning that basically every message is broadcast to the entire vehicle universe (the galaxy being inside the car), how does any device know that a diagnostic message to clear DTCs, read settings, load software etc is for that particular device? After all, many devices hang around on the bus, all in their different seats, and all are listening to the messages.
The diagnostic messages are special. I guess they had to be.
Within the 8 data bytes of every diagnostic message you have one byte that specifies the recipient of the message.
One byte. That's 256 possible devices, from 0x00 to 0xFF. That's enough for the P2 vehicles.
So what's the best way to find out these device addresses?
There are two ways:

  1. The Time Consuming Way
    Use VIDA, query each device and then try and determine the device address from a (potentially very large) log file of CAN bus messages. That takes time.

  2. The Easy and Fast Way
    Instead of the above, you can open VIDA, enter in the vehicle profile for any P2 based vehicle you want, and then view the addresses for every possible device directly in VIDA. Now that's what I call being hidden in plain sight.

So Where is This Magical Address Book? It's in VIDA, visible to everyone:
  1. Enter your desired P2 VEHICLE PROFILE
  2. Go to the SOFTWARE tab
  3. On the top, on the right hand side of the screen, click on ADVANCED
  4. The Advanced screen opens. The top section is called ECU information
  5. Drop down the first drop-down list in the ECU information section.
  6. Observe the entries in the list
  7. The first entry is AEM (52), the second BCM (01), the third CCM (29), etc.
    They are sorted alphabetically.
  8. The numbers in the brackets are the device addresses, in hex.
  9. So AEM (52) has diagnostic address 0x52, and the BCM can be found at 0x01, and the CCM is stting in seat 0x29 on the bus, etc. etc.

Using VIDA, I have verified that the address information is the same on a MY2009 XC90, a MY2005 S80, a MY2002 S60, and a C40. So it very strongly suggests that the device diagnostic addresses are constant across the entire P2 range of Volvo vehicles.

Now you know. Enjoy!

Saturday, 13 January 2018

The Hardware

DISCLAIMER - You do all this at YOUR OWN RISK. Everything you do, you are responsible for. Not Me.

Take:
  • 1 x Volvo XC90, any flavour from the P2 range (2003 to 2014)
  • 1 x Arduino Uno or your favourite clone thereof
  • 1 x CAN BUS Shield based on the MCP2515 CAN bus controller - I'm using the CAN-BUS Shield v1.2 from Seeed, but you can use whichever you like
  • Some wire for the CAN bus - I chopped up a nice bright red Ethernet cable to use, but you can use anything
  • A laptop of any flavour so you can run the Arduino IDE
  • Some Arduino source code.
  • A decent but simple serial logger like Realterm

Special Notes:

  • Volvo P2 cars use 29-bit device IDs on the CAN bus
  • The low speed CAN bus runs at 125kbps
  • The CAN bus is a twisted-pair, white and green, and runs throughout the Volvo nearly to every device
  • CAN-L is the green wire in the Volvo
  • CAN-H is the white wire in the Volvo


Method (at your Desk):
  • Install Arduino IDE on your laptop
  • Install Arduino source code in the IDE
  • Mount the CAN BUS shield to the Arduino
  • Connect Arduino to a free USB port on the laptop
  • Load the Arduino code into the Arduino
  • Install Realterm on your laptop and make sure it sees the COM Port
  • Make sure the Arduino initialises the CAN bus shield successfully
  • Make sure Realterm sees the text output of the Arduino after Arduino reboot
  • Study your Volvo wiring diagram and determine where you can best tap into the low-speed CAN bus on your car

Method (in your Garage)

  • Connect the CAN bus shield to the CAN bus. You only need CAN-L and CAN-H, don't bother with Ground, +12V etc
  • CAN-L is a green wire in the twisted-pair CAN bus in the Volvo
  • CAN-H is a white wire in the twisted-pair CAN bus in the Volvo
  • Plug in the Arduino to your laptop USB port
  • Start Realterm
  • Observe the bus magic!

Day 0 - The Beginning

Have you read http://hackingvolvo.blogspot.com/?
You should
I decided to continue where Olaf left off - but in a slightly different direction

Today I connected my Arduino to my Volvo XC90 low-speed CAN bus and was thrilled to see the 29-bit device IDs and the 8-byte data messages being printed in my console window...

"13.01.2018 16:45:06",Extended ID: 0x012173BE DLC: 8 Data: 0x20 0x20 0x00 0x04 0x00 0x22 0x80 0x02
"13.01.2018 16:45:06",Extended ID: 0x00217FFC DLC: 8 Data: 0x00 0x00 0x00 0x20 0xC0 0x00 0x00 0x00
"13.01.2018 16:45:06",Extended ID: 0x00E01008 DLC: 8 Data: 0x03 0x00 0x00 0x00 0x00 0x00 0x4C 0x00
"13.01.2018 16:45:06",Extended ID: 0x0131726C DLC: 8 Data: 0x00 0x0C 0x3D 0x00 0x00 0x00 0x00 0x3F
"13.01.2018 16:45:06",Extended ID: 0x03600008 DLC: 8 Data: 0x00 0x00 0x00 0x00 0x40 0x03 0xC0 0x00

Stay tuned...