Tuning the Prophet-5 Rev 2 (Sequential Circuits, ca 1977)

The two tuning procedures (Production and Simplified methods) provided by Sequential Circuits in the Rev 2 service manual are complex, easily misinterpreted, and abstract – if you don’t have an intuitive sense of what you are doing, it’s hard to tell when you are not doing something right. It’s easy to miss a step or to do it wrong without noticing, and then the whole procedure fails.

Here I describe a method that is more similar to the standard procedure of analog poly synth tuning. I’m sure there are techs out there that don’t have a problem with SCI’s original Simplified method (attached at the end of this document), but if you are not doing this more than once a year or so, you are likely to forget something and go wrong. At least I am.

What you need

  • Guitar-type tuner, or any type of tuner that you are comfortable with
  • Small Screw driver
n-Track tuner on a 10-year old iPad

I would like to have a Peterson Strobe tuner, but since I don’t, I use n-Track tuner App for its comprehensive way to display the information I need. I don’t use the Frequency display (here showing 92.6Hz), only the green needle and the Key display (F#).

I also don’t use my oscilloscope for tuning, it’s difficult since readings will be fluctuating constantly and also it’s hard to know what is a satisfactory value. It’s not made for musical applications.

Method, general description

  • Setup
  • Tune Voice 1 OSC A
  • Tune Voice 1 OSC B
  • Tune Voice 2 OSC A
  • Tune Voice 2 OSC B
  • …and so on for all 5 voices

Method, full description


  1. Open up your Prophet, set it in “service position” with the synth standing upright on the bottom of the chassis
  2. Turn it on, press Preset button, so that it’s unlit
  3. The Tuning Program:

    Pitch bend = Center
    Mod wheel = 0
    All modulation off

    OSC A Waveform = Saw
    OSC A Frequency = 12 semitone steps up from 0
    OSC B Waveform = Saw
    OSC B Frequency = 12 semitone steps up from 0
    OSC B Keyboard = On

    OSC A Mix = 10
    OSC B Mix = 10
    Noise Mix = 0

    Filter frequency = 10
    Filt Resonance = 0
Actually only the first of the PS LEDs is lit :)
  1. Defeat Autotune: On the front panel, hold down Program Select Button 1 (PS1) and press PS7. This removes any compensation voltages added by the Autotune process.

To tune a voice on the Prophet 5 Rev 2 you need to be sure that you are working on the right voice. Turn down level trimmers for voice 2-5. Now only voice 1 is audible and only one out of five keys pressed will produce a sound.

Voice level trimmers, at the low right end of the Voice PCB
  1. Press Unison. By doing this, all voices will play for every key pressed, but only the one whose Level trimmer is up can be heard

Tuning Voice 1 OSC A

  1. Set OSC A Waveform = Saw and OSC B Waveform = None.
  2. Make a mark on a piece of tape and put it under the Voice 1 OSC A trimmers.
In the service manual Offset is called INIT FREQ and Scale is called V/OCT
Key numbers
  1. Play C4. Tune the oscillator to C with Voice 1 OSC A Offset trimmer.
  2. Play C0. Tune the oscillator to C with Voice 1 OSC A Scale trimmer.
  3. Repeat 3 and 4 until there’s no improvement.
  4. On the front of the Prophet, set OSC A Waveform = None, OSC B Waveform = Saw.
  5. Move the indicator tape to Voice 1 OSC B. Remember to move the tape every time you decide to trim a new oscillator. It’s easy to get lost and accidentally adjust the wrong trimmers.
  6. Play C4. Tune the oscillator to C with Voice 1 OSC B Offset trimmer.
  7. Play C0. Tune the oscillator to C with Voice 1 OSC B Scale trimmer.
  8. Repeat 8 and 9 until there’s no improvement.
  9. On the front panel, set OSC A Waveform = Saw, OSC B Waveform = None.
  10. In the low right of the Voice PCB, turn down Voice 1 Level trimmer. Turn up Voice 2 Level trimmer.
  11. Repeat steps 3 to 12 for voice 2, 3, 4 and 5.
  12. Turn up all the volume trimmers. You will have to adjust them for same level on all voices.
  13. Done 


This particular Rev 2 was not possible to tune at all, because the Pitch Bend wheel / potentiometer assembly was unstable. After moving the PB wheel it was impossible to get it back in the exact same position. This is because the Prophet lacked a deadband circuit. The deadband adds an area in the center of the wheel where it doesn’t change voltage even if it’s moved slightly. The Rev 2 service manual does show a deadband circuit, apparently it was added after this unit was built. So I developed a separate PCB with the necessary circuitry. It can also be used to

  • Transpose the keyboard voltage slightly, should there be a problem tuning the Prophet so that the Master Tune knob is centered.
  • Set the bend range. Default for Prophet-5 could be 2 or 5 semitones, depending on who you ask.

The Original Simplified Tuning Method

The Simplified Tuning method by SCI.

SCI’s proposed method is probably great for those who tune a lot of Rev 2’s. It takes some effort to understand what you are doing and why.

Teisco SX-400 Basic Oscillator Tuning, Using Tuner and Oscilloscope

Teisco SX-400 (previously modded for more patch memories and LED display)


When tuning the Teisco SX-400, it’s hard to know what voice you’re currently hearing. Also you need to know which trimmer to use for upper end of the keyboard, and which to use for lower end. There are no tuning instructions in the Service Manual (which by the way is not much more than a set of schematics).

What you need

  • A tuner that shows what note you’re playing, such as a guitar tuner. I use the iPad app n-Track Tuner which has a big needle-type display. It shows the Pitch (as a deviation from the closest note), Note Number and Frequency.
  • Oscilloscope
  • Small cross-head screwdriver (Phillips)
  • Speakers

The idea here is to use the oscilloscope to identify the “voice”, or channel, you want to tune. Connect the oscilloscope on the Syn-29 board to Ground and Test Point CP-4, like this:

PCB Syn-29. Yes, I do apologize for the blurry image
Trimmer Designation – What trimmers to use


  • Turn on SX-400, wait 20 minutes for warm-up
  • Center all five tuning knobs on the front panel
  • Center the four tuning potentiometers on the back panel
  • Turn off all modulation
  • VCOs: Saw wave, Range = 16 (lowest)
  • Filters: Cutoff = Max, Resonance = 0, High pass filter at 16 Hz (lowest)
  • Poly Mode = QUAD

Step by Step

Let’s start with Channel 1, and the low end of the keyboard:

  • Press at least four different keys sequentally in the HIGH end of the keyboard. Now the oscilloscope should look something like the left image:
  • Now press one key after another and watch the oscillosope (that you previously connected to Channel 1 on the Syn-29 board).
  • As soon as the oscilloscope drops to a lower frequency (right side of image) you are playing Channel 1. It doesn’t matter exactly what note you are playing.
  • Lets say the oscilloscope changed when you hit lowest D. Now you have to remember that Channel 1 is on lowest D. (It will stick with that key if you press it repeatedly.)
  • Now look at the Tuner. Turn Trimmer 8 until the tuner it’s spot on D

Channel 1 and high and of Keyboard:

  • Press four keys sequentially in the high end of the keyboard
  • (At the fourth keypress) the oscilloscope should change to a high frequency
  • Remember what key it was, lets say highest A
  • Look at the Tuner. Use trimmer 6 to tune Channel 1 high end to A

The two trimmers affect each other, so repeat the steps a couple of times, until they both stick on the right pitch. On this SX-400, one channel had to be repeated 5 times, but 2-3 is more likely.

Now move the oscilloscope probe to Channel 2 (Test Point CP-5) on Syn-29. Repeat everything using the right trimmers.

Probe Test PointTrimmer Low Trimmer High
Channel 1CP-4TR-8TR-6
Channel 2CP-5TR-11TR-9
Channel 3CP-6TR-14TR-12
Channel 4CP-7TR-17TR-15

