There are two distinct methods for retrieving data digitally from the Orion BMS / Orion Jr.: Regularly transmitted CANBUS messages and active data polling (sometimes referred to as on demand polling).
Regularly Transmitted CANBUS Messages
Using regularly transmitted CANBUS messages is the broadest and most useful method for getting data out of the BMS in a reliable and consistent manner. Both the Orion BMS and Orion Jr. provide a number of programmable CANBUS messages that can be configured to transmit specific data values at set intervals. Because many CANBUS protocols are inherently complex, the Orion BMS and Orion Jr. utilities provide a significant level of customization to the user including the following items: Interface baud-rate (125Kbps, 250Kbps, 500Kbps, 1000Kbps), Message ID (both Extended and Standard ID), Message length, Message contents (including complete individual byte contents, byte order, bit order, custom arithmetic scaling, offset, max / min values), and Message frequency.
This method is also the simplest to implement because it doesn’t require messages to be sent to the BMS to initiate the data transmission (data transmission of messages occurs automatically after a programmable amount of time has transpired). These messages can be passively received by external nodes and devices and processed accordingly.
In addition to these customizable messages, both the Orion BMS and Orion Jr. provide a battery cell broadcast message (which can be enabled on the “CANBUS Settings” section of the BMS profile), which allows the BMS to automatically push the active cell related data to the CANBUS. This can be useful for diagnostics and debugging where automatic cell voltage publishing is desired.
For details on the regularly transmitted CANBUS message functionality, please see the “Edit CANBUS Messages” dialog under the “CANBUS Settings” section of the BMS Utility (both for the Orion BMS and the Orion Jr.).
Active Data Polling (OBD2)
Some applications only require on demand data access under certain conditions or in certain circumstances, or they require certain data to be transferred that would not be normally transmitted using regularly transmitted messages. To address this need, the Orion BMS implements the On Board Diagnostic Protocol (OBD2) found on modern vehicles. The OBD2 protocol provides a framework for actively requesting data from the BMS, viewing and clearing diagnostic trouble codes (DTCs) and other diagnostic functions.
For a complete description of how the OBD2 diagnostic protocol operates, please see the following regulatory documents:
SAE J1979 (this defines the core OBD2 protocol)
SAE J2190 (this defines several extended modes used by the OrionBMS, specifically mode $22)
ISO 15765 (this defines how large messages are handled by multiple CANBUS messages)
This application note is NOT intended to summarize the entire contents of the above documents. It is merely to provide a starting point for interface development or to provide examples of common tasks. More complex operations may require purchasing and reviewing the above documents.
OBD2 Basics
Physical Network Concept
An OBD2 network is comprised of multiple “nodes” which have a unique ID (referred to hereafter as the OBD2 ECU ID, or ECU ID for short).
Because each node has a unique ECU ID they can be individually addressed. This allows a diagnostic utility or device to be able to request specific information from one ECU at a time. Each node MUST have a unique ID, otherwise two nodes may fight each other to reply to requests. When selecting an OBD2 ECU ID for the Orion BMS, there must not be another node on the network with the same ECU ID.
Uses For The OBD2 Protocol
The Orion BMS uses the OBD2 protocol for the following functions:
- Actively requesting live data from the BMS (real-time state of charge, pack voltage, cell voltages, etc).
- Viewing and clearing diagnostic trouble codes (DTCs).
- Retrieving stored diagnostic freeze frame data.
The OBD2 diagnostic protocol is great to use for on-the-fly data acquisition where the type of data needed may not be known ahead of time or may change significantly based on the application (e.g. displaying large amounts of data or different types of data depending on which display screen is being selected). It does have some drawbacks though:
- Only 1 device may be polling data from any ECU node at once via the OBD2 protocol. If multiple devices are polling OBD2 data from a single node the traffic from the two may get mixed up and a data collision may occur. The Orion BMS utility uses the OBD2 protocol to view data from the BMS and configure it. Third party OBD2 devices may need to be disconnected or powered down for the BMS utility to connect properly.
- There are no sanity checks or checksums on the OBD2 responses. This means that it’s not possible to guarantee that the received data is uncorrupted or valid. Noise and EMI can alter received data which can make this an unreliable link. For this reason, we do not recommend using the OBD2 polling protocol for application control or high reliability messages. For high reliability messaging or control messaging please see the “Custom CANBUS Message” section for how to configure the BMS to automatically transmit customized data at regular intervals.
- Data requested via OBD2 is inherently slower than data collected by the regularly transmitted CANBUS messages from the BMS. Since the originating device must issue a “request”, wait for the BMS to acknowledge the request, and then wait for the response to be sent back, there is a fairly significant latency introduced. If high speed data transfer is required, the “Custom CANBUS Message” feature should be used to transfer data instead.
Anatomy of an OBD2 Message
A simple OBD2 message has the following format:
(Target ECU ID) (Message Length) (Message Mode) (Message PID) (Message Payload)
Target ECU ID: This is the OBD2 ECU ID of the target device. The default value for this on the Orion BMS is 0x7E3, but this can be changed in the profile settings.
Message Length: This is the total length (in bytes) of the message to be transmitted. This length includes the mode, the PID and the entire payload. It does NOT include the ECU ID.
Message Mode: This is the OBD2 mode that the message is being sent on. Different modes have different functions (e.g. Mode $22 is used to request live data from the BMS, mode $3 is used to request current fault codes from the BMS, mode $4 is used to clear fault codes, etc). These modes are defined in the SAE 1972 and SAE 2190 documents.
Message PID: This is specific data that the message is trying to retrieve. It is essentially a qualifier for the purpose of the message. For example, when requesting data via mode $22 the PID is used to specify which data parameter is being asked for (e.g. whether we are requesting battery state of charge or battery voltage). The PID may be 1 or 2 bytes depending on the mode (e.g. in mode $22 the PID is always 2 bytes, but in other modes it may be 1 byte).
Message Payload: This is the remainder of the data being sent. Typically this is blank when data is being requested (such as through mode $22), but if data is being sent to the BMS then this may contain data.
Here is an example of an OBD2 message that requests the battery state of charge from the BMS. All the numbers in this example are expressed in HEXADECIMAL format for simplicity.
7E3 | 04 | 22 | F00F |
ID | LEN | MODE | PID FOR SOC |
NOTE: All the spaces between the fields above should be removed. The spaces are inserted for illustrative purposes only.
OBD2 Message Reception
When a message is transmitted to an OBD2 node, that node needs a way to indicate to the requesting device that it successfully received the request and is sending the requested data back to it. For this reason a response is sent from the receiving ECU back to the originating device.
The target node makes the following changes to the message request before sending it back:
- It will add 0x8 to the ECU ID to indicate it is responding BACK to the requesting device.
- It will add 0x40 to the requested MODE to indicate which request it is responding to. This allows for the originating device to differentiate between multiple responses.
NOTE: The device initiating the OBD2 requests should wait for a response back before issuing another request. If multiple requests are received at once (or if the requesting device does not wait for a response before issuing another request) then one or more of the requests may be rejected.
Here is an example of an OBD2 transaction using the SOC example above. All numbers are expressed in HEXADECIMAL format.
Transmit Request To BMS:
7E3 | 04 | 22 | F00F |
ID | LEN | MODE | PID FOR SOC |
Response From BMS:
7EB | 05 | 62 | F00F | 0064 |
ID+8 | LEN | MODE+0x40 | SOC PID | SOC VALUE |
NOTE: In this particular instance, the SOC value received is actually SOC * 2 since it’s in 0.5% increments. Divide by 2 to get the actual value (this does not apply to all values, please see the OBD2 PID list for the default unit scalings).
NOTE: For a list of supported PIDs, please see the official OBD2 PID list:
https://www.orionbms.com/downloads/misc/orionbms_obd2_pids.pdf
Interfacing With The Standard Orion BMS (CANBUS)
Device Basics
The standard Orion BMS implements OBD2 via CANBUS. This means that the BMS uses the CANBUS protocol as the low level transport mechanism (meaning CANBUS messages are used to transfer the data to and from the BMS).
CANBUS has a couple extra steps that must be taken when using it with OBD2. First, every CANBUS message has an additional length field (this is different from the OBD2 length field and represents the length of the actual CANBUS message being sent). Fortunately this is very simple in OBD2 as the CANBUS length value will always be 8.
An example OBD2 exchange over CANBUS might look something like this:
CANBUS message request from an external device:
0x7E3 | 8 | 04 | 22 | F00F | 00 00 00 00 |
CAN ID | CAN LEN | OBD2 LEN | MOD | SOC PID | UNUSED PADDING |
CANBUS message response from the BMS:
0x7EB | 8 | 05 | 62 | F00F | 00 62 | 00 00 00 |
CAN ID+4 | CAN LEN | OBD2 LEN | MODE+0x40 | SOC PID | SOC VALUE | UNUSED |
Extended Frame Messaging Via CANBUS
The above example works for OBD2 CANBUS messaging that only need to transmit small amounts of data (eg: a single data value). Since a CANBUS message can have up to 8 bytes this can all be handled with a single message. In order to request larger data (such as cell voltages which respond back with considerably more than 8 bytes) the process is a bit more involved.
In order to support Extended Frame Messaging via CANBUS (messages with responses longer than fit in a single CAN message), the OrionBMS implements ISO 15765 (ISO-TP). Essentially this allows for longer messages to be broken up and divided into multiple CANBUS messages that are pieced together at the receiving node and the requesting node.
Covering the details of this protocol are beyond the scope of this document but here are some basics:
If the first byte in the response message is “0x10” then that means that there are additional frames waiting to be sent and only the first 3 bytes of the actual OBD2 payload was sent (bytes 5 6 and 7). The requesting device then needs to then send an “acknowledged, send the rest of the messages” response back. This response is called a flow control response.
This is best demonstrated with an example:
Transmit To BMS:
7E3 8 01 03 00 00 00 00 00 00
Receive First Message From BMS:
7EB 8 10 12 43 08 0A FA 0A C0
NOTE: The 0x10 as the first byte tells us that there is more data available. So the requesting device must request the additional data as follows.
Transmit “GO AHEAD” Flow Control Message To BMS:
7E3 8 30 00 00 00 00 00 00 00
Receive All Remaining Messages From BMS:
7EB 8 21 0A 01 0A 02 0A 03 0A
7EB 8 22 04 0A 05 0A 06 00 00
This tells us there are 8 fault codes set (P0AFA, P0AC0, P0A01, P0A02, P0A03, P0A04, P0A05, P0A06) and 3 messages are used to send this data.
NOTES:
- The OBD2 length ONLY shows up in the first message (0x12 in the above example in hexadecimal, or 18 in decimal). Followup messages that are sent later ONLY include the message counter (the first byte, starting with 0x20 and incrementing by 1 until all messages are received) and the remainder of the payload. The message counter byte does NOT count towards the total message OBD2 length.
- If the first byte of the first message is 0x10 then everything gets shifted down by 1 byte (e.g. the OBD2 length is now the second byte, the mode is now the third byte, etc).
- The “GO AHEAD” flow control message MUST be sent within 500ms of receiving the “I have more data” message from the BMS. If the flow control message is not sent within 500ms the “GO AHEAD” request is discarded and no further messages are transmitted.
- Once the “GO AHEAD” is successfully received, the BMS will transmit in rapid succession all the remaining data messages (it does not wait for individual acknowledgements between each message).
- All OBD2 CAN related messages MUST be 8 bytes long (even if the actual OBD2 message length is less). Unused bytes at the end of a message should be filled with 0s.
The Extended Frame Messaging does NOT apply to the Orion Jr. if using the onboard serial RS232 interface (the RS232 interface does not have the same message length limitations that CAN does so this is not needed). The Jr. does also support OBD2 over CANBUS (if used with a CAN enabled Jr.) in which case the above Extended Frame Messaging would apply.
For a more detailed explanation of this protocol, please see the official ISO-15765 document.
Discovering Available BMS Units
Since the OBD2 ECU ID is programmable, it may not be possible to know ahead of time which BMS units are available on the network. For this purpose, OBD2 has what is called a general broadcast ID that all ECUs on the network will respond to.
The general broadcast ID is 0x7DF.
Any device that receives a request on the ID 0x7DF will automatically generate a response to it on its’ own ID. The requesting OBD2 device simply needs to scan for which IDs it gets responses on to determine what ECUs are available.
Example:
General Broadcast To Network:
0x7DF | 8 | 01 | 3E | 00 00 00 00 00 00 |
Bcast ID | CAN LEN | LEN | MODE | UNUSED BYTES (PADDING) |
(Mode $3E is a “Keep Alive / Are You There” mode)
Possible Responses:
0x7EB 8 02 7E 00 00 00 00 00 00 – “I Am Here” from node 0x7E3
0x7EC 8 02 7E 00 00 00 00 00 00 – “I Am Here” from node 0x7E4
This example shows a response from 2 ECUs on the network. This doesn’t necessarily mean they are BMS units though (Mode $3E is supported by many ECUs).
In order to determine if the responding ECUs are BMS units, the user should send a Mode $9, PID 0x0B request. The BMS will respond back with a payload starting with the ASCII characters “ORIONBMS”. This will be a multi-frame response message and must be handled accordingly by the user software.
Interfacing With Orion Jr. (48v Version)
Device Basics
The Orion Jr. BMS primarily implements OBD2 via Serial RS232. This means the BMS uses the onboard serial RS232 interface as the low level transport mechanism (meaning serial messages are used to transfer the data to and from the BMS.
Some versions of the Orion Jr. also support CANBUS. CAN enabled versions do support OBD2 via CANBUS as well. For details on interfacing via CANBUS please see the “Interfacing With the Standard Orion BMS (CANBUS)” section above.
NOTE: When connecting via serial RS232 there is only one BMS available, which means it is not necessary to transmit the ECU ID (this is an important difference from the CAN connection method).
NOTE: The Jr. RS232 operates at 9600 Baud, Even Parity, 8 Data Bits, 1 Stop Bit
All RS232 OBD2 message requests and responses start with a colon (“:“)
A serial OBD2 request is nearly identical to the examples shown earlier. An example OBD2 exchange over Serial RS232 might look something like this:
RS232 message request from an external device:
:03 | 22 | F00F |
LEN | MOD | SOC PID |
RS232 message response from the BMS:
:05 | 62 | F00F | 00 64 |
LEN | MODE+0x40 | SOC PID | SOC VALUE |
NOTE: All the spaces between the fields above should be removed. The spaces are inserted for illustrative purposes only.
NOTE: All RS232 messages MUST be terminated with a newline character (‘\n’) to signify end of line.
Real World Examples
Requesting Active Fault Codes (Mode $3)
Example with mode $3 (requesting faults set on BMS)
CANBUS Transmit Request To BMS:
7E3 | 8 | 01 | 03 |
ID | CAN LEN | OBD2 LEN | MODE |
CANBUS Response From BMS:
7EB | 8 | 06 | 43 | 02 | 0A01 | 0A02 |
ID+8 | CAN LEN | OBD2 LEN | MODE=0x40 | # of codes | CODE 1 | CODE2 |
In this case, 2 fault codes are set. P0A01 and P0A02.
NOTE: Since no PID was provided (no PID is needed for mode $3 transactions) no response PID is included in the reply.
Clearing Active Fault Codes (Mode $4)
Example with mode $4 (clearing faults set on BMS)
CANBUS Transmit Request To BMS:
7E3 | 8 | 01 | 04 |
ID | CAN LEN | OBD2 LEN | MODE |
CANBUS Response From BMS:
7EB | 8 | 01 | 44 |
ID+8 | CAN LEN | OBD2 LEN | MODE+0x40 |
The BMS responds with an acknowledgement that the fault codes have been cleared.
NOTE: Since no PID was provided (no PID is needed for mode $4 transactions) no response PID is included in the reply.
Requesting Data (Mode $22)
Example with mode $22 (requesting data from BMS)
CANBUS Transmit Request To BMS:
7E3 | 8 | 04 | 22 | F00F |
ID | CAN LEN | OBD2 LEN | MODE | PID FOR SOC |
CANBUS Response From BMS:
7EB | 8 | 05 | 62 | F00F | 0064 |
ID+8 | CAN LEN | OBD2 LEN | MODE+0x40 | SOC PID | SOC VALUE |
NOTE: In this particular instance, the SOC value received is actually SOC * 2 since it’s in 0.5% increments. Divide by 2 to get the actual value (this does not apply to all values, please see the OBD2 PID list for the default unit scalings).
NOTE: For a list of supported PIDs, please see the official OBD2 PID list:
https://www.orionbms.com/downloads/misc/orionbms_obd2_pids.pdf
AN2586 - Copyright (C) 2019 Ewert Energy Systems