User:JackApplegarth/ENES-100/project 2

My Instructor's course page which points to this.

Electronic Music Interface

Problem Statement
Design a user-friendly open interface for a synthesizer.

Week 5 Narrative
Completed the test switch circuit. The circuit design was based on the test switch circuit documented on the electronic music interface wikiversity page. The original circuit was modified by implementing more conventional resistor values for this switch type. No code for the test switch was documented on the electronic music interface wikiversity, so no modifications can be noted. Below is the code for the modified test switch.

/* * Switch and LED test program with serial monitor read out */ int ledPin = 12;               // LED is connected to pin 12 int switchPin = 2;             // switch is connected to pin 2 int val;                       // variable for reading the pin status

void setup { Serial.begin(9600);          // set up Serial library at 9600 bps pinMode(switchPin, INPUT);   // sets the digital pin as input to read switch pinMode(ledPin, OUTPUT);     // Set the LED pin as output pinMode(switchPin, INPUT);   // Set the switch pin as input }

void loop{ Serial.print("Read switch input: "); Serial.println(digitalRead(ledPin));   // Read the pin and display the value delay(100); val = digitalRead(switchPin);  // read input value and store it in val if (val == LOW) {              // check if the button is pressed digitalWrite(ledPin, HIGH);  // turn LED on  } if (val == HIGH) {             // check if the button is not pressed digitalWrite(ledPin, LOW);   // turn LED off } }

Here is a VIDEO of the completed test switch working. The next step was to implement the Midi Shield into the test switch circuit. Test hooks were attached to the Midi shield pins that were occupying the necessary arduino inputs for the test switch. It was successful. Here is VIDEO of the working test switch with the Midi shield. The test hooks are the green and yellow lead wires connected to the midi shield.

The next step for this project will be to write code that will read the switch input, and send midi code to the electric piano.

Week 6 Narrative
Used the Test Switch code as a starting point to make the MIDI Signal Code, which makes the synth play specified notes when the beat bearing test switch is engaged.

Test Switch code that was used to be modified into the MIDI Signal code

/* * Switch and LED test program with serial monitor read out */ int ledPin = 12;               // LED is connected to pin 12 int switchPin = 2;             // switch is connected to pin 2 int val;                       // variable for reading the pin status

void setup { Serial.begin(9600);          // set up Serial library at 9600 bps pinMode(switchPin, INPUT);   // sets the digital pin as input to read switch pinMode(ledPin, OUTPUT);     // Set the LED pin as output pinMode(switchPin, INPUT);   // Set the switch pin as input }

void loop{ Serial.print("Read switch input: "); Serial.println(digitalRead(ledPin));   // Read the pin and display the value delay(100); val = digitalRead(switchPin);  // read input value and store it in val if (val == LOW) {              // check if the button is pressed digitalWrite(ledPin, HIGH);  // turn LED on  } if (val == HIGH) {             // check if the button is not pressed digitalWrite(ledPin, LOW);   // turn LED off } }

The first modification to be made was removing all unnecessary code. The LED code, and the serial monitoring code was removed. Both of these were unnecessary because they were only being used while the test switch was being built to verify the functionality of the circuit. The LED was also removed from the physical circuit. Here is a diagram showing the MIDI Signal test rig, and a picture.

The second modification to the code was replace the removed LED code under the "if" variable, with code that would send the synth a MIDI signal. Essentially the "if" variable checks the state of an input, which in this case was the input connected to the switch; pin 2. In this code it was defined that an action would take place under the "if" variable, if the state of the switch was read as being engaged. The third modification was to define the MIDI code, so that arduino understands the parameters of a single MIDI note. Here is the note used in the final code (0x90, 0x48, 0x40) the functions of each part were defined as follows: (0x90) is the command to play a note, (0x48) is the pitch of the note to be played, and (0x40) is the velocity, or how loud the note is to be played.

Here is the finished working code.

/* * Sends a switch acitived midi signal to a synthesizer */

int switchPin = 2;             // switch is connected to pin 2 int val;                       // variable for reading the pin status void noteOn(int cmd, int pitch, int velocity) { //Sets what each of the 3 values in the "noteOn" function does Serial.write(cmd); //All MIDI protocol messages start with 0x90 to signify the start of a MIDI message Serial.write(pitch); //The note. Middle C (0x3C), for example Serial.write(velocity); //Volume of note }

void setup { Serial.begin(9600);          // set up Serial library at 9600 bps pinMode(switchPin, INPUT);   // sets the digital pin as input to read switch Serial.begin(31250);         //MIDI protocol baud rate is 31250 bits per second }

void loop{ // Channel 0 (hex = 0xC0) is alto sax (65 on the Gen MIDI Patch Map) hex = 0x41 Serial.write(0xC0); Serial.write(0x41); // Channel 1 (hex = 0xC1) is piano 0 (0 on patch map) hex = 0x00 Serial.write(0xC1); Serial.write(0x00); // Channel 9 (hex = 0xC9) is drums 0 (the drum line is always channel 9) Serial.write(0xC9); Serial.write(0x00); val = digitalRead(switchPin);  // read input value and store it in val if (val == LOW) {              // check if the button is pressed noteOn(0x90, 0x48, 0x40);    // send sax midi signal to synth delay(1000); } if (val == HIGH) {              // check if the button is not pressed noteOn(0x90, 0x48, 0x00); }   // turn off sax synth signal }

Here is a VIDEO of the working rig.

Next steps will be, figuring out how to write a MIDI signal code that controls a circuit with more than one switch input.

Week 7 Narrative
Tested the Beat Bearing boards ribbon cable connector to see which inputs were connected to bearing switches on the board. It became apparent that this was necessary when it was discovered that there were 33 connections on the ribbon cable connector head, and only 16 wires running into this cable head that were actually connected to switches. Leads were inserted into the connections that were connected to switches to mark them.

Week 8 Narrative
Found code to use with the beat bearing board at www.beatbearing.co.uk. The code came in a bundle that included code for the arduino, processing code, and a MIDI library. Processing is a coding environment, that uses javascript. The Processing code is used to access the MIDI library and control the visuals of the beat bearing board; although it was decided to leave the visual aspect for a future group working on this project. The arduino code communicates with Processing, which accesses the MIDI library; this makes programming the MIDI signals easier. Listed below is the Arduino code. The Processing code is not listed because there is so much of it.

/* * Beatbearing firmware * * Peter Bennett * pete@petecube.com * * NOTE: * this isn't the most efficiently coded program, but is the one that I was using as a prototype * when writing up the BeatBearing article * * Keep an eye on www.beatbearing.co.uk for suggested updates to this firware, * including a version with proper debouncing and use of the digital pins for input. * * Make sure to choose correct board and serial port before programming * * This was written in Arduino v12 */

int A0_1 = 2;                  // declare output pins int A1_1 = 3; int A2_1 = 4; int A3_1 = 5; int A0_2 = 6; int A1_2 = 7; int A2_2 = 8; int A3_2 = 9;

int Z_1 = 0;                     // declare input pins int Z_2 = 1;

int thresholdLow = 3000; int thresholdHigh = 7000;

int stateMatrix[32][8] = {       // stores all of the values. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0};

int averages[32] = {       // stores all of the values. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0};

boolean bState[32] = { B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0};

void setup {

Serial.begin(9600);

pinMode(A0_1, OUTPUT);                   // set outputs pinMode(A1_1, OUTPUT); pinMode(A2_1, OUTPUT); pinMode(A3_1, OUTPUT);

pinMode(A0_2, OUTPUT); pinMode(A1_2, OUTPUT); pinMode(A2_2, OUTPUT); pinMode(A3_2, OUTPUT); }

void loop{

byte byteOut1 = B00000000; byte byteOut2 = B00000000; byte byteOut3 = B00000000; byte byteOut4 = B00000000; byte byteOut5 = B00000000; byte stopByte = B11111111;

for (int a = 0; a < 32; a++) {                               // first shift all old values up    for (int b = 7; b > 0; b--) { stateMatrix[a][b] = stateMatrix[a][b-1]; } }

for (long count = 0; count < 16; count++) {                 // now get all the states 0-1024

digitalWrite(A0_1, (count >> 3) & 1); digitalWrite(A1_1, (count >> 2) & 1); digitalWrite(A2_1, (count >> 1) & 1); digitalWrite(A3_1, (count >> 0) & 1);

digitalWrite(A0_2, (count >> 3) & 1); digitalWrite(A1_2, (count >> 2) & 1); digitalWrite(A2_2, (count >> 1) & 1); digitalWrite(A3_2, (count >> 0) & 1);

stateMatrix[count][0] = analogRead(Z_1);                     // and insert new values at position 0 stateMatrix[count + 16][0] = analogRead(Z_2); }

for (int a = 0; a < 32; a++) {                               // now calculate averages averages[a] = 0; for (int b = 0; b < 8; b++) { averages[a] += stateMatrix[a][b]; } }

// determine binary state using thresholds for (int n = 0; n < 32; n++) { if ((bState[n] == B0) && (averages[n] < (thresholdLow))) {                          // last sure value was 0 AND below low threshold bState[n] = B1;                                                                            // then set to 1; }    else if ((bState[n] == B1) && (averages[n] > (thresholdHigh))){                      // last sure value was 1 AND over high threshold bState[n] = B0;                                                                            // set to 0; } }

// now assemble the output bytes

int stateCount = 0;

// first byte for (int n = 0; n < 7; n++) { if (bState[stateCount] == B1) { byteOut1 |= (1 << n);               // then set to 1; }    else { byteOut1 &= ~(1 << n);             // set to 0; }   stateCount++; }

// second byte for (int n = 0; n < 7; n++) { if (bState[stateCount] == B1) { byteOut2 |= (1 << n);               // then set to 1; }    else { byteOut2 &= ~(1 << n);             // set to 0; }   stateCount++; }

// third byte for (int n = 0; n < 7; n++) { if (bState[stateCount] == B1) { byteOut3 |= (1 << n);               // then set to 1; }    else { byteOut3 &= ~(1 << n);             // set to 0; }   stateCount++; }

// fourth byte for (int n = 0; n < 7; n++) { if (bState[stateCount] == B1) { byteOut4 |= (1 << n);               // then set to 1; }    else { byteOut4 &= ~(1 << n);             // set to 0; }   stateCount++; }

// fifth byte (shorter than others) for (int n = 0; n < 4; n++) { if (bState[stateCount] == B1) { byteOut5 |= (1 << n);               // then set to 1; }    else { byteOut5 &= ~(1 << n);             // set to 0; }   stateCount++; }

// send the values over serial to Processing Serial.print(byteOut1, BYTE); Serial.print(byteOut2, BYTE); Serial.print(byteOut3, BYTE); Serial.print(byteOut4, BYTE); Serial.print(byteOut5, BYTE); Serial.print(stopByte, BYTE); }

It should be noted that the "BYTE" command is no longer supported by arduino. This is a modification that will have to be made to this code. The next steps of this project will be to complete the beat bearing board and test this code with the board.