Site Information

 Loading... Please wait...

SAE J1939 Programming with Arduino - Claiming Address With Contending Node

Posted by Wilfried Voss on

This post is part of a series about SAE J1939 ECU Programming & Vehicle Bus Simulation with Arduino.

SAE J1939 ECU Programming & Vehicle Bus Simulation with Arduino

Now let’s have the two nodes compete for their addresses, since they both use the same preferred source address. For that purpose, it is important to consider which node starts up first, and the test results will demonstrate the difference.

Test #1: Mega 2560 starts up first, then Uno

  • Line 1: The Arduino Mega 2560 starts up and claims an address of 0x80 (128).
  • Line 2: The Arduino Uno starts up and claims the same address.
  • Line 3: The Arduino Mega 2560 had compared both NAMEs and found that the competing node (Uno) has a lower NAME (due to the ECU Instance). Consequently, the Mega 2560 claims the next available address of 0x81 (129).

Note: Have a look at the ECU Instance (5th data byte) to identify the two nodes and their responses.

Test #2: Uno starts up first, then Mega 2560

This screen shot demonstrates clearly that the start-up sequence will result in a different communication process between the two nodes.

  • Line 1: The Arduino Uno starts up and claims an address of 0x80 (128).
  • Line 2: The Arduino Mega 2560 starts up and claims the same address.
  • Line 3: The Arduino Uno verified both NAMEs and found that its NAME was lower. Consequently, it sends its Address Claimed message again.
  • Line 4: The Arduino Mega 2560 had compared both NAMEs and found that the competing node (Uno) has a lower NAME (due to the ECU Instance). Consequently, the Mega 2560 claims the next available address of 0x81 (129).

The next test becomes even more interesting. In this case, I defined the Arduino Mega 2560 node as “not-arbitrary-address-capable,” meaning the node will have only one negotiable address.

The code modifications are:

1. ARD1939.h

// NAME Fields Default

:

#define NAME_ARBITRARY_ADDRESS_CAPABLE 0x00

2. ARD1939 – setup()

// Set the preferred address and address range

j1939.SetPreferredAddress(SA_PREFERRED);

// j1939.SetAddressRange(ADDRESSRANGEBOTTOM, ADDRESSRANGETOP);

// Set the NAME

j1939.SetNAME(NAME_IDENTITY_NUMBER,

              NAME_MANUFACTURER_CODE,

              NAME_FUNCTION_INSTANCE,

              NAME_ECU_INSTANCE,

              NAME_FUNCTION,

              NAME_VEHICLE_SYSTEM,

              NAME_VEHICLE_SYSTEM_INSTANCE,

              NAME_INDUSTRY_GROUP,

              NAME_ARBITRARY_ADDRESS_CAPABLE);

Test #3: Mega 2560 starts up first, then Uno

The result is somewhat surprising (the Mega wins the address claim), but in the end it makes total sense.

  • Line 1: The Arduino Mega 2560 starts up and claims an address of 0x80 (128).
  • Line 2: The Arduino Uno starts up and claims the same address.
  • Line 3: The Arduino Mega 2560 verified both NAMEs and found that its NAME was lower. Consequently, it sends its Address Claimed message again.
  • Line 4: The Arduino Uno had compared both NAMEs and found that the competing node (Uno) has a lower NAME (not due to the ECU Instance, but the Arbitrary Address Capable flag). Consequently, the Uno claims the next available address of 0x81 (129).

Note: The NAME, as it appears in the “Address Claimed” message, is LSB first and MSB last.

Test #4: Uno starts up first, then Mega 2560

The result is obvious, and I will refrain here from explaining all details.

Note: This last test scenario reveals one of the many ingenious details of the SAE J1939 protocol. Initially, one might assume that an ECU with a single source address has some disadvantages over those with multiple available addresses. However, the position of the “Arbitrary Address Capable” flag ensures that nodes “less capable” than others can still connect to the network.

In a next step, we will create scenarios where the node is unable to claim a source address. For this purpose, we will set the Arbitrary Address Capable flag in both nodes to ‘0’ and use the same single address of 0x80 (128).

