This is quite a useful little module that based around an ATTiny85 microcontroller. I chose this approach as building the logic with discrete IC's is a bit of a chore.
So what does it do? It takes an input CV signal (0-10v) and quantises it a specific value before outputing the signal (again 0-10v).
The easiest way to describe this is to consider the input voltage as being a straight line, and the output voltage being a series of steps. Where each step is a 1/12th of a volt (hence 1v/octave scaling over 12 notes per octave). This means that quantiser simply rounds up or down the voltage value to the nearest 1/12 of octave.
To give a bit more control we added a tune knob on the front that allows the output to be pitched up between 0-12 notes (ie an octave). This allows the simple 1-12 input to be shifted in key (relative) to help tune with other instruments.
The code logic is actually quite simple:
#include <tinySPI.h>
#define CS 1
#define IN A3
#define OFFSET A2
#define CLOCK_PIN 2
#define DATA_PIN 0
#define NOTE_SF 41.67f //47.069f
void setup() {
pinMode(IN,INPUT);
pinMode(OFFSET,INPUT);
pinMode(CS, OUTPUT);
pinMode(CLOCK_PIN, OUTPUT);
pinMode(DATA_PIN, OUTPUT);
digitalWrite(CS, HIGH);
}
void loop() {
int offset = map(analogRead(OFFSET),0,1024,0,12);
int val = map(analogRead(IN),0,512,0,12);
unsigned int value = (unsigned int) ((float) (offset+val) * NOTE_SF + 0.5);
digitalWrite(CS, LOW);
shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | (value & 0xF00) >> 8);
shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, value & 0xFF);
digitalWrite(CS, HIGH);
delay(10);
}
In action below with the step sequencer and playing nicely with the DrumBrute.