Loopstyler is like a 2D Stylophone.

In compare to traditional Stylophone, it uses an array of rows and columns, expanding the possibilities. You can think of it as a Stylophone combined with Le Strum.

The form factor, and design of electronics in the first prototypes was derived from Gecho Loopsynth v2, later switching to a more powerful SoC (a CPU with embedded RAM memory and audio chip). While the first prototypes used ESP32 and FreeRTOS real-time operating system, newer ones are already more advanced little computers, running Linux.

What can it do?


New Website:

As we started manufacturing it, we created a new website to explain everything in detail. Learn more and get your own Loopstyler!


Prototype #10 - September 2023

The tenth prototype had to be made to fix a few small issues around microphone / line input and powering for the RTC clock, and to test new components that replaced some which went out of stock in the meantime. As this PCB was only needed to verify the functionality and does not differ in appearance, I've selected green solder mask to minimize the costs and save a few days of waiting until a less common colour is manufactured.


Prototype #9 - May 2023

The ninth prototype features revamped stylus pad array, where the first row pads have special function. Second row was replaced with descriptive labels, which leaves 4 rows of playable pads. For easier orientation they are now arranged in 3 groups of 16 pads. Various small issues were fixed in the hardware. This is now close to what the production unit will look like, only some labels were changed and added.


Prototype #8 - March 2023

