Firmware template
The project template is what is created when you use Particle: Create new project in Particle Workbench, or particle project create with the Particle CLI. It's a good starting point to creating your own firmware.
Project overview
src directory
This will contain your source code and header files. The template includes a single file project.cpp but you can add more files.

lib directory
Firmware libraries provide additional functionality, such as interfaces to sensors, displays, algorithms, etc..
Most libraries are community written and supported and you can search the list from library search.
Workbench - Adding libraries
To add a library to your project from Workbench, use Particle: Install library from the command palette.
CLI - Adding libraries
To add a library to your project using the Particle CLI:
cdinto your project directory if you have not already done soparticle library add <libraryname>
Pseudo-libraries
In addition to community libraries, you can use Workbench pseudo-libraries to:
- Share code across multiple projects.
- Isolate code into more management sections.
- Work with a modified version of a community library.
project.properties
This file serves a few purposes:
- It marks the top level of your project directory and signifies that it is a Particle project in Workbench. This is necessary because Workbench supports multiple C/C++ development environments at the same time.
- It lists all of the community libraries that have been added and their versions.
- For public projects it includes author and license information.
There are other files such as particle.ignore. For more information see project file structure.
.github/workflows
Github actions is a CI/CD (continuous integration/continuous deployment) solution that is easy to integrate with the Particle platform. This can provide checks to make sure the source you commit can be compiled, and also provides the ability to deploy source, and to upload binaries to a product.
Source details
This include statement is required in all .cpp files. It's not required in .ino files so you won't see it in all example code, but it doesn't hurt to include it everywhere. It provides the definitions needed for the Particle Device OS API.
#include "Particle.h"
These two statements control how the cloud connection is managed, and whether threading is enabled.
Using AUTOMATIC or SEMI_AUTOMATIC system mode is recommended in most cases. See system modes for more information.
System threading should always be enabled. See system threading for more information.
SYSTEM_MODE(AUTOMATIC);
SYSTEM_THREAD(ENABLED);
This statement is recommended to enable logging to USB serial debug. You can view these messages using Particle: Serial Monitor in Workbench or particle serial monitor in the Paricle CLI.
For more information, see USB serial debugging.
SerialLogHandler logHandler(LOG_LEVEL_INFO);
The setup() function is called once when your device boots, and also when waking from HIBERNATE sleep mode. You can put initialization code in this function.
void setup() {
// Put initialization like pinMode and begin functions here
}
The loop() function is called continuously in most cases. You will typically your code in this function. You should try to return from loop as often as possible. Avoid having lenthy loops within loop() as it can cause unexpected behavior.

void loop() {
// The core of your code will likely live here.
// Example: Publish event to cloud every 10 seconds. Uncomment the next 3 lines to try it!
// Logging.info("Sending Hello World to the cloud!");
// Particle.publish("Hello world!");
// delay( 10 * 1000 ); // milliseconds and blocking - see docs for more info!
}
This bit of code is commented out in the template, but you can uncomment it to test publishing to the Particle cloud using Particle.publish().
// Example: Publish event to cloud every 10 seconds. Uncomment the next 3 lines to try it!
// Logging.info("Sending Hello World to the cloud!");
// Particle.publish("Hello world!");
// delay( 10 * 1000 ); // milliseconds and blocking - see docs for more info!
Compiling your project
Workbench
Use Particle: Configure Workspace for Device to select which device you want to work with.
Use local or cloud build options, such as Particle: Cloud Flash to compile and flash your device.
See the Workbench documentation for more information.
CLI
Using the Particle CLI from a Terminal or Command Prompt window, cd into the directory containing this source. You should be in the directory containing the project.properties file.
Use the particle compile to generate a .bin (or .zip if you are using Asset OTA) file. Often you will use a command like:
particle compile boron . --saveTo firmware.bin
- This compiles for the boron platform. Other valid values can be found using
particle compile --help. - Note the period
.by itself, separated by spaces. This means build the current directory and its subdirectories. --saveTo firmware.binis optional, and specifies the filename to save the binary to.
Or use the particle flash command to compile and flash to a device.
particle flash my-device-name .
- Replace
my-devce-namewith the name or Device ID (24 character hex) of your device. - Note the period
.by itself, separated by spaces. This means build the current directory and its subdirectories.
AI agents
If you are using an AI code generator like Claude Code or ChatGPT Codex, you can improve the performance by creating your project
with the --ai flag. This generates an AGENTS.md file in your project that contains hints to to AI agents.
# Create a mew project with AI agent support
$ particle project create --ai
# Adding AI agent support to an existing project
$ particle project ai
The AGENTS.md file contains:
- Basic coding instructions
- Pointer to the machine-readable Device OS firmware API manual
- Pointer to C++ header files
- Pointer to index of community software libraries in a machine-readable format
- Instructions for test compiling software
AI agent prompt examples
Simple publish project
Add a global
countervariable that starts at 0. Every 60 seconds while cloud connected, it should increment the counter and publish the value usingParticle.publishwith the event nametest-counter.
Analog read and publish
Read analog pin A0. If the value changes by more than 10 units, it's been more than 1 second since the last publish, and the device is cloud connected, publish the value using
Particle.publishwith the event nametest-value.
Then later:
Instead of publishing the raw value of A0, assume that A0 is connected to a TMP36 analog temperature sensor. Convert the ADC value to a temperature in degrees C. Include a connection diagram in the directory.
Using libraries
Use a DS18B20 1-Wire temperature sensor connected to a DS2482 1-Wire to I2C bridge, connected to the I2C interface of the Particle device.
Every 15 minutes while cloud connected the firmware should query the temperature sensor value in degrees Celsius. Publish the value using
Particle.publishwith the event nametest-temp. The value should be formatted in JSON with the key "temp" and value of temperature in °C.
