A Build with Variations

This is a build report, including as-built schematics and a small patch file.

Here is a picture of my just completed zynthian build (calipers for scale.)

On the small protoboard are the connections to the GPIO pins.

On the larger protoboard is the MIDI RxD interface hacked together from available parts.

Note the absence of the GPIO-ext (MCP23008 and related.) I found two unused GPIO signals on the rPi connector and referenced those in /zynthian/zynthian-ui/zynthian_gui.py rather than pins 7 and 8 on the GPIO-ext connector. More on that below.

The chief difficulties I met in building this:

  1. Small inconsistencies in the build docs. and lack of detail.
  2. Fritzing is no substitute for properly prepared schematics.
  3. There are at least two conventions for naming GPIO pins.
  4. Discovering usable GPIO signals.
  5. General unfamiliarity with rPi and wiringPi.

What follows is the “as built” documentation for this unit. I will be as complete as I can be in detailing the build. Including, calling out any differences from what I believe is the current canonical build. (Comments and corrections welcome.)

The Main Board

I used a Raspberry Pi 3 “Machine model: Raspberry Pi 3 Model B Rev 1.2” according to the kernel boot messages (dmesg | grep Rasp).

The SD image is zynthian_gorgona_rbpi3-2016-12-21.img.torrent (SHA1 37df1cdcea224f680e215b3e18ae28a99c3e9ca1) downloaded from http://blog.zynthian.org/download/.

Changes to the image according to the patch below.

The Audio Card

I used a HiFiBerry Pro DAC+ in the standard way. The audio card plugs into the rPi. I used the spacers that came with the audio card. I soldered a 20 pin connector to the top of the audio card. The ribbon cable plugs into the 20 pin connector.

The Ribbon Cable

I put a single male header facing up on the ribbon cable in between the existing male connectors that face down. The male header is for the display.

The Display

I used a 3.2 inch PiTFT from Adafruit (PiTFT Plus 320x240 3.2 TFT + Resistive Touchscreen : ID 2616 : $44.95 : Adafruit Industries, Unique & fun DIY electronics and kits).

I have the buttons soldered to it, but they play no role. The display plugs into the male header in the middle of the ribbon cable.

This is a variation on the canonical build where the display plugs into a 26 pin header split off at the end of the cable.

The GPIO Connections

I used an adafruit breakout header (Assembled Pi Cobbler Plus - Breakout Cable [for Pi B+/A+/Pi 2/Pi 3/Pi 4] : ID 2029 : $6.95 : Adafruit Industries, Unique & fun DIY electronics and kits) to connect the ribbon cable to the small proto board. This is a variation from the canonical build where individual GPIO connections are made to a male header installed on the ribbon cable. I prefer to use this protoboard since I anticipate that in the next iteration I will make the GPIO to encoder connections using a circuit board designed for the purpose.

The GPIO connections for this build are detailed on the schematics and will be discussed below.

The Encoders

I soldered wires directly to the encoder pins. The schematics mention some boards for the encoders. This anticipates a future build. I used the adafruit encoders (Rotary Encoder + Extras : ID 377 : $4.50 : Adafruit Industries, Unique & fun DIY electronics and kits).

The clever bit about the (future) boards is the wiring assignments. The encoders can be mounted on either the front or the back of the board depending on the encoder polarity. Similar to information hiding in object programming, this makes the encoder details private to the encoder assembly. The public interface is the colored wires which always connect in the same way to the rest of the machine.

The design of the encoder boards is a deviation from the canonical build. The wiring assignments and color code are also deviations.

The MIDI Input

This was hacked together from parts on hand. It is similar to the circuit on the 2in1 board but uses different IC circuits and discrete part values. The next build will likely use a different circuit.

I did not have a MIDI connector so I simply cut the end off a MIDI cable and connected to that directly. This means my circuit has a long tail. This is inconvenient, and I will change it in the near future.

The Final Result

The build was a success. When I plug the MIDI connector into the MIDI out of my ancient Roland S-10 I can play with sounds from the zynthian. My entire setup is as follows:

  • S-10 keyboard MIDI out ---> zynthian
  • zynthian audio out ---> mixer (Mackie 1202-VLZ3)
  • mixer ---> amp (Fender Princeton Chorus stereo effects return)
  • mixer ---> headphones

Mostly I use the headphones.

Now I will talk about what is on the schematic diagrams.

Encoder Schematic

