Adding a new Log Message

DataFlash Logs are stored on the flight controller’s onboard dataflash memory and can be downloaded after a flight. The logs provide detailed information about each flight which can be important especially when trying to diagnose why something went wrong.

This page explains how to write a new dataflash log message.

The Easy Way

Use DataFlash_Class:instance()->Log_Write(...):

void Log_Write(const char *name, const char *labels, const char *fmt, ...);
void Log_Write(const char *name, const char *labels, const char *units, const char *mults, const char *fmt, ...);

An example of the top function being used can be found in Compass_learn.cpp:

DataFlash_Class::instance()->Log_Write("COFS", "TimeUS,OfsX,OfsY,OfsZ,Var,Yaw,WVar,N", "QffffffI",
  • the 1st argument is the message name. This should be 4 characters or less and be unique
  • the 2nd argument is a comma separated list of field names
  • the 3rd argument is a format string with each letter holding the format for the corresponding field. The meaning of each letter can be found here in DataFlash/LogStructure.h
  • the remaining arguments are the actual values that will be logged. You may notice in the example above, some fields have a format of float (“f”) but are cast to (double) this is correct and necessary to avoid a compiler warning.

The 2nd Log_Write function is the same as the first except that it accepts two additonal string arguments, “units” and “mults”. Similar to the “format” argument, each character in these arguments specifies the units (i.e. “d” for degrees) or multiplier (i.e. “2” for *100, “B” for *0.01) for the following fields. These help the graphing tools scale the output correctly when displaying to the user.

For example, below is a “TEST” log message which outputs the current system time and altitude.

DataFlash_Class::instance()->Log_Write("TEST", "TimeUS,Alt",
                                       "sm", // units: seconds, meters
                                       "FB", // mult: 1e-6, 1e-2
                                       "Qf", // format: uint64_t, float
  • the time has units of seconds (“s”), multiplier of “F” to indicate the value should be divided by 1 million and format of “Q” to indicate it is output as a 64 bit unsigned integer.
  • the altitude has units of meters (“m”), multiplier of “B” to indicate the value should be divided by 100 (to convert from centimeters to meters) and format of “f” because the value is a float.

The Harder Way

For commonly used messages, especially those which are output at a relatively high rate (50hz or more) a slightly more efficient logging method can be used.

multiplier and format strings into the vehicle’s LogStructure array or DataFlash/LogStructure.h’s LOG_EXTRA_STRUCTURES array - add a new method to the vehicle code or DataFlash library called Log_Write_<something-or-other> which fills in the structure and then calls DataFlash/WriteBlock()

void Copter::Log_Write_Test()
    struct log_Test pkt = {
        time_us  : AP_HAL::micros64(),
        a_value  : 1234
    DataFlash.WriteBlock(&pkt, sizeof(pkt));
  • call this new function from the scheduler or from some other place in the code at the moment you wish to log the values