LIN bus decoder and LIN controlled alternators
by Ben Martins

LIN, Local Interconnect Network, it seems to be everywhere! HVAC, door locks, heated seats, mirrors, battery monitoring and charging systems. It tends to crop up on non-safety critical communications where speed isn’t a priority. As with the other network forum posts, we have to remember that PicoScope is not a dedicated data logger. There are devices better suited for this job out there on the market but when it’s all you have, there is a lot we can still do.

LIN is fully customizable meaning VM’s can give ID values to any ECU or control unit making it like CAN in this sense if you want to decode it to a higher level you will need a DBC file to interpret the decode data. For LIN you would need an LDF (Lin Description File) which holds the key to unlocking the data. Please don’t confuse LIN controlled alternators with PWM or BSD which are typically found on Ford and BMW respectively.

To help with this post some basic understanding of LIN is required. LIN is a single wire, bi-directional data bus transmitting at relatively low speeds with a max speed of 20 kBaud (kbits/s) with typical speeds of 9.6 kBaud and 19.2 kBaud. LIN can support up to 16 ECUs, 1 master and 15 slaves. It is a lot lower cost than that of CAN due to its single wire properties and is primarily used in places where high-speed communication isn’t required. LIN works on a master and multiple slave concept, such as a central electronics ECU which communicates with all the door locks. Voltages for this signal are generally a switching voltage from battery voltage to ground which is why it can be often mistaken for a PWM signal. The LIN specification document that I have referred to during writing this article can be found here.

The frame structure consists of a number of elements but its basic form consists of two sections, the header and the response, which is then broken down further.

The header is made of the break, the sync byte, and the ID field. The break acts as a notice to all the nodes on the bus to listen as messages are broadcast. It is usually quite long, taking up at least 11 bits, with most modern vehicles seeing 13 bits and more. Because of the length of this section, it cannot be mistaken for any other message. Directly following the break is the sync byte. This 8-bit sync byte is used to ensure that the slaves match the baud rate of the master. It is typical to see this byte in HEX as 0x55.

The Identifier section is one of the more important sections in the message as it delivers the instructions to the slaves as to what information the master needs to receive. The ID is made up of 6 bits and 2 parity bits. The full 8 bits make up the protected identifier. Slaves look at the parity bits to ensure the message is valid and either ignore the following data, listen to other slaves, or respond to the ID in the response field. The Pico LIN decoder already pulls the ID from the protected identifier in the decode table.

The following document from Texas Instruments does a great job of explaining the frame structure.

Before we move on to the response field, we must discuss the different frame types. With LIN there are 6 different ways the master can request data from the slaves. These are:
This is the most common way, where the master sends an id in the header requesting data from a specific slave.
Event Trigger
This is where the master requests data from multiple slaves if it believes data has been updated.
In this mode, the master acts as a slave by responding to its own header. This allows the slaves to ‘see’ data that the master sends and can use it. This is the format LIN controlled alternators use which we will look at in more detail.
IDs 0x3C and 0x3D are used for gathering diagnostic information from the master and slave. ID 0x3C is for information from the master and ID 0x3D is from the slaves.
ID 0x3E is defined by the user and could contain anything.
ID 0x3F cannot be used with LIN 2.0 networks, so if you see it in the decode table, something has gone wrong!
For the most part, unconditional is the chosen method and will generally appear on the decode table in this format unless you are looking at something where sporadic frame types are used, such as for LIN controlled alternators. But before we delve too deep into alternators, let's finish the LIN frame by looking at the response section.
The data field is just that, it contains the data requested by the master in the ID frame. It can be made up of 2, 4, 6 or 8 bytes. The length of the data can be attributed to the ID frame but this is typically specified by the supplier.
Finally, the frame ends with the checksum. This comes in either classic or enhanced format. The classic checksum is calculated using the data bytes only. The enhanced checksum uses the data bytes and the protected identifier. ID frames using 0x3C and 0x3D, the diagnostic frames, will always use the classic checksum.
It would be great if there was a set standard that would allow us to decode the identifier in the header to better understand the data response, but sadly there isn’t. This information is all locked up in the LDF and not available for general users. A couple of easy things we can look out for are the wake-up signals and go to sleep messages.
Wake Up
The LIN bus can be woken up to activate a function such as door locks on smart-entry systems. This can also have bigger issues when searching for a battery drain and the vehicle is momentarily waking up. This can easily be caught using PicoScope, as the LIN communication follows a set pattern. Any node can request a wake up of the network by transmitting a pulse by pulling the voltage down to a dominant state which should be held there for over 150µs. Dominant voltages can be determined by the signal dropping close to 0V with threshold levels being different for the master and slaves. Quite why that is I’m not sure, but it will allow a lot of variation in signal levels hopefully making the network more robust. For example, the master must drive the bus voltage level to within 20% of the battery voltage with recessive bits being within 80%. The slaves will acknowledge a dominant bit if it’s within 40% of the battery voltage and a recessive if with 60%.
Providing that the node sends the wake-up request and returns the bus to its recessive state, the request is valid and the node returns to listening to the bus for commands. If there is no response from another node after 100 ms to 250 ms, it can send another wake-up request. It can do this three times in a row before having to wait a minimum of 1.5 seconds before trying the wake-up request again and so continues this pattern for an infinite number of attempts.