Korg PolySix Tuning – The Long Story

The tuning of a Korg PolySix is mostly a tedious process. Let’s go in-depth to make it even worse. The tuning process described here is normally not necessary, but if you have replaced some components on the Voice PCB this might be your last resort.

Korg PolySix (with KiwiSix CPU board, your LED states may be different)

Sources of information

  • The PolySix Service Manual. There is some important information in there, like the fact that the PolySix is not speced to be able to tune in the highest octave. But generally the tuning instructions in the service manual should be read, understood and avoided.
  • The KiwiSix manual, section 5) “PolySix Adjustments”, paragraph 9) “Voice Pitch Tuning”. It has helped me out many times. (You don’t need to have the KiwiSix upgrade installed.)
  • This page. It’s for when you can’t get it right with the KiwiSix procedure.
The voice PCB, KLM-366

Step-by-Step Instructions

Front Panel Preparations

  • Set Waveform to Saw
  • Tune Knob = Center
  • Modulation Level = 0
  • Bend Intensity = 0
  • Move Modulation wheel to 0
  • Move Pitch Bend wheel to the Center detent

Voice Board Preparations

  • Everything will happen on the voice PCB (KLM-366). Pull the slide switch between VR1 and VR2 towards the rear of the PolySix (away from connector CN12). This is the ‘normal’ tuning position. The other position is for stretch tuning.

These “global” trimmers will affect all voices

  • VR1 (Adj Center)
  • VR2 (Tune High)
  • VR3 (Tune Low)
  • VR14 (D#4-E4 Adj)
  • VR15 (Tune Mid)

Per-voice trimmers

  • VR10 (Tune Low) * 6
  • VR11 (Tune High) * 6
Trimmer positions

Note: In early production models
VR14 is not present 
VR15 (Tune Mid) is called VR1 and sits on the KLM-396 daughter board

Early production daughter board

Tuning Procedure, Global + Voice 0

First adjust global trimmers together with Voice 0. Save Voices 1-5 for later. Use the LEDs on the Voice PCB to identify which voice is currently playing.

a) Set Octave to 4′ (on the front panel)

b) Hit C5 until the LED for Voice 0 is lit. Adjust VR11 to obtain C5 0 cents.
(If VR11 is far off from center: adjust VR2 (Global) Tune High a bit and try again)

c) Play C2 and adjust VR1 to obtain 0 cents for Voice 0.

Repeat (b – c) until C2 and C5 are in tune for Voice 0

d) Play C3 and adjust VR15 to obtain 0 cents (It might not be possible right now. If not, do your best)

e) Play D#4 and E4 and adjust VR14 until both are spot on. (It might not be possible right now.)

Repeat (d – e) to get C3 and D#4-E4 a bit closer to correct pitch

Repeat (a – e) until C5, C2 and C3 are good. Then go to (f).
If you can’t match C2 and C3, i.e. if step (c) and (d) seem to counteract each other, please also go to (f).

f) Set Octave to 16‘ and play C2. Adjust VR3 (Tune Low) for 0 cents. This can help with steps (c) to (d). Try to leave VR10 close to center position for Voice 0.

Repeat (a – f) until Voice 0 is in tune

The keys

Voices 1 – 5

Generally, from here on, you want to avoid changing the “global trimmers” VR1, VR2, VR3, VR14 and VR15.

h) Set Octave to 4′
Play C5 and adjust VR11 for Voice 1 – 5

i) Set Octave to 16’
Play C2 and adjust VR10 for Voice 1 – 5

Repeat (h – i) until Voice 1 – 5 are in perfect tune


Technical Notes

If you are unable to tune a PolySix, there are some components that fail more often than others in the “auto-tune” and expo converter section.

  • 4051 multiplexers are always suspects
  • The opto-coupler (aka “Vactrol”) HTV P1501, cannot be sourced nowadays, but might be replaced with VTL5C9 or NSL32-SR3. Due to differencies between specs, but also between individual optocouplers, other alterations may be needed in the PolySix “auto-tune” circuit. If VR15 (Tune Mid) and VR1 (Adj Center) counteract each other, so that C3 stays too sharp, and you finally hit bottom while turning VR15 clockwise, then you may need to decrease the value of R216 a bit.
  • Sometimes IC17 – 19 need to be replaced. If you change IC17 and IC18 to TL072, instead of the less common NJM072, there’s a resistor change you need to perform, specified in the KLM-266 schematic, in the service manual. Don’t bother to source NJMs, the TL072 is a higher performance OpAmp.


Arduino FastLED Library – a visual reference for the predefined colors

The FastLED Library for Arduino and other microcontrollers is used for controlling LED-strips with one to hundreds of individually addressable RGB LEDs. Here is a visual reference to the colors that are pre-defined within FastLED. In C++ they can be accessed by name, like this:

CRGB my_color; // Define a variable of type CRGB
my_color = CRGB::AliceBlue; // Variable now contains AliceBlue

The colors in this list appear in the same order as in the FastLED struct that defines them.

The struct itself looks like this:

