SparklingTones

The pedal

How to build the SparklingTones pedal — the parts, the diagrams, the assembly, the firmware — and how to use it: five footswitches that change the Spark's presets without a phone, a display that tells you what's playing, and the looper.

🔧 STEP 1

Build

A perfboard, seven buttons, four LEDs, a display and an 18650 cell, in a wooden case.

💾 STEP 2

Load the firmware

From the Arduino IDE, over USB. First the wiring test, then the real pedal.

🎸 STEP 3

Play

The pedal finds the Spark on its own. You put banks together in the app and send them to the pedal.

1

What it is

The app's Live view, taken off the phone and put under your foot.

The pedal connects by itself, over Bluetooth, to the Spark 2 or the Spark NEO. The phone is only needed to put banks together and send them over; after that it stays in your pocket.

The finished pedal: wooden case, five footswitches, display in the middle and two bank buttons on the right
The prototype: mahogany sides, oak top panel.
Amp Preset A1 Clean A2 Crunch A3 Lead display tempo bank L bank R 12 34 5 90 mm: your foot finds the fifth one
The names of the controls, on a drawing of the panel. The measurements are in «The case».

The names of the parts

Throughout this guide each part has one name only:

namewhat it is
boardthe perfboard carrying the XIAO and the expander
XIAOthe small microcontroller board with the USB-C socket (Seeed XIAO ESP32-S3)
expanderthe small board with the MCP23017 chip, the one marked PA and PB: it reads the buttons and drives the LEDs
raila strip of bare solder along the board: the 3V3 rail and the GND rail (ground)
header / connectorthe row of pins soldered on the board, where a cable plugs in
lineone pin of the expander: PA0…PA7, PB0…PB7
top panelthe top face of the case, the one you step on
casethe wooden enclosure
cablea bundle of wires from the board to the top panel
LED stripthe strip of perfboard with the four LEDs and their resistors, behind the top panel
footswitchesthe five foot switches
bank buttonsthe two small hand buttons
buttonsfootswitches and bank buttons together: seven

You need to know how to solder. The guide explains everything else step by step, but soldering a wire to a pad and using a multimeter (voltage and diode test) are taken for granted.

2

Parts

Everything inside the prototype. Buy more resistors and connectors than you need: they cost less than the shipping.

partqtywhat it's for, and what to check when buying
Electronics
Seeed XIAO ESP32-S31the brain. It must be the S3: it's the only XIAO that can act as a USB MIDI controller. With its stick-on u.FL antenna (it's in the box): without it, Bluetooth doesn't reach the Spark.
2.42" 128×64 OLED display1SSD1309 controller, 4-pin I²C (VDD, GND, SCL, SDA), address 0x3C. There are 7-pin (SPI) versions: they won't do.
MCP23017 expander1in the prototype a KAmod I2C-IOexp16. Sixteen lines: seven for the buttons, eight for the LEDs.
Ceramic capacitor 47–100 nF1between the expander's supply and ground, close to the chip: it filters out noise.
4.7 kΩ resistors2, spareonly if the display won't start (see «Troubleshooting»).
Buttons and lights
Momentary footswitches5push switches that don't latch (momentary, «soft touch»), single contact (SPST), 12 mm thread. Two terminals are enough.
Momentary panel push buttons2the bank buttons.
5 mm common-cathode RGB LEDs5four above the footswitches (red and green, blue unused) and one for the tempo (red only). Common cathode, not common anode.
330 Ω resistors6four on the LEDs' red, one on the tempo LED, one on the click.
560 Ω resistors4on the LEDs' green: higher than the red on purpose, because at the same current green looks much brighter.
35 mm piezo disc1the click of the looper's count-in. A bare disc, not a «buzzer»: the magnetic ones are barely audible driven by the XIAO.
Power
Protected 18650 cell1in the prototype an XTAR 18650, 3300 mAh, «Protected». Don't trust cells rated above 3600 mAh: they don't exist.
1×18650 cell holder with leads1protected cells are ~69 mm long: pick a holder that takes them.
Adafruit 6091 charger (bq25185)1charges the cell from its own USB-C socket, and the pedal plays while charging.
Toggle switch SPST, with nut1on/off. Metal and sturdy; it goes on the side, not on the top panel.
2-way screw terminal1the point the battery wires leave from, to the XIAO and to the divider.
100 kΩ resistors2the divider that lets the pedal read the cell's charge. They must be equal.
Small parts
Perfboard, 2.54 mm pitch1 + 1one for the board, one strip for the LED strip.
Female headers 2.54 mm, 7 pins2to plug the XIAO in instead of soldering it.
JST-XH connectors (2.50 pitch)a kit4 and 5 ways, with the crimping tool. Dupont connectors work loose: in the prototype one lost an LED's ground.
JST-PH connectors (2.0 pitch), 2 ways2the ones that fit the charger's sockets.
Thin stranded wire, three coloursa few metresred for positive, black for ground, another for signals.
USB-C extension, male–female, 20 cm1brings the XIAO's socket outside, for firmware and USB MIDI. A plain extension: the panel-mount lead tried first didn't carry data.
Heat-shrink, hot glue, M2–M2.5 standoffs—to insulate the resistors, hold the wires, lift the boards off the wood.
Case
10 mm mahogany strips—the sides.
5 mm oak boards—top panel and bottom.
3 mm smoked acrylic10 × 10 cmthe window over the display.
Tools
Soldering iron and solder, multimeter (voltage, current, diode test), JST crimping tool (in the prototype a DxCRIMP D2032), isopropyl alcohol to clean off flux, a USB-C cable that carries data.
3

