Skip to content

File formats ​

The exact bytes each recorder writes, for anyone writing an importer, a parser or a conversion script. Everything here is a property of the writer, not a specification the writer follows — where the output departs from BUSMASTER's own conventions, that is said explicitly.

Both formats use CRLF line endings and UTC timestamps throughout. Neither carries a timezone, an interface name inside the file, or a bus bitrate that means anything.

Raw capture — BUSMASTER text ​

Eleven lines, written when the file is opened. Ten of them are fixed literals; only the date line varies.

***BUSMASTER Ver 3.2.2***
***PROTOCOL CAN***
***NOTE: PLEASE DO NOT EDIT THIS DOCUMENT***
***[START LOGGING SESSION]***
***START DATE AND TIME DD:MM:YYYY hh:mm:ss:000***
***HEX***
***SYSTEM MODE***
***START CHANNEL BAUD RATE***
***CHANNEL 1 - Kvaser - Kvaser Hybrid 2xCAN/LIN #0 (Channel 0), Serial Number- 0, Firmware- 0x00000399 0x0003000f - 500000 bps***
***END CHANNEL BAUD RATE***
***<Time><Tx/Rx><Channel><CAN ID><Type><DLC><DataBytes>***
FieldNotes
DD:MM:YYYYday, month, four-digit year, colon-separated, UTC
hh:mm:ssUTC, and the seconds value is one greater than the real one
:000a constant; there is no sub-second part in the header
the CHANNEL 1 linea fixed literal. It names Kvaser hardware and 500000 bps whatever the interface actually is

Two consequences for a parser: do not read the bus bitrate or the adapter from the header, and do not treat the start second as exact.

Files written by BUSMASTER itself may additionally carry a ***START DATABASE FILES*** block between the header and the legend. This recorder never writes one, and anything reading these files should skip every line beginning with * rather than count header lines.

Data lines ​

One line per received frame, appended and flushed immediately.

hh:mm:ss:tttt Rx 1 0xID x DLC B0 B1 … Bn
FieldValueNotes
hh:mm:ssUTC time of the framefrom the kernel's receive timestamp
tttt0000–9999tenths of a millisecond — the microsecond count divided by 100
Rxalways Rxthe recorder never writes Tx; it does not transmit
1always 1channel number, a constant
0xIDuppercase hex, no leading zerosthe identifier masked to 29 bits
xalways xtype; see below
DLC0–8decimal
B0 …uppercase hex, two digits eachDLC bytes, space-separated

Example:

07:59:56:1193 Rx 1 0x40C1 x 8 00 00 00 00 16 00 18 00

Remote-transmission frames take a shortened form — the type becomes xr, the length is written as 0, and no data bytes follow:

07:59:56:1193 Rx 1 0x40C1 xr 0

Three properties a parser has to accommodate:

  • The type is always x. The identifier is masked with the extended-frame mask before printing and the type letter is a constant, so an 11-bit standard frame and a 29-bit extended frame are written identically. The distinction is not recoverable from the file.
  • Error frames are absent. Any frame carrying the error flag is discarded before the line is formatted. A gap in a capture may be silence or may be an error storm; the file cannot tell you which.
  • The identifier is not zero-padded. 0x40C1 and 0x1040 have four digits, 0x7 has one. Match on the 0x… field, not on column position.

Two lines, written on rotation and on a clean shutdown.

***END DATE AND TIME DD:MM:YYYY hh:mm:ss:000***
***[STOP LOGGING SESSION]***

The date is taken from the wall clock at the moment of closing, not from the last frame. Two defects in it, both harmless as long as you know:

  • The month is one lower than the real month. The header's month is correct; the footer's is not. In January it prints 00.
  • The seconds value is one greater than the real one, as in the header.

A file that ends without these two lines was not closed cleanly — the process was killed or the Brain lost power. Such a file is otherwise valid and can be read to its last complete line.

Parsing it ​

Every non-data line begins with *, which is the only reliable discriminator:

sh
zcat can0.3.log.gz | grep -v '^\*' | awk '{print $1, $4, $6}'

Fields are space-separated with no quoting and no escaping, so awk, cut and split() all work directly. Field 1 is the time, field 4 the identifier, field 5 the type, field 6 the length, and fields 7 onwards the data bytes.

Converting the time to seconds past midnight UTC:

sh
zcat can0.3.log.gz | grep -v '^\*' |
  awk -F'[: ]' '{printf "%.4f\n", $1*3600 + $2*60 + $3 + $4/10000}'

Decoded capture — CSV ​

One file per combination of function code, instance and broadcast identifier. The file extension is .log, the content is CSV.

Header row ​

datetime,<field>,<field>,…

The column names after datetime are generated from the frame's own field definitions in the MUXEN frame library, so the authoritative list for any given file is the header line in that file. Read it; do not assume it.

For a combination the recorder does not decode, the header is exactly:

datetime,

and every row carries a timestamp and one empty field.

Data rows ​

YYYY-MM-DDThh:mm:ss.mmmZ,<value>,<value>,…
FieldValue
YYYY-MM-DDThh:mm:ss.mmmZISO 8601, UTC, milliseconds. The Z is literal
the restthe decoded field values, in header order

There is no quoting, no escaping and no footer. A row is appended and flushed as each frame arrives.

What is decoded ​

The decoder is keyed on the function code and the broadcast identifier only — the instance is not part of the key, so every instance of a given function decodes with the same columns. Thirty-one combinations are recognised:

Device functionFrames decoded
Buttonlife
Power output, Bloc 8life, io, current 1, current 2
Power source interconnectionlife, state, current
Power source gensetlife, state
Power source batterylife, state, cycle
Converterlife, state
Motorlife
Lightinglife
Displaylife
Solarlife, state
Navigation instrumentsrelative wind, true wind, heading, speed, distance to destination, time to destination, time
IMOCA keel team accesssystem state, keel state, capacity state
Generic I/Olife

Anything else on the bus still produces a file, with the empty header described above. That is worth remembering when sizing a folder: the file count follows the bus, not this table.

Parsing it ​

The format is plain comma-separated with a header line, so any CSV reader works:

sh
zcat can0_device_5_0_1.1.log.gz | head -1        # the columns
zcat can0_device_5_0_1.1.log.gz | tail -n +2     # the rows

The timestamp column parses directly as ISO 8601 in every spreadsheet and every scripting language. Note the CRLF endings: readers that split on \n alone leave a trailing carriage return on the last field of each row.

What neither format records ​

Worth stating once, because each of these is a question a parser author eventually asks:

Not recordedConsequence
the interface name, inside the fileit is only in the filename
the bus bitratethe header's value is a fixed literal
standard versus extended identifierseverything is written as extended
error framesabsent from the raw capture entirely
transmitted framesthe recorder never transmits while recording
the recorder versionnothing in either file identifies the writer
any gap or overrun markera dropped frame leaves no trace

Integration of multiplexed solutions
MUXEN and the MUXEN logo are trademarks of MUXEN SAS.