At A1 we have the encoder circuit. It consists of three switches that make connections to a common GND. The signals from the switches are A, B and SW. The circuit is arranged so that if the encoder is mounted on the back of the circuit board the A and B signals are reversed. This is what Note 1 on the schematic talks about.

A task for the future is to compile a table of encoders and their polarity. We should be able to build encoder assemblies that encapsulate the differences in encoder design such that the differences have no consequences for the use of the assembly.

At A3 is a diagram of where the encoders mount. The diagram also assigns names to the encoders (enc 1 through enc 4). The lack of consistency in naming (or perhaps the non-obviousness of it) was one thing that I had difficulty with during the build.

At B1 is a table that ties together the encoder assemblies, the colors of the wires from the encoder assemblies, the signals from the encoder assemblies, the encoder function (knob labels), and what GPIO signal they are attached to.

This table departs from the canonical build in the following:

  • wire colors
  • the use of GPIO11 and GPIO22 instead of GPIO-ext-8 and GPIO-ext-7.
  • the need for a patch to the image (see patch below.)

Notes 2 and 3 discuss the mapping of this arrangement onto the dual controller board of the canonical build.

Note 4 mentions that the signal names follow the conventions of the wiringPi/Pi4J project. This is a critical point to keep in mind when reading the zynthian documentation. I started the build with the “element14” naming in mind and it led to no end of confusion.

Harness Schematic

At A2 we have the MIDI input circuit. This is not interesting except to say that it works. It deviates from the canonical build in choice of parts and part values. But otherwise it is the same.

The rest of the diagram is dedicated to showing the connections between the GPIO pins of the rPi, encoder signals, signal names, wire colors, and encoder assembly names.

Future Work

Everything that is on protoboards in this build (GPIO connections, MIDI input) will be on a dedicated circuit board at the end of the ribbon cable in my next build. I think there is room in the box for that. If not, the box can get bigger.

I don’t like using a lot of connectors. The encoder wires will be soldered at both ends and twisted together over their length. I will keep the ribbon cable. But the discrete wiring will all be soldered directly to a “jungle board” that makes the connection to the ribbon cable. No more “plate of spaghetti.” (Exceptions: The MIDI Connections, and maybe power/battery input.)

I didn’t use the mcp23008 in this build because I didn’t have one on hand. And, had I orderd one, it would have arrived too late. (This build took place over the Christmas break.) This led me down the rabbit hole of finding some available GPIO pins. Also, I had to learn how the GPIO pins are handled by the software.

That led me to look at what GPIO pins are used by the audio card. And I realized that there is no standard for this. The next audio board I choose will likely use a different set of GPIO pins than those the HiFiBerry Pro DAC+ uses.

If we want a robust design we must stay off of the GPIO pins entirely. Which is to say that, unlike this build, which sought to avoid the use of GPIO-ext pins, we should go all the way and put every encoder signal on the GPIO-ext. We need more pins on the GPIO-ext. This means using a mcp23017 or mcp23s17 instead of the mcp23008.

I am thinking of including a power backfeed circuit as well. This would use the rPi recommended 0v protection circuit on the 5v downstream from a nice stiff 5v buck/boost converter. It would also give us a way to power the box from batteries.

I think the current USB power supply is inadequate and likely responsible for some the reports of clicks and other strange behaviour (I have seen uncommanded reboots, for example.)

On the topic of auto-configuration based on eeprom data: The rPi HAT spec doesn’t allow for cascaded configurations. Because the audio card already has a config eeprom on it there is no possibility for accessing another eeprom to pick up the zynthian hardware configuration details. The only solution there is to design our own audio circuit. From there we can do whatever we want regarding the devices attached to the ribbon cable. That may be too much, though.

Well, one step at a time.

If there are errors or omissions in this report please call them out and I will address them.

Thank you to all for a great project!


The patch file:

— /zynthian/zynthian-ui/zynthian_gui_config.py-saved 2016-12-26 05:21:38.162831275 +0000
+++ /zynthian/zynthian-ui/zynthian_gui_config.py 2016-12-28 00:46:27.296328104 +0000
@@ -33,7 +33,7 @@
raise_exceptions=False

Wiring layout

-hw_version=“PROTOTYPE-4”
+hw_version=“PROTOTYPE-VS1”

Screen Size

width=320
— /zynthian/zynthian-ui/zynthian_gui.py-saved 2016-12-26 05:45:26.782830730 +0000
+++ /zynthian/zynthian-ui/zynthian_gui.py 2016-12-28 00:46:39.856328114 +0000
@@ -135,8 +135,13 @@