HTMLColorCode { 
AliceBlue = 0xF0F8FF, Amethyst = 0x9966CC, AntiqueWhite = 0xFAEBD7, Aqua = 0x00FFFF, Aquamarine = 0x7FFFD4, Azure = 0xF0FFFF, Beige = 0xF5F5DC, Bisque = 0xFFE4C4, Black = 0x000000, BlanchedAlmond = 0xFFEBCD, Blue = 0x0000FF, BlueViolet = 0x8A2BE2, Brown = 0xA52A2A, BurlyWood = 0xDEB887, CadetBlue = 0x5F9EA0, Chartreuse = 0x7FFF00, Chocolate = 0xD2691E, Coral = 0xFF7F50, CornflowerBlue = 0x6495ED, Cornsilk = 0xFFF8DC, Crimson = 0xDC143C, Cyan = 0x00FFFF, DarkBlue = 0x00008B, DarkCyan = 0x008B8B, DarkGoldenrod = 0xB8860B, DarkGray = 0xA9A9A9, DarkGrey = 0xA9A9A9, DarkGreen = 0x006400, DarkKhaki = 0xBDB76B, DarkMagenta = 0x8B008B, DarkOliveGreen = 0x556B2F, DarkOrange = 0xFF8C00, DarkOrchid = 0x9932CC, DarkRed = 0x8B0000, DarkSalmon = 0xE9967A, DarkSeaGreen = 0x8FBC8F, DarkSlateBlue = 0x483D8B, DarkSlateGray = 0x2F4F4F, DarkSlateGrey = 0x2F4F4F, DarkTurquoise = 0x00CED1, DarkViolet = 0x9400D3, DeepPink = 0xFF1493, DeepSkyBlue = 0x00BFFF, DimGray = 0x696969, DimGrey = 0x696969, DodgerBlue = 0x1E90FF, FireBrick = 0xB22222, FloralWhite = 0xFFFAF0, ForestGreen = 0x228B22, Fuchsia = 0xFF00FF, Gainsboro = 0xDCDCDC, GhostWhite = 0xF8F8FF, Gold = 0xFFD700, Goldenrod = 0xDAA520, Gray = 0x808080, Grey = 0x808080, Green = 0x008000, GreenYellow = 0xADFF2F, Honeydew = 0xF0FFF0, HotPink = 0xFF69B4, IndianRed = 0xCD5C5C, Indigo = 0x4B0082, Ivory = 0xFFFFF0, Khaki = 0xF0E68C, Lavender = 0xE6E6FA, LavenderBlush = 0xFFF0F5, LawnGreen = 0x7CFC00, LemonChiffon = 0xFFFACD, LightBlue = 0xADD8E6, LightCoral = 0xF08080, LightCyan = 0xE0FFFF, LightGoldenrodYellow = 0xFAFAD2, LightGreen = 0x90EE90, LightGrey = 0xD3D3D3, LightPink = 0xFFB6C1, LightSalmon = 0xFFA07A, LightSeaGreen = 0x20B2AA, LightSkyBlue = 0x87CEFA, LightSlateGray = 0x778899, LightSlateGrey = 0x778899, LightSteelBlue = 0xB0C4DE, LightYellow = 0xFFFFE0, Lime = 0x00FF00, LimeGreen = 0x32CD32, Linen = 0xFAF0E6, Magenta = 0xFF00FF, Maroon = 0x800000, MediumAquamarine = 0x66CDAA, MediumBlue = 0x0000CD, MediumOrchid = 0xBA55D3, MediumPurple = 0x9370DB, MediumSeaGreen = 0x3CB371, MediumSlateBlue = 0x7B68EE, MediumSpringGreen = 0x00FA9A, MediumTurquoise = 0x48D1CC, MediumVioletRed = 0xC71585, MidnightBlue = 0x191970, MintCream = 0xF5FFFA, MistyRose = 0xFFE4E1, Moccasin = 0xFFE4B5, NavajoWhite = 0xFFDEAD, Navy = 0x000080, OldLace = 0xFDF5E6, Olive = 0x808000, OliveDrab = 0x6B8E23, Orange = 0xFFA500, OrangeRed = 0xFF4500, Orchid = 0xDA70D6, PaleGoldenrod = 0xEEE8AA, PaleGreen = 0x98FB98, PaleTurquoise = 0xAFEEEE, PaleVioletRed = 0xDB7093, PapayaWhip = 0xFFEFD5, PeachPuff = 0xFFDAB9, Peru = 0xCD853F, Pink = 0xFFC0CB, Plaid = 0xCC5533, Plum = 0xDDA0DD, PowderBlue = 0xB0E0E6, Purple = 0x800080, Red = 0xFF0000, RosyBrown = 0xBC8F8F, RoyalBlue = 0x4169E1, SaddleBrown = 0x8B4513, Salmon = 0xFA8072, SandyBrown = 0xF4A460, SeaGreen = 0x2E8B57, Seashell = 0xFFF5EE, Sienna = 0xA0522D, Silver = 0xC0C0C0, SkyBlue = 0x87CEEB, SlateBlue = 0x6A5ACD, SlateGray = 0x708090, SlateGrey = 0x708090, Snow = 0xFFFAFA, SpringGreen = 0x00FF7F, SteelBlue = 0x4682B4, Tan = 0xD2B48C, Teal = 0x008080, Thistle = 0xD8BFD8, Tomato = 0xFF6347, Turquoise = 0x40E0D0, Violet = 0xEE82EE, Wheat = 0xF5DEB3, White = 0xFFFFFF, WhiteSmoke = 0xF5F5F5, Yellow = 0xFFFF00, YellowGreen = 0x9ACD32, FairyLight = 0xFFE42D, FairyLightNCC = 0xFF9D2A

Ursa Major Space Station SST-282, 82S123 replacement

How to make a replacement for the 82S123 ROM chip (ADS-1 board – U19) in Ursa Major Space Station SST-282, using an 22v10 Programmable Logic chip and a cheap EPROM programmer.

I used Atmel ATF22v10CQZ-20PU and the common TL866iiPlus.

This is not a step-by-step guide, you are expected to know how to use an EPROM programmer.

Main SST-282 main image
Two Space Stations in for service, one with a problematic 82S123

What is the N82S123N chip

The Space Station doesn’t have a processor, but you can still select different reverb-, filter- and delay algorithms. This is achieved with hardware buttons that make the 82S123 IC output various control signals to the rest of the machine.

Two M82S123N chips from the SST-282
82S123 from the two Space Stations above

The 82S123 is not an ordinary EPROM, it’s a bipolar TTL PROM. It is way faster than EPROM, with response times in the nanoseconds. You can get them NOS on eBay. The problem is that an EPROM programmer that supports this type of chip is expensive.

I haven’t verified this, but these chips should be direct replacements for the 82S123:
7112, 27S19, 6331-1N, 74S288, 18S030, 7603

The ATF22v10C Programmable Logic IC

Atmel F22v10CQZ-20PU and little brother F16v8BQL-15PU

The ATF22v10 is a Programmable Logic chip, made by Atmel. Other brands are sometimes called PAL chips. ATF / PALs are much more flexible than EPROMS, mainly because you can run small programs on them, so they behave differently depending on signals present on the input pins. They are also very fast, and that’s why they are fit to replace an 82S123.

So in short, I needed the 22v10 to output one of 32 numbers, depending on the state of its input pins – just like a small EPROM.


Luckily I found someone that made a 82S123 replacement using the GAL22v10D, which is “practically the same” chip: REPROGRAMMABLE 82S123. Beware though that not all EPROM programmers and ATF / PAL / GAL chips are compatible.

So I read a bit of documentation on 22v10, as well as the programming language (CUPL Compiler for Universal Programmable Logic) and tool (WinCUPL)

Hardware adapter

22v10 is a 24-pin chip, whereas 82S123 is only 16-pin, so an adapter is needed. Please refer to this site for detailed information: REPROGRAMMABLE 82S123

My version looks like this

82S123 socket to 22v10 IC adapter top
82S123 socket to 22v10 IC adapter bottom

Programming the Space Station data to 22v10

You need an EPROM programmer that is compatible with the 22v10 brand that you have


Ursa Major Space Station with the new ATF22v10C added


“Why not use the smaller 16v8 PAL instead? It’s smaller but it has enough pins…”

Well, if you try to compile any code that contains a 32 byte ROM table and the necessary pin bindings in WinCUPL it’s going to fail. WinCUPL even outputs a nice Word document that shows exactly where the resources are exhausted.

The differences between Roland Juno-106 and MKS-7

This page compares the Roland MKS-7 to the Roland Juno-106. To understand it, you need to know the Juno-106. Some people say the MKS-7 is the rack version of Juno-106. But it’s more… and less.

The Roland MKS-7, a “6 note polyphonic / mono bass / TR707 drum sound” module

The Roland MKS-7 was allegedly intended for MIDI-file playback and karaoke, thus being a consumer market product. The voicing hardware is similar, but not identical, to the Juno-106.

Roland Juno-106 patch-making controls


A Roland MKS-7 could be considered a more affordable, yet in some respects more capable, version of the Juno-106.

The MKS-7 has a somewhat complicated scheme of three different voice types. It is in a way a multi-timbral synth, but there are more restrictions than what you might be used to.

  • Two voices are assigned to Melody functions
  • Four voices are assigned to Chord functions
  • One voice is Bass
  • There is a drum kit based on the Roland TR-707

According to one of my customers, the MKS-7 can be set in “Juno-106 mode” and so the six first voices behave like one Juno-106. I have not tried it, and I have not researched it either.

Juno-106 advantages

  • Sliders and buttons for every patch parameter
  • User patch storage
  • No restrictions on how to use the 6 voices – simple

MKS-7 advantages

  • Velocity control of filter and VCA
  • Lower second hand price than Juno-106
  • More voices – 6 poly voices, plus one dedicated bass voice, plus drum sounds
  • Multitimbrality, to some extent

Here are the parameter differences between the two. The tables are from the MKS-7 service manual, with Juno-106 specifics noted in orange. My notes follow after the image.

Differences, not mentioning Juno-106 keys, knobs and sliders…

So what’s specific for the MKS-7?

  • Dynamic select (aka velocity control of VCA Level and / or Filter Cutoff) – Yeah baby! This is a big thing. The Juno-106 lacks any type of velocity sensitivity, which is one of its biggest weakness.
  • Sub OSC level in 4 steps instead of the Juno’s slider – Seriously, this wouldn’t make much of a difference.
  • High Pass Filter is ON/OFF instead of a slider – Personally I don’t think this damages patch creation much, but if you use HPF a lot it could be a problem.
  • Chorus, only one mode – This is a problem. A lot of the dreamy character of some Juno-106 pads and strings come from Chorus II. The MKS-7 only uses one BBD chip, compared to the Juno’s dual MN3009.
  • Noise – Noise is only available on the two Melody voices, and even so it’s only available at full volume or nothing. Some people like to add a bit of grit to a sound with a little noise.

The Bass voice

The bass voice differs from the ordinary voices in many respects. It has no modulation at all except envelope. It can switch between saw and pulse waveforms, but can’t have both at the same time. There’s no noise, no inverse envelope, no HPF etc. On the plus side, the Bass has an analog envelope. This is important because the control voltage it outputs has an exponential shape, and therefore has more punch with shorter attack- and decay settings. All things considered, this bass voice is a lot more trimmed-down than any Roland bass synth, like SH-101 or SH-09. Since it lacks velocity sensitivity I dare say it’s even more basic than the TB-303 sound engine which sports accent and slide controls. Still, it’s a rock solid bass, and a lot of people like it.

Creating patches and saving them

The MKS-7 comes with 100 chord / melody presets and 20 bass presets. They can be edited using SysEx, but they cannot be saved inside the MKS-7. It doesn’t even remember what patch you selected for Chord, Melody or Bass once you turn it off.

A software SysEx editor, or DAW plugin, can be used to edit the MKS-7 parameters, and that software could also save your custom patches. You would have to upload the patches to the MKS-7 every time you restart it.

But everybody ideally wants hardware sliders and buttons. You could get a Stereoping Juno-106 programmer or a Behringer BCR for that. But doing so, you will still have to save your SysEx patch in your sequencer, in a SysEx librarian, or within your programmer if it allows that (Behringer BCR does not).


Using the MKS-7 to get a Juno-106 is a bit too much hassle for me. What still makes me consider it is the price difference from 106 and that the MKS is velocity sensitive. I’ll stay with the JU-06 for now.

Arp Sequencer 1621 / 1601 Button Debounce

Arp Sequencer 1621 / 1601. The changes between versions are only cosmetic.

While servicing an Arp Sequencer 1621, I noticed that the three button switches were in a bad shape. One button press would produce anything from one to six signal changes.

These switches can’t be sourced nowadays. The switches are glued together from factory so they can’t be opened.

One possible fix would be to fit some type of modern (long slew) replacement switch inside. You would probably need to design an individual adapter PCB to make it fit the footprint on the 1621 PCB, and also 3D-print an adapter to stick the white button caps back on. However, there’s no guarantee that any other switch will work flawlessly even if it’s new. All electromechanical switches bounce.

I tried removing and washing the switches with ultrasound, warm water and dishwashing detergent. That helped to some extent, but they still exhibited double-triggering and trig on release.

Top traces show how a button press generates bounces

Using the original switches

I decided to hardware debounce the switches, using RC filters. I had the following design goals, in addition to making it work:

  • Don’t change any components on the 1621 PCB
  • Make it visually clear to anyone what my addition does
  • Stick my PCB to the main PCB, not the bottom of the unit, to keep it simple to open and service

The lower traces in the images above show the RC filtered signal, with the third image showing an extreme case, which I’ve not been able to replicate again. The RC filter will introduce a delay from button press to state change, but it can probably be kept under 10 ms. It depends on how badly degenerated the switches are, their original construction and possibly in what manner they will be hit in actual use: A more firm hit will probably make a shorter period of contact noise (?)

Here some Internet programmer’s well designed RC debounce circuit. Button closing will make pin 1 of U1 see a smooth signal falling towards LOW. Opening the button makes pin 1 see a signal rising to HIGH. The fall and rise rates are defined by R2 * C1 and R1 * C1 respectively.

The diode, while not necessary, makes the charge rate (going towards HIGH) of the capacitor depend only on R1, not R1 + R2.

U1 is an inverter, so the resulting voltage state at pin 2 will be the opposite of pin 1.


CD40106B inverter

The 40106 is a 20 volt tolerant inverter with Schmitt-trigger. Logic levels in the 1621 are +15 and 0 volt. The Schmitt-trigger handles noise and slowly rising or falling voltages well and is a good companion to the RC filter for debouncing.

Schmitt-trigger (noisy) input and output

There is no technical advantage of inverting the output signal, but the inverter isolates the switch and RC network from from the rest of the circuitry. This can be important when fitting a debounce circuit to an existing system, otherwise you’re likely to unintentionally create voltage dividers that will affect the performance of the debounce circuit, and possibly offset the resulting signal.

Upper trace: RC filtered signal. Lower trace: Filtered signal after inverter + Schmitt-trigger

Special considerations and adjustments are needed when fitting something like debounce to an existing system. In the 1621 the signals from the switches are later combined with other signals from the input jacks. The original switch construction doesn’t have a HIGH and a LOW state, it has LOW state and UNCONNECTED (in case of the “Start / Stop” and “Reset” switches), and HIGH state and UNCONNECTED (for the Step switch).

Start/Stop Example

When “Start/Stop” switch is UNCONNECTED there’s a weak pull-up that keeps the signal line in HIGH state. This pull-up is weak enough for another connected signal (via External input jack) to pull the line down to LOW if needed.

1601 schematic, the “Start/Stop” input signal and switch

The RC scheme however, can’t have an UNCONNECTED state, only HIGH, LOW or intermediate values. When the debounced switch is off it could therefore affect the “Start/Stop” signal line, and hinder other signals from forcing it LOW. To remedy that, I added D1 and D2 in the following image.


The schematic only shows two circuits. That’s because “Reset” and “Start/Stop” use the same top design (except for one resistor value). “Step” uses the bottom design.

When I tested everything out, I realized that I had created an unwanted behavior in the 1621. Every time I turned the power on, it jumped a number of steps into the sequence, as if the “Step” button had been pressed a few times after startup. That’s natural, since in practice I had delayed the switches by a couple of ms, not only when pressed, but also on startup. I changed R3 to 22k so it would appear to the 1621 as if “Reset” button was pressed a few ms after the other buttons, taking the sequencer back to step 1.

Breadboard test
All paths to switches are cut on the PCB, wires connect them to the debounce board
There’s a piece of acrylic between the PCBs to keep the distance
Keeping related wires together


This Arp Sequencer 1621 works as it was intended again. The reaction to button-presses is fast enough, and feels solid and reliable.

I could have done this with a lot fewer wires if I had been more creative with where I cut the PCB paths, in combination with inverting signals once more to get back to uninverted state. But then it would have been much harder to follow the signal flow for the next service technician.

I taped a printout of the schematic, and added a link to this site on the inside of the unit.

Korg Lambda ES-50 Tuning Instructions

Disclaimer: There may be a better way to tune the Korg Lambda. My method is a bit “hit and miss”. Still it took less than five minutes to accomplish.

Korg Lambda ES-50 string machine


The Lambda is not a VCO->Filter->VCA synthesizer, it’s constructed lika an organ / string machine. The tuning procedure is different and often simpler on an organ than on a synthesizer. Maybe that’s why, when searching the web for tuning info, I came across statements like these:

Actually, I don’t think the Lambda stringer has got any trimmers to do the tuning, except the little pot on the chorus circuit board, that tunes the LFO rate range of the effect.

Well, it’s very rare that such string machines would require tuning becuase they use different technology than synthesizers.

The knobs positions on the front

Tuning the Korg Lambda

Turn all instrument buttons off, except BRASS. Set Chorus Phase Off. Set all three TUNE knobs: Total Tune, Tune A and Tune B to center position. Vibrato Off. Get a very small screwdriver.

It’s likely that the Lambda sounds very dissonant in this state. If it does, adjust VR Tune A and VR Tune B until both LEDs are steadily lit. Now it doesn’t sound dissonant anymore, but it’s probably still out of tune.

The trimmers (VR). Their positions match the positions of the knobs on the front.

Now the guessing starts

  1. Adjust VR Total Tune right for sharper tuning, left for flatter. You will notice that the sound also gets dissonant, so you can’t really hear if you hav hit the right pitch.
  2. Adjust VR Tune A and VR Tune B until both LEDs are steadily lit again. Now you can hear the actual pitch of the instrument.
  3. It’s likely that you will realize you turned VR Total Tune too far, or not far enough. Repeat steps 1-2.

Soon you get familiar with how much you need to adjust VR Total Tune in order to raise or lower the pitch by a few cents.

That’s it

Korg Poly-61 – Changing the NiCd to a Litium Battery

It was pointed out to me that there is already a modification devised by Korg for this purpose. While my modification works, you should probably stick to Korg’s original Engineering Change Note, even though it’s a bit more complex.

The Korg Poly-61, DCO analog synthesizer

The Korg Poly-61 has the same type of battery as the Korg Polysix, the type that creates the infamous battery-leak disasters. Here’s how to modify the Poly-61 for a standard litium coin-cell battery. The coin-cell is seated in a battery holder, so can easily be changed by the owner, without soldering.


The original batteries in Korg Poly-61 (and Polysix) are charged at any time the synth is on. The coin-cell litium battery is not rechargeable. If you would just insert a litium battery in the circuit, the battery would break and possibly catch fire or explode. So you need to stop the current flow from the PSU to the battery.

Also don’t replace the NiCd battery with a new rechargeable battery such as Lithium-Ion or NiMh. The Poly-61 charging method is not suited for those, and they will break.

Old Crow (RIP) has info on battery modification and battery leak repair for the Polysix. I Adapted it for Poly-61.


Remove this

  • Old battery
  • Resistor R70 (replace with diode)
  • Capacitor C29 (aka C32) *

* I am referring to the electrolytic capacitor called C29 in the schematics. However, on the white screen print on the circuit board, it’s called C32.

Add this

  • Diode, eg 1N4148 (Please watch the direction, see schematic)
  • Coin cell battery holder
The changes
PCB positions of R70 and C29

PPG 1020 Tuning Instructions

Disclaimer: I have no idea. Maybe this can be done better. But here’s my best shot.


There is not much technical information around about this very rare synth. In order to figure out how to tune it, I had to remove the front plate which is a lot of work. This article is an attempt to save you from that.

The specimen I got to the workshop was close to a prototype. I don’t if the numerous modifications and extra installments were factory-made, or done later. The PSU is part of the main PCB, except for the transformer, so it’s not immediately apparent what is what. There is trimmer for +12 volt, and it was easy to get it very exact. There’s no trimmer for -12 however, and it was around -10.5 volts, don’t know if that’s within specs, but it seems a bit far off.

Thanks to Stefan Huebner I knew that the oscillator control voltage is part digital and part analog: The octave is selected digitally, and the voltages within an octave are analog. This means that if you notice that F1 key, for example, is off by 20 cents, then every F is going to be off by 20 cents. But some other note, say all D keys, could be in tune.

The problem

The two oscillators had the same pitch on some notes, but where off by almost a quarter-note on others. The behavior repeated for each octave. Which exact notes where in tune could be adjusted with the OSC B PITCH knob.

Some tuning info

On an analog synthesizer, there’s traditionally one Offset trimmer (VR), and one Scale VR for the Lin-to-Exponential Converter for an oscillator. The circuit assumes that the input is a fairly exact linear 1 v / octave voltage. I found Scale VR and Offset VR for OSC A, and a Scale VR for OSC B.

Part of the PCB

It was not possible to adjust the OSC A Offset enough to get it in tune, probably due to one of these reasons:

  • The negative supply was only -10.5 v
  • Some modification to the PCB has broken the voltage supplied to the lin-exp converter
  • I misunderstood how the TUNE knob is supposed to work. Maybe it’s more like the Sequential Pro-One, where the oscillator is in tune when the knob is at zero. I assumed that the “neutral” setting would be in the middle of the knob range, which is 5. Otherwise it would not be possible for the user to tune the synth if it is too sharp.

Tuning the PPG 1020

Oscillator A

OSCILLATOR CONTROLLER / TUNE = 5, turn down OSC B, all modulation off, OUTPUT I LEVEL = 0, OUTPUT II LEVEL = 10

  1. Press any G key, for example G2
  2. Use OSC A Offset VR to get correct pitch for G2. If not possible, adjust the OSCILLATOR CONTROLLER / TUNE knob
  3. Press G#2
  4. Use OSC A Scale VR to get correct pitch for G#2
  5. Repeat 1-4 until both G2 and G#2 are in tune

This is the way to get the best pitch overall. On my synth about half of the keys within the octave were in perfect pitch, while others were flat or sharp by up to 10 cents.

Oscillator B

Turn up OSB B in the mixer. You’ll hear some beating between OSC A and OSC B when playing notes.

  1. Press G2
  2. Use OSCILLATOR B; PITCH knob to get zero beating
  3. Press G#2
  4. Use OSC B Scale VR to get zero beating
  5. Repeat 1-4 until there’s no beating

You will notice that even if one key, say D#, is off by +8 cents, it’s exactly the same for both oscillators, so at least there’s no beating.

That’s it! Thanks for listening

Roland TR-505 – A Better Mod for Individual Outputs

Descriptions of Individual Audio Outputs modifications for the Roland TR-505 have been around for a while. I searched the web for sources that describe how to do the mod:

There are many sources talking about having it done, without explaining how:

The problem

However, the modifications that are described share one problem: They don’t handle Cymbals and Open HiHat very well. That is because the signal is tapped too early in the output summing circuitry, before the volume envelope is applied. Citing circuit benders’ description of their mod:

“Longer sounds such as the crash and hats consist of a compressed sample, with a primitive envelope applied to it so it sounds vaguely realistic. As the outputs have to be sourced in the circuit before the envelope is applied, some sounds will not be identical to the main mix outputs.”

Image from masutopedals.wordpress.com/

How to do it better

To sort it out, you need to tap audio from (LT MT HT TB) (CC RC) and (CH OH) after transistors Q6, Q7 and Q8 respectively, because the transistors apply the volume envelope to the audio signals. However the signal can’t be taken directly from the emitter of the transistor, because it’s is very weak at this point, and you will introduce noise, hum and instability. Instead, we take it after the buffers / amplifiers IC16 and IC15 respectively.

Red shows the standard 505 mods, green shows my modification spots

You will use the standard mod spots for (HCP RIM) (LCB HCB) (SD) (LCG HCG) and (BD), and the green ones for (LT MT HT TB) (CC RC) and (CH OH). I used breaking 3.5 mm jacks, so the sound is removed from the R / L mix when a cable is inserted in the individual output jack.

What you lose

You are going to lose the predefined, fixed panning that some of the sounds in the TR-505 have. But you will have all sounds on individual mixer channels to pan, equalize and add effects.

Also, the volume levels of the individual outputs may not be exactly the same as on the R / L outs.

Roland CR-8000 BD / SD Mod

This drum machine from 1981 is a close relative of Roland CR-78 and TR-808. It has a couple shortcomings, such as no user editable sounds, a Snare Drum with a lot of tone (what is called “Snappy” on 808) but a lack of noise / high frequency content. It sounds more like a tom. Also the Hand Clap is low volume, at least on this specimen.

This CR-8000 was modified for individual audio outputs for each instrument group, a louder Hand Clap, as well as couple of potentiometers for Bass Drum and Snare Drum tuning. The BD now has two controls: Pitch and Decay, the SD has two controls: Pitch of the “snappy” portion, and Noise level. 

The BD and Clap modifications are taken directly from gumielectronic. The exact changes with component values are listed further down in this article.

When servicing or modifing synths I try to conform to Hippocrates’ oath for medical doctors: “First, do no harm”. So I made a break-out box, instead of drilling holes in the CR-8000 exterior. Also I left the original parts in place on the PCB where possible, should someone want to reverse this mod in the future.

The break-out box sticks to the metal back plate of  the CR-8000 with neodyme magnets. The wires are routed through existing vent holes in the back.

The following list is an excerpt from gumielectronics’ extensive CR-8000 modifications. The red markings are the ones I chose to use (since there was limited space on the break-out box) along with my component selections. The Snare Drum are my own changes, as some of gumielectronics’ suggested changes didn’t make that much difference. C47 is Snappy Pitch, the changes after Q7 is the SD Noise portion boost.

Below are Snare Drum specifics. The exact original SD sound isn’t available anymore, it now has a bit more noise content.

Here are a couple of images of the PCB and break-out box internals:

Bass Drum (green wire and some resistors) and Snare Drum Snappy (yellow wire bridging R34):

Snare Drum Noise Boost (red wires) and Snappy pitch (blue wires):

Individual outputs:

Tidying up a bit:


Individual Outputs: The CR-8000 was not designed to have separate outs to begin with. Some things are not possible to do the way you’d want because of this. The Clap for example, is lower at the individual output than it is in the main mix. (Just mix it up a bit with the knob, or on your mixer). Also the accent effects are not applied to the individual outs, so in some cases the Main out instruments will sound beefier than the indy versions. This is often not a problem, since you can either do a lot to beef the sound up on an individual mixer strip, or you can leave that particular instrument on the main mix out and direct everything else to individual outputs.

BD Decay: The Bass Drum will not have the oomph of the TR-808, maybe because of a shorter trig pulse or some other volume envelope characteristic that might be different.

SD Decay: Decay of the Snare Drum is hard to modify, unlike the Bass Drum. The mod point called “decay” in gumi’s description doesn’t change the overall decay of the instrument, only the length of the Snappy portion within the (very short) total length of the Snare Drum, and this change is hard to hear to be honest. I think it would need a longer trig pulse to make the Snare longer, but I haven’t tested this idea.


I believe the changes described here are a significant improvement to the CR-8000.

Toaster with web server

Arduino files download: Sonoff_toaster_timer

First install ESP8266 support for Arduino IDE. Follow these instructions:

Reprogram Sonoff Smart Switch with Web Server. I didn’t use this in the end, but learned the basics:

ESP8266 ajax – update part of web page without refreshing. The main source for my toaster’s html page:

ESP8266 Timer / ticker examples. Helps keeping track of time / elapsed seconds:


My toaster had a mechanical problem: It didn’t release the bread, or turn off, when time was up – Instead it continued toasting forever. This is my second toaster of the same type that breaks. It’s obviously not reliable, but it does take long slices of bread

So I had the idea to control the power supplied to the toaster, instead of trying to fix its mechanics.

I got a couple of Sonoff WiFi relay switches off eBay, hoping to automate a few things at home. I soon realised it would not be possible because of the way they are programmed to work: They use your WiFi to connect to a global server, where you have used their “EWeLink” app to set up an on / off schedule for the switches. That scheme would be useless for my purposes for many reasons:

  • When I got the switches (Christmas 2017) there was a global Sonoff hype. The server was unreachable, probably due to heavy traffic.
  • You need internet to use the Sonoff. Of course I wanted to be able to make a toast even if my ISP was having problems that morning.
  • I suspect that if you would turn on a switch and then loose connection to the server, it would stay on forever. This would cause any inserted bread to catch fire.
  • The scheduling control was too unprecise. You can set events to minutes at best, but I needed second’s granularity.
  • There was no way (at least not back in 2017) to turn a switch on, and have it turn off after a set time interval. You could only turn it on (maybe 07.23) and then set it to turn off at another time stroke (07.25 or so).

The Project

I already nourished a long-standing toast dream: To be able to sequence the toasting like this: Toast-Pause-Toast-Stop. I had previously noticed that the toast quality was increased significantly when I did this manually – The slices didn’t get dry on the outside and wet on the inside. Instead they became crisp all the way through.

I also wanted presets for different types of bread, or for users with various demands.

The Sonoff serving a local web page

The Sonoff contains an ESP8266 processor that does most of the work. Most importantly ESP8266 has WiFi capabilities, which is why it’s used in many Internet of Things-applications. It’s possible to run a web server on the ESP8266, and have it serve a web page with a user interface for the Sonoff on / off switching. So in my case it serves a HTML / Javascript page with five buttons and a progress bar. The buttons select one of three toast sequence programs, a one-shot 30 seconds toast program or stop. The shortest toast program is for white bread that is a bit dry, the longest is for dark bread that is frozen.

The Stop button doesn’t fit on my medieval iPhone 5 screen

New firmware, Arduino, randomnerdtutorials.com

To upload firmware to the ESP8266. I used Arduino IDE 1.8.1 and a USB-Serial TTL converter. I followed these instructions for wiring: https://randomnerdtutorials.com/reprogram-sonoff-smart-switch-with-web-server/

Sorry, the power cord just popped off

There was also info on what libraries needed to be installed, how to set up an ESP web server, connect to Wifi and more. A good place to get started.

Maybe not randomnerdtutorials, after all

I soon realized that the code on randomnerdtutorials would be dangerous for this project. It works something like this: When you click a button on the web page, a new page is loaded. Appended to the URL is the name of the button that you clicked. This is a common way to pass data between html pages. The problem is that when the toast program is finished, it’s quite possible that you still have this page (with the button name) loaded in your web browser. Which means that if you reload the page (which can happen automatically in many situations, ie on a computer restart) the toaster will start again.

AJAX, circuits4you.com

Then I found this page: https://circuits4you.com/2018/02/04/esp8266-ajax-update-part-of-web-page-without-refreshing/ that demonstrates using AJAX XMLHttpRequest techniques to do calls without reloading the page. It was a better fit for my needs in many ways:

  • URL doesn’t change when you click a button
  • During development, the HTML code is kept in a well-formatted separate header file. When uploaded to ESP, the HTML is stored in Flash memory using the Arduino Flash memory routines. When the program runs, the HTML is read in to RAM when needed. Many examples online that do this use the SPIFF file system instead of Arduino Flash memory routines. SPIFF requires separate manual uploads from the computer to the ESP. I didn’t want to learn that in this project, I already had too many things that could go wrong
  • CSS styles in the header – I knew I didn’t want to download online (Bootstrap or similar) CSS definitions to my ESP at runtime. Because then it will fail if there’s no Internet connection. One of the reasons to do this project to begin with, was to make it suffice with a local network

The circuits4you code is a bit hard to understand, partly because there are about 10 different variables and handlers with similar names, partly because of the involved parallel code structures in HTML, Javascript and C. That’s why people hate web development. Also there were some small errors in the code :) Anyone who has done some HTML can probably spot this one:

