Thursday, 13 February 2014

Sorting Capacitors

I ordered some small value ceramic capacitors from ebay. for the princely sum of £3 I got 50 different values, 20 of each type including postage and packing! A bargain I though, until I came to the problem of how to organise them so I could use them. I really have run out of cash this month so didn't want to get ripped of buying another rubbish plastic monstrosity from Maplins. The solution I found was much more elegant ;)
Writing the resistor code number on left me with only the simple addition of a paper clip on each bag, then a bit of string strung up in my lab, hey presto, capacitor sorting method! Now when I come to picking a capacitor it is as easy as choosing a sirt from the wardrobe (and worryingly similar) :) 

Monday, 3 February 2014

Midi to CV - Arduino Code

So, I have written the code that handles the MIDI in and whacks a CV out. This very basically chucks out a number to the DAC that is based on a lookup table. At the moment the values in the lookup table are junk, and that's OK, because the ICL8038 is not looking like it is going to be as precise as I want it to be, so this will give me the ability to be flexible with it, when I find out what it needs.


#include  // this library has the "ShiftOut" command in it
#include  // Add Midi Library

#define gatePin 13
#define midiIn 0
#define clockPin 5
#define dataPin 6
#define latchPin 4
#define midiSwitchPin 2
#define cvPot A0
#define sweepSwitchPin 3
int oldNote;            // this is the last value that we did set
int newNote;            // this is the value we want to set
int noteCount;          // here we will count how many notes we have pressed at any one time
int midiLookup[144]     // here we define the MIDI lookup table, this is 12x12 (12 octaves)
                        // and will define C-2 to C10 (NOTE: This table WILL need adjusting)
= {   12,   13,   14,   15,   16,   17,   18,   19,   20,   21,   22,      // Octave -2
      23,   24,   25,   26,   27,   28,   29,   30,   31,   32,   33,      // Octave -1
      34,   35,   36,   37,   38,   39,   40,   41,   42,   43,   44,      // Octave 0
      45,   46,   47,   48,   49,   50,   51,   52,   53,   54,   55,      // Octave 1
      56,   57,   58,   59,   60,   61,   62,   63,   64,   65,   66,      // Octave 2
      67,   68,   69,   70,   71,   72,   73,   74,   75,   76,   77,      // Octave 3
      78,   79,   80,   81,   82,   83,   84,   85,   86,   87,   88,      // Octave 4
      89,   90,   91,   92,   93,   94,   95,   96,   97,   98,   99,      // Octave 5
     100,  101,  102,  103,  104,  105,  106,  107,  108,  109,  110,      // Octave 6
     111,  112,  113,  114,  115,  116,  117,  118,  119,  120,  121,      // Octave 7
     122,  123,  124,  125,  126,  127,  128,  129,  130,  131,  132,      // Octave 8
     133,  134,  135,  136,  137,  138,  139,  140,  141,  142,  143,      // Octave 9
     144,  145,  146,  147,  148,  149,  150,  151,  152,  153,  154       // Octave 10
  };
    

// Below is a function that will be called by the Midi Library
// when a MIDI NOTE ON message is received.
// It will be passed bytes for Channel, Pitch, and Velocity
void HandleNoteOn(byte channel, byte pitch, byte velocity) {
  if (velocity == 0) {//A NOTE ON message with a velocity = Zero is actualy a NOTE OFF
    noteCount = noteCount - 1;  // we remove 1 from the 'note on' count
  }
  else
  {
    newNote = midiLookup[pitch]; // set the newnote to be the value defined by the lookup table
    noteCount = noteCount + 1;   // we add one to the 'note on' count
  }
  if (noteCount >> 0)
    {digitalWrite (gatePin, HIGH);}
  else
    {digitalWrite (gatePin, LOW);}
}



void setup() {
  pinMode(clockPin, OUTPUT);        // configure the clock pin to be an output
  pinMode(midiIn, INPUT);           // configure the midi in pin to be an input
  pinMode(gatePin, OUTPUT);         // configure the gate pin to be an output
  pinMode(dataPin, OUTPUT);         // configure the data pin to be an output
  pinMode(latchPin, OUTPUT);        // configure the latch pin to be an output
  pinMode(cvPot, INPUT);            // configure the pot to be an input
  pinMode(midiSwitchPin, INPUT);    // configure the midi switch to be an input
  pinMode(sweepSwitchPin, INPUT);   // configure the sweepSwitch io be an input
  digitalWrite(clockPin, LOW);      // Here we write the clock pin to be low
  digitalWrite(latchPin, LOW);      // Here we set the latch high to tell the device we dont need it
  oldNote = 0;                      // the last value we set at this point is invalid, so we set this to 0
  newNote = 1024;                   // we want to start off somewhere sensible so ballpark? 1024
  noteCount = 0;                    // assume that all notes are off when the unit powers on
  
  MIDI.begin(MIDI_CHANNEL_OMNI); // Initialize the Midi Library.
  // OMNI sets it to listen to all channels.. MIDI.begin(2) would set it
  // to respond to channel 2 notes only.
  
  MIDI.setHandleNoteOn(HandleNoteOn); // This is important!! This command
  // tells the Midi Library which function I want called when a Note ON command
  // is received. in this case it's "HandleNoteOn".
}



