Saturday, November 10, 2007

More pots and switches to midi data

This post is a follow on post to the previous one.

This is an update to the analog and digital inputs to MIDI data sketch. The update allows one to select individual channels for each controller as well as individual on and off controller values for each digital switch. This sketch has not been tested.

The new variable arrays are:
byte ana_channel[] = {1, 1, 1, 1, 1, 1, 1, 1}
This array sets the channel numbers for the pots 1 - 8.

byte dig_channel[] = {1, 1, 1, 1, 1, 1, 1, 1}
This array sets the channel numbers for the switches 1 - 8

byte cc_on_byte[] = {127, 127, 127, 127, 127, 127, 127, 127}
This array sets data to send if button is pressed for switches 1 - 8

byte cc_off_byte[] = {0, 0, 0, 0, 0, 0, 0, 0}
This array sets data to send if button is depressed for switches 1 - 8

Arduino Code

/*
Digital and Analog Data to MIDI Output
by Sebastian Tomczak
Adelaide, Australia

Created: 8 November 2007
Modified: 9 November 2007
*/


// MIDI CHANNEL NUMBERS, CONTROLLER NUMBERS AND CONTROLLER VALUES VARIABLE ARRAYS

byte ana_cc[] = {
0, 1, 2, 3, 4, 5, 6, 7}
; // set controller numbers for the pots 1 - 8

byte dig_cc[] = {
8, 9, 10, 11, 12, 13, 14, 15}
; // set controller numbers for the switches 1 - 8

byte ana_channel[] = {
1, 1, 1, 1, 1, 1, 1, 1}
; // set the channel numbers for the pots 1 - 8

byte dig_channel[] = {
1, 1, 1, 1, 1, 1, 1, 1}
; // set the channel numbers for the switches 1 - 8

byte cc_on_byte[] = {
127, 127, 127, 127, 127, 127, 127, 127}
; // set data to send if button is pressed for switches 1 - 8

byte cc_off_byte[] = {
0, 0, 0, 0, 0, 0, 0, 0}
; // set data to send if button is depressed for switches 1 - 8


// 4021 DIGITAL I/O PINS

byte latchPin = 10;
// set the latch pin

byte clockPin = 11;
// set the clock pin

byte dataPin = 12;
// set the data in pin


// INTERNAL VARIABLES

byte data_ana_cc[] = {
255, 255, 255, 255, 255, 255, 255, 255}
; // keep track of analog data

byte data_dig_cc[] = {
0, 0, 0, 0, 0, 0, 0, 0}
; // keep track of digital data

byte data = 0;
// variable for general use

byte digital_data = 0;
// variable to store the state of the 8 switches

byte state = 0;
// variable to store the data that is shifted in


// BEGIN SETUP

void setup() {
Serial.begin(31250);
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);

pinMode(latchPin,OUTPUT);
pinMode(clockPin,OUTPUT);
pinMode(dataPin,INPUT);

digitalWrite(latchPin,HIGH);
digitalWrite(clockPin,HIGH);
}


// BEGIN MAIN PROGRAM

void loop() {
delayMicroseconds(20);
digitalWrite(latchPin, 0);
for (byte j = 7; j >= 0; j--)
{
digitalWrite(clockPin, 0);
delayMicroseconds(20);
state = digitalRead(dataPin);
if (state) {
if(data_dig_cc[j] != 1) {
Serial.print(175 + dig_channel[j]);
Serial.print(dig_cc[j]);
Serial.print(cc_on_byte[j]);
data_dig_cc[j] = 1;
}
}
else {
if(data_dig_cc[j] != 0) {
Serial.print(175 + dig_channel[j]);
Serial.print(dig_cc[j]);
Serial.print(cc_off_byte[j]);
data_dig_cc[j] = 0;
}
}
digitalWrite(clockPin, 1);
}
digitalWrite(latchPin, 1);
for(byte i = 0; i <= 7; i++) { PORTD = i * 4; data = analogRead(0) >> 3;
if(data_ana_cc[i] != data) {
Serial.print(175 + ana_channel[i]);
Serial.print(ana_cc[i]);
Serial.print(data);
data_ana_cc[i] = data;
}
}
}

10 comments:

Brian Durocher said...

This project is fantastic. Is there a way to make a 16-step version as well. I am trying to make a sequencer for a VCO that generates sin, tri and square waves using the Arduino as a controller. Do you have suggestions?

Sebastian Tomczak said...

Hi there Brian,
If with 16 step you mean 16 pots, then yeah - easy.

Add another 4051 and simply connect the common output to Arduino analog in 1.
Naturally, the code will need some adjustment, but you get the idea.

How are you planning on controlling the VCO from the Arduino?

Sebastian Tomczak said...

Hang on, the code will need quite a bit of adjustment.

But very easy and very doable. The only question is; how are you planning on controlling the voltage using the analog data from the pots using the Arduino? Perhaps an 8 bit digital pot that is acting as a voltage divider from ground to supply might be appropriate?

Brian Durocher said...

The project is based on an old ICL8038 chip. The VCO will be controlled by either a 555 or 556 similar to the Atari Punk Console project. But i will need to add an ADSR, or some sort of pulse width.

Have you posted the code for your project? The only work I have done with the Arduino this far is a wearable jacket that uses RGB leds. This audio thing is quite new to me.

blahger said...

Phwoar, this looks the ducks guts :)))

JMarler said...

I am using your basic design to build a MIDI controller with 16 pots and 8 buttons. I did my code a bit different, using the Arduino playground code for decoding the 4051 but it is very similar. I have the first version up and running on a breadboard. I'll be moving to protoboards and a makeshift box for the next evolution. I have a picture of the prototype here.

My loop code looks like this:

void loop() {
delayMicroseconds(20);

for(byte i = 0; i <= 7; i++) { // Loop to iterate through all 8 input pins on the 4051
// Setup the 4051 to read the pin we want
row = bin[i];
r0 = row & 0x01;
r1 = (row>>1) & 0x01;
r2 = (row>>2) & 0x01;
digitalWrite(s0pin, r0);
digitalWrite(s1pin, r1);
digitalWrite(s2pin, r2);

// Read in the value from the 4051
data = analogRead(zpin)/8;
if(data_ana_cc_a[i] != data) {
Serial.print(status_byte);
Serial.print(ana_cc_a[i]);
Serial.print(data);
data_ana_cc_a[i] = data;
digitalWrite(LEDpin, HIGH);
delay(50);
digitalWrite(LEDpin, LOW);
delay(50);
}
}
}

I am using the same types of arrays that you used in your example here. I have two of them setup, one for each 4051 with pots, and one for the third 4051 that will have buttons.

I blink an LED once every time I send a MIDI value for debugging ... and it just looks cool :)

I'll post more pics as the project progresses. It's an xmas present for a buddy of mine.

Jesse said...

One thing i don't understand is:

How are your reading the value from the pots?

-Thanks

Vik said...

so what happened since 2007? Has it been tested?

Vik said...


Hi, I'm a beginner in electronics and I have built this project. On Arduino I get this error message:

sketch_sep04c:0: error: expected constructor, destructor, or type conversion before '&&' token
sketch_sep04c.cpp: In function 'void loop()':
sketch_sep04c:68: error: 'status_byte' was not declared in this scope
sketch_sep04c:76: error: 'status_byte' was not declared in this scope
sketch_sep04c:88: error: 'status_byte' was not declared in this scope

(I have replaced the switch with buttons...)

Besides, in the monitor view's baudrate menu 31250 does not show.

Is there anybody out there to help?:88: error: 'status_byte' was

Vik said...

Is this project not supported anymore? obsolete?