server.send(200,”text/plane”, ledState); //Send web page

It’s not like we’re going to send an airplane to the web server. Also, data stored in Flash memory can’t be read into a C String variable like this:

String s = MAIN_page; //Read HTML contents

I changed it to:

String s = FPSTR(MAIN_page);   //Read HTML contents

Here’s the finished ESP8266 code, which is actually an Arduino sketch. It could be optimized a bit, and the States and Steps could be better clarified but still

  9bit.se 2018

// #define MQTT_USE 0

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <Ticker.h>
#include "index_html.h"

MDNSResponder mdns;

// Network credentials
static const char* ssid = "XXXXXX";
static const char* password = "YYYYYY";

ESP8266WebServer server(80);
Ticker rtc_second_ticker;
Ticker blink_ticker;
Ticker step_1_ticker;
Ticker step_2_ticker;
Ticker step_3_ticker;

static const int gpio13Led = 13;
static const int gpio12Relay = 12;

int toast_sequence_short[3]  = {100, 30, 30}; // {toast, pause, toast}
int toast_sequence_medium[3] = {130, 30, 30};
int toast_sequence_long[3]   = {160, 30, 30};
int toast_sequence_extra[3]  = {0, 0, 30};
int *sequence;

int seconds; // Counting the progress of a toast sequence