Wiring diagram

Every wire and where it ends up. The next chapters build it one piece at a time.

18650 cell protected, 3.0–4.2 V − + Charger Adafruit 6091 USB-C: charge here BATT− BATT+ LOAD− LOAD+ switch terminal 100 kΩ 100 kΩ XIAO ESP32-S3 + u.FL antenna BAT− BAT+ D0 D1 D3 3V3 GND D4 SDA D5 SCL (underside) 330 Ω Tempo LED (red only) 330 Ω click (piezo disc) → 3V3 rail → GND rail OLED display SDASCL VDD → 3V3 GND → GND address 0x3C MCP23017 expander SDASCL V+, RST → 3V3 GND, A0–A2 → GND 47–100 nF across V+ and GND PA → 7 buttons PB → 4 LEDs address 0x20 · chapter 5
positive ground (−, GND) SDA SCL battery reading
The three lines ending in the ⏚ symbol go to ground. Where two wires hop over each other with a small arc, they don't touch.

The XIAO, pin by pin

USB-C XIAO top view D0 battery D1 tempo LED D2 D3 click D4 SDA D5 SCL D6 5V GND 3V3 D10 D9 D8 D7 BAT+ and BAT− are pads on the underside
Coloured pins are used; grey ones stay free.
pingoes to
3V33V3 rail (one wire only)
GNDGND rail (one wire only)
D4SDA of the display and of the expander
D5SCL of the display and of the expander
D0the middle of the battery divider
D1330 Ω, then the tempo LED's red
D3330 Ω, then the piezo disc
BAT+ / BAT−the terminal: battery + and −, after the switch
5Vnothing
D6 · D7left free on purpose: they're the spare serial port
D2 · D8–D10free
4

The board

XIAO, expander, the two rails and the connectors the top panel's cables plug into.

