XR2206 making noise!
The XR2206 sinneb 6v is making semi-controlled noise! Check these design schematics and the sounds. Very nice I think ;) The current prototype is a combination of the XR2206 prototype, microprocessor (Arduino) controlled by the MCP42100 and MCP4912. Right now I’m working on a prototype PCB to explore the musical capabilities of the 6v… Keep you posted.
Updated: Eagle schematic & PCB now available
Male pin header 6 “WAVEFORM” is the XR2206 switchboard. Shorting pin 1&2, 3&4 or/and 5&6 influences the generated waveform type. To generate the default sine wave, short pins 1&2 and 3&4 (according to schematic)
Code inspired by various internet resources, for now especially by http://little-scale.blogspot.com/2007/07/spi-by-hand.html
//sinneb.com
//4921 & 42100 arduino controlled
#define _42100SLAVESELECT 9 // ic pin 1
#define _42100SPICLOCK 10 // ic pin 2
#define _42100DATAOUT 11 // ic pin 3
#define _4921SLAVESELECT 5 // ic pin 2
#define _4921SPICLOCK 6 // ic pin 3
#define _4921DATAOUT 7 // ic pin 4
byte cmd_byte0 = B00010001; // command byte to write to pot 0, from the MCP42XXX datasheet
byte cmd_byte1 = B00010010; // command byte to write to pot 1, from the MCP42XXX datasheet
byte cmd_byte2 = B00010011; // command byte to write to pots 0 and 1, from the MCP42XXX datasheet
byte work = B00000000; // setup a working byte, used to bit shift the data out
int freq_dac = 2500;
int freq_pot = 130; // center
int incomingByte = 0; // for incoming serial data
int current_note = 69;
// 128 midi notes 0 - 127
int freq_dac_midi[] = {2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500
,2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500 // 20
,2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500
,2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500
,2500, 2500, 2500, 2500, 2500, 2890, 2881, 2875, 2862, 2853 // 50
,2836, 2830, 2815, 2803, 2786, 2778, 2761, 2748, 2731, 2712
,2697, 2677, 2656, 2632, 2609, 2584, 2558, 2531, 2500, 2500 // 70
,2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500
,2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500
,2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500 // 100
,2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500
,2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500
,2500, 2500, 2500, 2500, 2500, 2500, 2500 };
int freq_pot_midi[] = {130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130
,130, 130, 130, 130, 130, 130, 130, 130, 130, 130 // 20
,130, 130, 130, 130, 130, 130, 130, 130, 130, 130
,130, 130, 130, 130, 130, 130, 130, 130, 130, 130
,146, 146, 146, 146, 146, 146, 146, 146, 146, 146 // 50
,146, 146, 146, 146, 146, 146, 146, 146, 146, 146
,146, 146, 146, 146, 146, 146, 146, 146, 146, 146 // 70
,130, 130, 130, 130, 130, 130, 130, 130, 130, 130
,130, 130, 130, 130, 130, 130, 130, 130, 130, 130
,130, 130, 130, 130, 130, 130, 130, 130, 130, 130 / 100
,130, 130, 130, 130, 130, 130, 130, 130, 130, 130
,130, 130, 130, 130, 130, 130, 130, 130, 130, 130
,130, 130, 130, 130, 130, 130, 130 };
void SPIInitialize()
{
byte clr;
pinMode(_42100SLAVESELECT, OUTPUT);
pinMode(_42100SPICLOCK, OUTPUT);
pinMode(_42100DATAOUT, OUTPUT);
pinMode(_4921SLAVESELECT, OUTPUT);
pinMode(_4921SPICLOCK, OUTPUT);
pinMode(_4921DATAOUT, OUTPUT);
digitalWrite(_42100SLAVESELECT,HIGH); //disable 42100
digitalWrite(_4921SLAVESELECT,HIGH); //disable 4921
}
//--- MCP42100 code
void spi_transfer(byte working) {
for(int i = 1; i <= 8; i++) { // setup a loop of 8 iterations, one for each bit
if (working > 127) { // test the most significant bit
digitalWrite (_42100DATAOUT,HIGH); // if it is a 1 (ie. B1XXXXXXX), set the master out pin high
}
else {
digitalWrite (_42100DATAOUT, LOW); // if it is not 1 (ie. B0XXXXXXX), set the master out pin low
}
digitalWrite (_42100SPICLOCK,HIGH); // set clock high, the pot IC will read the bit into its register
working = working << 1;
digitalWrite(_42100SPICLOCK,LOW); // set clock low, the pot IC will stop reading and prepare for the next iteration (next significant bit
}
}
void spi_out(int SS, byte cmd_byte, byte data_byte) { // SPI tranfer out function begins here
digitalWrite (SS, LOW); // set slave select low for a certain chip, defined in the argument in the main loop. selects the chip
work = cmd_byte; // let the work byte equal the cmd_byte, defined in the argument in the main loop
spi_transfer(work); // transfer the work byte, which is equal to the cmd_byte, out using spi
work = data_byte; // let the work byte equal the data for the pot
spi_transfer(work); // transfer the work byte, which is equal to the data for the pot
digitalWrite(SS, HIGH); // set slave select high for a certain chip, defined in the argument in the main loop. deselcts the chip
}
//--- MCP4921 code
void sendIntValueSPI(int value) {
// -------------------------------------------------------------
// initiate data transfer with 4921
digitalWrite(_4921SLAVESELECT,LOW);
// send 4 bit header
sendSPIHeader();
// send data
for(int i=11;i>=0;i--){
digitalWrite(_4921DATAOUT,((value&(1<<i)))>>i);
sendSPIClock();
}
// finish data transfer
digitalWrite(_4921SLAVESELECT,HIGH);
}
void sendSPIHeader() {
// -------------------------------------------------------------
// bit 15
// 0 write to DAC *
// 1 ignore command
digitalWrite(_4921DATAOUT,LOW);
sendSPIClock();
// bit 14 Vref input buffer control
// 0 unbuffered *
// 1 buffered
digitalWrite(_4921DATAOUT,LOW);
sendSPIClock();
// bit 13 Output Gain selection
// 0 2x
// 1 1x *
digitalWrite(_4921DATAOUT,HIGH);
sendSPIClock();
// bit 12 Output shutdown control bit
// 0 Shutdown the device
// 1 Active mode operation *
digitalWrite(_4921DATAOUT,HIGH);
sendSPIClock();
}
void sendSPIClock() {
// -------------------------------------------------------------
digitalWrite(_4921SPICLOCK,HIGH);
digitalWrite(_4921SPICLOCK,LOW);
}
//--- Application code
void setup()
{
SPIInitialize(); // Initialize the SPI interface
// start serial interface
Serial.begin(9600);
sendIntValueSPI(freq_dac_midi[current_note]);
spi_out(_42100SLAVESELECT,cmd_byte2,freq_pot_midi[current_note]);
Serial.println(freq_pot_midi[current_note]);
}
void loop()
{
if(Serial.available() > 0)
{
incomingByte = Serial.read();
if (incomingByte == 49) {
freq_dac--;
sendIntValueSPI(freq_dac);
Serial.print("dac:");
Serial.println(freq_dac,DEC);
}
if (incomingByte == 50) {
freq_dac++;
sendIntValueSPI(freq_dac);
Serial.print("freq_dac:");
Serial.println(freq_dac,DEC);
}
if (incomingByte == 51) {
freq_pot--;
spi_out(_42100SLAVESELECT,cmd_byte2,freq_pot);
Serial.print("pot:");
Serial.println(freq_pot,DEC);
}
if (incomingByte == 52) {
freq_pot++;
spi_out(_42100SLAVESELECT,cmd_byte2,freq_pot);
Serial.print("pot:");
Serial.println(freq_pot,DEC);
}
if (incomingByte == 53) {
current_note--;
sendIntValueSPI(freq_dac_midi[current_note]);
spi_out(_42100SLAVESELECT,cmd_byte2,freq_pot_midi[current_note]);
Serial.println(current_note);
}
if (incomingByte == 54) {
current_note++;
sendIntValueSPI(freq_dac_midi[current_note]);
spi_out(_42100SLAVESELECT,cmd_byte2,freq_pot_midi[current_note]);
Serial.println(current_note);
}
// for (int dac=500; dac<4500; dac+=500) {
// for (int i = 0; i < 255; i+=10) {
// Serial.print("DAC:");
// Serial.print(dac, DEC);
// Serial.print(" POT:");
// Serial.println(i, DEC);
// // set 4921
// sendIntValueSPI(dac);
// delay(5);
// // set 42100
// spi_out(_42100SLAVESELECT,cmd_byte2,i);
// delay(250);
// }
// }
}
}