String state_name;

// ---- Ticker callbacks: ----

void led_blink()
  digitalWrite(gpio13Led, !digitalRead(gpio13Led));  //LED blink

void add_second() {

// ---- The toast program. Step durations stored in "toast_sequences" ----
// ---- Some of these functions are also ticker callbacks ----

void begin_toast() 
  seconds = 0;

void toast_step_1()
  digitalWrite(gpio13Led, LOW);  //LED on
  digitalWrite(gpio12Relay, HIGH);
  step_1_ticker.attach(sequence[0], toast_step_2);
  rtc_second_ticker.attach(1, add_second);

void toast_step_2() // Pause
  digitalWrite(gpio13Led, HIGH);  //LED off
  digitalWrite(gpio12Relay, LOW);
  // blink timer here!!
  step_2_ticker.attach(sequence[1], toast_step_3);
  blink_ticker.attach(0.5, led_blink);

void toast_step_3()
  digitalWrite(gpio13Led, LOW);  //LED on
  digitalWrite(gpio12Relay, HIGH);
  step_3_ticker.attach(sequence[2], toast_step_4);

void toast_step_4()
  // End of program
  state_name = "Stop";
  digitalWrite(gpio13Led, HIGH);  //LED off
  digitalWrite(gpio12Relay, LOW);

void end_toast()
  state_name = "Stop";
  digitalWrite(gpio13Led, HIGH);  //LED off
  digitalWrite(gpio12Relay, LOW);

// ---- Handlers initiated by http requests ----

void handleRoot() // Serve Index.html, as defined in Flash memory
  String s = FPSTR(index_html); //Read HTML contents from Flash memory
  server.send(200, "text/html", s); //Send web page

void handle_progress() // Web page wants to know the width of the progress bar
  float percent = 0;
  float len = float(sequence[0] + sequence[1] + sequence[2]);
  if(len > 0) percent = 100 * float(seconds + 1) / len;
  if(percent > 100) percent = 100;
  if(state_name == "Stop") percent = 0;  // Reset the progres bar
  String progress = String(percent);
  server.send(200, "text/plain", progress);

void handle_action() // Web page button click selects toast sequence
  String s = server.arg("action");
  int server_action_state = s.toInt();

  if(state_name == "Stop") {
    switch (server_action_state) {
      case 1:
          sequence = toast_sequence_short;
          state_name = "Short";
      case 2:
          sequence = toast_sequence_medium;
          state_name = "Medium";
      case 3:
          sequence = toast_sequence_long;
          state_name = "Long";
      case 4:
          sequence = toast_sequence_extra;
          state_name = "Extra";
      case 0:
  } else {
    if(server_action_state == 0) {
      // Stop
      state_name = "Stop";
  server.send(200, "text/plain", state_name); //Send response to web server

// ---- setup, loop ----

void setup(void) {
  state_name = "Stop";
  sequence = toast_sequence_short;

  // preparing GPIOs
  pinMode(gpio12Relay, OUTPUT);
  digitalWrite(gpio12Relay, LOW); // Relay off

  pinMode(gpio13Led, OUTPUT);
  digitalWrite(gpio13Led, LOW);  //LED on

  WiFi.begin(ssid, password);

  Serial.print("Connecting to ");

  while (WiFi.status() != WL_CONNECTED) {

  // Create a static ip adress
  IPAddress static_ip(192, 168, 10, 92);
  IPAddress gateway_ip(192, 168, 10, 1);
  IPAddress subnet_mask(255, 255, 255, 0);
  WiFi.config(static_ip, gateway_ip, subnet_mask);

  Serial.print("IP address: ");

  if (mdns.begin("esp8266", WiFi.localIP())) {
    Serial.println("MDNS responder started");

  server.on("/", HTTP_GET, handleRoot);
  server.on("/select_action", handle_action);
  server.on("/progress_update", handle_progress);

  Serial.println("HTTP server started");

  digitalWrite(gpio13Led, HIGH);  //LED off

void loop(void) {

And here’s the code for the HTML page. It needs to sit in a file called index_html.h next to the main sketch file

static const char index_html[] PROGMEM = R"=====(
<!DOCTYPE html>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
    box-sizing: border-box;
label {
    padding: 12px 12px 12px 0;
    display: inline-block;
button {
    background-color: #1080AF;
    color: white;
    width: 100%;
    padding: 32px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    float: left;
    margin-top: 12px;
    margin-bottom: 12px;
button:hover {
    background-color: #00608F;
.container {
    border-radius: 5px;
    padding: 20px;
    width: 300px;
.row:after {
    content: '';
    display: table;
    clear: both;
.progress-container {
	background: #d0d0d0;
#progress-bar {
@media screen and (max-width: 600px) {
    container {
        width: 100%;
        min-height: 50px;

<div class='container'>
  <div class="progress-container"">
	<div id="progress-bar"></div>
  <span id="display"> </span>
  <div class='row'>
    <button type="button" name="Short" onclick="sendData(1)">SHORT (120 + 30s)</button>
  <div class='row'>
    <button type="button" name="Medium" onclick="sendData(2)">MEDIUM (160 + 30s)</button>
  <div class='row'>
    <button type="button" name="Long" onclick="sendData(3)">LONG (180 + 30s)</button>
  <div class='row'>
    <button type="button" name="Extra" onclick="sendData(4)">EXTRA (30s)</button>
  <div class='row'>
    <button type="button" name="Stop" onclick="sendData(0)">STOP</button>

function sendData(data) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      // document.getElementById("display").innerHTML = this.responseText;
      if(this.responseText == "Stop") {
        var elem = document.getElementById("progress-bar");
        elem.style.width = '0%';
  xhttp.open("GET", "select_action?action="+data, true);

setInterval(function() {getData();}, 2000); //2000 mSeconds update rate

function getData() { // The progress bar
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
  	  var elem = document.getElementById("progress-bar");
      elem.style.width = this.responseText + '%'; 
  xhttp.open("GET", "progress_update", true);


Upper Left is the Sonoff. The Green Led shows the state: On for Toast, Flashing green for Pause

Helpful links

Reprogram Sonoff Smart Switch with Web Server

ESP8266 ajax – update part of web page without refreshing

ESP8266 Timer / ticker examples

Doepfer MCV4 Mod for Roland SH5

It seems Doepfer cut some corners when designing the MCV4 MIDI to CV interface. Firstly the MCV4’s gate voltage is to low to drive the Roland SH5 gate input. This can be remedied by opening up the interface to move a jumper, and then replacing the 9v power supply with a 12 volt one. After that the MCV4 controlled the SH5 gate and Pitch CV as expected. But it had no effect on the filter at all. That is because the output from the DAC isn’t buffered, and the DAC itself cannot drive the load of the Filter CV input. An MCP6002 OpAmp was connected as a basic voltage follower to buffer the Note Velocity output.

Beware that the image shows an unsuccessful experiment with a TL072, that has a different pin configuration.

Don’t use this image as a guide for connecting the MCP6002!

Kawai R-100 MIDI-Controlled Pitch and Circuit Bend Mod

A mid-80’s drum machine, modified for MIDI-controlled sound chip selection, circuit bending and pitch. Any MIDI sequencer or keyboard can be used. No changes are made to the exterior of the machine.

The Kawai R-100 drum machine classic was modified using an Arduino Nano, the circuitbenders.co.uk “R-ROM Switcher” and a HC-SR08 board. The Nano reads incoming note data on MIDI channel 2 to control the HC-SR08 and ROM Switcher board. Incoming MIDI data can

  • Control the playback pitch of the entire machine
  • Select sound ROM chip
  • Control a couple of the circuitbend connection points

The pitch mod: The HC-SR08 is a development board for the Analog Devices AD9850 Direct Digital Synthesis chip. The output DDS frequency is controlled by The Nano, reading MIDI notes and pitch bend. The output square wave is used as a clock signal for the R-100’s Address Generation Unit. This means that when the Kawai R-100 tries to play any sound, the rate at which the sound sample data bytes are found in memory is set by the 9850 output.

Actually this can be done without the HC-SR08, only using a pwm output on the Nano. This is how I originally tested the idea. But while this would work fine for very low pitches, the closer you’d get to the R-100’s original pitch, the less pitch resolution you would get. Since I wanted to be able to play it in a resolution of semi-tones (or even cents, using pitch bend) I had to use a higher resolution clock generator :)

The circuit bend: There are pre-made circuit bend points in the ROM Switcher pcb. It’s sufficient to have the Nano connecting these points to ground, they don’t need to be interconnected. To get back to non-circuit bent sound, the Nano pins are left in a floating state. The sound quality of the bends are much like a comb filter or phaser.

The ROM chip selection: To enable one ROM chip, the original ROM-Switcher connects the Output Enable (or possibly Chip Enable) pin of that chip to ground. Others are in HIGH state. A very simple task for a microcontroller.

Instruments for exhibition – Control Surface

Two unusual electronic instruments that were part of a greater ensemble, built for an exhibition in China. Idea and hardware by Daniel Araya. Programming and I/O-electronics by 9bit.

The MIDI Control Surface

The Control Surface is a Standard MIDI Interface compliant unit, built to interface with a MAX MSP patch on a host computer. The Control Surface has about 40 faders, knobs, switches, touch controls and a status LED that is controlled from within MAX MSP.

Testing the first of the eight really nice capacitive touch controls

This is testing MUXes and SPI port expansions on a CNC-made prototype PCB. MIDI on the Arduino Uno was only implemented as “MIDI over USB”, since it was not to be connected directly to other MIDI-capable instruments, only to a computer running host software.

Boxing it…

Instruments for exhibition – Metronomes

Two unusual electronic instruments that were part of a greater ensemble, built for an exhibition in China. Idea and hardware by Daniel Araya. Programming and I/O-electronics by 9bit.

The Metronomes

Three metronomes were built, one master and two slaves. The tempos of the slave units are synced to the master but the beat patterns that they play differ. The pattern generation algorithms used are mostly Euclidean Polyrhythms of varying lengths and “densities”. Thank’s to Wouter Hisschemöller’s page for cutting my firmware dev time.

The master unit features a tempo knob, sync-to-slave output, metronome beep, metronome light flash, DMX output.

The slave units feature a pattern length knob, pattern density knob, sync-to-master input, metronome beep, metronome light flash, DMX output.

Analyzing a DMX signal

DMX sync test

Wrapping it up

Avrdude – Burn fuses (16 MHz clock out on CLK0 / B0)


Fuses. There are a couple of user selectable operation modes of the AVR microcontrollers. The fuses can’t be edited in the same way you normally program you Arduino. You will need a hardware AVR programmer, ie the one described here: Arduino as ISP. There are a few GUI softwares that are supposed to do this, but I couldn’t get any of the Mac OS X ones to connect to my Arduino/Genuino Uno, so I used AvrDude from the Terminal.

I wanted to do this in order to get a 16 MHz clock output on the Arduino Digital pin 8 / B0 / CLK0. This signal was to be used as a Reference Clock for the AV9110 Serially Programmable Frequency Generator.


Parts list

• AVR Programmer
• Arduino Uno
• AvrDude software


Setting (aka Programming) the fuses

Step 1, find out the new fuse settings
Use this site to get the hex numbers for your new fuse settings: http://www.engbedded.com/fusecalc (If you don’t understand the contents of this site you need to read your AVR docs, search the web, or ask yourself if you really need to change any fuses.)

Step 2, burn the fuses with AvrDude

In your shell, type avrdude. (If it says unknown command or similar, you need to CD to the directory where AvrDude is on your Mac.) If it presents a list of AvrDude parameters you’re good to go. This command changes the CKOUT fuse so the system clock is output on B0:

avrdude -c stk500v1 -p m328p -P /dev/cu.wchusbserial410 -b 19200 -U lfuse:w:0xBF:m -U hfuse:w:0xD2:m -U efuse:w:0x04:m 
-c stk500v1 (programmer is Arduino as ISP)
-p m328p (Microcontroller name)
-P /dev/cu.wchusbserial410 (port name)

The above settings can be gathered from the output of the Arduino IDE when uploading a sketch to your Arduino. Please turn on “Verbose Output when uploading”.

lfuse:w:0xBF:m -U hfuse:w:0xD2:m -U efuse:w:0x04:m (New fuse settings)

These are the new fuse settings from http://www.engbedded.com/fusecalc. I was mainly interested in CKOUT = true. Setting the fuses wrongly can make your Arduino unresponsive. Please read up on which fuses NOT to change, prior to experimentation.

Analog Joystick

Connect an analog joystick to an Arduino. Read two analog values (x- and y-position) and a switch using a method witch does not hog the processor during the whole ADConversion.

The capacitor reduces digital noise on the analog readings.


static const byte ADC_CHANNEL_JOYSTICK_X = 0;
static const byte ADC_CHANNEL_JOYSTICK_Y = 1;

static const byte ADC_CHANNEL_MAX = 2;

byte adc_channel = 0;
bool joystick_button = 0; // 1 or 0
uint16_t joystick_x = 0; // 0~1023
uint16_t joystick_y = 0; // 0~1023

void setup() {
 Serial.begin(115200); // Remove
 pinMode(A0, INPUT); // Analog pin A0
 pinMode(A1, INPUT); // Analog pin A1
 pinMode(2, INPUT_PULLUP); // Digital pin 2
 // Setup adc
 ADCSRA |= 1 << ADEN; // Enable ADC, with no interrupt!
 ADCSRA |= ((1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0)); // Main clock / 128
 ADMUX = adc_channel; // Channel
 ADMUX |= 1 << REFS0; // Aref pin -> 100nF -> gnd
 ADCSRA |= 1 << ADSC; // Start first conversion

void loop() {
 byte changed = 0;
 // Analog
 if ((ADCSRA & (1 << ADSC)) == 0) { // ADC done
 changed += read_analog();

 // Digital
 changed += read_digital();

 // Tmp
 if(changed > 0) {
 Serial.print("x: ");
 Serial.print("y: ");
 Serial.print("button: ");
 delay(100); // Remove

byte read_digital() {
 byte state = 0;
 byte val = !(bool)(PIND & 0b00000100); // PORT IN D, pin nr 2
 if(val != joystick_button) {
 state = 1;
 joystick_button = val;
 return state;

byte read_analog()
 byte state = 0;
 uint16_t val = ADC; // ADC is the full 10-bit, two-register, value from the last ADConversion
 switch(adc_channel) {
 if(joystick_x != val) {
 state = 1;
 joystick_x = val;
 if(joystick_y != val) {
 state = 1;
 joystick_y = val;

 if(adc_channel >= ADC_CHANNEL_MAX) adc_channel = 0;
 ADMUX = adc_channel; // Channel
 ADMUX |= 1 << REFS0; // Aref pin -> 100nF -> gnd
 ADCSRA |= 1 << ADSC; // Start next conversion
 return state;