The rule everything else follows: ground and 3.3 V aren't wires, they're rails. One wire runs from the XIAO to each rail, and everything else connects to the rails. Bringing everything to the XIAO's pin makes a bunch of wires on a single point, ugly to solder and hard to check.

  1. The rails. On a perfboard make two strips of bare solder from one side to the other: 3V3 rail at the top, GND rail at the bottom. A bare wire laid over the holes and soldered every two or three is fine. The two rails must never touch: that would short the supply.
  2. The XIAO's headers, top left, with the USB socket towards the edge: that's where the extension that brings the socket out of the case plugs in. The headers let you pull it out to replace it.
  3. The expander to the right of the XIAO, and the capacitor soldered between its supply pin (V+ or VDD) and ground, as close as possible. A ceramic capacitor has no polarity.
  4. Expander supply and address. V+ and RST to the 3V3 rail; GND, A0, A1 and A2 to the GND rail. If RST is left floating the chip stays in reset and doesn't answer. If the A pins aren't grounded the address isn't 0x20 and the firmware can't find the expander.
  5. XIAO to the rails and the bus. 3V3 to the 3V3 rail, GND to the GND rail. D4 to the expander's SDA and to the display connector; D5 to SCL, likewise. SDA and SCL swapped: nothing breaks, but display and expander stay silent.
  6. The JST-XH connectors. Each one has its own ground wire, taken from the GND rail next to it:
    • display, 4 ways: VDD (3V3 rail), GND, SDA (D4), SCL (D5);
    • footswitches, 5 ways: G, FS1, FS2, FS3, FS4;
    • footswitch 5 and bank buttons, 4 ways: G, FS5, bank L, bank R;
    • LEDs 1 and 2, 5 ways: G and four lines PB4…PB7;
    • LEDs 3 and 4, 5 ways: G and four lines PB0…PB3;
    • tempo LED and click: two wires from D1 and D3 plus ground (a 3-way works too).
    Which line goes to which button and LED is in the table in the next chapter.
  7. Clean off the flux with isopropyl alcohol and a small brush, before powering up. In the prototype, flux residue under the expander made it heat up: it looked like a dead chip.

The two LED connectors are identical: same number of ways, and you can't see them once the case is closed. Swapped, the left LEDs light up instead of the right ones, and it looks like a firmware bug. Mark them: a dot of colour on one, or better, a pin pulled from the header and the matching hole blocked in the plug.

The display

  1. Look at the back of the display. There's a row of pads with labels (some in Chinese); the one marked D2 must be closed, i.e. its two halves joined by a blob of solder or a 0 Ω resistor. Open, the display doesn't answer on the bus and stays black. On the prototype's unit it was already closed at the factory.
  2. Wire it to its connector with four wires: VDD, GND, SCL, SDA, following the display's labels, not the wire colours.

The antenna

The XIAO's stick-on antenna snaps onto the tiny u.FL connector, pressed straight down until it clicks. Only once: that connector survives few insertions. Stick the antenna inside the case, away from metal (footswitches, cell). Wood doesn't block the signal.

5

Buttons and LEDs

One reads and the other drives: the expander's port A listens to the buttons, port B lights the LEDs.

expander port A internal pull-up PA4 footswitch 1 two terminals, no polarity connector G
× 7. No resistor: the chip has it inside. Pressed, the line goes to ground.
expander port B PB5 330 Ω PB4 560 Ω common cathode LED 1: two colours in one LED
× 4. One resistor per colour, on the anode: never a single one on the cathode.

Which line goes where

This is the map the firmware expects. If you wire it differently nothing bad happens: the guided mapping in «The test» tells you yours, and you write it into the firmware.

buttonFS1FS2FS3FS4FS5bank Lbank R
linePA4PA5PA6PA3PA7PA1PA0
LED1 (above FS1)2 (above FS2)3 (above FS3)4 (above FS4)
red · 330 ΩPB5PB7PB1PB3
green · 560 ΩPB4PB6PB0PB2

PA2 stays free.

Footswitches and bank buttons

  1. Each footswitch has (at least) two terminals: one to its line, the other to ground. Polarity doesn't matter.
  2. Ground is daisy-chained: one wire from the connector's G to the first footswitch, from there to the second, and so on. Same for the bank buttons.
  3. Each line wire goes to its way on the connector, as in the table. Mark on the connector which way is which.

The LED strip

  1. Find each LED's legs with the multimeter on diode test: black probe on the longest leg (the common cathode), red on one of the others. The LED glows faintly in its colour. Usually the order is red, cathode, green, blue, but check it. Blue isn't used: cut it short. An LED fitted backwards doesn't light, but at this voltage it doesn't break either: just turn it round.
  2. Mount the four LEDs on a strip of perfboard, spaced like the footswitches (70 mm).
  3. On the red leg a 330 Ω resistor, on the green leg a 560 Ω one; all the cathodes together to the connector's ground. Each resistor under its own heat-shrink.
  4. Keep the cable from the strip to the board away from the footswitches' metal: those wires have no protection.
  5. Hot glue to hold the wires goes on after you've seen all four LEDs light up.

