Building a custom Zynthian

From ZynthianWiki
Jump to navigation Jump to search

This is the documentation of my first custom zynthian build. It is work in progress and will be expanded over time. I really got much help of others in the forum, this thread can also be seen as part of the documentation.


1 The plan

After initially only wanting to get into this project by connecting a bare PI to a HDMI display and an external USB audio interface I considered building a custom Zynthian with a nice case and at least four encoders and stereo input and output connectors. You can read below how that succeeded (it miraculously did).


2 Parts used

2.1 Parts used in this build

  • Raspberry PI5 8GB with official active cooler, official power supply and a fast SD card
  • 8 inch Waveshare HDMI capacitive touch display
  • HifiBerry DAC2 ADC Pro audio HAT
  • TPA6112 headphone amp
  • MCP23017 GPIO Extender
  • 4 rotary encoders
  • 8x 10nF ceramic capacitors for encoder movement debouncing
  • 4x 47nF ceramic capacitors for encoder button debouncing
  • Many little parts: DIY flat cables for display connection, Dupont cables, pin headers, permaboards and the lot


2.2 Things to consider when chosing parts

  • The MCP23017 chip used in this build has an internal 100k pull-up resistor onboard. If you examine the schematics in the zynthian-hw repository, you'll might find it there. If your model of the MCP already has this onboard, you'll not have to add it to your circuit.
  • The MCP23017 chip used in this build uses adress pins to state the expected adress. Others might have a jumper or switch to state the adress, others might have a fixed one. here you are on your own, but keep in mind the default adress for your first MCP is 0x20.
  • The encoders used in this build have a PCB on which they are mounted including a 10kOhm pull up resistor. This means here we have to power them, other bare encoders might not need to be powered.
  • There is a lively discussion about wheather debounce capacitors are needed or not, because there is a software debounce mechanism. Adding them doesn't do any harm. They are supposed to get a distinctive on/off state when the button hits instead of triggering short "bouncing on/off states of it.


2.3 Building step by step

If you, like me, build the custom Zynthian step by step, you can do so. If you don't feel like investing in a DAC and a headphone amp you can use your USB Audio interface. If you chose to use the Zynthian with touch display input only for the parameter control, you can delay the whole encoder circuit build.


3 Planning

I'll act here like I had the final device already in mind when I started out. The truth is, that the design changed over the process of building oftentimes, but I don't want to bore anybody with that.


3.1 GPIO accessability

If you mount an audio DAC on top of your PI, it acquires all of your 40 PI GPIOs, even if it doesn't use it. If you have an audio DAC with 40 pin outs like this one has, you can consider them being duplicates of the 40 PI GPIOs. In some cases you do not have the pins but only 40 holes where you have to solder an adequate 40 pin header to.


3.2 GPIO usage

We try to figure out which GPIOs not to use for our encoder wirings and other endeavours. Things to consider:

  • When reading documentations about that matter, here's one thing to always keep in mind. Pins are labeled differently, referring to things like "(physical) pin", "GPIO", "WiringPi No." and other obscurities.
  • Things that might conflict with your plans might be (not exclusively): GPIOs your DAC relies on, GPIOs your MIDI IN/OUT might rely on, GPIOs that have special purposes in this context (SCL, SDA, EEPROM, ...).
  • When using an MCP23017 GPIO extender like in this project, you only need to find 2 unused GPIOs from your PI. The Webconf wiring setup's dropdown menu when chosing the pins for Int-A and Int-B gives you a hint what you might want to consider (Again, see the above mention naming convention problem). We'll use Pin 36; 37 for that matter (More on that later).


3.2.1 DAC

The HifiBerry Documentation is pretty clear about what to use and what not. In out case with the DAC2 ADC Pro is says: "Do not use more than a few mA from the 3.3V line. If your circuit requires 3.3V, use the 5V power rail of the Raspberry Pi with an additional voltage regulator. Pin 27 and 28 are always reserved for an ID EEPROM on the Raspberry Pi. Independently which card you use, these pins are always reserved and should never be used to connect external components. [...] GPIO2-3 (pins 3 and 5) are used by our products for configuration. If you are experienced with I2C, you might add other slave devices. If you a a novice, we don’t recommend this at all. GPIOs 18-21 (pins 12, 35, 38 and 40) are used for the sound interface. You can’t use them for any other purpose." So there you go.

3.2.2 Zynthian MIDI

3.2.3 Other purposes

3.3 Cooling

In this case the PI has the official active cooler mounted. In the beginning when only the PI was mounted on the display in fresh air, it got ridiculously low CPU temperature values. Things to consider:

  • Many people here swear by passive cooling connected to a metal case, because cooling works good and it has no noise. I couldn't do that, because a wooden case can't distribute heat.
  • The PI living in a case forces you to think about air ventilation within the case.
  • A HAT mounted onto the PI will raise heat considerably, because the air from the cooler cannot move so well. I had to raise the audio hat with a 9mm 40 pin header to not conflict with the cooler anyway.