1. Ignition ON
2. Wake up message
The LIN bus in the image above was taken from the alternator. You can see where ignition was switched on followed by the wake-up message to bring the alternator online and then communication starts.
When the Master decides the bus should no longer be communicating it will issue the following message – 00 FF FF FF FF to indicate the bus should now be quiet. The go-to-sleep command is clearly visible in the last packet of the following capture:

What I find interesting in this last data frame is that the ID is 0x3C, which we know is reserved for diagnostics. It seems that this ID is also used for all slaves to shut down. This may be to ensure that if the slaves see this id, it can’t be confused with anything else. What we know, is that providing the 1st byte is equal to 0 following the id 0x3C, the bus will be forced to sleep. It is also worth noting that if there is a period of approx. 4 seconds where the bus is inactive, the slaves will automatically go to sleep to help save power.
LIN controlled alternators
Despite the lack of information surrounding the LCF, all is not lost when it comes to LIN controlled alternators. Decoding the data has some significant advantages.
The research below has been done in conjunction with the following datasheet from NXP. There are 11 configurations that can be used to define the information sent to and from the alternator. Some of these may have changed from when this document was first written, but so far it seems to still be applicable. These configurations are based on the IDs used to transmit and receive data packets.
The configurations are:

Where we only typically have two nodes present on this peer-to-peer network, it allows us to pick out which configuration the alternator is using with Pico’s built-in decoder. The keen-eyed reader will have noticed that the IDs in the table above are duplicated throughout the different versions. LIN1 Version A, which we will be looking at in more detail, uses the IDs 29, 11, 12 and 15. Looking down the list we can also see that LIN1 Version B also uses 29, 12 and 15 and LIN1 Version D also has 29, 11 and 12.

How do we determine which version we should use? We could spend some time researching this online using information from the manufacturer, though I’m not sure this is easily found. The easiest way, by far, is to perform a decode on the captured data. The LIN decoder will do all the hard work for us and display the IDs for the alternator and the ECM, which we can then refer to in the table above.

From the decode table above, we can see that there are two very distinct IDs present under the frame identifier: 29 and 11. We can then relate this to the LIN version table where we can see that we have two possible options, LIN 1 Version A and LIN 1 Version D.

When we look through the AR6000 datasheet, we have the message configuration for the two versions where there are some differences in both the Rx and Tx formats, but there are also some similarities. I think the most important ones for fault finding are the Rx for voltage setpoint and the Tx for diagnosis flags indicating failures.

Before we can look more closely at what this data means, we should understand the packet construction for these data frames. For the Rx, we have 4 bytes of data where the bits are used differently depending on what they represent.

 A. Voltage set point
 B. Load response ramp time
 C. Load response cut off speed
 D. Excitation current limit
 E. Variable and depends if Tx15 is present
 F. “Blind zone” (further detail in AR6000 document)
 G. Voltage limitation for high temperature
 H. “Blind zone inhibition” (further detail in AR6000 document)
