As we all know, networks on all types of machinery have been around for a lot longer than we give it credit for. From the early beginnings of slow data exchanges between two or three ECUs to today systems with 30+ ECUs covering everything from LIN to Ethernet. This combination of different networks is not uncommon, including combining old and new formats with varying different speeds and can be seen with many modern HGVs and construction and agricultural equipment where you will often find a combination of OEM specific CAN, J1939 and its predecessor J1587.
J1587 can be regarded as an obsolete network with most OEMs opting for the more standardised J1939. However, J1587 is still very much out there and can still be found on many new vehicles and machines. One customer got in touch and was asking if J1587 could be decoded with PicoScope as the normal CAN decoder and the newer J1939 decoder (see here for more details) just wouldn’t work. As I am always up for learning something new I decided to see if we could use PicoScope 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.6 kbits/s. You might think you could use the LIN decoder because of this speed, but sadly that won’t work, I tried it! The voltage levels are a little unexpected compared to the normal CAN that we see on J1939.
As you can see from the image above, the 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. The other option here is to take advantage of the 4X25/A ranges of scopes where we have a floating input that gives us the ability to measure across the two networks. See an example of this below.
It is difficult to start diagnosing something until we know how it works. For decoding J1587 I needed 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, and details on how to interpret the data along with the scale and offset values to convert the data into a unit we can use in a diagnosis. I will touch on this briefly, but all the information is in the SAE document.
J1587 is relatively straight forward with the message format consisting of just four parts:
1. Message ID (MID)
2. Parameter ID (PID)
3. Data (Variable number of bytes, typically 1 or 2. Number of bytes defined by the PID number)
When looking at a packet of decoded data the format is the following:
In the table 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 do will be done in decimal to help keep things straightforward.
The MIDs, Message-IDs, are set according to the SAE document and remain set. No two ECUs can have the same MID which helps us a great deal when trying to determine whether ECUs are online or not. One thing to be aware of is that there are some MIDs that may not conform to the J1587 format. These MIDs 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 example above 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. I will get more into this later on.
Onto decoding then. We are going to be making use of the UART decoding, which we also used to decode and understand K-Line. 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 easier to understand. To set up a decoder select More > Serial Decoding from the left-hand toolbar of PicoScope 7 Automotive.
1. In the first window you select R232/UART and click Next.
2. Select the channel you wish to decode. If you are using math channels, they will appear as an option along with the other active channels. I have set the threshold level to 0 V as the trace we are looking at was taken by floating across the high and low parts of the network and 0 V 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 on 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. The bit order is the least significant bit. Once this is complete, click Next.
3. 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 it easier to export it.
You should now see the table with the decoded data appear, as well as the decoder on the graph. Order the table in ascending order so the bytes are in order of time. To do this click on the Packet header and click on the Buffer Number.
We can now start to zoom in on 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 decoded data above 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 falls within the category where it has two data bytes: 156 and 8. We then get another PID 92 for Engine Load in per cent with just the one data byte: 26.
Converting 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 the 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 can be done using the built-in programmer on the Windows calculator or you can change the way the graph or the table represents the decoded data in PicoScope 7 Automotive software. To do this double click the decoded one 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.
This is where you can 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 this is purely preference. When you hover over a data byte on the graph it will bring up an overview that 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 make 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. When looking this up, we can see it has a scaling factor of just 0.25 rpm. The full conversion then makes 089C HEX = 2204 Decimal, 2204*0.25 = 551 rpm.
I hope this helps explain a little more about how, even when we don’t have a dedicated decoder for every network, we can apply the existing ones and do a little research, to help get the data we need. I will be doing another article where I look into how exporting the decoded data to CSV can then be used to determine which ECUs are present.