Skill Level: Intermediate
Table Of Contents
- Introduction
- What Is Needed
- Background Information
- TLDR
- Installing Doxygen
- Creating A Sample Sketch
- Creating The Doxygen Configuration File
- Running Doxygen
- Viewing The Generated Documentation
- Summary
Introduction
This tutorial will teach you how to use the Doxygen utility to generate program documentation for your Arduino sketches. A basic understanding of programming is expected along with some familiarity with the Arduino platform. If you are new to Arduino or would just like to refresh your knowledge, please see our Blink: Making An LED Blink On An Arduino Uno tutorial before proceeding with this one.
The resources created for this tutorial are available on GitHub for your reference.
What Is Needed
- Linux, macOS, Or Windows Based Computer
- Arduino IDE (optional)
Background Information
Doxygen is a utility that generates program documentation from source code. It parses programs written in various programming languages that are annotated with certain commenting styles. The generated documentation will include summary descriptions for almost all of the elements and members defined in your sketch. It can also include additional information based on special annotations used within the comments. Doxygen can generate documentation in a variety of formats, e.g. HTML, LaTex, XML, RTF, etc. appeasing to a wide audience.
While researching how to create Doxygen based documentation for Arduino sketches, I found that quite a few people were struggling with the same thing. I came across various work-arounds, e.g. changing the extension to .cpp, but nothing really seemed to be a robust solution. I spent some time working on this myself and wanted to share what I believe is a very good solution.
I am using a macOS based computer. If you are using a Linux or Windows computer, the vast majority of this tutorial should still apply, however, some minor changes may be necessary.
If you need assistance with your particular setup, post a question in the comments section below and I, or someone else, can try to help you.
TLDR
For those already experienced using Doxygen with other programming languages, the simple answer of how to get Doxygen to work with Arduino sketches is to make the following modifications to your Doxyfile.
- EXTENSION_MAPPING = ino=C++ (specify language parser)
- EXTRACT_ALL = YES (parse all source code)
- INPUT = <sketch_name> (specify sketch directory location)
- FILE_PATTERNS = … (add the .ino file extension to the list)
For those of you that would like more detailed instruction, please continue reading.
Installing Doxygen
Please see the Doxygen downloads and installation pages for general installation instructions for your computer platform.
Since I am using a Mac and do not plan to use the GUI front end, I chose an alternative approach and installed Doxygen from the command line via the Homebrew package manager using the following command.
$ brew install doxygen
This installed the doxygen executable into the /usr/local/bin directory on my Mac.
Once the program is installed, either make sure that it can be found within your executable path or prepend the full directory path upon execution. Test that it is installed correctly by executing the following command within a terminal or command window that will simply print its version number.
$ doxygen -v
Creating A Sample Sketch
In order to generate source code based documentation using Doxygen, we need to have source code for it to use. Create and save a sketch named DoxygenExample with the code shown below. This is just an example sketch showing how to go about commenting your source code so that it can be parsed properly by the Doxygen utility. It is not meant to actually run anything useful on the Arduino itself. It contains various types of elements that are common to Arduino sketches, e.g. constants, variables, and functions.
/** * @file DoxygenExample.ino * * @mainpage Doxygen Example Project * * @section description Description * An example sketch demonstrating how to use Doxygen style comments for * generating source code documentation with Doxygen. * * @section circuit Circuit * - Red LED connected to pin D2. * - Momentary push button connected to pin D3. * * @section libraries Libraries * - Arduino_LSM6DS3 (https://github.com/arduino-libraries/Arduino_LSM6DS3) * - Interacts with on-board IMU. * * @section notes Notes * - Comments are Doxygen compatible. * * @section todo TODO * - Don't use Doxygen style formatting inside the body of a function. * * @section author Author * - Created by John Woolsey on 03/12/2020. * - Modified by John Woolsey on 03/16/2020. * * Copyright (c) 2020 Woolsey Workshop. All rights reserved. */ // Libraries #include <Arduino_LSM6DS3.h> // Defines #define DEBUG 1 ///< The mode of operation; 0 = normal, 1 = debug. #define SAMPLE_RATE 1 ///< The sensor sampling rate in Hz. // Types /** The log level enumeration type. */ enum LogLevel { Error, ///< Log errors only. Warning, ///< Log errors and warnings. Verbose ///< Log everything. }; /** The sensor structure type. */ struct Sensor { String name; ///< The name of the sensor. float value; ///< The value of the sensor. }; // Pin Mapping const byte RedLED = 2; ///< The pin connected to the red LED. const byte Button = 3; ///< The pin connected to the momentary push button. // Global Constants const float EulersNumber = 2.71828; ///< Euler's number (e). // Global Variables int buttonCount = 0; ///< The number of times the button was pressed. unsigned long previousTime = 0; ///< The last time something happened. /** * The standard Arduino setup function used for setup and configuration tasks. */ void setup() { // Initialize serial bus (Serial Monitor) Serial.begin(9600); while (!Serial); // wait for serial connection // Pin configuration pinMode(RedLED, OUTPUT); pinMode(Button, INPUT_PULLUP); // utilize microprocessor's internal pull-up resistor // Configure the generic device configureDevice(); } /** * The standard Arduino loop function used for repeating tasks. */ void loop() { int value = getDeviceValue(7, 42); Serial.print("Device value: "); Serial.println(value); delay(1000); // wait one second } /** * Configures and initializes some device. * * Some additional detail about this function. */ void configureDevice() { // Configure the device } /** * Retrieves some value from some device. * * @param someThing The value of some thing. * @param otherThing The value of other thing. * * @return The result of something. */ int getDeviceValue(int someThing, int otherThing) { // Retrieve the value from the device return someThing + otherThing; }
Various comment formatting styles are supported by Doxygen. I chose what I believe to be the most clear and concise styles for this example. Please feel free to view and play around with other supported styles shown within the Doxygen manual.
Creating The Doxygen Configuration File
In order to effectively parse the source code to generate our project documentation, Doxygen requires the use of a configuration file. This file, named Doxyfile by default, is where we set up our project specific information and tell Doxygen how to parse Arduino sketches.
Within a terminal or command window, go to the directory where your DoxygenExample Arduino sketch directory is located, not within the sketch directory itself. Create a default Doxygen configuration file by running the following command.
$ doxygen -g
This will create a Doxyfile configuration file within the current directory.
Now we need to edit the Doxyfile file to enter our project specifics. The first change we want to make is to tell Doxygen the name of our project. This is accomplished by changing the following line, around line 35, from
PROJECT_NAME = "My Project"
to
PROJECT_NAME = "My Arduino Project"
This will be the title of the project within our generated documentation. You can, of course, change it to anything that makes sense for your project.
Since Arduino sketches are based on the C++ programming language, we need to tell Doxygen to use the C++ parser for files with the .ino extension. Change the following line, around line 326, from
EXTENSION_MAPPING =
to
EXTENSION_MAPPING = ino=C++
Next, tell Doxygen to generally parse all the source code. Change the line around 470 from
EXTRACT_ALL = NO
to
EXTRACT_ALL = YES
Note, the EXTRACT_PRIVATE and EXTRACT_STATIC settings can also be set to YES if you want to include private class members and static file members in the generated documentation as well.
Now, we need to tell Doxygen where to find the Arduino sketch by making the following change, around line 832.
INPUT =
INPUT = DoxygenExample
Next, we need to add the .ino file extension to the list of files that Doxygen will search for and parse. This is done by simply adding an extra
*.ino \
line to the existing file name extensions within the FILE_PATTERNS list, around line 859, of supported programming language extensions.
Doxygen creates LaTex based documentation by default. Since we will not be doing anything with this format in this tutorial, let’s just turn that off. Around line 1712, change
GENERATE_LATEX = YES
to
GENERATE_LATEX = NO
Save your updated Doxyfile configuration file when complete.
Running Doxygen
Now that the configuration file is updated, run Doxygen to generate the HTML based documentation for our Arduino project. In the same directory as the Doxyfile and the sketch directory, run the Doxygen executable.
$ doxygen
Doxygen will print to the screen the various tasks it is performing while running. Once complete, you should see that it created an html directory that contains all of your HTML based documentation that it generated for your project.
Viewing The Generated Documentation
Load the index.html file located within the html directory into your browser. This is the main project page and displays all of the information, separated by sections, we specified in the beginning comments of our sketch.
Across the top of the page, under the project title, you will see the Main Page, Classes, and Files tabs with their accompanying pull down menus. These tabs and menus will contain all of the documentation generated for your project.
Clicking on the Classes tab will provide us a list of the classes included in our project. The Sensor structure should be listed there. Clicking on Sensor will show us the detailed information of the Sensor structure along with the members defined in that structure.
Likewise, clicking on the Files tab will give us a list of the files included in our project. Here we see the DoxygenExample.ino file listed. Clicking on that file name will open the web page for that file. It will show us quite a bit of information about our Arduino sketch. Summary descriptions for items such as macros, enumerations, functions, and variables will be shown along with a listing of included libraries and files at the top.
Take a peak at the other menu options to get an idea of how the documentation is structured.
Summary
In this tutorial, we learned how to generate program documentation from our source code using the Doxygen utility for our Arduino sketches. Generously commenting and generating source code documentation with Doxygen is a great way to provide a high level architectural overview of a project and provide others the means to more easily understand your code. It can also help the original programmer who hasn’t worked on that code in a while.
We barely touched the surface of all the things you can do with Doxygen. If you are interested in learning more, please see the Doxygen manual.
The Arduino sketch and Doxygen configuration file used for this tutorial are available on GitHub.
Thank you for joining me in this journey and I hope you enjoyed the experience. Please feel free to share your thoughts in the comments section below.
Leave a Comment