Recent site activity

My Stuff‎ > ‎

40106 Oscillator controlled by digital potentiometer

This project might be interesting to you if you're trying to interface an analog (e.g. resistance or voltage controlled synth) to a microcontroller, perhaps to drive the synth via MIDI....
 
 
 
The basic circuit is a 40106 oscillator comprising 40106 (Hex Inverter), 0.1uF capacitor, 100K potentiometer and 5V power supply. I am playing mine through an external amplifier. See http://hackaday.com/2008/05/01/how-to-make-a-digital-synthesizer/ for ideas on building the basic oscillator
 
To make it play a tune, I replaced the 100K potentiometer with an Analog Devices AD5242BRZ100 digital potentiometer. At the time I could only get the SOP16 surface mount component and had to use an adaptor board (nightmare!). Still, its a natty little IC. Here it is, crudely (and painfully) soldered onto the adaptor
 
 
 
This is a dual digi-pot which can dial up 2 separate resistances between 0-100K on a granularity of 256 graduations, so pitch translation is not going to be perfect :)
 
You communicate with the digi-pot via I2C serial link. I drove it from an Arduino clone using the Arduino "wire" library which makes this whole process pretty easy. First off though, here is how I wired up the digi-pot
 
  • VDD (5) = Supply voltage (5V out from Arduino)
  • Inv.ShDn (6) = Tied to VDD
  • Serial Clock / SCL (7) = connected to analog input pin A5 of Arduino (as required by wire lib)
  • Serial Data / SDA (8) = connected to analog input pin A4 of Arduino (as required by wire lib)
  • A2 (16) , W2 (15) = Connected in place of potentiometer in the 40106 oscillator circuit
  • VSS (12) = 0V from Arduino
  • DGND (11) = Tied to VSS/0V
  • AD1 (10) = Tied to VSS/0V
  • AD0 (9) = Tied to VSS/0V
  • Other pins not connected.
On the Arduino the code to play the tune is as follows
 
#include <Wire.h>
void setup()
{
  Wire.begin(); // join i2c bus
}
// These are the digi-pot resistor values (0-255) that I worked out
// correspond to each note
byte note[25] = {
    60,  // C  0
    75,  //    1
    87,  // D  2
    93,  //    3
    105, // E  4
    115, // F  5
    124, //    6
    130, // G  7
    139, //    8
    144, // A  9
    151, //    10
    157, // B  11
    163, // C  12
    167, //    13
    173, // D  14
    177, //    15
    184, // E  16
    188, // F  17
    191, //    18
    195, // G  19
    199, //    20
    202, // A  21
    205, //    22
    208, // B  23
    211  // C  24
};
// this is the captain pugwash tun in note values (0-24). Pauses not currently supported!
byte tune[] = {
   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 19, 16, 16, 12, 16, 16, 19, 24, 24, 19, 16, 16, 12,
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 14, 11,  11, 7, 11, 11, 14, 17, 17, 14, 11, 11, 7,  
   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 19, 16, 16, 12, 16, 16, 19, 24, 24, 19, 16, 16, 12,
   12, 12, 24, 23, 23, 21, 19, 19, 17, 16, 16, 14, 12, 12, 12, 16, 16, 16, 12, 12, 12, 16, 16, 17,
   19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 21, 21, 23, 24, 24, 23, 21, 21, 19, 17, 17, 16,
   14, 14, 16, 17, 17, 16, 14, 14,  7,  9,  9, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 24, 23, 23, 21, 19, 19, 17, 16, 16, 14,
   12, 12, 12, 16, 16, 16, 12, 12, 12, 12, 12, 12, 12, 12
  
}  ;
// This is the I2C identifier for a digi-pot with AD0=0 and AD1=0
#define POT00  0b0101100
byte i=0;
void loop()
{
  // get the current note number
  byte j = tune[i];
 
  // Send out the I2C packed to the digital potentiometer
  Wire.beginTransmission(POT00); // transmit to device
  Wire.send(0b10000000);            // sends instruction byte 
  Wire.send(note[j]);             // sends potentiometer value byte 
  Wire.endTransmission();     // stop transmitting
  // step to next note
  if(++i >= sizeof tune)
    i=0; 
 
  delay(100);
}
 
Note that the digi-pot resistance values in the note[] array might need to be "tuned" if your 40106 oscillator plays different to mine... I worked these out by varying the resistance while I played each note of a scale on an electronic keyboard. I picked out note values that were approximately in tune with each key.. its always going to be a bit approximate anyway with the discrete steps used by the digi-pot
 
Here is a photo of the full circuit. The Arduino clone is one of Tom Scarff's MIDUINO boards. I am running the 40106 on an external 5V desktop supply.