Close

Log 3 - The Mini Controller.

A project log for SynBlox : Low Cost Modular Music Synthesizer

Modular Synths are expensive and complicated. I propose a low-cost, entry-level/educational system to make the basics available to anyone.

john-schuchJohn Schuch 04/23/2018 at 07:490 Comments

The Mini Controller provides the two basic control signals used by the modular synth; A variable voltage that would likely be used to set the pitch of a voltage controlled oscillator, and a trigger used to initiate envelopes, sequences, or any number of things. 

It would be very easy to presume that all we need is a potentiometer set up as a voltage divider to provide the Control Voltage (CV), and a simple push button to create the trigger.  If only things were that easy.

The pot for a variable voltage is fine, but we have no idea what an end user is going to plug this control signal into. More importantly, the load of whatever they are going to use. This unpredictable load means that we can not predict the output of the controller. 

As for the trigger, if all we wanted to do was gate an audio signal, or trigger an envelope generator, a simple push button would probably work fine. The issue is if the user wants to plug this trigger source into a sequencer, or some other logic based device. For a sequencer, any electrical bounce in the switch is likely to send it to some random state, rather than the next step.

The lower half of the schematic is the control voltage circuit. You can see we have a 100K pot set up as a voltage divider as you would expect, but now we feed it into a buffer. The MCP601 op-amp is set up as a voltage follower. That is, whatever voltage level is presented to the non-inverting input will be sent to the output. But the input impedance of the op-amp is very high and will not change with changes in output load, so the voltage level generated by the pot will remain stable and predictable. 

The upper half of the schematic is our trigger circuit. There are a LOT of ways to debounce a push button switch, and this is my favorite. A PIC10F200 is dirt cheap, and using software to debounce the switch give us all sorts of variability and control. In this circuit we're going for the simplest application; just debounce the switch and send the output on it's way.

The code to do this is so small I'm going to include it right here ...

/**************************************************************************
 * File:   debounce.c
 * Author: John Schuch
 * File Version : 1.0
 * Created on April 14, 2018, 3:00 PM
 * 
 * This software is released as PUBLIC DOMAIN. No rights reserved
 * 
 * ************************************************************************
 *  Target           : PIC10F200
 *  Compiler         : MPLAB X v3.45 (free mode)
 *  Additional files : NONE
 * 
 *  Description :   Provides debounce of the pushbutton on the SynBlox
 *                  mini controller, part of my submission to the 2018
 *                  Hackaday Prize contest.
 * 
 *  Pins :  PIN 1 : N/C
 *          PIN 2 : Vdd
 *          PIN 3 : GP2 - pushbutton input, 10K pull up
 *          PIN 4 : GP1 (ICSP clk) output, indicator LED
 *          PIN 5 : GP0 (ICSP data) Module trigger output
 *          PIN 6 : N/C
 *          PIN 7 : Vss
 *          PIN 8 : GP3 (ICSP Vpp)
 * 
 */

# include <xc.h>
# include <pic10f200.h>

// CONFIGURATION ------------------------------------------------------------
#pragma config WDTE  = OFF      // Watchdog Timer (WDT disabled)
#pragma config CP    = OFF      // Code Protect (Code protection off)
#pragma config MCLRE = OFF      // Master Clear Disabled

// MAIN PROGRAM -------------------------------------------------------------
 void main(void) {
     
     // Initialization 
     TRIS = 0b1100;                 // Set GP0 & GP1 as outputs
     int Out_State = GPIObits.GP2;  //read initial button state
     GPIObits.GP0 = Out_State;      //write initial Out_State to output
     GPIObits.GP1 = Out_State;      //write initial Out_State to LED indicator
     int count = 0;                 //loop counter for bounce
     
     // Main Loop 
     for(;;) 
     {
         while (Out_State == GPIObits.GP2) {} 
                            //wait for button (GP2) to change
         
         while ((count++ <= 200) && (Out_State != GPIObits.GP2)) {}
                            //wait for button (GP2) to be stable for 200
                            //loops or button to revert to it's previous
                            //state (bounce event) 
         
         if ( count <= 199) //if we didn't get to 200 loops this was a
            { count = 0; }  //bounce event. Clear count and loop
         else
            {               //if we hit 200 loops, we are confident that
                            //the button changed state and is now stable.
             
            Out_State = GPIObits.GP2; //write GP2 state to Out_State
            GPIObits.GP0 = Out_State; //write Out_State to output
            GPIObits.GP1 = Out_State; //write Out_State to LED indicator
            count = 0;                //clear count and loop
            }
     }
 }
 

After breadboarding both circuits and getting the code just right, I built the controller on one of my PIC dev boards (see Log #1). 

Construction was uneventful, though I really need to find a way to cut cleaner square holes in these boxes for the RJ-11 connectors. With everything buttoned up, and using the power supply from the last build log, both the CV output and the Trigger output worked perfectly.

Next up... I have the audio amplifier on the breadboard and working, so it's time build that into it's case!

PARTS USED:

Discussions