The eighth prototype fixes issues with the previous iteration, and finally is fully functional as intended. The production PCB will be most likely white or black (like prototypes #2 and #4) instead of purple, but for prototyping I used various colours to easily tell the prototypes apart. The front panel in this picture was not yet updated, it is missing two status LEDs in the top right corner.


Technical Specifications


After reworking the pad array scanning logic once again, some space was freed next to it on the left, and there were enough signal lines from the microprocessor left; this allowed to add an ambient light sensor (marked "LS" in the 1st and 6th photo below). Another remaining signal was connected to 2nd stereo line of the line-in connector (the line input is normally monophonic), so the other line can receive digital signals, for example sync pulses like for example Pocket Operators do.


Prototype #7 - March 2022

The seventh prototype fixes the problems with previous design (and as usual, creates a few new ones :) But after a few fixes it worked very well. The pad array scanning mechanism was altered a bit to make it more reliable, however this required to use signals for the LEDs that were meant to be near the top 4 butons.


Prototype #6 - July 2021

The sixth prototype tests DC-DC converters instead of LDO regulators, because the new microprocessor uses lower voltages and higher currents (in 3 separate power domains). ESD protective elements were added, those are the microscopic elements with "PB" marking as seen on the latest picture.


Prototype #5 - March 2021

The fifth prototype solves a few problems with previous design, and tries a different approach to scanning the pad array. A few experimental modifications were done on it, however during the process I have realized that the selected microprocessor is not ideal for the task, hence this prototype was not fully completed.


Prototype #4 - February 2021

The fourth prototype radically changed underlying hardware. Instead of ESP32 (as used in our Gecho v2 and Glo v2), it uses a bit more powerful CPU, like in Don Iguano prototypes. Now it is a miniature Linux machine! Currently it boots from SD card, but there is a plenty of Flash memory too so later the SD card will not be required to be present at all times.

The front panel is the same as in previous versions, and we finally have a stylus too! Indeed it's a classic 6.3mm Jack, and works very well.


Prototype #3 - July 2020

For the third iteration, I tried JLCPCB's prototyping service with limited machine assembly. It can only use green PCB, so the white silk scren was used to mask the green colour where visible. This is not perfect but close enough to what could be done with white solder mask. The remaining problem was how to print texts, as there is no 2nd silkscreen that could add black print - therefore the labels at the right side of the contact pad array had to be done using negative space, filled with copper.

The assembly service at the time supported only one side, which is fine - on the top side there are only LEDs, switches and microphones. Some components were out of stock or missing in the library of components available for assembly (also there are some limitations when it comes to amount of different components that can be used at once), so a few remaining components needed to be hand soldered too (ESP32, FTDI, I/O expanders, opto-coupler, SD card slot and connectors. Still, this already saved me 80% of time.

This is how the PCB arrived from the factory.

And here is the third version next to the second version.


Prototype #2 - June 2020

In the next iteration, white PCB was used. The main improvement was that there are now two rows of LEDs.

And we have a front panel too! Here is a video of the previos version with the new front panel.


Prototype #1 - February 2020

In this image you can see a prototype board. What is missing are 6 buttons and front panel. The design is similar to our Loopsynth.


The back side is almost assembled. What is missing is the rest of voltage dividers. This is because it took some experimenting to determine the best values, as explained in the "How does it work" paragraph below.


Technical Specifications

An open platform, featuring some of the newest elements, driven by a well-maintained open-source software framework (ESP-IDF).


What can it do?


How does it work?

The classic Stylophone is analog. When we look at the schematic (original one using discrete components [1] or these variations with 555 IC [2] [3]), we can see that it uses resistor ladder to set the frequency of each note. When stylus touches a key pad, it completes the oscillator circuit with desired resistance. This requires every resistor to be precisely "tuned". In real world resistors are manufactured with certain tolerance (usually 5% or 1%), which is not ideal, however it looks like there is no need to pick a "perfect" resistor from a bunch, as the resulting error is usually quite within our perception of a well enough tuned note (+/- 2Hz, or 2-8 cents depending on the octave).

This simple approach works well for a typical Stylophone with one row of keys and about two octaves. It would probably work well for even 4 or 5 octaves. But what if we are happy with one octave but want more rows instead? Not sure how exactly might this be useful in the analog circuit - we'd need a oscillator per row and tune every resistor ladder differently, so the "columns" represent individual chords. That would be interesting, but limited to a set of pre-defined chords. Thankfully in a digital device there is a lot more flexibility, as we merely need to detect which pad was touched with the stylus; translation to exact frequency for each note happens in the software.

Implementing the digital stylus

Common embedded microcontrollers like those used in Arduino, STM32 and other prototyping boards have input pins with ADC capability (analog to digital converter), which are very useful. There is usually two or more ADC blocks, each with a couple of "channels" - each channel connected to a separate pin. The measurements are read in sequence and the conversion happens so fast that there is no need to have a separate ADC block per pin.

Imagine that in a digital Stylophone, we have the same resistor ladder, with one end connected to the positive voltage source (Vdd), e.g. 3.3V or 5V, and another one to ground (GND). The stylus is connected to ADC input and measures the voltage. When touching a key, voltage is detected somewhere between 0 and Vdd. We could just use the same resistors everywhere, as many as needed, and the measured voltages will be evenly spaced (as that's how voltage dividers work). If Vdd was 3.3V and there were 15 resistors as on the picture above, we would measure a voltage of 0.22V over each resistor. If stylus touches pad P1, ADC will measure 0.22V, if P2 then 0.44V and so on. Since from the perspective of writing the code, measured values are rather integers from 0 to maximum resolution (determined by bits, for example 1024 for 10-bit ADC), we will receive values like 68, 136, 204..., which are easy enough to analyse in the code with some simple math.

We could also save two of these resistors, having first pad connected directly to GND and the last pad to Vdd. In such case, the first pad will result in a measured value of 0 and the last of 1023 (which is 2^10-1). Of course all this is theoretical, in reality everything is less precise due to element tolerances, voltage fluctuations etc..

Now, doubling this circuit will not help us much as we would not know which row's key is touched by the stylus - the same values will come from corresponding pads in each row. Changing first and last resistor by the same amount (for example to 3k3 and 6k1) will shift the entire array of values accordingly, but that is not fundamentally different from having just one long chain of resistors spreading over more rows. Because of how the measured values fluctuate, at some point the voltage differences will become too small to detect reliably, resulting in errorneous triggering of adjacent keys.

What if we could use more than one ADC channel, ideally one per row of keys? It would work, only if there was a separate stylus connected to each ADC pin. In order to be good with only one stylus, we need to reverse the whole thing.

Let's have a similar ladder, with the pad after the first resistor connected to ADC input. Now, the stylus will be simply connected to GND. By touching individual pads, it will shorten them to ground and effectively remove the remainder of the ladder from the equation. This will directly influence measured voltage. We can have as many ladders as there is ADC channels, and will always know which pad in which row is grounded by the stylus. Even better, this allows for some level of polyphony. If the stylus did not just have a rounded tip but a wider one that can cover more pads simulatenously, we could tell which pads in which row is it touching. Of course we will not be able to tell if two pads in the same row are touched, only the leftmost one will be detected.

It should be easy to see that touching P1 will ground the ADC directly, resulting in a measured value 0. P2 will create a voltage divider consisting of two equal resistors, so it will generate a value in the middle, fluctuating around 512 (we are still talking about 10-bit ADC as in previous example). Then it gets more complicated, P3 will set the resulting voltage at 2/3 of the range (measured value of 683), P4 at 3/4 (768) etc.. The farther to the right we move, the differences will be smaller. P13 vs. P14 will be 12/13 vs. 13/14, or 945 vs. 951, which might already be too close to detect reliably at this ADC resolution.

Tangent about the internal workings of ESP32

The ESP32 chip we are using in our designs has ADCs that can operate with up to 12-bits of resolution (it can be configured). This gives integer values from 0 to 4095 (2^12-1). Below you can see predicted result of what values will we get from an evenly spaced resistor ladder as described above. In reality the values slightly differ thanks to element tolerances and internal conditions of ADC. It contains a source of so called "reference voltage" with which the incoming voltage is compared, and this reference is not always set precisely due to environmental influences like temperature or manufacturing tolerances - simply saying, every chip is slightly different.

Also, the ESP32 ADC block uses reference voltage of 1100mV (which in reality can be 1000-1200mV), and there is an "attenuation" parameter that allows to measure voltages above the reference voltage (normally, the range of reference voltage will map over the whole ADC range, e.g. from 0 to 4095). To measure voltages up to 3V as we need in our application, we are selecting attenuation of 11dB (parameter is ADC_ATTEN_11db) which expands the range to 3.9V (clamped to Vdd by protective diodes at input).

Optimizing the resistor ladder

Anyway, we can see that the first half of the range (from 0 to 2048) is unused, while towards the end of the range, we have the voltages packed too close together. Still, in the first iteration of Loopstyler, this already worked reasonably well. However we want to avoid the necessity of "calibrating" this in any way, it will be much better to allow the values fluctuate more wildly without any adverse effect.

The solution is to distribute the resistances differently. While it is possible to calculate values which will result in evenly spaced voltages, ideally we should re-use values that are already elsewhere in the design. The reason is that the manufacturing cost of the PCB increases not only with number of elements, but sometimes even more with number of different elements. This is because the elements come to the assembly machine in reels, and every new value requires installing of a new reel. The machine can only handle a certain amount of reels at the time, so having more reels means that it might be necessary to swap them in the middle of the assembly process. Therefore we want to keep using resistors like 1k0, 2k0, 4k7, 10k, 20k and no other. Some of these values are the "must have", dictated by things like I2C pullups (4k7), MCP73831 charging circuit current setting (2k0), driving of LED diodes (1k0), or ESP32 external circuitry requirements (20k). Arguably, this value could be avoided altogether by replacing it with a pair of 10k resistors, but there is hardly enough space to accommodate them close to the CPU where they need to be. There are also 47k resistors used at the output of TLV320AIC3104 sound chip, but we do not want to use this value as it would result in an unnecessarily high overall resistance of the ladder.

Excel is a great program and it is easy enough to tweak the spreadsheet and instantly see the impact. It only took a few minutes to arrive at this configuration, which distributes the voltages quite well. The difference in integer values is never below 100, and if you think of the "delta" column as percentages (as the floating point values are "normalized", by GND being at 0 and Vdd at 100%), you can see no two points are closer together than 3% of the whole range. Compare this to previous configuration, where the rightmost points were as close as 0.5% of the range. The column "improvement" compares the delta value against corresponding one from the previous configuration. As you can see, it got worse in the first few points, where it does not matter, and got much better at the latter points.

With this method we could easily have 33 pads in the row (over 2½ octaves), with the same 3% clearance between them.


Prototype PCB

This is the first iteration of the circuit board. In compare to Loopsynth, most things were turned upside down. Four buttons, switches and USB connector are now at the top, to make space for array of metal pads. What used to be SET and RST buttons were moved to right, and will probably be renamed. Most LEDs were removed, only one row of 8 LEDs remains - they will probably be yellow. Power LED will most likely be white, as it is easier to look at than other colours. There will be no blue LEDs this time, only some red to indicate charnging and recording.


The resistor ladders are situated on the lower side of the PCB, bottom side. On this see-through picture you can see how the pads are connected to the resistors.


This is the top side of the board, with silkscreen visible (white text). The larger copper area between left 12 columns and 2 remainig columns is a touch-sensitive pad, connected to one of the ESP32 inputs with this capability. This was not originally planned but as there is micro-SD card holder underneath, it is not possible to put more columns of pads over it - there would not be enough space for the resistors. The electrodes at left and right are connected to GND, for the purpose of attaching a crocodile clip for the stylus' wire (later there will probably be a dedicated connector).


And this is the bottom side, also with silkscreen visible (yellow text, although in reality it is white too).