Wiring layout => GPIO pin assignment (wiringPi numbering)

#-------------------------------------------------------------------------------

+if hw_version==“PROTOTYPE-VS1”:

  •    zyncoder_pin_a=[25,26,4,0]
    
  •    zyncoder_pin_b=[27,21,3,7]
    
  •    zynswitch_pin=[23,11,2,22]
    
  •    select_ctrl=3
    

First Prototype => Generic Plastic Case

-if hw_version==“PROTOTYPE-1”:
+elif hw_version==“PROTOTYPE-1”:
zyncoder_pin_a=[27,21,3,7]
zyncoder_pin_b=[25,26,4,0]
zynswitch_pin=[23,None,2,None]

2 Likes

GPIO Conflict

I made a little chart to see which combinations of sound cards and other devices can coexist on the rPi 3 GPIO pins. I discovered that my build works more by accident than design. It works only because the touch screen is not used. This lets me use pin 26 as an input for the encoders.

The chart:

Column A lists the pin numbers.

Column B the names according to the Pi4j convention that seems to apply for this project.

Column C marks the power and ground pins.

Column D marks the pins used by the hifiBerry DAC+.

Column E marks the pins used by the IQAudio Pi DAC+ (and related devices.)

Volumn F marks the SPI pins, and column G the MIDI pins.

Column H marks the pins used by the display: A PiTFT 3.2 w/ touch screen.

Notice that there is no conflict between the pins used by the display and the two audio cards mentioned so far (the hifiBerry and the IQAudio.)

In my build I wired the encoders to pins 7, 11, 13, 15, 16, 26, 29, 31, 32, 33, 36, and 37 (Column J). This conflicts with the PiTFT’s use of pin 26 as a SPI chip select for the touch screen function. It just happens to work because the touch screen is not used.

I was also interested in the cirrus logic sound card. It’s use of pins is marked in column K. It uses the SPI interface and would conflict with the PiTFT display. A different display would have to be used. The likely candidate is something driven by the HDMI output of the rPi since that would be independent of the GPIO pins.

What I conclude from this is that I should proceed with the plan to put all the encoder signals on GPIO-ext using an mcp23017.

Edit: Updated the chart to show a ‘u’ for the GPIO pins that cirrus has marked ‘unused’ and which they claim their driver ignores. If we need gpio pins we should choose one of these that their driver currently ignores. (previous chart here)

1 Like

Nice description! I also don’t like Fritzing & ended up making my own schematic & GPIO excell sheet just like you did.

Having all of the encoders behind a IO expander would make sense. It would make the HW design more flexible by reducing the IO usage. I also found the mcp23017… But I wonder if we’d start to get timing/performance problems if all of the encoder signals were read through an expander. I did some Googling & came across claims that reading inputs via expanders is 20 to 50 times slower than direct GPIO. So it will work for the select buttons, but you might start to miss events when the encoders are rotated.

We should start a sticky thread about soundcard compatibility. I’ve tried a couple of HifiBerry DAC & DAC+ ‘compatible’ cards but couldn’t get them to work correctly. Zynthian needs jackd server running & it’s touch & go if it works with different soundcards.

Well, there are timing concerns but for comparasion, the standard hardware used with Midibox.org projects is SRIO devices, 74hc165s and 74hc595s. On the latest STM32F4 core, the shift registers are handled with an SPI interface and can read >64 encoders at a 1 mS refresh rate.This works very well for UI use as a user is unlikely to turn the knob at more than 2 or 3 rpm.
Not sure about the handling within Zynthian but it should be possible to use IO expanders for the encoders and switches.
Yogi

Hi all,

some moths ago I had the following idea: Why not using a micro-controller as “input collector”? With the background of easy building a Zynthian with minimal level of knowledge of electronics I think using an Arduino would be the nicest way. The Arduino can be used to evaluate the encoders (perhaps additional input solutions?) and send it to the Raspi. Also the easiest way would be a protocol via USB-serial, like this: 1>\n (meaning: Encoder1 one step right).

What do you think about this?

Regards, Holger

You are describing a USB control surface. Why invent your own protocol? Just adapt one of the USB MIDI projects for the arduino and send MIDI controller messages. It is certainly something that can be done.

It ties up one of the USB ports, though. And it sends a wire outside the box.

The present discussion is less about how to read the encoders, and more about how to best use the rPi pins. Keeping the wires inside the box has been an unspoken constraint.

That said, external control surfaces are interesting. And, I intend to build one eventually (drawbars for the setBfree).

