Sunday, December 7, 2014

MIDI Distributor Redux

I recently finished my version of the YU SYNTH oscillator, I made quite a few convenience changes to the schematic which I' not totally sure how to write about that. I designed a new PCB and built 4 single width VCOs with those changes.

The panels were made using a subtractive Laser printing (just made that up).  Basically I painted the modules black and I used a laser to removed the paint to create the image.  because the modules are painted, they are far darker than the etched modules.

I'll have some more to say about these VCOs later.

I recently designed a MIDI distributor module which splits up incoming polyphonic  MIDI commands into monophonic MIDI commands on separate channels.  I designed it with the intention of turning my modular into a polyphonic synth.  I used the Arduino atmega328.  I recently rewrote the code to utilize the <MIDI.h> library.

Main code

the code uses the MIDI.h library but you also need to add my MIDIbuddy.h file

Sunday, September 14, 2014

What I know about etching single sided PCB's

Because I get so many questions about my PCB etching technique, I decided to dedicate a post to what works best for me. I've divided my advice into a few different sections.

Designing the trace:  There's a few things to consider while designing your PCB that will make the whole etching/transfer process more successful.  Keep your traces nice and fat.  I use Eagle Cad and I try to stick to .032" and above. You can certainly go smaller, but smaller traces are harder to repair if the transfer process results in an imperfect transfer (and it almost always does).  Along the same lines, use large pads whenever possible.  In Eagle, you can change global pad sizes with the "restring" parameter.  Give yourself plenty of space between traces and if you use a "ground pour", make sure the isolation is around the width of a trace( .032" ).

Transfer medium: I use Press-n-Peel blue transfer sheets (search "press peel blue" on ebay).  They are prices but I have yet to find anything which can transfer as well as they do.  You will need a laser printer in order to print on them.  Laser printers use a plastic toner which, when heated, can stick to the copper clad PCB board.  Wash your hands with dish soap before working with the transfer.  To save as much of the transfer paper as possible, print your design without the transfer paper,  cut out a piece of the transfer paper slightly larger than the design, use scotch tape to adhere the transfer paper over your design,  reload in printer and print again.  cut out the Transfer as close to the design as possible,  this is make it easier to place it on the copper.  Touch the transfer as little as possible.

PCB material: I buy this stuff off ebay too. Look for single sided using keywords like "copper clad" or "PCB".  If you want a flexible or more transparent PCB, try to find something around .030" or thinner.  I always prepare the board with a green scowling pad, even if it already appears to be prepared.  if you cut the PCB down to a smaller size, you're gonna want to make sure it doesn't have any raised edges, use a file to get rid of them.  When my board is prepared, I wash it with dish soap to make sure the surface is grease free.

Heat Transfer Process:  I use a griddle to do my transfers but you can use a Iron or whatever.  The temperature is very important.  I tend to set my griddle to around 270 degrees F.  Unfortunately, the griddle is not a precision machine, so you may find that you need more or less heat.  Too much heat will cause the transfer image to smear.  So will to much pressure.  I like to start with the griddle cool.

The transfer is plastic and can collect static, it's good to blow it off before you place it on the copper to clear away any dust that may have stuck to it.  For my setup, I place the copper clad material face up on the griddle with the transfer paper face down on the board.  Then I place a piece of aluminum over the board to apply pressure.  Then I place a book (or a box) on top of that, something of appropriate weight for the amount of surface area the transfer has (I know that is vague but I guess some of this is from practice/intuition).  Then I plug in the griddle and wait for the little warm up light to turn off.  if you're using something with a heating element similar to a griddle, do your best to keep your material/transfer from being directly over the heating coil.

Moment of truth:  After you are sure that the material as reached the right temperature, remove the aluminum/weight arrangement and check out your board.  I have this nice little speedball print roller I can use to make sure the transfer as made full contact with the copper clad board.  DON'T PRESS TO HARD!  After you've done a few boards, you'll get a feel for how the transfer paper looks when it has made a full transfer.  Turn off the griddle and use an oven mitt or something to removed the board.  I like to cool my board by holding it to the window.  When the board is cool, use your finger nail or something to start peeling back the transfer, anyplace where toner was, should be almost completely clear.  If, as you are removing the transfer, you notice it has not fully transferred, you can stop and place it back on the heating element and try again.

Making repairs:  I've only had a few transfer go well enough to not need any touch ups.  Use a very sharp(new) sharpie to touch up any places in which the image didn't completely transfer.  This is where having nice large traces can come in handy.  There were a few of bigger errors in this transfer because I wasn't careful about blowing the dust off the transfer when I placed it on the copper.  If you get any smearing action, or just want to clear up a trace, you can use the tip of a screw driver ( I use a dentist tool ) to scratch away any excess toner.

