DBC Introduction
DBC is a CAN data description file format introduced by Vector Informatik GmbH. DBC files are text files so can be created and edited using a simple text editor like the one built into the OVMS web UI.
DBC files can be used to support vehicles that don’t have a dedicated native adaption yet. This is done using the generic DBC vehicle type, which can use DBC files to translate CAN data into metrics.
This section tries to show you how to create and use a DBC specification on the OVMS. Of course you’ll need to know how to decode your vehicle’s CAN frames first. You can use the OVMS RE (reverse engineering) toolkit to identify which messages are on the bus and which changes correlate to actions and status on the car.
There’s also a very good general introduction to DBC from CSS Electronics including an explanatory video: https://www.csselectronics.com/screen/page/can-dbc-file-database-intro/language/en
DBC files only specify the passive (reading) part, they don’t provide a means to define transmissions.
If you need to send frames to request certain information, you can still use the OVMS DBC engine to
decode the results (instead of doing the decoding in C++ code). So a DBC file can be used as a base
for a real vehicle module. To request OBD2 data during development, you can use the re obdii
commands.
Basic Example
Warning
The DBC support is usable, but considered to be an alpha release. The way it works may change in the future.
This example is taken from the Twizy, which sends some primary BMS status data at CAN ID 0x155 (341). Note: the Twizy module actually does not use DBC, this is just an example how you would decode this message if using DBC.
Message example: 05 96 E7 54 6D 58 00 6F
Byte 0: charge current limit [A], scaled by 5, no offset:
05
→ 25ABytes 1+2: momentary battery current [A], big endian, lower 12 bits, scaled by -0.25, offset +500:
_6 E7
→ 58.25ABytes 4+5: SOC [%], big endian, scaled by 0.0025, no offset:
6D 58
→ 69.98%
These can be translated to metrics directly:
Charge current limit:
v.c.climit
Momentary battery current:
v.b.current
Battery SOC:
v.b.soc
Create DBC File
Copy & paste the following into a new editor window:
VERSION "DBC Example 1.0"
BS_: 500000 : 0,0
BO_ 341 BMS_1: 8 Vector__XXX
SG_ v_c_climit : 7|8@0+ (5,0) [0|35] "A" Vector__XXX
SG_ v_b_current : 11|12@0+ (-0.25,500) [-500|1000] "A" Vector__XXX
SG_ v_b_soc : 39|16@0+ (0.0025,0) [0|100] "%" Vector__XXX
What does this mean?
BS_
defines the bus speed (500 kbit in this example) and bit timings (unused)BO_
defines the data object, a CAN frame of length 8 with ID 341 (0x155) (“BMS_1” is just an arbitrary name)SG_
lines define the signals (values) embedded in the object (see below)Vector__XXX
is just a placeholder for any sender/receiver (currently unused by the OVMS)
Signals are defined by their…
Name (= metric name with
.
replaced by_
)Start position (bit position) and bit length (
7|8
)Endianness:
0
= big endian (most significant byte first),1
= little endian (least significant byte first) (Note: the DBC format documentation is wrong on this)Signedness:
+
= unsigned,-
= signedScaling and offset:
(-0.25,500)
=> real value = raw value * -0.25 + 500Minimum/maximum:
[-500|1000]
= valid real values are in the range -500 to 1000Unit: e.g.
"A"
(ignored/irrelevant, defined by the metric)
The metric to set can be given as the name of the signal. You may use the metric name directly
on the OVMS, but to conform to the DBC standard, replace the dots by _
.
Bit positions are counted from byte 0 upwards by their significance, regardless of the endianness. The first message byte has bits 0…7 with bit 7 being the most significant bit of the byte. The second byte has bits 8…15 with bit 15 being the MSB, and so on:
[ 7 6 5 4 3 2 1 0 ] [ 15 14 13 12 11 10 9 8 ] [ 23 22 21 20 …
`----- Byte 0 ----´ `------- Byte 1 --------´ `----- Byte 2 …
For big endian values, signal start bit positions are given for the most significant bit. For little endian values, the start position is that of the least significant bit.
Note
On endianness: “big endian” means a byte sequence of 0x12 0x34
decodes into 0x1234
(most significant byte first), “little endian” means the same byte sequence decodes into 0x3412
(least significant byte first). “Big endian” is the natural way of writing numbers, i.e. with their
most significant digit coming first, “little endian” is vice versa. Endianness only applies
to values of multiple bytes, single byte values are always written naturally / “big endian”.
Use DBC File
Save the DBC example as: /store/dbc/twizy1.dbc
(the directory will be created by the editor)
Open the shell. To see debug logs, issue log level debug dbc-parser
and log level debug v-dbc
.
Note: the DBC parser currently isn’t graceful on errors, a wrong DBC file may crash the module. So you should only enable automatic loading of DBC files on boot when you’re done developing and testing it.
So let’s first try if the DBC engine can parse our file. The dbc autoload
command loads all
DBC files from the /store/dbc
directory:
OVMS# dbc autoload
Auto-loading DBC files...
D (238062) dbc-parser: VERSION parsed as: DBC Example 1.0
D (238062) dbc-parser: BU_ parsed 1 nodes
D (238062) dbc-parser: BO_ parsed message 341
D (238072) dbc-parser: SG_ parsed signal v_c_climit
D (238072) dbc-parser: SG_ parsed signal v_b_current
D (238082) dbc-parser: SG_ parsed signal v_b_soc
Looks good. dbc list
can tell us some statistics:
OVMS# dbc list
twizy1: DBC Example 1.0: 1 message(s), 3 signal(s), 56% coverage, 1 lock(s)
The coverage tells us how much of our CAN data bits are covered by signal definitions.
Now let’s load the file into the DBC vehicle:
OVMS# config set vehicle dbc.can1 twizy1
Parameter has been set.
OVMS# vehicle module NONE
I (1459922) v-none: Generic NONE vehicle module
OVMS# vehicle module DBC
I (249022) v-dbc: Pure DBC vehicle module
I (249022) v-dbc: Registering can bus #1 as DBC twizy1
Nice. Let’s simulate receiving our test frame and check the decoded metrics:
OVMS# can can1 rx standard 155 05 96 E7 54 6D 58 00 6F
OVMS# me li v.b.soc
v.b.soc 69.98%
OVMS# me li v.b.current
v.b.current 58.25A
OVMS# me li v.c.climit
v.c.climit 25A
So the decoding apparently works.
To configure DBC mode for autostart we now just need to set the DBC vehicle mode to be
loaded on vehicle startup, and to enable autoloading of the DBC files from /store/dbc
. You can
do so either by using the user interface page Config → Autostart (check “Autoload DBC files” and
set the vehicle type to “DBC”), or from the shell by…
OVMS# config set auto dbc yes
OVMS# config set auto vehicle.type DBC
Try a reboot to see if everything works.
You can now add more objects and signals to your DBC file.
Note
During development of a DBC file, you’ll need to reload the file frequently. The DBC engine
locks the currently used vehicle, so you’ll need to unload the DBC vehicle (vehicle module NONE
),
then reload the DBC file (dbc autoload
), then reactivate the DBC vehicle (vehicle module DBC
).