@C0d3man YES, been thinking a lot about something like you describe. I’m inspired by this project by cube48
http://www.warmplace.ru/forum/viewtopic.php?f=16&t=3733&hilit=moonbox
It packages a gutted USB Midi controller with a Pi to run Sunvox. While I like the concept, Zynthian with the current selection of synths is more attractive to me.

Being familiar with the Midibox project, I lean towards it over the Arduino as development is easier once you understand the underlying RTOS and modular hardware. One of the current MB apps related to this discussion is the NG, ( the Next Gen controller) which allows users to build custom control surfaces without a great amount of programming, just setting up config files to support the custom HW.

A big question is which form factor is more favored, the current compact Zynthian with optional external controllers or a larger ‘all in one’ box?
@vagnscott I really would argue for USB Midi as the expansion interface. Port extension cables (or a hub) on the Zynthian could handle ‘the wires inside’ problem for a larger box and support by the GUI for USB controllers would allow current builds to upgrade with external USB knob boxes.

Another question is how to handle user feedback with 8 or 16 or 24 encoders? Labeling each knob would be impractical when switching between synths and it would be good to allow the user to select/recall knob-to-synth pram mappings. For feedback, each knob’s movement could triggers LCD displaying the mapped pram, momentarily? And how to map for different synths? Maybe config files for each supported synth to map a generic set of CC messages to specific synth prams. Maybe Mididings could do this.

Anyways, just my ramblings. I’m kind of planning a general purpose Pi build for a ‘studio’ computer based on some of these ideas, in addition to a standard Zynthain build. But would love to see some of this added to the Zynthain :slight_smile:
Yogi

Hi @vagnscott @yogi

Yes, you are right. To avoid using all GPIOs it maybe necessary to build a micro-controller based aggregator for the four encoders. perhaps not via USB-serial… maybe with SPI?

For parameter changing there are better ways to do this: OSC or MIDI.

Regards, Holger

Hmm, years ago I build something like this for a Rpi Squeezebox Player… Used Attiny85’s connected to a MPC23017.
Found a crude schematic for it. The Attiny decodes the rotary encoder to value up and down and the MPC sends it to the Pi. And since we already use a MPC… why not use a bigger one to get more IO-pins.

Hi @vagnscott!

Congratulations for your excellent work and thanks for sharing with us!! It’s a big pleasure to meet new zynthian builders improving the design! Really!

In the next days i will improve the documentation, trying to fix the inconsistencies and lack of detail. Also, i will include the wiring schemes and the nice GPIO usage table contributed by you and other community members.

Regarding the 2 different types of incremental encoders, i prefer a “software” approach. It’s really easy to change the GPIO assignment by software. As you know, currently you can do it by editing the UI source code. In the next 2-3 weeks, i intend to release a web-based configuration tool for Zynthian that will allow to setup the wiring layout, among other options, from an easy to use web interface. I will add an option for choosing the type of encoder :wink:

Well, the problem with this approach is that, as much as i know, wirinPi library doesn’t implement IRQs for GPIO expanders, so you have to poll. This is not a big problem for switches, but i’m pretty sure it could be a problem for encoder signal. In the best case, you will be using a good amount of high priority (real time!) CPU cycles. Probably it can be done and it should work quite well, but using IRQs for detecting encoder ticks is more efficient and easy to implement.

IMHO, the Zynthian UI encoders, should be connected to the RBPi GPIO. The switches can be connected to GPIO expander, but i prefer to have the 2 “main” switches (select and back) connected to the RBPi GPIO. It’s more robust: If the GPIO expander fails, zynthian is usable yet!!

Anyway, that’s only my point of view and i really think is good to try new approaches, so please, feel free to do it!! I will love it!! As you know, the wiring layout is easy to reconfigure by software, so almost every wiring layout scheme should be compatible with Zynthian UI (*). And ff course, if you find a wiring layout that can’t be configured, please, let me know and i will try to help!!

(*) Configuring encoder pins in the GPIO expander is not supported currently. If you want to do it you should patch the zyncoder library, adding the encoder polling code.

Yesssss! It’s in my TODO list too. Should we open a new topic about this?

Best Regards!

Hi @vagnscott!

Could you share the “excel” source file with the GPIO análysis? I would like to use it in the wiki documentation :wink:

Thanks!

1 Like

I will put up a git repo with schematics, patch, spreadsheet and description. Probably tonight, but maybe in the next few days.

I also have some thoughts on naming and things like that. I will post when I have a bit of time.

2 Likes