Tempo LED and click

  1. Tempo LED: another RGB LED, of which only the red is used. D1 → 330 Ω resistor → red leg; cathode to ground. It goes in a 5 mm hole in the top panel.
  2. Click: the piezo disc has two wires, and polarity doesn't matter. D3 → 330 Ω resistor → one wire of the disc; the other wire to ground.
  3. The disc is louder when held only by its edge, over a gap: glued flat to the wood it's barely audible. The click only sounds during the looper's count-in, never over the amp: it doesn't need to be loud.
6

Power

Cell, charger, switch and terminal: the part that does damage if you get the polarity wrong.

Never solder on the cell, and keep the cell out of its holder while soldering. And before connecting the XIAO, check with the multimeter that + and − arrive where they should: reversed, the XIAO burns out.

Cell in its holder Charger USB-C at the top BATT LOAD + − switch terminal + − XIAO BAT+ XIAO BAT− 100 kΩ + 100 kΩ → D0 on the sockets: + left, − right (with the USB-C at the top)
The switch is on the positive, after the charger: that way the charger charges even with the pedal off.
  1. Cell holder → charger BATT, with a JST-PH plug. Polarity is given by the board's silkscreen, not by the wire colours (pre-crimped leads are sometimes reversed): with the USB-C at the top, + on the left and − on the right.
  2. LOAD + goes to one terminal of the switch; from the other terminal a wire to the terminal block's +.
  3. LOAD − goes straight to the terminal block's −.
  4. Test. Cell in, switch on, multimeter on voltage across the terminal block's two screws: between 3.6 and 4.2 V, with positive where it should be. Then switch off and take the cell out.
  5. Terminal block → XIAO. The + to the BAT+ pad on the underside of the XIAO, the − to BAT− (the labels are on the board).
  6. The divider: one 100 kΩ resistor from the terminal block's + to D0, another from its − to D0. In the prototype they sit in two short leads, under heat-shrink. It's after the switch: with the pedal off it draws nothing. Without it the pedal still works, but the battery icon doesn't tell the truth.
  7. The charger's «PWR» LED stays on even with the pedal off and drains the cell in about six weeks (2.1 mA measured). In the prototype it was removed, prised off with the tip of a screwdriver. The other LEDs are useful.

Charge from the charger's socket, with any USB-C charger, even while playing. The XIAO's socket only charges at 50 mA: it's for the firmware, not for the cell. Out of the box the charger charges at 500 mA or 1 A (its documentation disagrees with itself), with a 6-hour limit: one night is enough.

7

The case

Wood, because it's transparent to Bluetooth's 2.4 GHz.

whatsizewhy
outside360 × 120 × 35 mm25 mm are left inside, and a footswitch takes 20
usable top panel340 × 100 mm
footswitch spacing70 + 70 + 70 + 90the 90 between the fourth and fifth let your foot find the fifth without looking. Before drilling, try them with your own foot
sides10 mm mahoganywith braces between footswitches reaching the sides
top panel and bottom5 mm oakset in, grain along the row of footswitches
panel-mount USB-C socketsup to 8 mmthe 10 mm side must be countersunk from inside around the hole
display window3 mm smoked acrylicglued under the top panel, with the opening chamfered at 45°
The pedal's bottom: a plate fixed with four screws at the corners, with the logo cut out
The bottom: four screws at the corners, and the cut-out logo.
8

Firmware

You load it once; after that the banks come from the app, no cable.

  1. Install Arduino IDE 2 from arduino.cc.
  2. The board package: in Tools → Board → Boards Manager search for esp32 (by Espressif Systems) and install it. The pedal is tested with version 3.3.
  3. The display library: in Tools → Manage Libraries search for U8g2 (by olikraus) and install it.
  4. Download the project from github.com/mazzrelaz/SparklingTones (Code → Download ZIP) and unzip it outside the Documents folder.
  5. The test first: open pedale/prova-espansore/prova-espansore.ino. In the Tools menu: Board XIAO_ESP32S3, USB Mode Hardware CDC and JTAG (the default), and the Port that appears when you connect the XIAO to the computer. Then the Upload arrow. It's for checking the wiring: that's the next chapter.
  6. The real pedal: open pedale/prova-ble/prova-ble.ino (it brings along the other files in the folder) and change two settings: USB Mode USB-OTG (TinyUSB) and USB CDC On Boot Enabled. For English screens, change the line #define INGLESE 0 near the top of the file to #define INGLESE 1 (out of the box they're in Italian). Same port, Upload. On restart the display shows the logo and the version for four seconds. With any other «USB Mode» the pedal won't compile, on purpose: without TinyUSB there's no MIDI mode.