With all these things in mind: My Zynthian never exceeds 60°C CPU temperature.


4 Soldering and assembling

4.1 Audio inputs and outputs

4.1.1 Mouting the audio HAT

I chose the HifiBerry DAC2 ADC Pro, because I wanted these input connectors to use the Zynthian as an effect unit. The Board fits easily onto your PI, but if you use the official active cooler like me, you need to raise the height with some 40 pin extenders (9mm in my case). With this specific board you have the 40-pin DSP header on top, others may only have holes where you might need to solder a 40-pin header on top. The convenient thing is that these only copy the PI's GPIOs, so you can use it for your connections. You only have to consider which GPIOs not to use (see section "GPIO usage").

4.1.2 Connecting the input and output jacks

The connectors with HifiBerry DACs are quite well documented.

For the output you basically connect both GND to your 1/4 inch jacks sleeves and the L and R connector to tip, while leaving the 5V connectors disconnected. You see in picture 5 that I ordered balanced jacks, but since the DAC doesn't feature balanced out I just soldered sleeve and ring together. Using a mono jack makes things easier, unless you have a board featuring balanced outs.

For the inputs you just connect GND to sleeve as well, while connecting the + to tip and - to ring for each of the stereo inputs. This is obviously only true if you use a board featuring balanced inputs like this.

Except for the DSP header which is used in this case as the extended PI GPIOs nothing more needs to be connected right now.

4.1.3 Connecting the headphone amp

This will be added later. For now you can read this forum thread.


4.2 Encoder circuit

4.2.1 Assembling on a prototyping board

First things first: This did not work for me. I put everything like I planned to do it in the correct manner, but the MCP wasn't recognized. You may succeed in prototyping with jumper cables and little parts, but putting a 26 pin MCP with two 13 pin headers on a prototyping board loosely (Picture 1) will likely not work.

4.2.2 Soldering to a permaboard

So I went all in and soldered everything together.

On picture 4 you can see how the holes are connected to each other. On picture 3 you see this:

  • In the middle the MCP23017 is soldered onto to 13-pin headers (Picture 2) and these again soldered to the board.
  • Two additional 13-pin headers are soldered right next to the corresponding pins for external connection via Dupont cables.
  • The pins D0, D1 and D2 are soldered with jumpers to the ground (GND) line. This is to get the address 0x20.
  • GND is also connected to the ground line, while VIN and Rst goes to the hot line (+5V)
  • The longer grey cables connect the two corresponding GND and +5V lines with each other
  • On the top left you see a 4-pin header soldered to GND. These are supposed to connect the encoder GNDs. Later on I soldered the same 4-pin header right next to it to the +3.3V line. We'll come back to this later.
  • The 12 light brown thingies are the decounce capacitors. They connect each signal line of the encoders to GND (see Parts section above)

4.2.3 Assembling

Now everything gets assembled.

First we need to connect some PI GPIOs to the soldered board. We use the two 13-pin headers next to the MCP23017. Therefore we check the Pi GPIO pinouts.

Connections from PI GPIOs to MCP23017 board
From Pi... (Physical Pin Number) 5V (2) GND (6) SDA (3) SCL (5) GPIO (36) GPIO (37)
To MCP23017 VIN GND SDA SCL Int-A (IA) Int-B (IB)

Now we connect the encoders to the respective pins, in that version labeled A0-A7; B0-B7. You can basically chose every combination (see section "wiring setup"), but we'll use this, because it's convenient for cable lead:

Connections from MCP board to encoders
MCP23017 B4 B5 B6 B0 B1 B2 A4 A5 A6 A0 A1 A2
Encoders Enc1 CLK Enc1 DT Enc1 SW Enc2 CLK Enc2 DT Enc2 SW Enc3 CLK Enc3 DT Enc3 SW Enc4 CLK Enc4 DT Enc4 SW

Additionally we connect all encoder GND to the boards GND line, where we soldered the 4-pin header mentioned above. In picture 5 you see the second 4-pin header soldered to the 5V line already, where we connect the encoder "+" to 5V. Why is that?

I happened to have ordered encoders mounted on a PCB, don't ask why. This includes 10kOhm pull-up resistors (don't ask why). The two options were to desolder these resistors, cut their lines or just power the encoders. I chose the latter option. Without connecting them to 5V they actually worked, but very clumsy, unreliable and sometimes triggering other actions than intended.


5 Setup

The software sided setup of your hardware is typically done in Webconf. You may also feel like editing the file /zynthian/config/zynthian_envars.sh which is basically edited when you do changes in Webconf. The code snippets below are taken from that file for better readability. You may find the according Webconf page and settings very quickly. If you find a "\n" in these snippets, this expands to an EOL (line break).


5.1 Wiring setup