The difference between LIN 1 version A and version D is that version D doesn’t use any data from byte 4, which in some ways helps simplify the decoding. From the above then, diagnostically we can use 2 pieces of data effectively in our fault-finding. If we know what the setpoint is supposed to be we can compare this with what the actual alternator puts out. Much like how we would observe the target and actual values for something like an EGR valve.

From what we have learnt about the 6 different frames we can use, we are almost certain that the only way the above format can take place is by using sporadic frames. To recap, this is where the master responds to the ID it has sent out to provide additional data to the slaves. As we typically only ever have one slave, the alternator, then the above would be true.

As an example, let's look at the frame above. The master sends ID 0x29 which it then responds to with information about the voltage setpoint in the data field 1F A5 1F 00. This is followed by the master sending the ID 0x11, requesting information from the slave that responds with the data 2A 02. 

To fully understand the data present from ID 0x29 and ID 0x11, we have to change the hex values into binary. Click on the LIN decoder underneath the channel options, click Next on the first decoder panel and select binary from the display options before you click Finish.

By using the table from earlier, which describes how the bit allocation is done for ID 0x29, we end up with the following:

Just by looking at the voltage setpoint, we know this is made up of the first 6 bits of the first byte which from the table above is 111110. Within the AR6000 document, there are a number of lookup tables where these values can be used to determine the value in human-readable form. In the case of 111110, this equates to 16V.

When we work with LIN data, it is usually best to look at the binary data. This is because the LIN format uses a Least Significant Bit (LSB) bit order.

The LSB is the bit that corresponds to the lowest potential value (i.e. it will be 0 or 1), whereas the Most Significant Bit (MSB) is the bit that corresponds to the highest potential value (e.g. 255 or FF if within an unsigned byte). Then, when binary data is transmitted, it is important to know whether it arrives in order of increasing bit significance (i.e. LSB first, or bit position 0 first) or decreasing bit significance (i.e. MSB first or bit position 7 first). In the former case, you need to read the set of transmitted bits from left to right to correctly determine the corresponding decimal or hexadecimal values, whereas, in the latter case (such as when looking at CAN data), you read from right to left.

If you don't correctly adjust for the bit order your calculated hexadecimal values may be incorrect when you have LSB-first binary data (binary to hexadecimal conversion normally assumes MSB-first data). Likewise, if converting from hexadecimal to binary.

The PicoScope LIN decoder takes care of this by automatically arranging the binary positioning into LSB for you, so no further action is needed. However, to prove that it is working, try to use the programmer feature with a Windows calculator and enter the HEX value 1F which is the first bit from the first data packet in the images above. Converting 1F into binary using the Windows calculator results in 00011111. As this assumes MSB, bit 7 is first. In this case, it is a 0 and the LSB at bit 0 is a 1. Rearranging the format to fit the LIN protocol means we flip the order around to read LSB first, resulting in 11111000, which is the value we see written in the decode table of PicoScope.

Having tested that our format is correct with binary, we can use the export feature from the serial decode table to manipulate that data in Excel, much like how we graph SENT related data in the following article.

Once you have the exported data open in CSV you should have something that looks like the image below. I have only exported one buffer in this instance but it would make sense to export all buffers to give you more data to work with.

Before you do anything else, you will need to save this CSV document as an Excel workbook. The reason being that as soon as you close the document, the formulas you have entered will not be saved. This caused me some headache as I originally didn’t do this. After I had saved the document and then returned back to it the next day, I had lost all of my formulas and the look-up tables! 

Once you have saved the workbook, the next task is to add in a filter. To do this, click Data on the top toolbar, followed by Filter. This will add a little drop down to each column header and allow you to quickly sort the data based on the options you select from the drop-down menu. We’re currently interested in just the frame with voltage setpoint which we know falls at the beginning of an 8-byte data field. We can sort the data to only display these frames by clicking on the drop-down arrow on the protected identifier column and selecting the id that contains the 8 bytes of data.

This will leave you with just the data associated with that ID, meaning we can focus purely on the voltage setpoint throughout the entire buffer. For those that are familiar with Excel, you will know that there are a vast number of formulas you can use in order to manipulate the data. Excel has some very useful tips when it comes to formulas and if you’re ever stuck do use the help button. It’s saved me a number of times!

