Video URL:
http://youtube.com/watch?v=ZvP9OOhNrh0Length: 1:40
A simple single-channel, 8 step standalone step sequencer that is controlling a Nintendo running a
MIDINes cart.
I ran out of pots, that is why there are only 8 notes (instead of my desired amount of 16). The pots on the right are the 8 notes. The top right one is note 1, the bottom right one is note 4, the top left one is note 5 and the bottom left one is note 8.
On the left are the pots that control the following functions (from top to bottom):
1. the length of time between two notes
2. the octave
3. the length of a note
4. the length of the loop
5. the duty cycle of the NES' pulse wave
The sequencer always plays in A
Aeolian (the white notes on a piano keyboard).
[expand / collapse code]
/*
MIDI Step Sequencer
by Sebastian Tomczak
10 June 2007, Adelaide, Australia
*/
// pin naming
int pitch_in = 0; // analog input
int tempo_in = 1; // analog input
int octave_in = 2; // analog input
int note_length_in = 3; // analog input
int loop_length_in = 4; // analog input
int duty_cycle_in = 5; // analog input
// pitch array
byte pitch_array[16] = {
0, 21, 23, 24, 26, 28, 29, 31, 33, 35, 36, 38, 40, 41, 43, 45 }; // base MIDI values
// operations
byte set_port; // setting portd for multiplex
byte loop_length = 7;
byte pitch = 0;
byte pitch_data = 0;
byte octave = 0;
byte duty_cycle = 0;
int note_length = 0;
int pause_length = 0;
// MIDI command bytes
byte CC_1_B1 = 176; // control number channel out
byte CC_1_B2 = 1; // control number data
// begin setup
void setup() {
Serial.begin(31250); // open serial port at MIDI baud rate
pinMode(2,OUTPUT); // connected to 4051 control pin C (LSB)
pinMode(3,OUTPUT); // connected to 4051 control pin B
pinMode(4,OUTPUT); // connected to 4051 control pin A (MSB)
}
// begin main loop
void loop() {
for(byte a = 0; a <= loop_length; a++) { // begin loop
duty_cycle = analogRead(duty_cycle_in) / 8; // read duty cycle into byte
Serial.print(CC_1_B1); // send byte 1
Serial.print(CC_1_B2); // send byte 2
Serial.print(duty_cycle); // data
set_port = a * 4; // ignore RX and TX byte for the PORTD command
PORTD = set_port; // set pins 2, 3, 4 to a binary value between 0 and 7
pitch = analogRead(0) / 64; // read pitch value into byte
octave = analogRead(octave_in) / 256; // read octave into byte
octave = (octave * 12) + 24; // now in semitones!
pitch_data = pitch_array[pitch]; // lookup array for pitch (A aeolian)
if (pitch_data == 0)
{
note_length = (analogRead(note_length) / 4) + 20;
delay(400);
pause_length = (analogRead(tempo_in) / 2) + 20;
delay(400);
} // dont play anything if 0!
else // play something if not 0!
{
pitch_data = pitch_data + octave; // get actual pitch
Serial.print(144, BYTE); // send byte 1
Serial.print(pitch_data, BYTE); // send pitch data
Serial.print(127, BYTE); // send velocity
note_length = (analogRead(note_length_in) / 4) + 20;
delay(note_length); // delay before turning the note off
Serial.print(144, BYTE);
Serial.print(pitch_data, BYTE);
Serial.print(0, BYTE);
pause_length = (analogRead(tempo_in) / 2) + 20;
delay(pause_length); // delay before turning playing the next note
}
loop_length = analogRead(loop_length_in) / 128;
if(a > loop_length) {
a = 0;
}
}
}
3 comments:
So simple, and so cool at the same time :-)
The Arduino Rocks!
~ Marcus
www.littlebirdelectronics.com
my point exactly.
Well, I don't actually think this is likely to have effect.
Post a Comment