Make an example your own
SDK 1.xWritten for core 1.53+ and gui 1.23+.
Goal: an app of your own, copied from the cookbook example closest to your idea, with its own id, name, icon and git repo, that builds next to the example without a clash and is ready for Publish an app.
You need: the recipe for that example done on the board (Start here and a first flash), and the crosspad-examples clone. Publishing later needs gh auth login.
An example is a complete app, but every name in it says “example”: its id, its folder, its icon, the name it registers, and the names in its C++. Two apps must not share any of these, so a copy that keeps them clashes with the example in the build. This page renames all of them in one pass. It uses Pads and LEDs as the starting point and my-instrument / MyInstrument as the new names; The names to change lists them for every example.
Prefer an empty app? Start from the template generates one with your names already in it.
The names to change
Section titled “The names to change”| What | In the example | In your app | Where it is used |
|---|---|---|---|
| App id | example-pads-leds | my-instrument | id in crosspad-app.json, the folder crosspad-<id>, component_path, the catalog |
| App name | PadsLeds | MyInstrument | The first argument of REGISTER_APP / REGISTER_APP_PL: the label in the simulator’s launcher, the name app start and mode_overlay_open_app() take. A C++ identifier, unique among all apps |
| Pad logic name | "PadsLeds" | "MyInstrument" | registerPadLogic("…") and the last argument of REGISTER_APP_PL (only apps that own the pads); the two must match |
| Icon | assets/example-pads-leds.png | assets/my-instrument.png | The third argument of REGISTER_APP, and icon in the manifest. Every app’s icons end up in one folder, so name it after the id |
| Header folder | include/example-pads-leds/ | include/my-instrument/ | The #include lines |
| C++ names | PadsLeds_create, PadsLedsPadLogic, namespace example_pads | MyInstrument_create, MyInstrumentPadLogic, namespace my_instrument | Functions and classes outside an anonymous namespace are global: the same name in two apps fails to link |
The other examples follow the same pattern:
| Example | App name | Namespace |
|---|---|---|
01-hello-screen | HelloScreen | example_hello |
02-pads-leds | PadsLeds | example_pads |
03-play-sample | PlaySample | example_play |
05-midi-out | MidiOut | example_midi |
07-tempo-transport | TempoTransport | example_tempo |
09-motion | Motion | example_motion |
10-ui-kit | UiKit | example_ui |
The id is always example- plus the folder name without its number. Replace Motion with care: it is also part of other names in that example (MotionGesture, MotionModel.hpp), so rename Motion_create, Motion_destroy and the REGISTER_APP line one by one.
Copy and rename
Section titled “Copy and rename”-
Copy the example’s folder into the firmware project, under the name
crosspad-<your id>. The build looks for apps only in folders namedcrosspad-*. Copy from your crosspad-examples clone, not from an example you installed: an installed copy carries a.crosspad-examplemarker forinstall.py.Terminal window cp -r examples/02-pads-leds ~/CrossPad/components/crosspad-my-instrumentcd ~/CrossPad/components/crosspad-my-instrumentTerminal window Copy-Item -Recurse examples\02-pads-leds C:\CrossPad\firmware\components\crosspad-my-instrumentcd C:\CrossPad\firmware\components\crosspad-my-instrumentYou should see:
crosspad-app.json,CMakeLists.txt,assets,include,srcandtestsin the new folder. -
Rename the folder and files that carry the old names.
Terminal window mv include/example-pads-leds include/my-instrumentmv include/my-instrument/PadsLedsPadLogic.hpp include/my-instrument/MyInstrumentPadLogic.hppmv assets/example-pads-leds.png assets/my-instrument.pngmv src/PadsLedsApp.cpp src/MyInstrumentApp.cppmv src/PadsLedsPadLogic.cpp src/MyInstrumentPadLogic.cppTerminal window Rename-Item include\example-pads-leds my-instrumentRename-Item include\my-instrument\PadsLedsPadLogic.hpp MyInstrumentPadLogic.hppRename-Item assets\example-pads-leds.png my-instrument.pngRename-Item src\PadsLedsApp.cpp MyInstrumentApp.cppRename-Item src\PadsLedsPadLogic.cpp MyInstrumentPadLogic.cppThe build compiles every
.cppinsrc/, whatever its name, so the source file names are only for you. The header folder and the icon must match the names in the code, which the next step changes. -
Replace the three old names in every text file. Match case:
PadsLedsandexample_padsare case-sensitive names.Terminal window grep -rlI -e PadsLeds -e example-pads-leds -e example_pads . | xargs perl -pi -e 's/PadsLeds/MyInstrument/g; s/example-pads-leds/my-instrument/g; s/example_pads/my_instrument/g'grep -rnI -e PadsLeds -e example-pads-leds -e example_pads .In your editor, open the folder and replace in all files with Match Case on (Visual Studio Code: Ctrl+Shift+H):
PadsLedswithMyInstrument,example-pads-ledswithmy-instrument, andexample_padswithmy_instrument. Then search for each old name once more.You should see: no output from the second command (Windows: no results for any old name).
src/MyInstrumentApp.cppnow ends withREGISTER_APP_PL(MyInstrument, nullptr, "my-instrument.png",and the pad logic name"MyInstrument". -
Describe your app in
crosspad-app.json. The id, the icon andcomponent_pathare already right; setname,descriptionandcategory(music,audio,toolsorother; the examples useexample), and startversionandchangelogat your first version. Manifest fields explains each field.{"name": "My Instrument","id": "my-instrument","version": "0.1.0","description": "What it does, in one line","category": "music","icon": "my-instrument.png","component_path": "components/crosspad-my-instrument","platforms": ["esp-idf", "pc"],"requires": {"crosspad-core": ">=1.53.0","crosspad-gui": ">=1.23.0"},"changelog": ["0.1.0: first version"]}Keep
requiresas the example had it: UI kit’s asks for gui>=1.23.1. Draw your own 48 × 48 px icon overassets/my-instrument.pngwhen you have one. -
Build it into the firmware, from the project root (
~/CrossPad, WindowsC:\CrossPad\firmware) with ESP-IDF loaded, as in 2. Build the firmware. The example can stay installed next to your app: with every name changed, the two do not clash. Each one takes one of the board’s 24 app slots, so remove the example withtools/install.py --target idf … --removefrom the examples clone when you no longer need it.Terminal window cd ~/CrossPadidf.py -B build_v2 fullcleanidf.py -B build_v2 -DSDKCONFIG=sdkconfig.v2 buildTerminal window cd C:\CrossPad\firmwareidf.py -B build_v2 fullcleanidf.py -B build_v2 "-DSDKCONFIG=sdkconfig.v2" buildFor a v1 board, use
build_v1andsdkconfig.v1. Used the one-line installer? Usecrosspad-idfin place ofidf.py.You should see: the lines under Check it worked while CMake configures, and
Project build complete. To flash, run:at the end.If not:
multiple definition ofat link time means a global name still matches another app’s: go back to step 3. The app missing from the list: a new app does not show up.Asset collisionwhile configuring: the icon still has another app’s file name. -
Give the app its own git repository and push it to GitHub, so it can be published and cloned into the simulator.
tests/build/is the host test’s build folder (step 7); keep it out of the repo.Terminal window cd ~/CrossPad/components/crosspad-my-instrumentecho "tests/build/" > .gitignoregit init -b maingit add -Agit commit -m "My Instrument, from the pads-leds example"gh repo create you/crosspad-my-instrument --public --source . --remote origin --pushTerminal window cd C:\CrossPad\firmware\components\crosspad-my-instrumentSet-Content .gitignore "tests/build/"git init -b maingit add -Agit commit -m "My Instrument, from the pads-leds example"gh repo create you/crosspad-my-instrument --public --source . --remote origin --pushyouis your GitHub user name. The examples are GPL-3.0-or-later, and so is an app made from one: keep theSPDX-License-Identifierline at the top of each file, and add the licence text asLICENSE(copy it from the crosspad-examples clone).You should see:
ghend with✓ Pushed commits to …. -
Keep the host test.
tests/test_pads_leds.cppstill tests your model (PadsModel.hpp); its build file lives in crosspad-examples, not in the example’s folder. Copy crosspad-examples’tests/CMakeLists.txtinto your app’stests/and change its two globs:../examples/*/tests/*.cppbecomes*.cppand../examples/*/includebecomes../include. Then build and run it from the app’s folder as in Test it on your computer, without-R.You should see:
100% tests passed, 0 tests failed out of 5for the copied pads-leds test.
To run the app in the PC simulator too, clone its repo into the simulator’s apps folder, ~/crosspad-pc/src/apps/crosspad-my-instrument (Windows C:\crosspad-pc\src\apps\crosspad-my-instrument), and rebuild the simulator. Work in one of the two copies and pull in the other, so they do not drift apart.
Check it worked
Section titled “Check it worked”The firmware build from step 5 lists your app while CMake configures (somewhere inside each list, not at the end):
Generated app_registry_init.cpp with N apps: ...;MyInstrument;...Assets: staged 1 assets from component 'crosspad-my-instrument'After a flash, the app opens as MyInstrument, the same way as the example did (Opening an app).
- Publish an app: your repo already exists, so start at step 2, the manifest.
- How an app works: the rules to keep as your app grows.