void writeClockAndData (byte TopNumToSend, byte BottomNumToSend)
{
  digitalWrite(latchPin, HIGH);
  digitalWrite(gatePin, LOW);  // default position at the start is notes off
  digitalWrite(clockPin, LOW);  // we are interfacing with a device that is clocked by rising edges, so we must first set the clock pin low
  shiftOut(dataPin, clockPin, MSBFIRST, TopNumToSend);  // here we send the data top end of the data
  shiftOut(dataPin, clockPin, MSBFIRST, BottomNumToSend);  // here we send the data bottom end of the data
  digitalWrite(latchPin, LOW); // driving the latch high updates the DAC
}



void loop () { // Main loop
  oldNote = newNote; //transfere the old value into oldNote before updating newNote
  if (digitalRead(midiSwitchPin) == HIGH) {
     MIDI.read(); // Continually check what Midi Commands have been received.
  }
  else
  {
    noteCount = 0; // this is a soft reset incase we get MIDI notes stuck on, 
                   // we can flip in and out of MIDI mode to clear the problem
    digitalWrite(gatePin, LOW);  // this does a hard clear of the 'note on' count
    if (digitalRead(sweepSwitchPin) == HIGH) {
      delay(10);
      newNote = newNote + analogRead(cvPot);  // set the note to be incremented by the value of the analog pot
      if (newNote > 4096) {newNote = 0;}      // reset the sweep if it hits max.
    }
    else
    {
      delay(10);
      newNote = analogRead(cvPot);            // set the value of the note to be played to the value of the analog pot.
      newNote = newNote * 4;                  // scale the 0 to 1024 value from the pot to 0 to 4096 for the DAC
    }
  }



  if (oldNote != newNote) {                    // if the note value has changed from the last application scan...
    writeClockAndData(highByte(newNote),lowByte(newNote)); // here we set the data
  }
}

MIDI to CV circuit design

So, I am led to believe that this circuit should do the trick. I am going to lay it out on veroboard so there is enough room for tweaks in case I need to do something more to smooth the Control Voltage, but if I'm honest, I am not going to know until I start playing with the ICL8083 (waveform generator chip). At this stage I feel that its best that I get this end built up. The fine calibration is going to have to happen afterwards, when I have the 8083 to play with, because I really need to 'listen' to the results to see if they are good enough.
At the moment I'm finding progression hard because I do not have a stable platform. After I have the 3 core modules (CV, Waveform, Mixer/amp) sorted, the subsequent modules will be open to a lot more prototyping.

Description: U2 is the Arduino Chip that will need to be bootloaded and programmed up with my desired software (more discussion on this later). U7 is the opto-isolator that is required for the 'Midi In' stage. U1 is the DAC (that apparently doesn't like being de-coupled). U3 is the reference generator (the application notes in the data sheeet don't ever mention decoupling caps, but I will leave space for this on the board just in case). U8 is an op amp, I'm not sure how essential this is, but because I do not know exactly what we will be doing with the CV afterwards I thought this was a good idea to stabilise the system, hopefully I won't accidental put too much strain on the DAC. J6 J7 and R9 are the extras that will allow the right information into the arduino to create the static voltages and the sweep. J4 will we software controlled and provide a "Gate" output, 0V to +5V. This will be used later by the VCF.
This is the power and bus requirements of the circuit, R2 and R3 provide us with a split +12v and -12v power to play with, but because this circuit does not require -12v have have not included the -12v VREG. The Arduino however requires regulated +5v so I have provided one. The reason I have opted for the top end out the +24v to be used is because In the next module, the waveform generator, I would like to give the chip +/-12v, the common ground will be 0V. because all these modules will be linked I wanted the Common ground between the modules to be the same. Making 0v on the PSU -12v below the gorund for these circuits. (kinda making my +12 and +5 on my PSU bus redundant, but... Que Sera...)

MIDI to CV - Getting the DAC working

OK, so it's been a while since my last post. I found a bit of software, "NI - Multisim" for simulating my circuits, while simulating my first circuit i found that it really wasn't kicking the correct voltages out, the design was all crappy. I'd built it on veroboard and made a right mess of it. The module was only supposed to be a half way house anyway, so I have decided to scrap it and start all over again. Doing things properly and not rushing it.
Sooooo...
The first module in the system needs to generate my Control Voltage, but I want a keyboard to control it, so I thought I could use an Arduino to take MIDI in and turn it into a stable CV. I have a 12-bit DAC (LTC1257) that I found at the bottom of a cupboard gathering dust. So first things first, get the Arduino talking to the DAC.
   I wrote a little program to send the clock and data using an arduino external library calling the "ShiftOut" command. Because it's a 12-bit DAC and the shiftout command only works on bytes, I've had to split the integer in half and send both halves separately. Sorting out the endianism was a bit of a nightmare, getting my clock and data the right way round always floors me, and  controlling the 'Load' pin of the DAC HIGH or LOW at the right time so the DAC pays attention was also a challenge, but the end result is fairly positive.
   I have had to buy a scope at this stage, and I have opted (due to cheapness) for a Hantek 6022BE which is essentially just a data acquisition module that then displays its data on the computer. Quite nifty really, I'm a fan, dead cheap for what it does. Anyway, the end result you can see on the picture.

The application is driving the DAC up in steps of 90! which is massive for what seems like little change (the DAC is railed from 0v to +12v). In an effort to remove noise out of the DAC I have tried many different values of decoupling capacitors, but have found that each one of them make things worse not better. I have decided to invest in a Voltage Reference generator chip for the DAC (which is mentioned by the DAC datasheet) in the hope that it will produce a more stable voltage out.
   In addition to the MIDI in, I have decided to include a software feature that will allow a selectable voltage out or a selectable sweep speed of 0 to 12v (simply because the arduino chip has spare pins and it seems a shame not to use them.