Zynthian hardware network controller project

Basic idea: Hardware controller for one or more Zynthian synths. To assess the life of capability based on raspberry pi zero, special keyboards and OSC CUIA communication. Therefore, the connection is realized only and only using the network. In the first phase, I resigned myself to bold and long pressing of the buttons. Only simple short presses are implemented.

I quickly assembled the following components:
raspberry pi zero
Waveshare ETH/USB HUB HAT (B)
2x Keyboard with 12 buttons + 2 knobs, one-handed macromechanical keyboard

I taught the keyboard to send a letter and ENTER, so that I would not have to treat the input specially in the bag. The first keyboard sends lowercase letters, the second uppercase. The knobs also send letters, eg knob #1 when turned clockwise will write ‘n’ to the terminal.

A simple python script that starts when rpi zero is turned on, then converts the input from the keyboard to an OSC command. Before that, of course, the connection with Zynthian is established.

My test Zynthian is not quite typical, it is headless:
Raspberry Pi 400 Rev 1.1
Audio: Behringer UMC404HD
Display: WaveShare 7 HDMI+USB 1024x600
I2C: Not detected
Profile: NoWire
zyncoder: testing (055771b)
zynthian-ui: testing (961111b)
zynthian-sys: testing (5b85b59)
zynthian-data: testing (1321e5d)
zynthian-webconf: testing (15682e4)

After a few hours I was done.

You can see how this assembly looks in the photo. The zero is out of the picture :-).

I also tried workflow capture. I caught how /CUIA/SCREEN_ZYNPAD and /CUIA/SCREEN_PATTERN_EDITOR work. I haven’t figured out how to share it, so I’m sending it in a zip file.
ui_sesion-20231029145629.zip (1.2 MB)

I found the following issue.

Since communication is unidirectional, rpi sends OSC commands to zynthian. I am not able to find out the active channel number for the commands:
CHAIN_CONTROL %i Set active layer to %i and show control screen. Defaults to current chain.
CHAIN_OPTIONS %i Show options for chain %i. Defaults to current chain.

So I tried sending these commands without the %i and of course nothing happens. The problem is that I can’t get to the Options Screen without simulating a bold and long click. Would it be possible to ensure the same behavior as with the command /SCREEN_PATTERN_EDITOR, where sending it in the case of displaying the Zynpad screen turns on the editing of the active pattern? Or can another trick be used?

I looked into zynthian_gui.py and found that if %i is not defined for /CUIA/CHAIN_CONTROL, then self.layer_control() will be started. In case of /CUIA/CHAIN_OPTIONS, the code only ends with an error message

If this could be overcome, then this setup would cover all Zynthian control needs. And then I would try to add switches so that I could control other zynthians from one controller. I’m considering a maximum of 4 units :-).


Hi @ToFF !

Nice project, mate!

I just tested a little bit and CHAIN_CONTROL woks OK when sending it without the %i parameter. It defaults to current active screen.

In the other hand, CHAIN_OPTIONS seems to always show the current active chain options, ignoring the %i parameter. I will fix it.

All tests are done in testing branch, of course :wink:



Thanks @jofemodo, I like to play with zynthian anyway.

I took some pictures of UI from the current test branch (with upgrade today).

Thme main screen is SCREEN_AUDIO_MIXER for me. This CUIA working perfectly.

I assume correctly that the active channel is channel number 2 according to the picture.
When I’m in SCREEN_ZYNPAD or SCREEN_ADMIN and I give the CHAIN_CONTROL command, it should take me to the next screen, see the picture. But that doesn’t happen. It doesn’t work from SCREEN_AUDIO_MIXER either.

I like that ARROW_LEFT and ARROW_RIGHT allow scrolling through all channels of this screen. This perfect functionality.

For the CHAIN_OPTIONS command I should get the following image.

This screen is so ‘poor’. I would be in favor of the bottom bar (PRESTS | NEXT CHAIN …etc.) appearing on it as well, as it is on the previous screen (CHAIN_CONTROL). For people with a touchscreen-only headless zynthian, it would be fine. And those who have a V5 would appreciate moving through the channels with the arrows (ARROW_LEFT and ARROW_RIGHT). I would like both :slight_smile:

I know, these are my ideas, but maybe you will find them useful.

Basic description of controller and script I put on GitHub - ToFFmashines/zynnetcontroller


This could be done quite easily. Please, open a feature request :wink:


1 Like

Hi @ToFF !

I just fixed the CUIA chain_options so now it honors the parameter %i.
BTW, now from chain options you can also use the ARROW_LEFT & ARROW RIGHT commands for rotating across the chains.


1 Like

Thanks @jofemodo,

now I can confirm that OSC commands works in shape:


ARROW_LEFT & ARROW_ RIGHT works also nice in Option screen.

I probably described it wrong before, I would be glad if the commands in the form:


that is without the channel number, switch screen to active channel (Control or Option) screen . Is it possible to modify it like this?

It should work too. I tested this morning and it worked for me. Let me re-check.


I just checked and it works OK with parameter and without it.


The mistake was on my side. Who would have thought it wasn’t the same

arg1 = ''
arg2 = ''
liblo.send(target, com, arg1, arg2)


liblo.send(target, com)

The second one is correct.

@jofemodo thanks for your patience, if I tried it in Open Stage Control it would work for me on the first try.


Thanks to @jofemodo , my project is now viable. Now I can think about how to use hardware switches to provide control for various zynthians in the local network and make a box.

I will inform about the continuation. I’m really excited because the combination of buttons, i.e. accessing different screens and setting parameters with the knob, now makes working with zynthian faster than using only the touchpad.