Prototype Interactive Keyboard

 

Prototype Interactive Keyboard from rupert.russell on Vimeo.

 

 

/*
Note this code requires an Arduino MEGA due to the number of inputs and outputs required

Based on Example Code:

Button by DojoDave <http://www.0j0.org>  created 2005   modified 30 Aug 2011   by Tom Igoe   http://www.arduino.cc/en/Tutorial/Button  This example code is in the public domain.
Neopixel library for Arduino https://github.com/adafruit/Adafruit_NeoPixel released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library
NeoPixel Ring simple sketch (c) 2013 Shae Erisson
Matrix Keypad Arduino library http://playground.arduino.cc/Code/Keypad
Membrane 3x4 Matrix Keypad + extras - 3x4  https://www.adafruit.com/products/419 Example Code

Mary had a little lamb score from
http://www.music-scores.com/graphics/tr_ma_vo_du.gif

The Keypad is used to select the song to play
The Keyboard buttons play each note using the Sound Board

Mary Had a Little Lamb programmed by Rupert Russell as an example

The notes were generated by Rupert Russell using Audacity and a 2 second Pluck and MIDI notes for the C Major Scale
using inofrmation from
http://www.electronics.dit.ie/staff/tscarff/Music_technology/midi/midi_note_numbers_for_octaves.htm


*/

 

 

// Create Vriables and Load the required libraries
#include <Adafruit_NeoPixel.h>
#include "Arduino.h"
#include "Keypad.h" // Used for the Keypad