Test #5: Mega 2560 starts up first, then Uno

This is the first scenario where one of the two nodes, namely the Arduino Mega 2560, in the network is not able of claiming a source address.

  • Line 1: The Arduino Mega 2560 starts up and claims a source address of 0x80 (128).
  • Line 2: The Arduino Uno starts up and claims the same address.
  • Line 3: The Arduino Mega 2560 compares both NAMEs and determines that the contending node has a higher priority (lower NAME). Since the node does not have any further addresses available, it sends out a Cannot Claim Address message.

Note: The “Cannot Claim Address” message is identical to the “Address Claimed” message, but it reports the NULL address (254) as the source address.

Test #6: Uno starts up first, then Mega 2560

Here again (and as expected), the Arduino Uno wins the address claim process.

  • Line 1: The Arduino Uno starts up and claims a source address of 0x80 (128).
  • Line 2: The Arduino Mega 2560 starts up and claims the same address.
  • Line 3: The Arduino has compared both NAMEs and found that its NAME has a higher priority (lower NAME). In consequence, it sends its Address Claimed message again.
  • Line 4: The Arduino Mega 2560 compares both NAMEs and determines that the contending node has a higher priority (lower NAME). Since the node does not have any further addresses available, it sends out a Cannot Claim Address message.

Last, but not least, here comes the most interesting test, because it does involve some serious network simulation. The question is, does our J1939 ECU manage its available address range correctly?

For this purpose, we add code to the Arduino Uno’s application program that will enable us to reject a defined set of addresses claimed by the Arduino Mega 2560.

The test conditions are:

  • Both ECUs have a preferred source address of 0x80 (128).
  • Both ECUs are Arbitrary Address Capable.
  • Both EUCs support a negotiable address range between 129 and 135.
  • The Arduino Uno has an ECU instance of 0x00.
  • The Arduino Mega 2560 has an ECU instance of 0x01.

In both sketches, the Uno and the Mega 256, we change/add the following code in the setup() function (see highlighted sections):

First, we are using a “fake” NAME to assure that the Uno will win the process claim process no matter what. A NAME filled will all-zeros will do exactly that. After all, this is a simulation program.

Behind the j1939.Operate(…) function we are able to determine whether the received PGN is an application message (nMsgId = J1939_MSG_APP) or a network management message (nMsgId = J1939_MSG_PROTOCOL).

If the PGN is a network management message, we check whether or not it is the Address Claimed message. Further we check for the address range claimed by the other node.

Then follows the “nasty” line where we deny the Arduino Mega 2560 any address it attempts to claim by calling the j1939.Transmit(…) function. We transmit an Address Claimed message and use the same source address as claimed by the Mega 2560. Since the Uno’s NAME is unbeatable, the Mega 2560 will try claiming more addresses until it runs out of resources.

The following screen shot shows exactly what I described:

First the Arduino Mega 2560 attempts to claim its preferred address 0x80 (128), and, after being denied, attempts to claim 129 (0x81) through 135 (0x87).

Finally (line 17), it runs out of addresses and sends a Cannot Claim Address message.

As the final test, we will throw the Mega 2560 a bone and allow address 135 (0x87). That means, in the Uno’s loop() function we change one parameter, i.e. we set the last address to 134 instead of 135.

As the screen shot proves, the Mega 2560 goes through all available addresses until it gets to 135 (0x87). It is finally able to claim an address (line 15).


A Comprehensible Guide to J1939

SAE J1939 has become the accepted industry standard and the vehicle network technology of choice for off-highway machines in applications such as construction, material handling, and forestry machines. J1939 is a higher-layer protocol based on Controller Area Network (CAN). It provides serial data communications between microprocessor systems (also called Electronic Control Units - ECU) in any kind of heavy duty vehicles. The messages exchanged between these units can be data such as vehicle road speed, torque control message from the transmission to the engine, oil temperature, and many more.

A Comprehensible Guide to J1939 is the first work on J1939 besides the SAE J1939 standards collection. It provides profound information on the J1939 message format and network management combined with a high level of readability.

Read more...