J1587 could be regarded as an obsolete network with most OEM’s opting for the more standardised J1939. However, J1587 is still very much out there and can still be found on a number of new vehicles and machines. One customer got in touch and was asking if J1587 could be decoded with PicoScope as the normal CAN and newer J1939 decoder (see here for more details - topic22615.html) just wouldn’t work. Always up for learning something new I decided to see if we could use Pico to determine anything more than just voltage levels.
Underneath the higher layer of J1587 sits J1708 which defines the physical layer. This is still a twisted pair of wires creating a differential signal which provides a reliable and stable environment to transmit data with any interference being cancelled out. J1708 is a much slower data transfer compared to modern day standards, at just 9.6kbits/s. You might think you could use the LIN decoder because of this speed but sadly it won’t work, I tried it! Voltage levels are a little unexpected compared to the normal CAN that we commonly see with the likes of J2534 & J1939.
As you can see from the above image, voltage values from J1708 + are between 1V and 4V and for J1708 -0.4V and 4V. Creating a math channel to take the positive away from the negative leaves us with a -3.5V to +4V signal approx. The other option here is to take advantage of the 4*25/A range of scopes where we have a floating input to allow us to measure across the two networks. An example of this can be seen below.
When it comes to most things we do, we can’t start to diagnose something until we know how it works. For decoding J1587 we need to work out the format of the packets which thankfully due to its age, there are infinite details available on the internet for free. For anything network based though I would urge those interested to make sure they take a look at the appropriate SAE documents. They are packed with information about the network, details on the how to interpret the data along with the scale and offset values to convert the data into a unit we can use in diagnosis. I will touch on this briefly but all the information is the in the SAE document - https://www.sae.org/standards/content/j1587_201301/.
J1587 is relatively straight forward with the message format consisting of just 4 parts -
- Message ID (MID)
- Parameter ID (PID)
- Data (Variable number of bytes, typically 1 or 2. Number of bytes defined by the PID number)
In the above we can see that our message ID is 128 which is followed by the first parameter ID of 190. There are two data bytes associated with PID 190 which are 32 and 28. Following this there is another PID 100 with data of 20 with the packet completed with the checksum of 14 to ensure the message is valid. One thing to note here is the format that the bytes are written in. Normally when we are dealing with CAN decoding, we tend to view it in Hexadecimal however I’ve found that the IDs listed in the SAE document are all in Decimal format. For this reason, any decoding I will be doing to help keep things straight forward will be done in Decimal.
The MID’s, Message ID, are set according to the SAE document and remain set. No two ECU’s can have the same MID which helps us a great deal when trying to determine whether ECU’s are online or not. One thing to be aware of is that there are some MID’s that may not conform with the J1587 format. These MID’s range from 0 to 127.
PIDs add a little more confusion due to the different lengths they can have depending on the parameter they represent. PIDs 0 to 127 and PIDs 256 to 383 use a single data byte to represent the value. For PIDs 128 to 191 and PIDs 384 to 447, two data bytes are used to represent the value. For the above example we have a PID of 190 which following the above conditions mean the next 2 bytes make up our data. PID 100 though falls in the first category which means there is only 1 data byte. More on this later.
Onto decoding. We are going to be making use of the UART decoding which we also used to decode and understand K-Line - viewtopic.php?p=101250#p101250. This decoder breaks up the data into bytes with no packet arrangement. This makes decoding networks a little more difficult but if we know the structure of the packet then it is a little easier to understand. To setup the UART decoder select from the left hand tool bar of PicoScope 7 Automotive More > Serial Decoding.
- On the first window select R232/UART and click Next.
- Select the channel you wish to decode on. If using math channels, they will appear as an option along with the other active channels. The threshold level I’ve set to 0V as the trace we are looking at was taken by floating across the high and low parts of the network and 0V is roughly in the middle. The threshold is the crossing point you would like the decoder to look for the changing parts of the signal. Hysteresis is the amount either side of the threshold you will ignore if the signal was to change. As we are working with networks, any unintended change is not common and so the hysteresis can be set low. The Baud rate may be calculated automatically, if it isn’t then please set this to 9.6 kBaud. There are 8 bits to a byte with one stop bit and no parity. Bit order is by least significant bit. Once complete click Next.
- On the final screen we can rename the decoder. In my example I’ve changed this to J1587. The displayed decoded data can be in varying formats as listed. For both the graph and the table I’ve selected Decimal as I mentioned earlier this is how the SAE document describes the MIDs and PIDs. Selecting All Buffers gives you everything in the table which can make exporting easier.
We can now start to zoom in packets of data and work out how they are arranged. To quickly go to a packet, you can double click/tap a data byte in the table which will zoom straight in on that byte. The earlier example used a MID of 128 and we have this at packet 7. Once selected, zoom back out slightly by either using the mouse wheel, pinch the screen or use the horizontal zoom control in the zoom overview window.
With this view we can now apply the structure we learnt earlier. In the above decoded data, we have – One thing we have to ignore now is the checksum. As the data is being decoded in Bytes this value does not represent the true checksum which is done as a calculation on the bytes within the packet. However, everything else is up for converting into real world data.
Referring to the SAE J1587 document, as well as a number of online sources, we can see that MID 128 refers to the Engine ECU No.1. PID 190 represents Engine Speed and as falls within the category where it has two data bytes, 156 and 8. We then get another PID 92 for Engine Load in percent with just the one data byte, 26.
To convert the data bytes into actual units gets a little more complicated, especially when there are 2 bytes. Let’s first focus on PID 92 with data of 26. Referring to the SAE J1587 and looking up PID 92 we can see that it has a Bit resolution, or scale, of 0.5%. As we have already decoded into decimal all we need to do is use this scale factor to the data which equates to -
26* 0.5 = 13%
To calculate PID 190 we have to do a little more work as we have to convert the data back to the hexadecimal in order to rearrange it. This format is exactly the same as that of converting the engine speed from J1939. Converting the 2 data bytes back to Hex then can be done using the built-in programmer on the Windows calculator or you can change the way the graph or the table represent the decoded data in PicoScope 7 Automotive software. To do this double click the decoded on under the channel options where you will be presented with the configuration screen. No changes are needed here so proceed to the next screen by clicking Next.
The next screen will let you change the table or the graph to display the data differently. I like to still maintain the graph view in decimal to see the structure so I tend to change the table to display HEX but it’s a purely preference. When you hover over a data byte on the graph it will bring up an overview which includes the packet number. You can also double click/tap the date byte which will automatically zoom in around it as before but it will also highlight the byte in the decode table.
Here we can see that packet 9 on the decode table has the value 9C. We also know that the following byte is required which is 08. We now have to reverse the order and join the 2 together to read as follows – 089C. We can now convert this value back into a decimal in order to perform the scaling and any offset as per the SAE J1587 document. Looking this up we can see it has just a scaling factor of 0.25 rpm. For the full conversion then -
089C HEX = 2204 Decimal
2204*0.25 = 551 rpm.
I hope this helps explain a little more about how we even when we don’t have a dedicated decoder for every network, with a little research we can apply the existing ones to help get the data we need. I will be doing another post following this looking at how exporting the decoded data to CSV can then be used to determine which ECU’s are present.