# The Well-Automated Arduino Library

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/050/299/medium800/maker_business_Tessa-Pride.png?1516308275)

Writing software is like gardening - the flowers are beautiful but you're going to spend a lot of time weeding! Except instead of weeding, its keeping up to date with new frameworks, operating systems and dependancies. It's a ton of work! So why not make it easy on your self with automation?

In this guide we'll go through how to use [GitHub](https://github.com/) (a free service for storing source code) + [Doxygen](http://doxygen.org) ( a free documentation standard/parser) + [TravisCI.org](http://TravisCI.org) (a free service for continuous integration/testing) To automatically document and test your code.

_In specific_, we'll be showing how to automate wide-range compilation tests for an Arduino library to make sure that updates to the Arduino IDE, language, and board support packages don't end up breaking builds.

_In general_, the same steps can be used for any codebase, including every-day source code projects - Arduino and otherwise! (But, it's really good for Arduino because we have scripts that do a lot of work for you already written)

This guide doesn't teach you how to write code, or how to write a library. But it will show you how to make your existing libraries live long fruitful lives as they age!

### 

Yep, this guide is how to do it using only free services for open-source software

### 

Yep, this guide is how to do it using only the techniques I know how to use

### 

Yep, this guide is how to do it without having to host anything on your own server

# The Well-Automated Arduino Library

## Repository

# Overall Structure

In this guide we'll watch as I transform [Adafruit\_TSL2561](https://github.com/adafruit/Adafruit_TSL2561), one of our first libraries, spruce it up and automate it. This guide doesn't talk about how to _write code_ - just how to make it fancy!

We'll be using the 'classic' Arduino library structure. In this case, we make a new repo, with no spaces or dashes, on GitHub: **Adafruit\_TSL2561** and `git clone` it into our **ArduinoSketches/libraries** folder. This makes it easy to test in Arduino and commit in the same folder

![](https://cdn-learn.adafruit.com/assets/assets/000/050/295/medium800/maker_business_librarystruct.png?1516301441)

Inside the folder you'll need these 4 parts:

- `Adafruit_TSL2561.cpp` - the main cpp file that contains your code
- `Adafruit_TSL2561.h` - the main header file that has macros, enums, classes, etc!
- `library.properties` - the file that lets Arduino IDE and library manager know what's inside your library
- `README.md` - Appears in the front of the GitHub repo, a good place to put descriptions, images, instructions and a Travis tag

You may also have optional parts like

- ` .gitignore` (see below) - helps keep your git commits from accidentally including temporary files
- `.github folder` with ISSUE\_TEMPLATE.md and PULL\_REQUEST\_TEMPLATE.md - [see our examples here](https://github.com/adafruit/Adafruit_TSL2561/tree/master/.github) if you like you can adapt and reuse them.

 **library.properties** is very particular about its formatting, [see here for a guide on how to make sure you get this in the right formatting](https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification)! We won't cover it in detail here

For **README.md** we do recommend adding a Travis tag and you might as well do that now. Open it up in a text editor and after the first heading add text like this:

`[![Build Status](https://travis-ci.com/adafruit/Adafruit_TSL2561.svg?branch=master)](https://travis-ci.com/adafruit/Adafruit_TSL2561)`

Except change the two sub-URLs to match your repository

![](https://cdn-learn.adafruit.com/assets/assets/000/050/296/medium800/maker_business_buildstat.png?1516301723)

When it renders for now it will say **Build Unknown** - we'll get that going later!

![](https://cdn-learn.adafruit.com/assets/assets/000/050/297/medium800/maker_business_unkn.png?1516301834)

# Create Empty gh-pages Branch

Rather than storing the documentation in your master branch, cluttering your repo, we'll have TravisCI put the files into the **gh-pages** branch. GitHub can be informed that documentation is there and it will host the webpages for you, it's very slick!

Make sure you've committed and pushed _all_ your code before you continue, since you will be deleting from a branch and it can be scary!

```auto
cd /path/to/repository
git checkout --orphan gh-pages &amp;&amp; \
rm -rf * .github .travis.yml .gitignore &amp;&amp; \
echo "My gh-pages branch" &gt; README.md &amp;&amp; \
git add . &amp;&amp; \
git commit -a -m "Clean gh-pages branch" &amp;&amp; \
git push origin gh-pages &amp;&amp; \
git checkout main
```

![](https://cdn-learn.adafruit.com/assets/assets/000/050/260/medium800/maker_business_ghpage.png?1516230323)

On GitHub you can verify the **gh-pages** branch is empty

![](https://cdn-learn.adafruit.com/assets/assets/000/050/261/medium800/maker_business_ghempt.png?1516230386)

# Enable GitHub Pages on gh-pages

Now you've created **gh-pages** you can set it up so GitHub will automatically create a website with our auto-generated documentation

Go to the **Settings** for the repository

![](https://cdn-learn.adafruit.com/assets/assets/000/050/285/medium800/maker_business_settings.png?1516291716)

And scroll down to **GitHub Pages**. From the drop-down select **gh-pages** as the source and hit Save

![](https://cdn-learn.adafruit.com/assets/assets/000/050/287/medium800/maker_business_source.png?1516291831)

Save and you'll get notification of your new github.io URL. Note that nothing will be there at this time - that's OK! We'll get that going soon.

![](https://cdn-learn.adafruit.com/assets/assets/000/050/288/medium800/maker_business_pages.png?1516291897)

# Optional: .gitignore

Put the following into your **master** branch's `.gitignore`, it will help you avoid committing doxygen files later

```
# Our handy .gitignore for automation ease
Doxyfile*
doxygen_sqlite3.db
html
```

# Optional (For Adafruit Only!) Add Adafruit Librarians group

If you're working on an official Adafruit library, add the **Arduino Librarians** group to your repository with **write** access, which will let [adafruit-adabot](https://github.com/adafruit/adabot) push pages on your behalf!

![](https://cdn-learn.adafruit.com/assets/assets/000/050/264/medium800/maker_business_librarians.png?1516230590)

![](https://cdn-learn.adafruit.com/assets/assets/000/050/263/medium800/maker_business_image.png?1516230559)

# The Well-Automated Arduino Library

## Doxygen

![](https://cdn-learn.adafruit.com/assets/assets/000/050/194/medium800/maker_business_doxygen.png?1516165801)

# About Doxygen

Doxygen is a somewhat ancient but popular method for creating documentation for C and C++ project (it also supports other languages but its _great_ at C/C++). What's great about Doxygen is that the documentation lives with the source code in the same file so you are less likely to get out of sync

From [doxygen.org](http://doxygen.org)'s website:

> _Generate documentation from source code__Doxygen is the de facto standard tool for generating documentation from annotated C++ sources, but it also supports other popular programming languages such as C, Objective-C, C#, PHP, Java, Python, IDL (Corba, Microsoft, and UNO/OpenOffice flavors), Fortran, VHDL, Tcl, and to some extent D.__Doxygen can help you in three ways:_
> 1. _It can generate an on-line documentation browser (in HTML) and/or an off-line reference manual (in ![$\mbox{\LaTeX}$](http://www.stack.nl/~dimitri/doxygen/form_0.png)) from a set of documented source files. There is also support for generating output in RTF (MS-Word), PostScript, hyperlinked PDF, compressed HTML, and Unix man pages. The documentation is extracted directly from the sources, which makes it much easier to keep the documentation consistent with the source code._
> 2. _You can [configure](http://www.stack.nl/~dimitri/doxygen/manual/starting.html#extract_all) doxygen to extract the code structure from undocumented source files. This is very useful to quickly find your way in large source distributions. Doxygen can also visualize the relations between the various elements by means of include dependency graphs, inheritance diagrams, and collaboration diagrams, which are all generated automatically._
> 3. _You can also use doxygen for creating normal documentation (as I did for the doxygen user manual and web-site)._
> 
> _Doxygen is developed under Mac OS X and Linux, but is set-up to be highly portable. As a result, it runs on most other Unix flavors as well. Furthermore, executables for Windows are available._

Doxygen runs on the source code itself, and create HTML output that we can then point people to when they want detailed information about the library.

To keep our lives easier, instead of running Doxygen every commit, we'll use **Travis CI** to keep the documentation up to date. Every commit on GitHub will trigger TravisCI to call Doxygen on the source code, verify that documentation exists for each function, and will refresh the website pages.

However, to get started, we'll want to run Doxygen locally so we can make sure our files are in good shape before committing them (otherwise we'll have to run Travis over and over until we get it right, which takes a lot longer than fixing it all locally)

# Step 1) Install Doxygen

Doxygen runs in the command line, and is available for Mac, Win and Linux. On Mac/Linux we suggest using **brew** or **apt-get** or whatever package manager you have

For Windows, [visit the downloads page](http://www.stack.nl/~dimitri/doxygen/download.html) and scroll down to download the installer, then run it to install. Or if you have something like MSYS2, use the package manager.

In this guide we'll be using version 1.8.13 - if its something much older you may get errors

![](https://cdn-learn.adafruit.com/assets/assets/000/050/195/medium800/maker_business_doxy.png?1516165833)

# Step 2) Grab our Doxyfile

Doxygen needs a 'setup' file called _Doxyfile_. There's two ways to go about this step.

**If you are not going to be using our Travis CI auto-doxy-runner&nbsp;_or_ if you have needs for a custom Doxyfile** you should run `doxygen -g` from within the library folder, which will create a Doxyfile. Then edit it to your hearts desire and commit it to your GitHub repo

![](https://cdn-learn.adafruit.com/assets/assets/000/050/196/medium800/maker_business_doxy-g.png?1516165960)

However, **if you are planning to use TravisCI to auto-generate Doxygen and you don't have any big changes you want to make to our setup** we recommend using our default Doxyfile, and _not_ committing it. Our TravisCI will automatically grab the Doxyfile for you, which means we can update it from time to time as doxygen updates and changes the config file. **This is what we'll assume you're doing and continue as-is!**

In which case, download or `wget` our example Doxyfile from [https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/Doxyfile.default](https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/Doxyfile.default), place it in the base of the library, and rename it `Doxyfile`

![](https://cdn-learn.adafruit.com/assets/assets/000/050/197/medium800/maker_business_doxydefault.png?1516166172)

# Step 3) Run doxygen

Now you can try running `doxygen Doxyfile` and see the output

![](https://cdn-learn.adafruit.com/assets/assets/000/050/198/medium800/maker_business_doxy_complaints.png?1516166290)

It's normal to get a massive number of complaints. Now it's time to document and get those complaints down to zero!

- [Read the Doxygen Manual](http://www.doxygen.nl/manual/)! Its detailed and very informative
- [Check out our Doxygen tips page](../../../../the-well-tempered-arduino-library/doxygen-tips), which is basically my cheat-sheet since I often forget the @ tags and formatting
- Look online or at other Doxygen'd code for inspiration

OK its a little annoying to do but _eventually_ you'll get to zero output from Doxygen. Actually, because my compiled doxygen binary didn't come with CLANG support, I do get two warnings, but you can ignore these.

![](https://cdn-learn.adafruit.com/assets/assets/000/050/199/medium800/maker_business_clangwarn.png?1516169694)

# Preview Documentation

OK now you can look in the folder and you'll see that in addition to the `Doxyfile`, you also have a `sqlite3.db` and an `html` folder.

![](https://cdn-learn.adafruit.com/assets/assets/000/050/208/medium800/maker_business_doxfiles.png?1516172418)

Don't commit these to your git repo! Instead, open up the html folder and double-click the **index.html**

![](https://cdn-learn.adafruit.com/assets/assets/000/050/200/medium800/maker_business_index.png?1516169854)

You will now be able to _browse_ the documentation. You can see the nice front page you set up in the` .cpp` file

![maker_business_doxyindex.png](https://cdn-learn.adafruit.com/assets/assets/000/050/201/medium640/maker_business_doxyindex.png?1516169971)

Click the **Classes** button

![](https://cdn-learn.adafruit.com/assets/assets/000/050/202/medium800/maker_business_classbutton.png?1516169997)

And you can locate your object, click on that...

![](https://cdn-learn.adafruit.com/assets/assets/000/050/203/medium800/maker_business_classes.png?1516170020)

Now you can see the details of your class documentation! Check it over for typos, corrections, or other stuff you want to add. Re-run `doxygen` as desired until you get it to a good spot

![maker_business_classdetails.png](https://cdn-learn.adafruit.com/assets/assets/000/050/205/medium640/maker_business_classdetails.png?1516170080)

# Commit Documented Code

You are very nearly done!

Commit and push your updated code to GitHub

Warning: 

![](https://cdn-learn.adafruit.com/assets/assets/000/050/206/medium800/maker_business_commit.png?1516170249)

![](https://cdn-learn.adafruit.com/assets/assets/000/050/207/medium800/maker_business_push.png?1516170276)

OK you are ready for the next, amazing step... **automation!**

# The Well-Automated Arduino Library

## Doxygen Tips

# Main .cpp File Header

This fancy file header from KTown has multiple @ tags that will make a very nice 'front page' for your documentation _and_ contains useful information! Copy and paste the whole chunk, then edit as necessary:

- `@file` - change this to the name of the file the header is at the top of!
- `@mainpage` - This will be the name of the documentation page, so make it short but descriptive
- `@section intro_sec Introduction` - Your intro. Longer than the header
- `@section dependencies Dependencies` - What other libraries or hardware are required
- `@section author Author` - You and others!
- `@section license License` - How you want others to use this code

```
/*!
 * @file Adafruit_FXOS8700.cpp
 *
 * @mainpage Adafruit FXOS8700 accel/mag sensor driver
 *
 * @section intro_sec Introduction
 *
 * This is the documentation for Adafruit's FXOS8700 driver for the
 * Arduino platform.  It is designed specifically to work with the
 * Adafruit FXOS8700 breakout: https://www.adafruit.com/products/3463
 *
 * These sensors use I2C to communicate, 2 pins (SCL+SDA) are required
 * to interface with the breakout.
 *
 * Adafruit invests time and resources providing this open source code,
 * please support Adafruit and open-source hardware by purchasing
 * products from Adafruit!
 *
 * @section dependencies Dependencies
 *
 * This library depends on &lt;a href="https://github.com/adafruit/Adafruit_Sensor"&gt;
 * Adafruit_Sensor&lt;/a&gt; being present on your system. Please make sure you have
 * installed the latest version before using this library.
 *
 * @section author Author
 *
 * Written by Kevin "KTOWN" Townsend for Adafruit Industries.
 *
 * @section license License
 *
 * BSD license, all text here must be included in any redistribution.
 *
 */
```

Info: 

# Main .h File Header

The .h is shorter, and doesn't have the special sections but you **do** need to add a `@file` tag!

```
/*!
 * @file Adafruit_FXOS8700.h
 *
 * This is part of Adafruit's FXOS8700 driver for the Arduino platform.  It is
 * designed specifically to work with the Adafruit FXOS8700 breakout:
 * https://www.adafruit.com/products/3463
 *
 * These sensors use I2C to communicate, 2 pins (SCL+SDA) are required
 * to interface with the breakout.
 *
 * Adafruit invests time and resources providing this open source code,
 * please support Adafruit and open-source hardware by purchasing
 * products from Adafruit!
 *
 * Written by Kevin "KTOWN" Townsend for Adafruit Industries.
 *
 * BSD license, all text here must be included in any redistribution.
 *
 */
```

Danger: 

# Documenting Functions

The most work will be in documenting functions. Here's another lovely example from KTown we can reference:

```
/**************************************************************************/
/*!
    @brief  Gets the most recent sensor events.
            This function reads from both the accelerometer and the
            magnetometer in one call, and is a deviation from the standard
            Adafruit_Sensor API, but is provided as a convenience since most
            AHRS algorithms require sensor samples to be as close in time as
            possible.
    @param    accelEvent
              A reference to the sensors_event_t instances where the
              accelerometer data should be written.
    @param    magEvent
              A reference to the sensors_event_t instances where the
              magnetometer data should be written.
    @return True if the event read was successful, otherwise false.
*/
/**************************************************************************/
bool Adafruit_FXOS8700::getEvent(sensors_event_t* accelEvent, sensors_event_t* magEvent)
```

The first and last `/ ************************************************************************** /` are not _required_ but we think it looks good.

### Brief & Description

Start with `@brief` and add a short sentence, ending with a . After that&nbsp; you can write as much as you like and it goes into the longer description of the function. KTown did some fun text-justification to make it all line up but if your editor doesn't do that, you can make it one long sentence like so:

`@brief Gets the most recent sensor events. This function reads from both the accelerometer and the``magnetometer in one call, and is a deviation from the standard Adafruit_Sensor API, but is provided as a convenience since most AHRS algorithms require sensor samples to be as close in time as possible.`

## Parameters

Each parameter needs a `@param` line. If you have no parameters to the function, skip this part. The word _right after_ `@param` must be the same as the name of the parameter (make sure the parameter name in the .cpp file matches the one in .h) If you want you can make the name and the text on separate lines, or just put on one line like:

`@param magEvent
              A reference to the sensors_event_t instances where the
              magnetometer data should be written.`

### Return Value

Lastly, we need to put in the return value details. You can skip this if your function returns void or is a constructor. Otherwise, put in a `@returns` with a line explaining what it returns

# Macros and Enums

After functions, you'll need to document all your enumerations and macros (`#define`s)

For enums, you only need a comment beforehand like so, but I like to add a comment per line also:

```
/** TSL2561 offers 2 gain settings */
typedef enum
{
  TSL2561_GAIN_1X                   = 0x00,    // No gain
  TSL2561_GAIN_16X                  = 0x10,    // 16x gain
}
tsl2561Gain_t;
```

```
/** TSL2561 I2C Registers */
enum
{
  TSL2561_REGISTER_CONTROL          = 0x00, // Control/power register 
  TSL2561_REGISTER_TIMING           = 0x01, // Set integration time register
  TSL2561_REGISTER_THRESHHOLDL_LOW  = 0x02, // Interrupt low threshold low-byte
  TSL2561_REGISTER_THRESHHOLDL_HIGH = 0x03, // Interrupt low threshold high-byte
  TSL2561_REGISTER_THRESHHOLDH_LOW  = 0x04, // Interrupt high threshold low-byte
  TSL2561_REGISTER_THRESHHOLDH_HIGH = 0x05, // Interrupt high threshold high-byte
  TSL2561_REGISTER_INTERRUPT        = 0x06, // Interrupt settings
  TSL2561_REGISTER_CRC              = 0x08, // Factory use only
  TSL2561_REGISTER_ID               = 0x0A, // TSL2561 identification setting
  TSL2561_REGISTER_CHAN0_LOW        = 0x0C, // Light data channel 0, low byte
  TSL2561_REGISTER_CHAN0_HIGH       = 0x0D, // Light data channel 0, high byte
  TSL2561_REGISTER_CHAN1_LOW        = 0x0E, // Light data channel 1, low byte
  TSL2561_REGISTER_CHAN1_HIGH       = 0x0F  // Light data channel 1, high byte
};
```

For `#define`'s you'll need to add a proper one-line comment. the `///<` style comment is easy to put after each line

```
#define TSL2561_LUX_LUXSCALE      (14)      ///&lt; Scale by 2^14
#define TSL2561_LUX_RATIOSCALE    (9)       ///&lt; Scale ratio by 2^9
#define TSL2561_LUX_CHSCALE       (10)      ///&lt; Scale channel values by 2^10
#define TSL2561_LUX_CHSCALE_TINT0 (0x7517)  ///&lt; 322/11 * 2^TSL2561_LUX_CHSCALE
#define TSL2561_LUX_CHSCALE_TINT1 (0x0FE7)  ///&lt; 322/81 * 2^TSL2561_LUX_CHSCALE
```

# Classes & Objects

Don't forget classes/objects also need a description!

```
/**************************************************************************/
/*! 
    @brief  Class that stores state and functions for interacting with TSL2561 Light Sensor
*/
/**************************************************************************/
class Adafruit_TSL2561_Unified : public Adafruit_Sensor {
```

# Optional: Code Snippets and Fixed Width Text Blocks

While you might want to avoid inserting complex code snippets since it becomes a maintenance risk, if you do need to include a code snippet or a block of 'fixed width' text, you can use the `@code` and `@endcode` tags, as shown below:

Info: 

```
@section example_getevent Example

The following loop implementation shows how you can use the .getEvent
function to continuously read data from the sensor, and display it on the
Serial Monitor:

@code
void loop(void)
{
  sensors_event_t aevent, mevent;

  // Get a new sensor event from the accelerometer and magnetometer
  accelmag.getEvent(&amp;aevent, &amp;mevent);

  // Display the accel results (acceleration is measured in m/s^2)
  Serial.print("A ");
  Serial.print("X: "); Serial.print(aevent.acceleration.x, 4); Serial.print("  ");
  Serial.print("Y: "); Serial.print(aevent.acceleration.y, 4); Serial.print("  ");
  Serial.print("Z: "); Serial.print(aevent.acceleration.z, 4); Serial.print("  ");
  Serial.println("m/s^2");

  // Display the mag results (mag data is in uTesla)
  Serial.print("M ");
  Serial.print("X: "); Serial.print(mevent.magnetic.x, 1); Serial.print("  ");
  Serial.print("Y: "); Serial.print(mevent.magnetic.y, 1); Serial.print("  ");
  Serial.print("Z: "); Serial.print(mevent.magnetic.z, 1); Serial.print("  ");
  Serial.println("uT");

  Serial.println("");

  delay(500);
}
@endcode
```

This will result in something resembling the following output:

![](https://cdn-learn.adafruit.com/assets/assets/000/050/209/medium800/maker_business_code_endcode.png?1516188214)

# The Well-Automated Arduino Library

## Travis CI

Danger: 

![](https://cdn-learn.adafruit.com/assets/assets/000/050/246/medium800/maker_business_Tessa-1.png?1516227372)

Now that we have fully documented the library, we are ready to add automation. Automation means we don't have to remember to run doxygen, or compile every platform every time. Automation will do this for you after _every commit or pull request_! You'll make fewer mistakes and get better pulls from the community. We'll be using **Travis CI** , a very popular and well run **C** ontinuous **I** ntegration service. You might be wondering - how much is the monthly subscription? **Nothing!** For open source libraries, you can run travis free of cost at [travis-ci.org](https://travis-ci.org/)

(Adafruit pays for the .com version of the service which we use a lot for internal repositories, and we recommend paying for it if you're building anything commercial because it's soooo worth it.)

# Sign up for Travis
Use your GitHub login to register for Travis at [travis-ci.org](https://travis-ci.org). This is required

![maker_business_travissign.png](https://cdn-learn.adafruit.com/assets/assets/000/050/249/medium640/maker_business_travissign.png?1516227674)

Once logged in, you can **Sync** your account and **Search** for the repository you want to automate

![maker_business_orgs.png](https://cdn-learn.adafruit.com/assets/assets/000/050/258/medium640/maker_business_orgs.png?1516228877)

Flick the switch to turn on Travis for that repository

![](https://cdn-learn.adafruit.com/assets/assets/000/050/259/medium800/maker_business_tsl2.png?1516228944)

Nothing will happen quite yet. That's OK! We have to add our Travis config file to the repository

# Travis YML

Travis will create a fully new computer image every time and run your shell script instructions to compile the code and document it.

Here is our demo configuration file:

https://github.com/adafruit/travis-ci-arduino/blob/master/example_travis.yml

And here's what it all means:

`language: c` This part is easy, we're going to be compiling C / C++ code.  
`sudo: false` means We don't need root on the container (if you don't need it, don't use it!)

```
# Blacklist
branches:
  except:
- gh-pages
```

This means we will not perform the full compile/documentation step on when we push to the **gh-pages** branch. This is so we don't accidentally trigger Travis to run twice after we push the documentation

```
env:
  global:
- PRETTYNAME="Adafruit FT6206 Arduino Library"
```

This is the 'nice pretty' name of the library, which will be displayed at the header of the documentation. **You must change this to avoid confusion!**

```
        before_install:
- source &lt;(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh)
  
  
```

This step will install Arduino on your virtual computer and set up the board types as well, such as Uno, ESP8266, Zero, Due, etc! It's just a shell script so you can check it out at the URL to see what its' doing

```
install:
- arduino --install-library "Adafruit ILI9341","Adafruit GFX Library"
```

This line adds more configuration setup. The text after the **-** is literally a bash shell command. We're [calling the Arduino binary on the command line and instructing it to do stuff like install some libraries](https://github.com/arduino/Arduino/blob/master/build/shared/manpage.adoc). If you do not need to install any libraries or any other configuration steps, just remove these two lines.

```
script:
- build_main_platforms
```

This calls a function we created in the **before\_install** step, when we ran that shell script from `adafruit/travis-ci-arduino`

We have a few different functions, but this one will build for the main platforms we aim to support: Arduino UNO (ATmega328P), Leonardo (ATmega32u4), Zero (ATSAMD21), Due (ATSAMX), and ESP8266

```
# Generate and deploy documentation
after_success:
  - source &lt;(curl -SLs  https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/library_check.sh)
- source &lt;(curl -SLs  https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/doxy_gen_and_deploy.sh)
```

Lastly we have two more scripts we run. `library_check.sh`, at this time, is an empty hook but we hope to add some things like checking format of the library and looking for missing or misformatted lines.&nbsp; You can remove this.

`doxy_gen_and_deploy.sh` Is the script that will do the doxygen generation and then push the pages to your gh-pages branch

Warning: 

# Add travis.yml To Library

OK now you are ready! Grab our example travis.yml file from [https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/example\_travis.yml](https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/example_travis.yml), rename it `.travis.yml` and place in your library repository.

![](https://cdn-learn.adafruit.com/assets/assets/000/050/265/medium800/maker_business_extrav.png?1516230950)

Edit it as we explain above, **in particular edit the PRETTYNAME variable and change the extra-library-installation line as necessary!**

![](https://cdn-learn.adafruit.com/assets/assets/000/050/266/medium800/maker_business_edittrav.png?1516231012)

Save, commit and push the new `.travis.yml` file to your **master** branch

# Checking Status

You can now check out the status of your build by visiting http://travis-ci.org

If you have multiple repositories, they'll appear on the left hand side. Yellow means working, green means pass and red means fail.

![](https://cdn-learn.adafruit.com/assets/assets/000/050/271/medium800/maker_business_building.png?1516232319)

# Failure/Passes

After every commit you may get an email or notification that Travis failed, or if it succeeded after failing you can get one too

![](https://cdn-learn.adafruit.com/assets/assets/000/050/270/medium800/maker_business_fail.png?1516232209)

Lets go and check out in the build log avialable at https://travis-ci.org/_yourgithubaccount_/_repositoryname_

In this case, you can see we failed to compile the **sensorapi.ino** demo when running the zero test (SAMD21) due to an `#include "avr/delay.h"` now we know we need to either `#ifdef` it out or restructure our code.

![](https://cdn-learn.adafruit.com/assets/assets/000/050/276/medium800/maker_business_error.png?1516289858)

Travis builds take 5 minutes or so, so you're best off doing fast iterative tests locally. After you've fixed the bug and tested it locally, commit and push!

This time, with any luck, you'll pass the main compilation tests!

![](https://cdn-learn.adafruit.com/assets/assets/000/050/277/medium800/maker_business_build-main.png?1516290669)

However your CI will probably still fail because we cannot 'push' the documentation to **gh-pages** so the last thing we have to do is give Travis CI permission to push to our repository

# Adding Write Permissions

Log in to GitHub again and visit [https://github.com/settings/tokens](https://github.com/settings/tokens)

Click on **Generate New Token**

![](https://cdn-learn.adafruit.com/assets/assets/000/050/278/medium800/maker_business_gentken.png?1516290829)

You'll need to set up the _scope_ for this token, give it a nice name (you can have one token per repository or one token for all your repos)

And, if it's a public repo, click **public\_repo** (otherwise you'll need to click all of **repo** for the access)

![](https://cdn-learn.adafruit.com/assets/assets/000/050/279/medium800/maker_business_public_repo.png?1516291014)

Now click **Generate Token** to get your key, which will be a bunch of numbers and letters. **Keep this token safe! It's the same as your GitHub login!**

![](https://cdn-learn.adafruit.com/assets/assets/000/050/280/medium800/maker_business_token.png?1516291111)

Back in your Travis CI page, go to the **Settings** for your repository

![](https://cdn-learn.adafruit.com/assets/assets/000/050/281/medium800/maker_business_settings.png?1516291170)

Scroll down to the **Environment Variables** section and create a **new** variable called `GH_REPO_TOKEN` then paste in the generated token in the box

![](https://cdn-learn.adafruit.com/assets/assets/000/050/282/medium800/maker_business_token.png?1516291274)

Danger: 

Save it, your token is now stored safely and securely

![](https://cdn-learn.adafruit.com/assets/assets/000/050/283/medium800/maker_business_hidden.png?1516291327)

# Final Run and Check!

Now you can re-trigger a Travis build from the menu

![](https://cdn-learn.adafruit.com/assets/assets/000/050/284/medium800/maker_business_trigger.png?1516291385)

This time, success!

![](https://cdn-learn.adafruit.com/assets/assets/000/050/289/medium800/maker_business_fixed.png?1516291946)

![](https://cdn-learn.adafruit.com/assets/assets/000/050/290/medium800/maker_business_success.png?1516291951)

And if you look at your GitHub activity history you will see that 'you' pushed the code documentation in a Travis build

![](https://cdn-learn.adafruit.com/assets/assets/000/050/291/medium800/maker_business_pushed.png?1516292035)

And at github.io you'll see your newly updated documentation!

![](https://cdn-learn.adafruit.com/assets/assets/000/050/294/medium800/maker_business_githubio.png?1516300759)

And in the main repo, our Travis tag says its passing! Congrats, its a little tough the first time to do all these steps but once you get the hang of it, you'll be glad you did it later

![](https://cdn-learn.adafruit.com/assets/assets/000/050/298/medium800/maker_business_pasin.png?1516302037)

# The Well-Automated Arduino Library

## Formatting with clang-format

## About ClangFormat
ClangFormat (often called Clang) is a tool that allows you to automatically format C, C++, and Objective-C files. It makes your code more readable and saves your time and the time of anyone reviewing your code for a pull request by making it so neither of you has to worry about formatting very much. On Adafruit repositories, clang-format is run automatically on every commit and pull request, but you still have to run it locally since when it is run through a CI, it just tells you what needs to be reformatted without actually reformatting it.

### Step 1) Install clang-format

For mac/linux, you can install with a package manager

macOS:

```none
brew install clang-format
```

If you don't already have Homebrew installed, you can do it [here](https://brew.sh)

Linux:

```none
sudo apt install clang-format
```

![](https://cdn-learn.adafruit.com/assets/assets/000/097/250/medium800/maker_business_Screenshot_from_2020-11-24_17-50-51.png?1606258279)

Windows:

Download the "Windows Installer" from the "Windows Snapshot Builds" section from the link below.

[LLVM Snapshot Builds](https://llvm.org/builds/)
### Step 2) Run it

Navigate to the folder you'd like to run clang-format in and then run the following command, replacing **File\_To\_Format.cpp** with the filename of the file you'd like to format:

```none
clang-format -i File_To_Format.cpp
```

### Step 3) Add an alias to your .bashrc (optional)

I've found it can be really useful to have one simpler command that runs clang on all the pertinent files in a directory, and I modified a command from our Arduino CI repository to do that. Here's how you can use that too.

Linux:

1. Open a terminal
2. Type `nano .bashrc` and hit enter.
3. Paste the following near the bottom of the file:
  1. `alias format='find . -name "*.cpp" -o -name "*.c" -o -name "*.h"|xargs -I {} clang-format -i {}'`

4. Close the file with Shift+X and then enter Y when prompted if you would like to save the file.
5. Type&nbsp;`source .bashrc`
6. If there are no errors, then go back into the directory you'd like to run clang-format in, type&nbsp;`format`, and hit enter.
7. The command should look through the directory you're in and run clang-format on all .cpp, .c, and .h files.

These instructions may work on mac, but you will have to replace `.bashrc` with `.bash_profile`.


## Featured Products

### Arduino - Skill badge, iron-on patch

[Arduino - Skill badge, iron-on patch](https://www.adafruit.com/product/1300)
Arduino! You learned how to program and use the Arduino Microcontroller board. Adafruit offers a fun and exciting "badges" of achievement for electronics, science and engineering. We believe everyone should be able to be rewarded for learning a useful skill, a badge is just one of...

No Longer Stocked
[Buy Now](https://www.adafruit.com/product/1300)
[Related Guides to the Product](https://learn.adafruit.com/products/1300/guides)
### Micro-controllers - Skill badge, iron-on patch

[Micro-controllers - Skill badge, iron-on patch](https://www.adafruit.com/product/484)
You are learning micro-controllers! From Arduino, Netduino, Propeller, PIC, ARM and beyond! Adafruit offers a fun and exciting "badges" of achievement for electronics, science and engineering. We believe everyone should be able to be rewarded for learning a useful skill, a badge is...

No Longer Stocked
[Buy Now](https://www.adafruit.com/product/484)
[Related Guides to the Product](https://learn.adafruit.com/products/484/guides)
### Micro-controllers - Sticker!

[Micro-controllers - Sticker!](https://www.adafruit.com/product/689)
You are learning micro-controllers! From Arduino, Netduino, Propeller, PIC, ARM and beyond! Adafruit offers a fun and exciting stickers to celebrate achievement for electronics, science and engineering. We believe everyone should be able to be rewarded for learning a useful skill, a badge is...

No Longer Stocked
[Buy Now](https://www.adafruit.com/product/689)
[Related Guides to the Product](https://learn.adafruit.com/products/689/guides)

## Related Guides

- [Programming with Scratch 2 or 3 on Raspberry Pi](https://learn.adafruit.com/programming-with-scratch-on-raspberry-pi.md)
- [Adafruit STSPIN220 Stepper Motor Driver Breakout Board](https://learn.adafruit.com/adafruit-stspin220-stepper-motor-driver-breakout-board.md)
- [Control Electronics with your Brain using NextMind](https://learn.adafruit.com/control-electronics-with-your-brain-using-nextmind.md)
- [Adafruit TRRS Trinkey](https://learn.adafruit.com/adafruit-trrs-trinkey.md)
- [1.8" TFT Display Breakout and Shield](https://learn.adafruit.com/1-8-tft-display.md)
- [Adafruit SEN54 or SEN55 Adapter Breakout](https://learn.adafruit.com/adafruit-sen54-or-sen55-adapter-breakout.md)
- [Commodore 64 - The Most Popular Retro Computer of All Time](https://learn.adafruit.com/commodore-64-retro-guide.md)
- [Adafruit DACx578 - 8 x Channel I2C DAC](https://learn.adafruit.com/adafruit-dac7578-8-x-channel-12-bit-i2c-dac.md)
- [Program an AVR or Arduino Using Raspberry Pi GPIO](https://learn.adafruit.com/program-an-avr-or-arduino-using-raspberry-pi-gpio-pins.md)
- [Using Board Package Tool to Update Adafruit Arduino Packages](https://learn.adafruit.com/using-board-package-tool-to-update-adafruit-arduino-packages.md)
- [Adafruit Kegomatic](https://learn.adafruit.com/adafruit-keg-bot.md)
- [Adafruit SPA06-003 - Temperature + Pressure Sensor](https://learn.adafruit.com/adafruit-spa06-003-temperature-pressure-sensor.md)
- [Adafruit ATWINC1500 WiFi Breakout](https://learn.adafruit.com/adafruit-atwinc1500-wifi-module-breakout.md)
- [Adafruit 4-Channel ADC Breakouts](https://learn.adafruit.com/adafruit-4-channel-adc-breakouts.md)
- [Working with Multiple Same Address I2C Devices](https://learn.adafruit.com/working-with-multiple-i2c-devices.md)