The pedal's start-up screen: SparklingTones logo, author's name and version v2.16
The start-up screen, with the firmware version.

The times after

With the pedal's firmware the USB socket becomes the MIDI controller, and the Arduino IDE can no longer upload on its own. Before each upload you put the XIAO back into listening mode, without pressing any button: you open its port at 1200 baud and close it again.

  1. Connect the pedal and look up its port number in Tools → Port (for example COM3).
  2. In PowerShell, with that number:
    $p = New-Object System.IO.Ports.SerialPort 'COM3',1200; $p.Open(); $p.Close()
    A «device does not exist» error is normal: the port disappears because the XIAO restarts.
  3. A new port appears (on the prototype COM13): choose it in Tools → Port and press Upload.

Until you upload, the pedal stays still: it's waiting for the firmware. If you change your mind, unplug the cable and switch the pedal off and on again.

9

The test

Before closing the case: every button and every LED on the right line.

With prova-espansore loaded (its screens are in Italian):

  1. Hold any two buttons for a second and a half: the guided mapping starts.
  2. The buttons: the display asks you to press them one at a time, in order — footswitches 1 to 5 from the left, then the left and right bank buttons.
  3. The LEDs: the display lights one line at a time and asks what lit up. Answer with the footswitch under the LED that lit (with the fifth if nothing lit), then with the colour: left bank button red, right green.
  4. At the end the display shows the two tables and stays put: compare them with the ones in chapter 5. If they match, the wiring is right. A line you answered «nothing» to is a loose wire or an LED turned round. A button that doesn't respond is skipped after 30 seconds.
  5. The manual test: right after, the four LEDs light in the bank colour, the footswitch you press leaves only its own lit, the fifth changes colour.

If the tables differ you don't need to rewire: write yours into the three lines LINEA_PULSANTE, LINEA_ROSSO and LINEA_VERDE near the top of prova-ble.ino, before uploading it. The numbers are the line numbers: PA4 is written 4, PB5 is written 5.

Then upload prova-ble, and the pedal is ready.

10

Playing

Switch on the Spark, switch on the pedal. It does the rest.

The drawings and photos show the pedal's Italian screens, with translations where it matters. With INGLESE 1 (chapter 8) the pedal shows them in English.

Amp Preset S A1 Clean A2 Crunch A3 Lead A4 Ambient
A2 is playing. At the top: the bank, the battery, and the filled S = Spark 2 connected (N for the NEO).
Amp Preset Spark 2 NEO lo sto cercando
No amp: the bank buttons choose which one to look for. «lo sto cercando» = «looking for it»; the moving dots say it's searching.
  1. Switch on the Spark, and make sure no phone is connected to it (neither the official app nor this one): the Spark only accepts one connection.
  2. Switch on the pedal with the switch on the side. Four seconds of logo, then it looks for the amp.
  3. The first time, choose the amp: left bank button Spark 2, right NEO. The pedal remembers.
  4. When the square in the top right fills in, play.
The pedal connected to the Spark: the display shows the Amp Preset bank with A1–A4
Connected: the «Amp Preset» bank, the battery and the filled square in the top right.

What each control does

controlwhat it does
FS1…FS4plays the preset on that row. The row is highlighted, and the LED above lights up: red for half A, green for half B.
FS5shows the other half of the bank (A1–A4 ↔ B1–B4) without changing the sound. If the half on screen isn't the one playing, the LEDs are off.
bank L bank Rprevious and next bank. Its name appears at the top; a new bank starts from half A. When switched off, the pedal remembers where you were.
FS5 held 3 senters the looper, and leaves it (Spark 2 only).
bank L + bank R held 1.5 sopens the bridge to the app for two minutes: it's for sending banks.
FS1 + FS4 held 1.5 sswitches to MIDI mode, and back.
Half A of a bank: A3 is playing, the LED above the third footswitch is red
Half A: A3 playing, LED red.
Half B of the same bank: B3 is playing, the LED above the third footswitch is green
Half B: B3 playing, LED green.

Banks

Battery