My wiring setup, which you may easily find also in your Webconf -> Hardware -> Wiring page looks like this:

# Zynthian Wiring Config
export ZYNTHIAN_WIRING_LAYOUT="MCP23017_ENCODERS_V5TOUCH"
export ZYNTHIAN_WIRING_ENCODER_A="112,108,104,100"
export ZYNTHIAN_WIRING_ENCODER_B="113,109,105,101"
export ZYNTHIAN_WIRING_SWITCHES="-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,114,110,106,102"
export ZYNTHIAN_WIRING_MCP23017_I2C_ADDRESS="0x20"
export ZYNTHIAN_WIRING_MCP23017_INTA_PIN="27"
export ZYNTHIAN_WIRING_MCP23017_INTB_PIN="25"

5.1.1 Wiring layout

We use MCP23017_ENCODERS_V5TOUCH because we have physical encoders, but no physical buttons, why we are using the virtual V5-onscreen buttons.

5.1.2 Encoders

In Enc_A (CLK), Enc_B (DT) and Switches (SW) field you type in the numbers you chose when wiring the encoders to your MCP23017 circuit. Numbers between 100 and 115 are connected to the A0 to B7 pins like that: A0=100, A1=101, ... B7=115. So your encoder4-CLK we connected to A0 (see table above) means, you'll state it as 100 (=A0) on 4th position.

The bunch of 20 "-1" in the switches field represent the virtual buttons you'll use if you use the touch or virtual V5-buttons setup. If you don't have 20 physical buttons connected to match the V5 layout, just type it in like that.

5.1.3 MCP Adress

We soldered the adress pins all to GND, remember? This leads to adress 0x20, which has to be chosen in the corresponding field. If you add another MCP (for buttons or whatever) or you just feel to use another adress, you need to connect the adress pins in another fashion. Think binary numbers (D2; D1; D0):

--- > 0x20
--+ > 0x21
-+- > 0x22
   ...
+++ > 0x27

5.1.4 Int-A and B pins

We connected the IA and IB pins of the MCP to physical pins 36 and 37. If you look them up in the webconf menu, you can chose for example "WPi GPIO 27 (Pin 36)", where pin 36 is the physical pin 36 (if you count on the hardware), and WPi GPIO 27 is the "WiringPi" number (not the GPIO 27). Check the pinout overview linked above: You'll see that this Pin is actually GPIO 16. So why is the setup file storing it as "27" and "25"? It uses the WiringPi naming convention (see issue above).

To make things easier here: if you, like me, chose to use psysical pin 36 and 37, also chose that in the webconf menu.


5.2 Audio setup

My working setup:

#Audio Config
export SOUNDCARD_NAME="HifiBerry DAC+ ADC PRO"
export SOUNDCARD_CONFIG="dtoverlay=hifiberry-dacplusadcpro\nforce_eeprom_read=0"
export SOUNDCARD_MIXER="Digital_0,PGA_Gain_Left,Digital_1,PGA_Gain_Right,ADC_Left_Input,ADC_Right_Input"
export JACKD_OPTIONS="-P 70 -s -S -d alsa -d hw:sndrpihifiberry -r 48000 -p 128 -n 2 -o 2 -i 2 -X raw"

In the SOUNDCARD_CONFIG we chose the suitable dtoverlay for the DAC (see their instructions) and force_eeprom_read=0 because Hifiberry recommends that for PI5.

In the JACKD_OPTIONS you might see where I changed the sample rate to 48000Hz and the buffer size to 128 samples.


5.3 Display setup

I basically adapted the setup of any 7 inch Waveshare display and adapted the parameters (resolution) from my 8 inch. It worked. I added "ndtoverlay=vc4-kms-v3d-pi5,noaudio" because I use a PI5 and because I want to disable the audio out of the HDMI connection for obvious reasons:

#Display Config
export DISPLAY_NAME="Generic HDMI/DSI Display"
export DISPLAY_CONFIG="disable_overscan=1\nhdmi_force_hotplug=1\nhdmi_drive=1\nhdmi_group=2\nhdmi_mode=87\nhdmi_cvt=1280 800 60 6 0 0 0\ndtoverlay=vc4-kms-v3d-pi5,noaudio"
export DISPLAY_WIDTH="1280"
export DISPLAY_HEIGHT="800"
export FRAMEBUFFER="/dev/fb0"
export DISPLAY_KERNEL_OPTIONS=""


6 Building a case

7 Final state

Here is how it looks right now:


8 Further plans

I already have some parts lying around if ever I find time to add these to the build and also find the courage to disassemble a working device. These include:

  • More MCP23017 expanders for physical buttons
  • 20 Capacitive buttons to mount under the thin wooden top to act like the 20 V5 buttons.
  • A TOF sensor for altering parameters with magic air gestures
  • Some plywood to build a more sturdy case
  • Probably moving the audio HAT off the PI with a 40-pin GPIO extention cable for better air ventilation