// Used for the Keypad
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte rowPins[ROWS] = {8, 7, 6, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {4, 3, 2}; //connect to the column pinouts of the keypad


// Instantiate the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

// More pin definitions:
char key = keypad.getKey();


// Which pin on the Arduino is connected to the NeoPixels?
#define PIN            51

// Slight pause bewteen notes to sepearte each note from the previous one
int pause = 8;

// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
// example for more information on possible values.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);


// constants won't change. They're used here to
// set pin numbers:
const int ledPin =  13;      // the number of the LED pin



// How many NeoPixels are attached to the Arduino?  
// ***** ******  ****** ****** ****** ****** ****** ****** ****** ****** ****** ****** ******
//  ****  Note when you finish adding all the pixels you will need to change this number to 8
#define NUMPIXELS      2


// variables will change:
// ***** ******  ****** ****** ****** ****** ****** ****** ****** ****** ****** ****** ******
// you will have to add additional variables for the extra buttons when you ass them to the keyboard
int highC = 0;         // variable for reading the pushbutton status for highC
int keyB = 0;          // used for the Keyboard key B


void setup() {

pixels.begin(); // This initializes the NeoPixel library.


// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);

// initialize Outputs to Sound Board
pinMode(14, OUTPUT);
pinMode(15, OUTPUT);
pinMode(16, OUTPUT);
pinMode(17, OUTPUT);
pinMode(18, OUTPUT);
pinMode(19, OUTPUT);
pinMode(20, OUTPUT);
pinMode(21, OUTPUT);

// initialiase inputs from Keyboard
pinMode(40, INPUT);
pinMode(41, INPUT);
pinMode(42, INPUT);
pinMode(43, INPUT);
pinMode(44, INPUT);
pinMode(45, INPUT);
pinMode(46, INPUT);
pinMode(47, INPUT);

digitalWrite(14, HIGH);
digitalWrite(15, HIGH);
digitalWrite(16, HIGH);
digitalWrite(17, HIGH);
digitalWrite(18, HIGH);
digitalWrite(19, HIGH);
digitalWrite(20, HIGH);
digitalWrite(21, HIGH);

}

// Start of the main program loop
void loop() {


pixels.begin(); // This initializes the NeoPixel library.

// Read Keypad Press
char key = keypad.getKey();

if (key == '1')
{
// Keypad Key 1 Pressed call keyPad1 Procedure
keyPad1();  //  C Major Scale  Note this is the name of a procedure located towards the end of the program
}


if (key == '2')
{
// Keypad Key 1 Pressed call keyPad1 Procedure
maryHadaLittleLamb();  //  Mary Had a little lamb procedure located towards the end of the program
}

// ***** ******  ****** ****** ****** ****** ****** ****** ****** ****** ****** ****** ******
// I would recommend that you break the song down into sections so that you can demonstrate just the first verse
// rather than playing the whole song at once.

 

// ***** ******  ****** ****** ****** ****** ****** ****** ****** ****** ****** ****** ******

// you will have to add additional code to read each key on the keyboard
// read the state of the keyboard presses:
highC = digitalRead(40);
keyB = digitalRead(41);


// check if the highC is pressed on the kayboard.
if (highC == HIGH) {
// turn LED on:
digitalWrite(ledPin, HIGH);
digitalWrite(14, LOW);
pixels.setPixelColor(0, pixels.Color(0, 150, 0)); // Moderately bright green
pixels.show(); // This sends the updated pixel color to the hardware.
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
digitalWrite(14, HIGH);
pixels.setPixelColor(0, pixels.Color(0, 0, 0)); // Off
pixels.show(); // This sends the updated pixel color to the hardware.

}

// ***** ******  ****** ****** ****** ****** ****** ****** ****** ****** ****** ****** ******
//  You will need to add additional if statements for each of the 6 additional keys on the keyboard that need to be soldered onto the board.

// check if the B is pressed.
if (keyB == HIGH) {
// turn LED on:
digitalWrite(ledPin, HIGH);
digitalWrite(15, LOW);
pixels.setPixelColor(1, pixels.Color(150, 0, 0)); // Moderately bright red
pixels.show(); // This sends the updated pixel color to the hardware.
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
digitalWrite(15, HIGH);
pixels.setPixelColor(1, pixels.Color(0, 0, 0)); // Off
pixels.show(); // This sends the updated pixel color to the hardware.
}


}  // End of void loop()

void keyPad1() {
// Play the C Major Scale when you press Number 1 on the Keypad
lowC(400);
d(400);
e(400);
f(400);
g(400);
a(400);
b(400);
c(400);
}

 

void  maryHadaLittleLamb() {

// Play Mary Had a Little Lamb
// the leter is the note in the scale eg c,d,e,f,g  etc  the number in bracket is the duration of the note up to a
// maximum of 2000 for 2 seconds)

e(400);    //Mar
d(400);    //y
lowC(400); //had
d(400);    //a
e(400);    //litt
e(400);    //le
delay(4);
e(800);    //lamb,
d(400);    //litt
d(400);    //le
delay(4);
d(800);    //lamb,
e(400);    //litt
g(400);    //le
g(400);    //lamb,
e(400);    //Mar
d(400);    //y
lowC(400); //had
d(400);    //a
e(400);    //litt
e(400);    //le
e(400);    //lamb,
e(400);    //its
d(400);    //fleece
d(400);    //was
e(400);    //white
d(400);    //as
lowC(1600);//snow.


}

 


// The following procedures are for each note in the scale.

void lowC(int noteLenght) {
digitalWrite(ledPin, HIGH);
digitalWrite(14, LOW);
pixels.setPixelColor(0, pixels.Color(0, 150, 0)); // Moderately bright green
pixels.show(); // This sends the updated pixel color to the hardware.
delay(noteLenght);
digitalWrite(14, HIGH);
pixels.setPixelColor(0, pixels.Color(0, 0, 0)); // OFF
pixels.show(); // This sends the updated pixel color to the hardware.
delay(pause);
}

void d(int noteLength) {
digitalWrite(15, LOW);
pixels.setPixelColor(1, pixels.Color(150, 0, 0)); // Moderately bright red
pixels.show(); // This sends the updated pixel color to the hardware.
delay(noteLength);
digitalWrite(15, HIGH);
pixels.setPixelColor(1, pixels.Color(0, 0, 0)); // OFF
pixels.show(); // This sends the updated pixel color to the hardware.
delay(pause);
}

void e(int noteLength) {
digitalWrite(16, LOW);
pixels.setPixelColor(0, pixels.Color(150, 0, 0)); // Moderately bright red
pixels.show(); // This sends the updated pixel color to the hardware.
delay(noteLength);
digitalWrite(16, HIGH);
pixels.setPixelColor(0, pixels.Color(0, 0, 0)); // OFF
pixels.show(); // This sends the updated pixel color to the hardware.
delay(pause);
delay(pause);
}

void f(int noteLength) {
digitalWrite(17, LOW);
pixels.setPixelColor(1, pixels.Color(150, 0, 0)); // Moderately bright red
pixels.show(); // This sends the updated pixel color to the hardware.
delay(noteLength);
digitalWrite(17, HIGH);
pixels.setPixelColor(1, pixels.Color(0, 0, 0)); // OFF
pixels.show(); // This sends the updated pixel color to the hardware.
delay(pause);
}

void g(int noteLength) {
digitalWrite(18, LOW);
pixels.setPixelColor(0, pixels.Color(150, 0, 0)); // Moderately bright red
pixels.show(); // This sends the updated pixel color to the hardware.
delay(noteLength);
digitalWrite(18, HIGH);
pixels.setPixelColor(0, pixels.Color(0, 0, 0)); // OFF
pixels.show(); // This sends the updated pixel color to the hardware.
delay(pause);
}

void a(int noteLength) {
digitalWrite(19, LOW);
pixels.setPixelColor(1, pixels.Color(150, 0, 0)); // Moderately bright red
pixels.show(); // This sends the updated pixel color to the hardware.
delay(noteLength);
digitalWrite(19, HIGH);
pixels.setPixelColor(1, pixels.Color(0, 0, 0)); // OFF
pixels.show(); // This sends the updated pixel color to the hardware.
delay(pause);
}

void b(int noteLength) {
digitalWrite(20, LOW);
pixels.setPixelColor(0, pixels.Color(150, 0, 0)); // Moderately bright red
pixels.show(); // This sends the updated pixel color to the hardware.
delay(noteLength);
digitalWrite(20, HIGH);
pixels.setPixelColor(0, pixels.Color(0, 0, 0)); // OFF
pixels.show(); // This sends the updated pixel color to the hardware.
delay(pause);
}

void c(int noteLength) {
digitalWrite(21, LOW);
pixels.setPixelColor(1, pixels.Color(150, 0, 0)); // Moderately bright red
pixels.show(); // This sends the updated pixel color to the hardware.
delay(noteLength);
digitalWrite(21, HIGH);
pixels.setPixelColor(1, pixels.Color(0, 0, 0)); // OFF
pixels.show(); // This sends the updated pixel color to the hardware.
delay(pause);
}