The icon at the top has four bars. Below 3.5 V it blinks and the display says batteria scarica (battery low). A charge lasts about 17 hours of pedal on (measured). With a USB cable plugged in the icon shows full: that's the cable, not the cell.

11

Sending banks from the app

The Live view's banks, copied into the pedal.

  1. On the pedal, hold both bank buttons together for a second and a half. At the top appears ponte 1:59 (bridge), counting down: you have two minutes. While the bridge is closed the pedal can't be found: that way nobody passing by makes it drop the amp.
  2. In the app, Live view → ⋯ menu → Pedal → Find the pedal, and choose SparkPedale.
  3. Choose the bank and the place in the pedal (1–8), then Send. A bank goes over in a couple of seconds.
  4. In What's in the pedal you can move and remove banks; nothing happens until you press Update the pedal.
  5. Disconnect, or close the panel: the pedal takes the Spark back by itself.

While the app is connected to the pedal, the pedal doesn't play: it has let go of the Spark (the display says Spark all'app, «Spark to the app»). That's intended: the Spark has one master at a time.

12

Looper

The Spark 2's looper, run with your feet. The NEO has no looper.

Looper 90 bpm S 1 Sovraincidi 2 Annulla 3 Suona 4 Ferma/Canc
The loop is playing: row 3 highlighted, the ring fills one bar at a time. Rows: Overdub, Undo, Play, Stop/Clear.
controlwhat it does
FS1record (Registra); pressed again it closes and plays. With a loop ready it overdubs (Sovraincidi); pressed again it closes.
FS2undo the last overdub (Annulla), then redo (Ripeti).
FS3play (Suona).
FS4stop; held 2 s it clears the loop (Ferma/Canc).
FS5tap tempo, with the loop empty; held 3 s it leaves the looper.
bank L bank Rhow many bars: 1, 2, 4, 8, 12, 16 or free. With the loop empty.
The looper with an empty loop: Looper 178 bpm, the four rows and the empty ring
Empty looper, ready to record.
The looper while recording: row 1 highlighted, red LED on FS1, tempo LED lit, ring filling up
Recording: FS1 red, the tempo LED beats, the ring fills up.
13

MIDI mode

The same pedal for a program on a computer (AmpliTube, for example) or on an iPad (BIAS FX).

FS1 + FS4 held for a second and a half: the pedal switches to MIDI, lets go of the Spark, and an M appears in the top right. Same combination to go back. The pedal remembers which mode it was in.

pagefootswitches 1–4LEDs
presetProgram Change, channel 1. Left bank button: presets 1–4; right: 5–8red (1–4) or green (5–8) on the last one sent
stompControl Change 80, 81, 82, 83, on/off at each pressgreen on each effect that's on

FS5 switches between the two pages.

?

Troubleshooting

Things that really happened to the prototype, and what fixed them.

what happenswhat to do
The footswitches do nothingFirst suspect: the app is still connected to the pedal. Disconnect from the Pedal panel, or close the app.
It can't find the SparkIs the Spark connected to a phone? Close the app. Is the right amp chosen (S or N)? Switch the Spark off and on.
Sometimes it doesn't connectThe antenna: the u.FL connector has come off, or the antenna is near metal. Without the antenna the signal collapses.
Black displayIs the D2 pad on the back of the display closed? Are SDA and SCL swapped? If everything is right: two 4.7 kΩ resistors, one from SDA to the 3V3 rail and one from SCL to the 3V3 rail.
An LED doesn't light, or another one doesRedo the guided mapping (chapter 9): a «nothing» answer is a loose wire or an LED turned round.
A chip gets hotSwitch off. It's almost always flux left between the pins: clean it with isopropyl alcohol.
The display whines through the ampA drop of hot glue on the 4R7 coil on the back of the display.
After an upload the pedal doesn't respondIt's still waiting for the firmware: upload again, or unplug the cable and switch the pedal off and on.
The battery doesn't seem to chargeCharge from the charger's socket, not the XIAO's. The charger's CHRG LED must light up.
The battery icon is always fullA USB cable is plugged in: unplug it to read the cell. If it stays full, check the divider on D0.

The pedal is a personal project, built and tested on a single unit. The code and the story behind every choice are on GitHub (in Italian). ← The app guide