Ferric Chloride Etching:  You can buy ferric chloride at Radio Shack.  You'll need a tub of some kind to do your etching. I use a piece of tupperware.  Before placing the board in the tub with the ferric chloride, run it under some water and lightly rub/tap your thumb across the surface.  This will break any surface tension on the board and allow the etchant to get into all the tiny holes and lines.  Now place the board in the tub, pour enough Ferric Chloride to submerge the board.  For the next 30 minutes, agitate the Ferric Chloride by gently rocking it back and forth, I use a pencil and make a "see saw."  You can tell when the etching has finished when the board is completely transparent in all places not covered by the toner/transfer.  Keep in mind that the edges etch before the center.

Cleaning:   When your board has finished etching, pour the ferric chloride back into its container.  You want as little ferric chloride as possible to end up in the drain.  I usually rub clean the board with a paper towel, then rinse it off with water.  Now you need to remove the toner from the copper.  I like to use acetone to do this.

There you have it! Ferric chloride seems to last for a really really long time.  I've done more than 40 etches with mine and it still does the job (even though it's super dirty).

Monday, August 25, 2014

Polyphonic MIDI on a single channel to Monophonic MIDI on separate channels

UPDATE! 9/19/14  I'm working on a new version of the sketch for this project which uses the midi library.

It's been a while.  Since my last post, I've taken two C++ programming classes and hopefully it will show in my coding.  I've been working on several projects over that past few months but all of them have been big and though they have working prototypes, they remain unfinished.

I'm working on a simple MIDI controller that works like a flute/guitar.  The left hand does the fingering to select a root note and the right hand can "pluck" variations of that root.

combinations of buttons on the headstock choose a root note.  for example, when no buttons are depressed, the root note is "E".  When only the first button is depressed, the root note is "G".  The arcade style buttons on the body actually trigger a note to play.  The yellow button will play the root note.  The red button will play one step down from the root.  

In addition to my MIDI controller, I've been working on a Robot Drummer.  This project has entailed building a MIDI to Solenoid "brain" and the actual solenoid drumming mechanisms.  I chose to design a simple bracket which screws on to quick clamps that I bought at Harbor Freight.  This project also has a working prototype but I am continually finding things that need to be changed/updated. 

I have a nice video of this in action

So, I've been working a lot with MIDI lately.

My modular has a pretty simple 4 channel MIDI2CV DAC.  I've been wanting to build a new one that could handle polyphonic messages and thus allow my modular to be more polyphonic.  Instead of building a whole new MIDI2CV DAC, I thought, as a start, I'd build a little MIDI box that could take incoming polyphonic MIDI and distribute it to a selected number of channels as monophonic MIDI messages.  Here is what I came up with.

so, below is all the code needed for the distributor box.  because the Arduino IDE doesn't allow you to define a class in a sketch, I had to write my own header/library files.  I decided against the MIDI library because I couldn't really understand all the implementation.  You can copy and paste the code into text edit or whatever but you need to save the files as charlesMIDI.h and charlesMIDI.ccp,  then in the Arduino IDE,  past the main sketch into the main coding window and then under the menu labeled "sketch" you can select "add file", then choose charlesMIDI.h and charlesMIDI.ccp.


This PCB is different from ones I've done in the passed because I decided to etch the TOP copper instead of the BOTTOM.  Normally, components go through the board and and soldered onto the bottom.  I decided I wanted components and the copper on the same side.  this is why the numbers in PCB image bellow are backwards.

 I did a few alterations after I created the PCB.  The JP1 in the bottom right corner of the schematic should be collected to the other leg of the priority switch.  the diode near the power hook up(bottom left) is a 5v zener diode for power protection.  the optocoupler chip is a 6n137.  that's just about everything.

Because I have access to a laser cutter, that's how I made the box.  I'm not really sure how to post a vector file on my blog so if you are interested in the box, I can send it to you.  there is no label for mono-mode because it was an after thought.

Here is a little demo of it working.  It's a little bit ridiculous, the size of the box and circuit board I created for this project, but the whole project was a bit of a prototype for other projects in which viewing the circuit board is the focus of the device.

Well,  that's all for now folks.

Friday, March 7, 2014

Simple Arduino baby 8 sequencer with reverse and random mode

UPDATE!!!!! 9/18/14  I did some modifications to the PCB and here it is for those who would like to etch it. 

UPDATE!!!! 8/27/14 -- I apologize for the sloppy coding below.  It was written before I'd learned any standards for C++.  From now on,  I'll name variables and functions in a way to indicate how they are used (not after  my favorite movie shit).  I'll probably do a follow up to this sequencer fairly soon but as I've been using it now for many months, I can say that it has performed flawlessly. 

I've been getting into coding lately and so I thought it would be cool to come up with a modular project in which I needed to code.  This is a very simple sequencer similar to a baby 10 but instead of using a CD4017, I used an arduino programmed atmega chip.  I feel like this project was in the spirit of the modular. 

