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 a 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 20kBaud (kbits/s) with typical speeds of 9.6kBaud and 19.2kBaud. 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 -
https://www.cs-group.de/wp-content/uplo ... e_2.2A.pdf
The frame structure consists of a number of elements but it’s basic form consists of 2 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 for all the nodes on the bus to listen up as a message is about to 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 8bit sync byte is used to ensure 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 which can be found here -
https://www.ti.com/lit/an/slla383/slla3 ... o%2024%20V.
Before moving 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 where the master sends an id in the header requesting data from a specific slave.
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 used 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. 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 which 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.
The LIN bus can be woken in order 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 Pico 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. As an 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 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 after 100ms to 250ms there is no response from another node, it can then send out another wake-up request. It can do this 3 times in a row before then 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 above image 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 can clearly be seen 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. Whether that’s to ensure that if the slaves see this id, it can’t be confused with anything else if not sure. What we know is that providing the 1st byte is equal to 0 following the id 0x3C, the bus will be forced to sleep. Also worthy of noting is that if there is a period of approx. 4s 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 as 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 data sheet from NXP which can be found here - https://www.nxp.com/docs/en/data-sheet/AR6000.pdf. There are 11 configurations which can be used to define the information being sent to and from the alternator. Some of these may have changed from when this document was first written but so far in my experience it seems to still be applicable. These configurations are based on the ID’s used the transmit and receive data packets.
These 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 by using Pico’s built-in decoder. The keen eyed out there will have noticed that the IDs in the above table are duplicated through 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 & 15 and LIN1 Version D also has 29, 11 & 12.
How do we determine which version we should use? We could spend some time researching this online using the manufacturer information although I’m not sure this will be easily found. By far the easiest way 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 relate to the table above.
From the above decode table we can see that there are 2 very distinct IDs present under the frame identifier which is 29 and 11. We can then relate this to the LIN version table where we can see we have 2 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 which I think the most important ones for fault finding being the Rx for voltage set point and the Tx for diagnosis flags indicating failures.
Before we can start to 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 differences between LIN 1 version A and version D are 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 probably 2 pieces of data effectively in our fault finding. If we know what the set point is supposed to be we can compare this with what the actual alternator is outputting. Much like how we would observe 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 in order to provide additional data to the slaves. As we typically only ever have one slave, the alternator, then the above would be true.
For example, let's look at the above frame. ID 0x29 is sent by the master which it then responds to with information about the voltage set point in the data field 1F A5 1F 00. This is then followed by the master sending the ID 0x11 but is now requesting information from the slave which it responds with the data 2A 02.
In order to fully understand the data present from ID 0x29 and ID 0x11, we have to change the HEX values into Binary. This can easily be done by clicking the LIN decoder underneath the channel options, clicking next on the first decoder panel and now selecting binary from the display options and then clicking finish.
Using the above table from earlier which describes how the bit allocation is done for ID 0x29 we end up with something as below -
Just looking at the voltage set point, we know this is made up of the first 6 bits of the first byte which from 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 are working 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 ordering:
The least significant bit 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 then 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.
However, 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 using 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 which in this case is a 0 with the LSB at bit 0 being 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.
Knowing that our format is correct with binary we can use the export feature from the serial decode table to now manipulate that data within Excel much like how we graph SENT related data as seen in the following article.
https://www.picoauto.com/library/traini ... -picoscope.
Once you have the exported data open in CSV you should have something that looks a little like 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 is 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 saved 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 allows you to quickly sort the data based on the options you select from the drop down. We’re currently interested in just the frame with voltage set point 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 then selecting the id that contains the 8 bytes of data.
This will now leave you with just the data associated with that ID meaning we can focus purely on the voltage set point 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 set point. 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 tool tips.
This function will return the characters from a cell based on starting position counting from the left and then 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 this
=MID(I2, 1, 6)
We can then 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, however, it is worth it! I tend to create a new sheet to put the table into in order 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 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). In order 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 in order to find the value in the cell we have selected and return the value in the table. Our formula should as
=VLOOKUP(VALUE(O2),'Voltage Set Point table'!B2:C65,2)
Here 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 this –
=VLOOKUP(VALUE(O2),'Voltage Set Point table'!$B$2:$C$65,2)
This means 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 set point values given for that one buffer. You could of course combine the two formulas to have just one output column which 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 we have our data we can then graph this 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 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 which 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 (Look up table available)
E. Measured excitation current and/or temperature measurement (Look up table available)
F. Diag flag for LIN error
G. Diag flag for LIN communication time out.
As you can see, there are some very useful items present in this frame and fortunately using the MID function from earlier we can separate out the bits so we can get the values from the data field. Focussing on just the items that are 1 bit long.
As you can see from the table this particular alternator has actually 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 with understanding why a new alternator still might cause an issue by observing flags that may be present under the LIN error and LIN timeout entries.
I’ve made a lot of reference to the AR6000 document in the above alternator information. There is a lot more in this document then I’ve not mentioned but please be aware 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 in helping to understand the communication between the ECM and an alternator and will hopefully help to diagnose LIN controlled alternators.
I hope this helps.
Hey Ben,ben.martins wrote: ↑Tue Aug 17, 2021 10:59 amDominant 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. As an 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%.
We actually see similar things in the J1939 standards. In the J1939 documentation, the tolerances for the voltage from a transmitting transceiver are much tighter than the voltage tolerances for a receiving transceiver.
This is primarily to compensate for to voltage drop caused by poor connections, poor copper, receiver's getting a voltage spike on ground, or other unexpected transient events. To use big round numbers, if we require the transmitter to send 100v for dominant but the receiver will recognize anything above 90v as dominant, we can drop 10v across the cable without any concerns.
This is why the receiving specifications are different than the transmitting specifications.
With that said, I work for a vehicle OE and quite a few of the devices that our suppliers make do NOT follow the j1939 standards properly. I wouldn't be surprised to hear similar things of LIN bus. For example, we have suppliers that provide an ECU that uses a source address of 248 which is reserved in J1939. They refuse to change it. We had another supplier that was sampling the voltage about 10% into the bit, instead of the spec which is around 60-70% into the bit. This was causing the controller to sample during ringing (the high and low spikes you see when the bus transitions from dominant to recessive or vice-versa) and set fault codes.
I've no doubt that will be the case with all networks as well. I think LIN has one of the widest tolerances that I've seen which may be down to the fact it's a single wire bus as opposed to a differential.
Very helpful that a supplier is using a pre-existing SA, what could possible go wrong?!
It's hard enough as it is without having to deal with the challenges that some suppliers provide us. I always remember dealing with aftermarket trackers that used to cause problems and were usually buried under the dash somewhere.
As Steve Smith often says, 'Nothing is easy!"
I've been over and over your original post. I've tried to apply your technique to a LIN waveform from a 2018 Lexus. I can get through the LIN decode in Pico, exporting as .csv, saving as Excel workbook, found the applicable table in the AR6000 document and copied it into Excel. The problem I am having is getting the Excel formulas to work. I am no Excel expert, but I have used the Excel help features and searched the internet for additional help. The .psdata file I am working with is 46.5MB, too large to upload to the picoauto forum. Using search I'm not able to find a max file size for forum uploads. I have attached my Excel worksheet file derived from this .psdata.
Do you have the .psdata file from your original post so I can try to follow your process?
- (178.15 KiB) Downloaded 241 times
Not a problem. Hopefully you can find the file here - https://drive.google.com/file/d/1-3aFRN ... sp=sharing. Again too large to upload here and I will find out what the limit is for uploads to our forum.
Unfortunately I was unable to open your CSV file. I will try again in case something happened during the download but when I try to open the file it asks me to open and repair. If needed I find that WeTransfer.com is a good way to send large files. It's a temporary site as well so after 7 days the file will be removed. You have to have an email address to send it to though so if needed you can send the file to email@example.com and I'll pick it up from there.
Happy to work through it with you and see what's happening.
Just to let you and everyone know the upload file limit to the forum is currently set at 30MB. If trying to upload PSDATA files with a large number of buffers, trying saving just one buffer or a range that keeps it under this 30MB.
Hope that helps
Thank you very much for this comprehensive article! Based on it I took a record of the LIN communication between PCM of my 2012 Ford 1.6 Ti-VCT and new alternator, which does not work correctly (DTC U012D:88-2E).
Beyond the expected IDs 0x29 and 0x11 that you documented I can see IDs 0x34 and 0x32 there coming from PCM. Have you perhaps come across with these two and know why they are there? I have not found any info about them anywhere (despite having read datasheets from Infineon, NXP and STM).
In 0x29, the PCM requires a voltage of 15,3 V, but the alternator responds that the duty cycle is 0 % and excitation 0 A as well, without setting any error flag on...
Please accept my apologies for not getting back to you sooner.
Glad the document has helped and by no means do I confess to know everything about LIN, but hopefully it helps with an initial understanding. Another useful resource both Steve and I use is from CSS electronics. They explain some complicated subjects very well and the one on LIN is no exception - https://www.csselectronics.com/pages/li ... tro-basics.
With regards to 0x34 and 0x32, they're not something I've seen from any alternator I've looked at. Do you have any other slave modules on the same network as the alternator such as oil level sensors, battery monitoring etc? These ID's are listed in the LIN 2.2A specification document as valid ID's but sadly without the LDF we're going to be a little stuck I'm afraid.
We do know that the ECU can send a message to itself which it can respond too. It may be that this is something the ECU is doing internally.
Interesting you don't have any error flags for those responses especially as it looks like an electrical failure. If you upload you're file here I don't mind taking a look at it with you.