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.
If you are unfamiliar with GitHub and Git or would like to refresh before starting, we have a great guide on using the features of GitHub here >>>.
Fork the Adafruit_WipperSnapper_Boards Repository
WipperSnapper's board definition files are stored in the WipperSnapper_Boards repository on GitHub. You'll want to create a fork of this repository on your account before continuing.
Locally Clone the Fork of WipperSnapper_Boards
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).
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? 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 to WipperSnapper. Using the questions above, you can identify two things about this board:
- The microcontroller used is the ESP32-S3 by Espressif.
- The form factor for this board is the Adafruit Feather form factor.
While the Wippersnapper_Boards/boards directory does not (at the time of writing) contain an ESP32-S3 board, there are a number of Feather boards including one using the Espressif ESP32-S2 (an older version of the ESP32-S3).
Select the folder for a board within Wippersnapper_Boards/boards that is closest to your board and make a copy of it.
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-S2 folder would be named
adafruit-feather-esp32s3
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. 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:
-
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 directory should look like the following:
(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.
To have your board appear in the steps of the web-based installer, you'll need to first add a new directory in 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. -
drag-drop.png
- A screenshot of dragging and dropping the WipperSnapper UF2 file for this board, onto its boot drive. -
reset.png
- An image showing your board's reset button. -
usb.png
- An image of your board plugged into a USB cable.
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
Edit Board Definition
Open the definition.json file within the board's directory in a text editor. It should look something like the following.
{ "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 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).
"productPageURL":"https://www.adafruit.com/product/5000", "documentationURL":"https://learn.adafruit.com/"
Adding ESPTool Information for Boards without Native USB
If you are 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.
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.
"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:
-
fileSystemSize
- The size of the chip's filesystem in bytes -
blockSize
- The size of the logical block size 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).
- While these entries vary between chips (ESP8266 v.s. ESP32) but not between boards, the board name must be changed (i.e: wippersnapper.
We have an example of the esptool
array for the ESP8266 here.
We have an example of the esptool
array for the ESP32 here.
Component Array
The next chunk of text in the definition.json 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:
"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 thedataType
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.
"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.
(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 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:
"analogPins":[ { "name":"A18", "displayName":"A0", "dataType":"int16" }, ... ], ...
Each entry within the analogPins
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. Analog pinsint16
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
. This value can be found in two locations. First, check the board's pinout page provided by the vendor.
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. 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
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.
(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 to0
.- 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
"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 by running git add .
Finally, verify that the definition JSON file and image have been added by running git status
one last time.
Use git commit
to commit your changes and git push
to push the changes to your fork.
Use GitHub to create a pull request (PR) to the WipperSnapper_Boards repository with your changes.
- If you need assistance with creating a PR, follow the process explained in the Git/GitHub guide on the Create Your Pull Request and the Open Pull Request 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, an example of the pull request for this guide is here >>>
Next, you'll need to add code to the WipperSnapper firmware to detect your board.
Page last edited March 31, 2024
Text editor powered by tinymce.