# How to Add a New Board to WipperSnapper

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/122/891/medium800/adafruit_io_adafruit_20boards_wippersnapper_io.jpg?1689875480)

Do you want to use your favorite WiFi development board with [Adafruit.io WipperSnapper](https://learn.adafruit.com/quickstart-adafruit-io-wippersnapper)?

This guide will walk you through the process of adding a new board to Adafruit.io WipperSnapper - our **no-code IoT platform**. Upon completion of the guide, your board will be included with every new release of the WipperSnapper library.

You'll begin by **creating a board definition** to describe the physical characteristics and properties of your board. Then, you **create local forks of WipperSnapper and its required build tool** and test that everything is working correctly by **building the firmware**. You'll **edit files so WipperSnapper can detect your development board** and **create a pull request to add the board to WipperSnapper**. Finally, once your board is added to the WipperSnapper library, its corresponding firmware file(s) will be built and distributed with each release of the library.

You will need to be familiar with Git and GitHub to complete this guide. Adafruit has a great guide on [Contributing to CircuitPython with Git and GitHub](https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github/) if you're unsure how to get started. You will also be asked to modify some Python, C++, and JSON code. If you are unfamiliar with any of these - don't fret - this guide will explain what to do, step by step.

### Is my board's microcontroller compatible with WipperSnapper?

The following platforms/microcontrollers are compatible with the Adafruit.io WipperSnapper firmware at this time:

- ESP8266
- ESP32
- ESP32-S2
- ESP32-S3
- ESP32-C3
- Raspberry Pi RP2040
- SAMD51 + Adafruit "AirLift" ESP32 Co-Processor

If your development board uses one of these platforms - you can add it to WipperSnapper by following the steps in this guide!

# How to Add a New Board to WipperSnapper

## Create a the Board Definition JSON 

We're first going to create a board definition for the development board. This is a required step and is used to help WipperSnapper identify a development board's physical characteristics.

**What is a board definition?**

In WipperSnapper, a board definition is a JSON file that contains a virtual representation of a physical development board. The definition file contains information about the board's physical pin locations, microcontroller type, and vendor information. WipperSnapper requires one board definition file for each development board it supports.

Warning: 

 **If you are unfamiliar with GitHub and Git or would like to refresh before starting,** &nbsp;[we have a great guide on using the features of GitHub here \>\>\>.](https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github/overview)

## Fork the Adafruit\_WipperSnapper\_Boards Repository

WipperSnapper's board definition files are stored in the [WipperSnapper\_Boards repository on GitHub](https://github.com/adafruit/Wippersnapper_Boards/). You'll want to create a fork of this repository on your account before continuing.

## Locally Clone the Fork of WipperSnapper\_Boards&nbsp;

Once forked, create a clone on your computer of the Wippersnapper\_Boards repository you forked above.

## Duplicate an Existing Board Directory

After you've locally cloned the _WipperSnapper\_Boards_ repository, navigate to this folder on your computer. Hardware definition files are kept within the _Wippersnapper\_Boards/boards_ folder and are organized by board name.

Each folder contains two files: the board definition ( **definition.json** ) and an image of the board ( **image.png** ) **.**

![](https://cdn-learn.adafruit.com/assets/assets/000/110/938/medium800/adafruit_io_boards.png?1650400385)

Finding an existing development board that matches your development board is the simplest method of adding a new board to WipperSnapper. For the best results, pick an existing board directory to duplicate based on the following:

- **Which microcontroller are you using?** You'll want to match as closely as possible to ensure RAM, size, etc are the same. You can do this by verifying that the full name of the chip, e.g. ESP32-S3, matches the board you're copying from.
- **What's your board's form factor?&nbsp;** If your board uses the standard Arduino Uno form factor, you may want to duplicate an Adafruit Metro board. If it uses the Feather or QT Py form factors, we have a number of Feather-compatible boards to select from.

As an example, this guide will illustrate the process of adding the [Adafruit Feather ESP32-S3](https://www.adafruit.com/product/5323) to WipperSnapper. Using the questions above, you can identify two things about this board:

- The microcontroller used is the ESP32-S3 by Espressif.&nbsp;
- The form factor for this board is the Adafruit Feather form factor.

Select the folder for a board within _Wippersnapper\_Boards/boards&nbsp;_that is closest to your board and make a copy of it.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/113/medium640/adafruit_io_fs3.png?1743522409)

Rename this folder to the name of your development board. We suggest using the following naming convention for the folder: `vendor-product-chip`

- For example, the Adafruit Feather ESP32-S3-Copy folder would be named `adafruit-feather-esp32s3`

![](https://cdn-learn.adafruit.com/assets/assets/000/136/114/medium640/adafruit_io_s3-rename.png?1743522491)

## Add Board Image

Next, you'll need to add an image of your board. For Adafruit boards, it's preferred to use a vectorized illustration of the board from the [Adafruit Fritzing Library](https://github.com/adafruit/Fritzing-Library). If you do not have an illustration of the board, you will want to take an image from the manufacturer's website.

Next, make sure your image adheres to the following specifications:&nbsp;

- The image file's extension can be any one of: JPG, JPEG, GIF, PNG, SVG  
- The image file's size must be at least 3kb and must not exceed 100kb

With the photo added, the new _Wippersnapper\_Boards/boards/adafruit-feather-esp32s3&nbsp;_directory should look like the following:

![](https://cdn-learn.adafruit.com/assets/assets/000/110/940/medium800/adafruit_io_boards_image.png?1650401488)

## (Optional) Add Board Installation Photos

Installing WipperSnapper on a board for the first time involves using the web-based installation processes on Adafruit IO, shown below.

![](https://cdn-learn.adafruit.com/assets/assets/000/112/122/medium800/adafruit_io_plug.png?1653680395)

To have your board appear in the steps of the web-based installer, you'll need to first add a&nbsp;new directory in&nbsp;`boards/BOARD_NAME/images`.

Next, you'll want to fill this directory with the following image files (_note_ - the image files can have any image extension):

- `boot-drive.png` - [A screenshot of a file browser displaying the board in bootloader mode](https://github.com/adafruit/Wippersnapper_Boards/blob/main/boards/funhouse/images/boot-drive.png).
- `drag-drop.png` - [A screenshot of dragging and dropping the WipperSnapper UF2 file for this board, onto its boot drive](https://github.com/adafruit/Wippersnapper_Boards/blob/main/boards/funhouse/images/drag-drop.png).&nbsp;
- `reset.png` - [An image showing your board's reset button](https://github.com/adafruit/Wippersnapper_Boards/blob/main/boards/funhouse/images/reset.png).
- `usb.png` - [An image of your board plugged into a USB cable](https://github.com/adafruit/Wippersnapper_Boards/blob/main/boards/funhouse/images/usb.png).

Optionally, you can add a GIF, `boot-loader.gif`, which is used to instruct a user on how to enter the UF2 bootloader on the board.

We have examples of all of these images within the WipperSnapper\_Boards repository under each Adafruit board: [https://github.com/adafruit/Wippersnapper\_Boards/tree/main/boards/funhouse/images](https://github.com/adafruit/Wippersnapper_Boards/tree/main/boards/funhouse/images)

## Edit Board Definition

Open the **definition.json** file within the board's directory in a text editor. It should look something like the following.

```auto
{
    "boardName":"adafruit-feather-esp32s2",
    "mcuName":"esp32s2",
    "mcuRefVoltage":2.6,
    "VID":"0x239A",
    "PID":"0x80EB",
    "displayName":"Adafruit ESP32-S2 Feather",
    "vendor":"Adafruit",
    "productPageURL":"https://www.adafruit.com/product/5000",
    "documentationURL":"https://learn.adafruit.com/",
    "components":{
       "digitalPins":[
          {
             "name":"D1",
             "displayName":"D1",
             "dataType":"bool"
          },
          ...
          {
             "name":"D14",
             "displayName":"D14",
             "dataType":"bool"
          }
       ],
       "analogPins":[
          {
             "name":"A18",
             "displayName":"A0",
             "dataType":"int16"
          },
          ...
          {
             "name":"A8",
             "displayName":"A5",
             "dataType":"int16"
          }
       ],
       "i2cPorts":[
          {
             "i2cPortId":0,
             "SDA":3,
             "SCL":4
          }
       ]
    }
 }
```

### Editing the Board's Metadata

The first section of the **definition.json&nbsp;** file to fill out contains information related to the development board including the hardware's name, description, chipset, and other unique identifiers.

### Change boardName

The `boardName` field is the board's identifier when it logs into Adafruit IO. This field should be **the same as the folder name**. For the Feather ESP32-S3, it would be changed to:

`"boardName":"adafruit-feather-esp32s3"`

### Change mcuName

The mcuName field contains an identifier for the type of microcontroller used on the board. For example, the microcontroller used by the Adafruit Feather ESP32-S3 is the ESP32-S3, the field would look like the following:

`"mcuName":"esp32s3"`

If you are unsure about what to enter in this field, reach out to the vendor you bought your hardware from.

### Change the mcuRefVoltage

The `mcuRefVoltage` field sets the reference voltage of the microcontroller's ADC. This value is found within the microcontroller's datasheet. The ESP32-S3's reference voltage is **2.6V** , so we'll set mcuRefVoltage field to be 2.6.

`"mcuRefVoltage":2.6`

### Add Product Information

The next few fields in the JSON file deal with descriptive product information about the board being adding. This information will be visible on the Adafruit IO WipperSnapper website under the board's image.

The `displayName` is the full name of the board. This is how the board's name will be displayed on the Adafruit IO WipperSnapper website. You can also put extra information in the string about hardware configuration.

`"displayName":"Adafruit Feather ESP32-S3 No PSRAM"`

The vendor field is the name of the _board's_ manufacturer (_not_ the chip's manufacturer). Since this page is using an Adafruit board, the vendor is Adafruit.

`"vendor":"Adafruit"`

The `productPageURL` and `documentationURL` are two fields which contain the URLs for the hardware's product page (_where someone would purchase the hardware_) and the documentation page (_where someone would go for extra information about the hardware_)_.&nbsp;_

` "productPageURL":"https://www.adafruit.com/product/5000", "documentationURL":"https://learn.adafruit.com/"`

### Adding ESPTool Information for Boards without Native USB

**If you are&nbsp;not adding a WipperSnapper board that contains an ESP8266, ESP32, or ESP32-C3 chip -** Skip this step.

Boards that use the ESP8266, ESP32, or ESP32-C3 do not contain Native USB and WipperSnapper can not be installed using a .UF2 file. Instead, for these boards, WipperSnapper presents a web-based firmware uploader to the user.&nbsp;

If you are adding an ESP32/ESP8266 board, you will need to add an `esptool` array to tell WipperSnapper that your board uses the web uploader workflow.

An example of the `esptool` array is as follows.

```auto
"esptool": {
      "fileSystemSize": 94208,
      "blockSize": 4096,
      "offset": "0x290000",
      "structure": {
          "0xe000": "wippersnapper.feather_esp32.littlefs.VERSION.boot_app0.bin",
          "0x1000": "wippersnapper.feather_esp32.littlefs.VERSION.bootloader.bin",
          "0x10000": "wippersnapper.feather_esp32.littlefs.VERSION.bin",
          "0x8000": "wippersnapper.feather_esp32.littlefs.VERSION.partitions.bin"
        }
```

The esptool array contains the following parameters which differ between chipsets (ESP32, ESP8266, ESP32-C3) but **not** between boards:&nbsp;

- `fileSystemSize` - The size of the chip's filesystem in bytes
- `blockSize` - The size of the logical&nbsp;_block size_&nbsp;used by the filesystem in bytes
- `offset` - The flash offset at which the firmware binaries will be flashed
- `structure` - An array containing the 4 binary files produced by the Arduino compiler when WipperSnapper is compiled
  - While these entries vary between chips (ESP8266 v.s. ESP32) but not between boards, the **board name must be changed** (i.e: wippersnapper.`feather_esp32`.littlefs.VERSION.boot\_app0.bin).

We have an example of the `esptool` array [for the ESP8266 here](https://github.com/adafruit/Wippersnapper_Boards/blob/main/boards/feather-esp8266/definition.json).

We have an example of the `esptool` array [for the ESP32 here](https://github.com/adafruit/Wippersnapper_Boards/blob/main/boards/feather-esp32/definition.json).

### Component&nbsp;Array

The next chunk of text in the **definition.json&nbsp;** file is a large array called `components`. This array contains a map of the board's pins, buses, and capabilities.

Note - While chips like the ESP32-S3 have _lots of pins_, not all of them are easily accessible or "brought out" to physical pins on the microcontroller. Since WipperSnapper is a _beginners-first_ platform, Adafruit only maps the usable pins to this file, which are visible on the board's silkscreen.

#### Add Digital Pins

These are the digital input and digital output pins used to connect your board to digital components like push buttons, digital sensors, LEDs, and more.

These pins are stored within the `digitalPins` array. Since you started with an existing JSON file, delete all the existing items in the list except for the first item. Your list should look like the following:

```auto
"components":{
      "digitalPins":[
        {
          "name":"D1",
          "displayName":"D1",
          "dataType":"bool"
        }
      ]...
```

Each entry within the `digitalPins` array contains the following information:

- `name` - The physical location of the pin (i.e: How you'd access this pin in the Arduino IDE). This string will be sent from Adafruit IO to the development board.
- `displayName` - The "pretty name" for the pin. This string will be used by the component picker on Adafruit IO and shown to users. You can find this value by looking at the labels on the board's silkscreen.
- `dataType` - What type of data is being sent to Adafruit IO by this pin. You're working with digital pins only right now, so the `dataType` is a boolean.

The Adafruit Feather ESP32-S3 has a LED built into the board on Digital Pin 13. As an example, let's add it to the `digitalPins` array above. Note that the `displayName` string contains both the pin's logical number on the board and information that it's a LED.

```auto
"components":{
      "digitalPins":[
        {
          "name":"D1",
          "displayName":"D1",
          "dataType":"bool"
        },
        {
            "name":"D13",
            "displayName":"Red LED (D13)",
            "dataType":"bool"
        }
      ],
      ...
```

For a full example of how the Adafruit Feather ESP32-S3's digital pins are configured, [check out the definition.json file on GitHub here](https://github.com/adafruit/Wippersnapper_Boards/blob/main/boards/adafruit-feather-esp32s3/definition.json).

#### (Optional) Add Analog Pins

Next, let's add the board's analog pins. These pins are used for reading analog values from sensors. At this time, WipperSnapper does&nbsp;_not_ support Analog Output, it only supports reading from analog pins.

Since you started with an existing JSON file, delete all the existing items in the `analogPins` list except for the first item. Your list should look like the following:

```auto
"analogPins":[
        {
          "name":"A18",
          "displayName":"A0",
          "dataType":"int16"
        },
        ...
      ],
      ...
```

Each entry within the&nbsp;`analogPins`&nbsp;array contains the following information:

- `name`&nbsp;- The physical location of the pin (i.e: How you'd access this pin in the Arduino IDE). This string will be sent from Adafruit IO to the development board.
- `displayName`&nbsp;- The "pretty name" for the pin. This string will be used by the component picker on Adafruit IO and shown to users. You can find this value by looking at the labels on the board's silkscreen.
- `dataType`&nbsp;- What type of data is being sent to Adafruit IO by this pin. Analog pins `int16` values to Adafruit IO. This value should be sent by an analog pin.

Note that for the Adafruit Feather ESP32-S3, analog pin "A0" on the silkscreen is internally referenced as `A18`.&nbsp; This value can be found in two locations. First, check [the board's pinout page provided by the vendor](https://learn.adafruit.com/adafruit-esp32-s2-feather/pinouts#logic-pins-3106362-21).

If it was not referenced by the vendor, or you're still having trouble finding it - locate the Arduino Board Support Package (BSP/"Arduino Core") for your development board. In the case of this example, the Feather ESP32-S3 uses the [Espressif ESP32 Arduino Core](https://github.com/espressif/arduino-esp32). The pin map is found within the board support package's variants/your-board-name folder. For example, the Adafruit Feather ESP32-S3 pin mapping for the Arduino IDE is located at [https://github.com/espressif/arduino-esp32/blob/master/variants/adafruit\_feather\_esp32s3\_nopsram/pins\_arduino.h](https://github.com/espressif/arduino-esp32/blob/master/variants/adafruit_feather_esp32s3_nopsram/pins_arduino.h)

For a full example of how the Adafruit Feather ESP32-S3's analog pins are configured, [check out the definition.json file on GitHub here](https://github.com/adafruit/Wippersnapper_Boards/blob/main/boards/adafruit-feather-esp32s3/definition.json).

#### (Optional) Add I2C Port

A large number of sensors can connect over the 2-wire I2C 'bus' protocol. The `i2cPorts` array contains three values:

- `i2cPortId` - The I2C port, defaults to `0`.
  - **NOTE:** While some development boards may have more than 1 I2C port, **WipperSnapper only supports one I2C port at this time.**

- `SDA` - The I2C clock pin
- `SCL` - The I2C data pin

```auto
"i2cPorts":[
        {
          "i2cPortId":0,
          "SDA":3,
          "SCL":4
        }
      ]
   ...
```

## Create a Pull Request on WipperSnapper\_Boards

First, let's push the changes you made to the build script within your CI-Arduino fork.

In a terminal window, navigate to the location of Wippersnapper\_Boards on your computer.

Use the `git branch` command to create a new branch. The branch should contain the name of the board you're adding. As an example, we named our branch `add-esp32-s3-feather`.

Next, use the `git status` command to verify that only the folder for your development board has been added.

Add the files&nbsp;by running `git add .`

Finally, verify that the definition JSON file and image have been added by running `git status` one last time.

![](https://cdn-learn.adafruit.com/assets/assets/000/111/175/medium800/adafruit_io_1__fish__Users_brentrubell_Desktop_github_brentru_Wippersnapper_Boards__fish_.png?1651085520)

Use `git commit` to commit your changes and `git push` to push the changes to your fork.

![](https://cdn-learn.adafruit.com/assets/assets/000/111/177/medium800/adafruit_io_1__fish__Users_brentrubell_Desktop_github_brentru_Wippersnapper_Boards__fish_.png?1651085687)

Use GitHub to create a pull request (PR) to the [WipperSnapper\_Boards](https://github.com/adafruit/Wippersnapper_Boards/)&nbsp;repository with your changes.

- If you need assistance with creating a PR, follow the process explained in the Git/GitHub guide on the&nbsp;[Create Your Pull Request](https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github/create-your-pull-request)&nbsp;and the&nbsp;[Open Pull Request](https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github/open-pull-request)&nbsp;pages.

The repository will run checks on these files. If the checks pass, Adafruit will review the files and merge the board definition into WipperSnapper.

For reference,&nbsp;[an example of the pull request for this guide is here \>\>\>](https://github.com/adafruit/Wippersnapper_Components/pull/25)

Next, you'll need to add code to the WipperSnapper firmware to detect your board.

# How to Add a New Board to WipperSnapper

## Build WipperSnapper with PlatformIO

The easiest way to build WipperSnapper firmware on your computer is by using a combination of [Microsoft Visual Studio Code](https://code.visualstudio.com/) (VSCode) and [PlatformIO](https://platformio.org/).&nbsp;

Navigate to [https://code.visualstudio.com](https://code.visualstudio.com) and install the latest version of the VSCode editor.&nbsp;

Once downloaded and installed, open VSCode and navigate to the Extensions tab (If you do not have this tab, you can find it using the toolbar by navigating to _Settings-\>Extensions_).

![](https://cdn-learn.adafruit.com/assets/assets/000/122/482/medium800/sensors_extensions.png?1689108006)

Search for the [_PlatformIO_](https://marketplace.visualstudio.com/items?itemName=platformio.platformio-ide) extension.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/483/medium800/sensors_platformio_search.png?1689108152)

Select the PlatformIO extension and click Install.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/484/medium800/sensors_platformio_install.png?1689108159)

## Fork WipperSnapper Firmware

To contribute to WipperSnapper, you will need to create a copy of the [WipperSnapper project's repository](https://github.com/adafruit/Adafruit_Wippersnapper_Arduino). This copy is called a **fork&nbsp;** and you will use it to make changes to WipperSnapper before submitting them to the official project repository.

Sign in to your [Github.com](https://github.com/) account and navigate to [the WipperSnapper firmware repository](https://github.com/adafruit/Adafruit_Wippersnapper_Arduino).

![](https://cdn-learn.adafruit.com/assets/assets/000/122/486/medium800/sensors_f1.png?1689108952)

Click the "Fork" button to fork your own copy of the _adafruit/Adafruit\_Wippersnapper\_Arduino&nbsp;_repository.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/487/medium800/sensors_f2.png?1689109037)

Click "Create Fork" and wait a few seconds for GitHub to create a copy of the WipperSnapper repository on your account.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/488/medium800/sensors_f3.png?1689109229)

## Clone WipperSnapper Firmware

Next, let's clone your fork of the Wippersnapper firmware so we can download it, make changes locally, compile it, and eventually send your changes up to the official repository.

On the page for your forked repository, click the green Code button. The dropdown should present a link like the one below:

[https://github.com/brentru/Adafruit\_Wippersnapper\_Arduino.git](https://github.com/brentru/Adafruit_Wippersnapper_Arduino.git)

Copy the link to your clipboard.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/522/medium800/sensors_brentru_Adafruit_Wippersnapper_Arduino__WipperSnapper_is_a_firmware_for_creating_no-code_IoT_electronics_projects__%F0%9F%94%8A.png?1689195280)

Using a terminal program, enter the following command to clone the forked repository to your computer. Be sure to replace `youruserid` with your GitHub user ID, and paste the URL from your clipboard.&nbsp;

`git clone -o youruserid https://your-fork-URL`

![](https://cdn-learn.adafruit.com/assets/assets/000/122/525/medium800/sensors_termclone.png?1689196079)

Now that the WipperSnapper firmware is local on your computer, check out a new branch and move on to the new step - building WipperSnapper.

If you are unfamiliar with how to check out a new branch, [Kattni wrote a great overview of the process here](https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github/always-work-on-a-branch)...

## Open WipperSnapper Firmware in PlatformIO

Open Visual Studio Code and click Open to bring up the file explorer.

Navigate to the _Folder_ containing your local copy of _Adafruit\_Wippersnapper\_Arduino_ and click Open.&nbsp;&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/122/526/medium800/sensors_open.png?1689196471)

VSCode should open to WipperSnapper's _platformio.ini&nbsp;_file. A notification on the bottom-right of your VSCode instance shows a message that PlatformIO is configuring the project and installing the required libraries to build WipperSnapper.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/529/medium800/sensors_pio_install.png?1689196871)

When the libraries finish installing, you should see a notification (or terminal output) that the "Project has been successfully updated!".

Click the PlatformIO logo (it looks like an alien's head) on the left-hand side of the VSCode editor to open PlatformIO.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/530/medium800/sensors_vscode_sidebar.png?1689197006)

Under PlatformIO's Project Tasks tab, every board WipperSnapper supports is listed as a folder.

Select the board you'd like to build for. For example, I have an Adafruit Feather ESP32 v2 and I will select the `featheresp32v2` board from the dropdown.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/531/medium800/sensors_platformio_ini_%E2%80%94_Adafruit_Wippersnapper_Arduino.png?1689197138)

When PlatformIO is loading tasks for a new environment, a blue clock appears on top of the logo. Wait until the blue clock disappears before continuing the build process.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/532/medium800/sensors_platformio_ini_%E2%80%94_Adafruit_Wippersnapper_Arduino.png?1689197147)

When PlatformIO loads the featheresp32v2 environment, you should see a Build step underneath featheresp32v2-\>General-\>Build.&nbsp;

Click Build and PlatformIO should begin to build WipperSnapper firmware for the Feather ESP32 V2.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/533/medium800/sensors_build_out.png?1689197368)

Once WipperSnapper builds successfully, the terminal will show SUCCESS along with the time it took to build.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/534/medium800/sensors_ok_build.png?1689197621)

Congrats- you've successfully built WipperSnapper locally!&nbsp;

## Upload Locally-Built WipperSnapper Firmware

To upload and test WipperSnapper on your device, you will need to specify the [`upload_port`](https://docs.platformio.org/en/latest/projectconf/sections/env/options/upload/upload_port.html) belonging to your device.

Within VSCode, open the platformio.ini file and navigate to the board you are using. Using this guide as an example, we previously compiled for the Adafruit Feather ESP32 V2. The build environment looks like the following.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/586/medium800/sensors_env.png?1689355040)

Next, add the [upload\_port](https://docs.platformio.org/en/latest/projectconf/sections/env/options/upload/upload_port.html) for your board. This port name varies but will take the form of:

- `/dev/ttyUSB0`&nbsp;- Serial port (Unix-based OS)

- `COM3`&nbsp;- Serial port (Windows OS)

![](https://cdn-learn.adafruit.com/assets/assets/000/122/588/medium800/sensors_upload_port.png?1689355215)

On the VSCode sidebar, click the PlatformIO logo.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/589/medium800/sensors_pio_alien.png?1689355241)

Under Project Tasks-\> Your Board (for this example, the board is featheresp32v2), click Upload to upload WipperSnapper firmware to your development board.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/590/medium800/sensors_upload_good.png?1689355418)

After the PlatformIO upload succeeds, press the RESET button on your board and navigate to [https://io.adafruit.com/devices](https://io.adafruit.com/devices)

![](https://cdn-learn.adafruit.com/assets/assets/000/122/591/medium800/sensors_device_online.png?1689355423)

If the upload was successful, you should see your board connected to Adafruit IO!

# How to Add a New Board to WipperSnapper

## Modifying Firmware

When a board running Wippersnapper "checks in" to Adafruit.io, it sends information about itself to Adafruit IO. Then, if the firmware supports the board, Adafruit IO recognizes the board and associates it with the board definition.

The next step in this process is to add two files within WipperSnapper firmware in order for the firmware to associate itself with a board type.

## Add Code to Detect Your Board

Open your fork of Adafruit\_WipperSnapper\_Arduino within Visual Studio Code and navigate to the file [Adafruit\_Wippersnapper\_Arduino/src/Wippersnapper\_Boards.h](Adafruit_Wippersnapper_Arduino/src/Wippersnapper_Boards.h). This file is used for detecting which type of development board is being used with WipperSnapper at compile-time.

Add a new conditional case at the end of the `WipperSnapper_Boards.h` file. This case is used by the Arduino compiler to detect which board it's building WipperSnapper for.

To find the build name used by Arduino, locate the board's support package. For example, the Adafruit Feather ESP32-S3 uses the [Arduino-ESP32 board support package](https://github.com/espressif/arduino-esp32). Within the [arduino-esp32/boards.txt](https://github.com/espressif/arduino-esp32/blob/master/boards.txt) file (or **boards.txt** file for your platform), search for the board you're using. Once you've found your board, navigate to the `build.board` entry.

In the case of the Feather ESP32-S3, the `platformName.build.board` string is: `ARDUINO_ADAFRUIT_FEATHER_ESP32S3`:

```auto
...
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3)
// TO-DO: Add more here!
...
```

Add the`BOARD_ID`, a&nbsp; **required** &nbsp;string identifying the board. This is the same as the `boardName`&nbsp;entry in the board definition JSON file.

```auto
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3)
#define BOARD_ID "feather-esp32s3"
...
```

Boards are provisioned with a `secrets.json` credentials file in two ways:

If the board supports native USB and has a UF2 bootloader, we `#define USE_TINYUSB` to make the board appear as a USB Drive.

If the board does not support native USB, we tell the firmware that it was installed using the web-based installer by using `#define USE_LITTLEFS`.&nbsp;

The Feather ESP32-S3 has a native USB and a UF2 bootloader.&nbsp;

```auto
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3)
#define BOARD_ID "feather-esp32s3"
#define USE_TINYUSB
...
```

WipperSnapper firmware **requires** a status pixel on a board. This status pixel is used to display connectivity status or notify a user of an error.

Depending on what type of status pixel your board has (NeoPixel, DotStar, or a LED), you'll need to #define the following:

- 
  - `USE_STATUS_NEOPIXEL`&nbsp;- If your development board has a NeoPixel built-in for displaying the status
    - `STATUS_NEOPIXEL_PIN`&nbsp;- The data pin on the board the NeoPixel is connected to.
    - `STATUS_NEOPIXEL_NUM`&nbsp;- The number of NeoPixels connected to your board.

  - `USE_STATUS_DOTSTAR`&nbsp;- If your development board has a DotStar (APA102) built-in for displaying the status.
    - `STATUS_DOTSTAR_PIN_DATA`&nbsp;- The data pin on the board that the DotStar LED is connected to.
    - `STATUS_DOTSTAR_PIN_CLK`&nbsp;- The clock pin on the board that the DotStar LED is connected to.
    - `STATUS_DOTSTAR_NUM`&nbsp;- The number of DotStar LEDs connected to your board.

  - `USE_STATUS_LED`&nbsp;- If your development board has a LED (one-color) built-in for displaying the status.
    - `STATUS_LED_PIN`&nbsp;- The pin on the board that the status LED is connected to.

The Feather ESP32-S3 uses a NeoPixel as the status pixel.

```auto
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3)
#define BOARD_ID "feather-esp32s3-4mbflash-2mbpsram"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
#define STATUS_NEOPIXEL_NUM NEOPIXEL_NUM
...
```

That's it! WipperSnapper should now be able to detect your board during compilation.

## Modify TinyUSB (UF2-backed Workflow) Provisioning File
Warning: 

This step is for boards using the TinyUSB provisioning workflow. Open the file [src/provisioning/tinyusb/Wippersnapper\_FS.cpp](https://github.com/adafruit/Adafruit_Wippersnapper_Arduino/blob/main/src/provisioning/tinyusb/Wippersnapper_FS.cpp) and add the build string you located above (ex: `ARDUINO_ADAFRUIT_FEATHER_ESP32S3_NOPSRAM`) to the top of the file:

```auto
#if defined(ARDUINO_MAGTAG29_ESP32S2) || defined(ARDUINO_METRO_ESP32S2) ||     \
    ...
    defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3_NOPSRAM)
#include "Wippersnapper_FS.h"
```

Info: Each new `defined(BOARD_DEFINE_NAME)` check is separated by the double pipes, `||`, meaning OR.

Also each broken line of the big _if statement_ ends with a special continuation character, the backslash `\`, which is used for each line-break, except the final one at the end of the if statement!

## Modify LittleFS (Web-backed Workflow) Provisioning File
Warning: 

This enables your board to use the web-backed provisioning workflow. Open the file **provisioning/littlefs/WipperSnapper\_LittleFS.cpp** in a text editor and add the build string you located above to the top of the file.

```auto
#if defined(ARDUINO_FEATHER_ESP32) ||                                          \
    defined(ARDUINO_ESP8266_ADAFRUIT_HUZZAH) ||                                \
    defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2) ||							   \
    defined(YOUR_PLATFORM_HERE)
#include "WipperSnapper_LittleFS.h"
```

## Add Board to Platformio.ini File

The `platformio.ini` build environment file needs to be updated with the board we're adding. This build environment file supports three platforms: ESP32, ESP8266, and ATMEL SAM.

Navigate to the PlatformIO board listing for your board's platform:

- [PlatformIO ESP32 Board Listing](https://docs.platformio.org/en/latest/platforms/espressif32.html#boards)
- [PlatformIO ESP8266 Board Listing](https://docs.platformio.org/en/latest/platforms/espressif8266.html#boards)
- [PlatformIO ATMEL SAM Board Listing](https://docs.platformio.org/en/latest/platforms/atmelsam.html#boards)

On the board listing, locate your board:

![](https://cdn-learn.adafruit.com/assets/assets/000/122/889/medium800/adafruit_io_s3_found.png?1689874945)

On the board's page, scroll down to the["Configuration" header. The board option's name should be listed here along with the board name.](https://docs.platformio.org/en/latest/boards/espressif32/adafruit_feather_esp32s3_nopsram.html#configuration)

Copy the environment name and add it to the&nbsp;`platformio.ini`&nbsp;file:

Within the `platformio.ini` file, add the board name:

```auto
; Adafruit Feather ESP32-S3 2MB PSRAM
[env:adafruit_feather_esp32s3]
...
```

To reduce the amount of code in this file, we have _common build environments_ for ESP32-X, ESP8266, and SAMD.

The ESP32-S3 uses the ESP32 build environment:&nbsp;

```auto
; Adafruit Feather ESP32-S3 2MB PSRAM
[env:adafruit_feather_esp32s3]
extends = common:esp32
```

Add the board name (this is from the [configuration page](https://docs.platformio.org/en/latest/boards/espressif32/adafruit_feather_esp32s3_nopsram.html#configuration)):

```auto
; Adafruit Feather ESP32-S3 2MB PSRAM
[env:adafruit_feather_esp32s3]
extends = common:esp32
board = adafruit_feather_esp32s3
```

Add a build flag for the compiler to identify this board. The build flag should be identical to the #elif defined(board\_identifier\_for\_compiler) string you added earlier in `src/WipperSnapper_Boards.h`:

```auto
; Adafruit Feather ESP32-S3 2MB PSRAM
[env:adafruit_feather_esp32s3]
extends = common:esp32
board = adafruit_feather_esp32s3
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S3
```

Info: 

If your board uses the TinyUSB workflow, add the following line:

```auto
; Adafruit Feather ESP32-S3 2MB PSRAM
[env:adafruit_feather_esp32s3]
extends = common:esp32
board = adafruit_feather_esp32s3
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S3
extra_scripts = pre:rename_usb_config.py
```

## Build WipperSnapper Firmware with Platform IO

Click the PlatformIO logo on the Visual Studio Code sidebar to open Platform IO.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/122/893/medium800/adafruit_io_piopen.png?1689876317)

Under Project Tasks, click Refresh to refresh the project's tasks.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/122/894/medium800/adafruit_io_refresh_logo.png?1689876422)

After refreshing, you should see the board you just added.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/895/medium800/adafruit_io_s3_1.png?1689876573)

If you do not see your build environment appear, click the toggle button to toggle between the multi-environment project tasks.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/896/medium800/adafruit_io_toggle_btn.png?1689876625)

Within your board's folder, click General-\>Build to start the build process.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/122/897/medium800/adafruit_io_s3_build.png?1689876693)

Once WipperSnapper is done building, it'll show SUCCESS at the bottom of your screen.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/898/medium800/adafruit_io_good_build_pio.png?1689876765)

## Upload WipperSnapper Firmware to Board

Upload the modified WipperSnapper firmware to your board by navigating to PlatformIO and clicking Upload.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/899/medium800/adafruit_io_upload.png?1689878450)

After uploading, from the PlatformIO tab, click Monitor. A new serial monitor should open. You should see the following debug output stating WipperSnapper is running.

![](https://cdn-learn.adafruit.com/assets/assets/000/122/900/medium800/adafruit_io_sensors_monitor.png?1689878489)

## Add Credentials/Secrets File to Board

Next, you'll need to add your Adafruit.io and network credentials to your board so it can connect to Adafruit.io WipperSnapper. Depending on which provisioning method you've used, the process differs:

Info: 

 **For platforms that use LittleFS** - [navigate to the WipperSnapper Web Uploader website](https://adafruit.github.io/WipperSnapper_Firmware_Uploader/). Select a board from the dropdown which uses the same chip as your board and follow the steps to connect the board.

After entering your credentials, click the **Update Credentials Only** button to add your WipperSnapper credentials to your board's filesystem.

![adafruit_io_update_creds_only.png](https://cdn-learn.adafruit.com/assets/assets/000/111/165/medium640/adafruit_io_update_creds_only.png?1651080302)

Info: 

For platforms that use TinyUSB, the&nbsp; **WIPPER** &nbsp;drive should automatically appear on your computer as a USB flash storage drive.

[Follow this guide to add your network and Adafruit.io credentials to the secrets.json file](https://learn.adafruit.com/adafruit-esp32-s2-feather/wippersnapper-setup#wippersnapper-configuration-3114250-12)

![adafruit_io_WIPPER.png](https://cdn-learn.adafruit.com/assets/assets/000/111/168/medium640/adafruit_io_WIPPER.png?1651080517)

After adding credentials to your board, press the board's RESET button. Navigate to [adafruit.io](http://io.adafruit.com/) and let the board connect.

You should see a pop-up with the text "New Device Detected!" appear along with a picture of the board.

![](https://cdn-learn.adafruit.com/assets/assets/000/111/169/medium800/adafruit_io_image.png?1651080760)

Your board now works with WipperSnapper! Next, create a pull request for adding the board to the WipperSnapper firmware so everyone can use it!

# How to Add a New Board to WipperSnapper

## Submit a Pull Request

Now that the library files and build script have been updated, it's time to open two pull requests: one on Adafruit\_Wippersnapper\_Arduino and one on the CI-Arduino repository.

## Submit a Pull Request to CI-Arduino

First, let's push the changes you made to the build script within your CI-Arduino fork.

In a terminal window, navigate to ci-arduino's location on your computer.

Use the `git branch` command to create a new branch. The branch should contain the name of the board you're adding. As an example, name the branch `add-esp32-s3-feather`.

![](https://cdn-learn.adafruit.com/assets/assets/000/111/150/medium800/adafruit_io_image.png?1651077002)

Next, use the `git status` command to verify that only the **build\_platform.py** file has been modified.

Add the **build\_platform.py&nbsp;** file by running `git add build_platform.py`.

Finally, verify that **build\_platform.py** has been added by running `git status` one last time.

![adafruit_io_build_status.png](https://cdn-learn.adafruit.com/assets/assets/000/111/159/medium640/adafruit_io_build_status.png?1651077463)

Use `git commit` to commit your changes and `git push` to push the changes to your fork.

![adafruit_io_git_commit_push.png](https://cdn-learn.adafruit.com/assets/assets/000/111/160/medium640/adafruit_io_git_commit_push.png?1651077589)

Use GitHub to create a pull request (PR) to the [CI-Arduino](https://github.com/adafruit/ci-arduino/pulls) repository with your changes.

- If you need assistance with creating a PR, follow the process explained in the Git/GitHub guide on the&nbsp;[Create Your Pull Request](https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github/create-your-pull-request)&nbsp;and the&nbsp;[Open Pull Request](https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github/open-pull-request)&nbsp;pages.

## Submit a Pull Request to WipperSnapper Arduino Library

Next, to push the changes you made to the build script within your fork of the WipperSnapper Arduino Library.

First, verify that you have modified only the following files:

- The board detection file
  - **src/Wippersnapper\_Boards.h**

- And one of the provisioning method files:
  - **src/provisioning/tinyusb/Wippersnapper\_FS.cpp**
  - _or_
  - **src/provisioning/littlefs/WipperSnapper\_LittleFS.cpp**

Next, in a terminal window, navigate the location of Adafruit\_WipperSnapper\_Arduino on your computer.

Use the&nbsp;`git branch`&nbsp;command to create a new branch. The branch should contain the name of the board you're adding. As an example, this branch is named `add-esp32-s3-feather`.

Next, use the&nbsp;`git status`&nbsp;command to verify that only the files listed above have been modified.

Add the files by running&nbsp;`git add .`

Finally, verify that your files have&nbsp;been added by running&nbsp;`git status`&nbsp;one last time.

![adafruit_io_1__fish__Users_brentrubell_Documents_Arduino_libraries_Adafruit_Wippersnapper_Arduino__fish_.png](https://cdn-learn.adafruit.com/assets/assets/000/111/164/medium640/adafruit_io_1__fish__Users_brentrubell_Documents_Arduino_libraries_Adafruit_Wippersnapper_Arduino__fish_.png?1651078402)

Now commit your changes, and push your branch to your fork. Use GitHub to create a pull request to the [WipperSnapper Arduino library](https://github.com/adafruit/Adafruit_Wippersnapper_Arduino/) with your changes.

- If you need assistance with creating a PR, follow the process explained in the Git/GitHub guide on the&nbsp;[Create Your Pull Request](https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github/create-your-pull-request)&nbsp;and the&nbsp;[Open Pull Request](https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github/open-pull-request)&nbsp;pages.

## What's next?

Once your pull requests are created, it's now up to Adafruit! We'll take a look at it and make sure everything is in order before merging your changes into WipperSnapper Arduino. If anything was missed, we'll let you know so you can get it taken care of. Once the changes in both repositories are merged, your board is officially part of WipperSnapper.

The next time WipperSnapper is released, all the boards that have been added to the repository will be included in the release. That includes your board! Firmware builds are [available on the latest release on GitHub](https://github.com/adafruit/Adafruit_Wippersnapper_Arduino/releases/latest). The web-based [WipperSnapper firmware uploader](https://adafruit.github.io/WipperSnapper_Firmware_Uploader/) will also populate with the latest firmware and supported boards on a new release.


## Featured Products

### Adafruit IO+ 1 Year Subscription Card

[Adafruit IO+ 1 Year Subscription Card](https://www.adafruit.com/product/3980)
It's the Internet of the Things!&nbsp;[Adafruit IO+](https://io.adafruit.com/plus) is the easiest way to stream, log, and interact with your data. Whether you're interesting in&nbsp;datalogging or communicating with your microcontroller over the web, Adafruit IO is our cloud...

In Stock
[Buy Now](https://www.adafruit.com/product/3980)
[Related Guides to the Product](https://learn.adafruit.com/products/3980/guides)
### Adafruit IO+ Subscription Pass – One Year

[Adafruit IO+ Subscription Pass – One Year](https://www.adafruit.com/product/3792)
The all-in-one Internet of Things service from Adafruit you know and love is now _even better_ with IO+. The 'plus' stands for MORE STUFF! More feeds, dashboards, storage, speed. Power up your [Adafruit IO](https://io.adafruit.com/) with the $99 pass for 1 year of the...

In Stock
[Buy Now](https://www.adafruit.com/product/3792)
[Related Guides to the Product](https://learn.adafruit.com/products/3792/guides)
### Adafruit ESP32-S3 Feather with STEMMA QT / Qwiic

[Adafruit ESP32-S3 Feather with STEMMA QT / Qwiic](https://www.adafruit.com/product/5323)
The ESP32-S3 has arrived in Feather format - and what a great way to get started with this powerful new chip from Espressif! With dual 240 MHz cores, WiFi and BLE support, and native USB, this Feather is great for powering your IoT projects.

That's right - it's the new...

In Stock
[Buy Now](https://www.adafruit.com/product/5323)
[Related Guides to the Product](https://learn.adafruit.com/products/5323/guides)

## Related Guides

- [Adafruit ESP32-S3 Feather](https://learn.adafruit.com/adafruit-esp32-s3-feather.md)
- [No-Code Counters and Email Reports with Adafruit IO Actions](https://learn.adafruit.com/no-code-counters-and-email-reports-with-adafruit-io-actions.md)
- [Ikea Vindriktning Hack with QT Py ESP32-S3 and Adafruit IO](https://learn.adafruit.com/ikea-vindriktning-hack-with-qt-py-esp32-s3-and-adafruit-io.md)
- [Using Piezo Buzzers with WipperSnapper](https://learn.adafruit.com/using-piezo-buzzers-with-wippersnapper.md)
- [itsaSNAP Daily Weather Forecast Board](https://learn.adafruit.com/itsasnap-daily-weather-forecast-board.md)
- [Networking in CircuitPython](https://learn.adafruit.com/networking-in-circuitpython.md)
- [IoT Bird Feeder with Camera](https://learn.adafruit.com/iot-window-bird-feeder-with-camera.md)
- [CircuitPython Webcam with OV2640](https://learn.adafruit.com/circuitpython-webcam-with-ov2640.md)
- [itsaSNAP by Adafruit](https://learn.adafruit.com/it-s-a-snap-by-adafruit.md)
- [Adafruit IO Basics: Analog Output](https://learn.adafruit.com/adafruit-io-basics-analog-output.md)
- [DIY IoT Doorbell Camera with MEMENTO](https://learn.adafruit.com/diy-iot-doorbell-camera-with-memento.md)
- [Using ItsaSNAP for HomeKit PIR Motion Detection](https://learn.adafruit.com/itsasnap-homekit-pir-motion-detection.md)
- [Adafruit IO Basics: Feeds](https://learn.adafruit.com/adafruit-io-basics-feeds.md)
- [Adafruit IO Basics: Digital Output](https://learn.adafruit.com/adafruit-io-basics-digital-output.md)
- [Memento Photo Capture with itsaSNAP](https://learn.adafruit.com/memento-photo-capture-with-itsasnap.md)