Getting the atmega chip to respond both to clock inputs and reset inputs that are triggered at the same time was the most difficult part of this project.  Unlike CMOS chips which respond instantaneously to changes at inputs, the atmega must read each input in cycles.  The cycle happens very fast but for things like clock signals in which timing is important, getting the arduino to reliable check the clock input at the correct time is difficult.

In order to "catch" the clock inputs rising edge, I initially put and if statement inside of a while statement like....

While(clock pin is low)
       if (clock pin goes high)
       { x = x +1;
The above general code worked ok but every once in a while, like when the cycles matched up with the speed of the clock, the sequencer would lose a step.  I ultimately solved this by using an attachInterrupt();

The interrupt will interrupt the main code to execute code specific to a change to one of the two interrupt pins.  I set it to interrupt on the rising edge.  I did the same for the external reset input.  unfortunately when the external reset and the clock input go high at the same time (which tends to happen often), it is somewhat unpredictable which code will take precedent, either the clock code or the reset code, and for my original code, I would get different results depending on the order.  I resolved that by rewriting the code so that it didn't matter which happened first.

int dataPin = 4;
    //data pin for shift register
int latchPin = 6;
    //latch pin for shift register
int clockPin = 5;
    //clock pin for shift register or "shiftout" 
int togglePin = 7;
    //toggle pin for direction read
int randomEnable = 8;
    //source enable pin
volatile byte count;
    //4 digit variable
byte countArray[8];
    //4 digit array with 8 spaces
boolean reset = 0;
    //boolean reset toggle variable
boolean toggleDirection = 0; 
    //boolean direction toggle variable 
volatile int j = 0;
    //variable for counting through count array
int k = 0;
int l = 0;
    //for making random non repeating
volatile int x = 1;
    //variable for counting
volatile boolean bishop = 0;
    //create a variable that can be used for clock
boolean hudson = 0; 
    //create variable used in clock function 
boolean hicks = 0; 

void setup(){
  pinMode(dataPin, OUTPUT);
    //set shift register pin to output
  pinMode(latchPin, OUTPUT);
    //set latch pin to output
  pinMode(clockPin, OUTPUT);
    //set clock pin to output
  pinMode(togglePin, INPUT);
    //set reset pin to input
  pinMode(randomEnable, INPUT);
    //set sourceEnable pin to input
  attachInterrupt(0, sigourney, RISING);
    //when pin 2 changes (rising edge) move to "sigourney" reset loop
  attachInterrupt(1, alienClock, RISING); 
    //when pin 3 changes (rishing edge) move to "alienClock" clock loop
     //read analog pin 0 for start of pseudo random sequence
  countArray[0] = 1;   //0000 0001, step 0
  countArray[1] = 2;   //0000 0010, step 1
  countArray[2] = 4;   //0000 0100, step 2
  countArray[3] = 8;   //0000 1000, step 3
  countArray[4] = 16;  //0001 0000, step 4
  countArray[5] = 32;  //0010 0000, step 5
  countArray[6] = 64;  //0100 0000, step 6
  countArray[7] = 128; //1000 0000, step 7
void loop(){    
  if(bishop != hudson){
    //limites access to this loop, once per external clock cycle until random is enabled
    hicks = digitalRead(randomEnable);
    //check to see if random mode is enabled
    if(hicks == 1){
      //if random mode is enabled then do the following
      l = k; 
      k = j; 
      //creates a history.  k is j last cycle and l is j from the cycle before
      do {
        j = random(8);
      while (j == k || j == l);
      //generate random value for j and make sure it does not match previous 2 value
  else {
    j = j + x;
    // add 1 to j
   hudson = !hudson;
  //prevents function from returning to this loop before another cycle of the external clock
  //toggle hudson
  if(j > 7) j = 0;
    //when j reachers 8, go to startpoint
  if(j < 0) j = 7;
    //when j is less than 0 go to startpoint

void sigourney(){
  j = 0;
  count = countArray[j];
    // set count eaqual to present state of starting point   
  digitalWrite(latchPin, 0);
    //ground latchPin and hold low for as long as you are transmitting
  shiftOut(dataPin, clockPin, MSBFIRST, count);
    //serial output count
  digitalWrite(latchPin, 1);
    //bring latch pin high to end transmission
void alienClock(){
  count = countArray[j];
    // set count eaqual to present state of j    
  digitalWrite(latchPin, 0);
    //ground latchPin and hold low for as long as you are transmitting
  shiftOut(dataPin, clockPin, MSBFIRST, count);
    //serial output count
  digitalWrite(latchPin, 1);
    //bring latch pin high to end transmission
  bishop = !bishop; 
  toggleDirection = digitalRead(togglePin); 
   if(toggleDirection == 1){
  x = -1;
  x = 1;

The schematic is large and hard to read as a single pictures so I broke it down to three.