At some point in my work with SAE J1939, I decided to develop my own protocol stack.
There is nothing particularly mysterious about doing that. An experienced embedded programmer can certainly write a J1939 protocol stack. The challenge is not so much the programming itself. The challenge is understanding SAE J1939 well enough to know exactly what the software needs to do.
And that is where the investment becomes significant.
SAE J1939 is considerably more than sending and receiving CAN Bus messages. Once you get into address claiming, network management, request messages, transport protocol, diagnostics, and the various timing requirements, there is a substantial learning curve involved.
I already had that J1939 knowledge. What I wanted was a protocol stack that I understood completely, that I could use for my own projects, and—perhaps most importantly—that was not tied to one particular microcontroller.
That became ARD1939.
Starting With the Arduino Uno—Deliberately
I started with about the most basic development platform I could find: an Arduino Uno combined with a CAN Bus shield.
That may seem like an unusual choice for developing a protocol stack. The Uno is hardly a powerhouse. Its memory is limited, its processing capability is modest, and compared with today’s ESP32 and ARM-based controllers, its resources are extremely constrained.
But that was precisely the point.
My reasoning was simple:
If I can make a J1939 protocol stack work reliably on an Arduino Uno, and if I write the software in proper, portable C/C++, moving it to more powerful processors should be relatively straightforward.
That approach worked.
ARD1939 was subsequently adapted to the Arduino Mega 2560, Arduino Due, and ESP32, all while remaining within the familiar Arduino IDE environment. I also ported the stack to an ARM Cortex-based system using its respective development environment, demonstrating that the architecture was not dependent on Arduino hardware or the Arduino IDE.
The Uno did impose some practical limitations, particularly when dealing with the memory requirements of the SAE J1939 Transport Protocol. But as a starting point for the architecture, it accomplished exactly what I wanted it to accomplish.
Separating J1939 From the Hardware
One of the most important decisions I made during development was to keep the actual J1939 protocol logic independent of the hardware.
The stack itself should not care whether it is running on an Arduino Uno, an ESP32, an ARM Cortex processor, or some other embedded platform.
Hardware-specific functions were therefore separated into their own hardware abstraction module. This layer handles functions that inevitably depend on the processor and development platform, primarily:
CAN Bus initialization, transmission, and reception
Timer functions required by the J1939 protocol
Other processor-specific services required by the stack
When moving ARD1939 to another processor, this is the part that needs to be adapted.
The actual J1939 protocol code remains essentially unchanged.
This architecture is what allowed the same basic stack to operate on platforms ranging from the resource-constrained Arduino Uno to significantly more capable processors.
Do You Really Need the Source Code?
ARD1939 is currently available in precompiled form rather than as complete source code.
I occasionally encounter the assumption that having the source code must automatically be better. From a developer’s perspective, I certainly understand that instinct. I like having access to source code myself.
But there is another side to the argument.
If your objective is to develop a J1939 application, do you really want to become an expert on the internal operation of the protocol stack?
Having the source code gives you the ability to modify the stack. But doing that responsibly means understanding its architecture, internal state machines, timers, message handling, address claiming, Transport Protocol implementation, and the interactions between all of those components.
In other words, you have simply introduced another learning curve.
For the vast majority of J1939 applications, that effort provides very little benefit.
ARD1939 already provides the protocol functionality required by typical J1939 applications. Your application communicates with the stack through its defined interface. The stack takes care of the protocol mechanisms underneath.
That allows you to spend your development time where it matters:
On your application.
If you are building an ECU, gateway, display, data logger, diagnostic device, sensor interface, or another J1939 node, the objective is usually not to develop a J1939 protocol stack. The objective is to develop the device that uses J1939.
There is an important distinction between the two.
Focus on the Application, Not the Protocol Stack
This is also one of the principles behind the embedded J1939 material I am developing for this website.
Understanding J1939 is important. An engineer working with the protocol should understand PGNs, source addresses, address claiming, request messages, Transport Protocol, diagnostics, and the other mechanisms that make a J1939 network work.
But understanding the protocol does not necessarily mean that you need to implement every mechanism yourself.
The same principle applies throughout embedded development. We routinely use CAN controller drivers, TCP/IP stacks, USB libraries, file systems, and operating-system services without rewriting them for every project.
The protocol stack should be infrastructure.
Your application is the reason the infrastructure exists.
Where ARD1939 Goes From Here
My plan is to eventually release the complete ARD1939 source code here on wilfriedvoss.com.
That will make it possible for developers who genuinely need to examine, modify, or port the internal implementation to do so. It will also provide a practical companion to my ongoing material about J1939 development for embedded systems.
Until then, the precompiled versions remain a practical way to develop J1939 applications without having to build the protocol layer from scratch.
The existing implementation supports the core mechanisms required for Classical CAN-based SAE J1939 applications, including address claiming and network management, the SAE J1939 Transport Protocol, and diagnostic message handling.
And because of the hardware-independent architecture, the same fundamental approach can be carried from Arduino-class hardware to considerably more capable embedded processors.
Documentation and Programming Examples
I will continue publishing information about ARD1939 and embedded SAE J1939 development here on wilfriedvoss.com.
The eventual release of the ARD1939 source code will also be announced here.
If you would like to follow the project and be informed when new material becomes available, you can subscribe to wilfriedvoss.com with either a free or paid subscription.
Paid subscribers will additionally receive access to the ARD1939 documentation and programming examples published through this website.
My objective is not to turn every embedded developer into a J1939 protocol-stack developer. It is to provide the tools and knowledge necessary to understand J1939—and then let you get back to developing the application you actually wanted to build. The current precompiled ARD1939 protocol stack can be downloaded free of charge from ard1939.com.The complete source code is planned for release here on wilfriedvoss.com.
ARD1939 – Implementation and Technical Insights
All technical information about ARD1939, the SAE J1939 protocol stack for Arduino, plus detailed description of implementation and available function calls is included in SAE J1939 ECU Programming & Vehicle Bus Simulation with Arduino by Wilfried Voss.
While this book primarily uses Arduino-based platforms such as the Uno, Due, and Mega 2560 for its examples, the documentation of the ARD1939 protocol stack and the associated programming concepts apply equally to other supported microcontroller families, including ESP32, Teensy, and similar platforms. Since the protocol stack is implemented in standard, hardware-independent C++, the underlying concepts and programming techniques remain the same regardless of the target hardware.
Arduino sketches (software projects) include a J1939 network scanner, and a simple SAE J1939 to USB Gateway application with associated Windows GUI (Visual Studio C# project).
The collection of sketches is concluded by the ARD1939 project, a fully functional SAE J1939 protocol stack for the Arduino Uno and Mega 2560.