As we know, the first 6 bits in the data field are what we are interested in to establish the voltage setpoint. To remove them from the rest of the data we are going to use the MID function. Some will say why not just use LEFT, but if I describe how to use MID it can be used for other bits that don’t start from the left-hand side of the cell. To understand the MID function, it’s easier to use Excel’s tooltips.

This function will return the characters from a cell, based on the starting position counting from the left and then the number of characters after. For example, if we take the byte from the first row in the data field, which is 10101000. We know we’re after the 6 bits starting from the left so we need the function to look for the starting point of 1 and return 6 characters which will leave us with 101010.

Our formula then reads as follows: 
 =MID(I2, 1, 6)

Now we can select and drag this cell to fill the remainder of the cells.

The next part is a little time consuming as it involves copying the table over from the AR6000 document into Excel but it is worth it! I tend to create a new sheet to put the table into to keep it separate from the data.

Please bear in mind that Excel doesn't like leading zeros. Because of this, we have to remove them in the binary values for the table as the vlookup formula won't find a match if we keep them in. With the table complete we can now use the VLOOKUP function to convert our 6 bits into a value we can use.

One point I need to make is that Excel doesn’t like to look up values that are created by a formula as technically the cell value is =MID(I2, 1, 6). To make Excel look at the value, we have to insert the Value function into our lookup formula.

We can then proceed to inform Excel where the data is located to find the value in the cell we have selected and return the value in the table. Our formula should look like this: 
 =VLOOKUP(VALUE(O2),'Voltage Set Point table'!B2:C65,2)
We are asking Excel to take the value present in cell 02, and look it up in the cells on sheet ‘Voltage Set Point table’ between cells B2 and C65. If it finds a value it needs to return the value present in column 2.

Sadly, we can’t just drag and fill now as we did with the previous formula as this will change the cell range for the lookup table. Because we don’t want the table range to alter, we have to insert the $ symbol in front of the table range to read as follows:  
 =VLOOKUP(VALUE(O2),'Voltage Set Point table'!$B$2:$C$65,2)
As we now drag and fill to the rest of the rows, only the lookup value cell number changes and not the table range.

We now have a full list of the voltage setpoint values given for that one buffer. You could, of course, combine the two formulas to have just one output column. The formula for that would be: 
 =VLOOKUP(VALUE(MID(I2,1,6)),'Voltage Set Point table'!$B$2:$C$65,2)
However, I think it’s good to see how it all fits together by keeping it in stages. Now that we have our data, we can graph it to see how the master was trying to control the alternator based on the voltage set point.

We can apply the same method to ID 0x11, which contains the data sent from the alternator back to the master. The data in the response is only 2 bytes but does contain some very useful information. Again, referring back to the AR6000 document, there are 2 options as we mentioned earlier, LIN 1 Version A and LIN 1 Version D. For ID 0x11 there are two versions that depend on whether the temperature is transmitted. The frame looks like this:

A. Diag flag for high temperature
 B. Diag flag for mechanical failure
 C. Diag flag for electrical failure
 D. Duty value for excitation current PWM (lookup table available)
 E. Measured excitation current and/or temperature measurement (lookup table available)
 F. Diag flag for LIN error
 G. Diag flag for LIN communication timeout.
As you can see, there are some very useful items present in this frame and fortunately, we can use the MID function from earlier to separate out the bits and get the values from the data field. Let's focus on the items that are only 1 bit long.

As you can see from the table, this particular alternator has flagged a mechanical failure. Using these flags could help better understand why an alternator has failed or is bringing the EML light on the dash when the trouble codes are not particularly useful. The flags can also help us understand why a new alternator might cause an issue by observing flags present under the LIN error and LIN timeout entries.

I’ve referenced the AR6000 document in the above alternator information quite a lot. There is more in this document that I’ve not mentioned, but please be aware that this is just one source. It may be that there are other LIN chips used in alternators that use a slight variation on this document. However, it is by far the most comprehensive document when trying to understand the communication between the ECM and an alternator and it will hopefully help to diagnose LIN controlled alternators.


Add comment

Your email address will not be published. Required fields are marked *