0
Offline
Newbie
Karma: 0
Posts: 7
Arduino rocks
|
 |
« on: October 08, 2012, 05:54:45 am » |
Hello world  After searching for hours a way to make a keyboard from Arduino and MI shield from sparkfun, and with the helps of few people, I finally get my program. It will probably seems a bit simple for advanced users, but It was quite a lot of work for me to make it works as a beginner. I thought it could be great to save time for other beginners if I share this program in this topic, so here we go , but before, if advanced users have some suggestions to improve it, you are more than welcome to contact me as I'm waiting to learn more : #include <SoftwareSerial.h> SoftwareSerial mySerial(2, 3); //Soft TX on 3, we don't use RX in this code int inputPins[] = {5,6,7,8,9,10,11,12,13}; int note[]={72,74,76,77,79,81,83,84,86}; int pinCount = 9; int buttonState[9]; int lastButtonState[9]; byte resetMIDI = 4; //Tied to VS1053 Reset line int instrument = 13; void setup() { //Setup soft serial for MIDI control mySerial.begin(31250); for(int i=0; i<pinCount; i++){ pinMode(inputPins , OUTPUT);//pinMode(outputPins, OUTPUT); digitalWrite(inputPins, LOW);// this enables the pull up resistors to reduce noise pinMode(inputPins, INPUT); }
//Reset the VS1053 digitalWrite(resetMIDI, LOW); delay(100); digitalWrite(resetMIDI, HIGH); delay(100); talkMIDI(0xB0, 0x07, 126); //0xB0 is channel message, set channel volume to near max (127) talkMIDI(0xB0, 0, 0x79); //Default bank GM1 talkMIDI(0xC0, instrument, 0); //Set instrument number. 0xC0 is a 1 data byte command
}
void loop() { for (int i=0; i<pinCount; i++){
buttonState = digitalRead(inputPins); delay(1); if (buttonState != lastButtonState) { if (buttonState == HIGH) { noteOn(0,note,100); } }
lastButtonState = buttonState; } }
//Send a MIDI note-on message. Like Pressing a piano key void noteOn(byte channel, byte note, byte attack_velocity) { talkMIDI( (0x90 | channel), note, attack_velocity); }
//Send a MIDI note-off message. Like releasing a piano key void noteOff(byte channel, byte note, byte release_velocity) { talkMIDI( (0x80 | channel), note, release_velocity); }
//Plays a MIDI note. Doesn't check to see that cmd is greater than 127, or that data values are less than 127 void talkMIDI(byte cmd, byte data1, byte data2) { mySerial.write(cmd); mySerial.write(data1);
//Some commands only have one data byte. All cmds less than 0xBn have 2 data bytes //(sort of: http://253.ccarh.org/handout/midiprotocol/) if( (cmd & 0xF0) <= 0xB0) mySerial.write(data2);
}
Here is a link to see it working : http://www.youtube.com/watch?v=jNWv-yBQ84Y&feature=youtu.be
I also wrote the program to have this keyboard working with the Touch pad shield from Sparkfun. If people are interested , don't hesitate to ask.
All the best,
Plankton.
|
|
|
|
|
Logged
|
|
|
|
|
Dubai, UAE
Offline
Edison Member
Karma: 20
Posts: 1627
|
 |
« Reply #1 on: October 08, 2012, 06:41:25 am » |
Hi, I like how you used a single header pin as the keys, I wanted to make something like a stylophone interface but this looks a lot easier. I assume that you are sending midi messages from the Arduino to the keyboard ? Have you tried going the other way midi into Ardiuno ? I have bought a five dollar keyboard that I plan to drive some of my recent synth experiments with - http://rcarduino.blogspot.com/2012/10/arduino-modular-synthesizer-part-one.html I am considering getting a simple midi keyboard to drive them with instead - the five dollar keyboard is pretty nasty. Duane B
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 7
Arduino rocks
|
 |
« Reply #2 on: October 08, 2012, 04:02:11 pm » |
Hi Duane,
My keys are simple switches... then, as you guessed, the Arduino send midi data to the shield to play notes. Regarding your case, have you take in consideration the possibility to connect a PS/2 keyboard to your Arduino, using the appropritate library ?
|
|
|
|
|
Logged
|
|
|
|
|
Dubai, UAE
Offline
Edison Member
Karma: 20
Posts: 1627
|
 |
« Reply #3 on: October 11, 2012, 01:23:16 am » |
Hi, The PS2 is a good idea, it looks like midi into Arduino is give a few people problems, I have already broken out the key scanning matrix from the 5 dollar keyboard so I will go with this for now. Thanks Duane B rcarduino.blogspot.com
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 7
|
 |
« Reply #4 on: October 22, 2012, 07:58:41 pm » |
MusicIntrument_Keyboard_Error
Hello. Thank you very much for posting your Arduino Music Instrument_Keyboard. I pasted your program on Arduino 1.01 and verified it.
Then I get lots of error messages as I post the image here.
For example, In the void setup() The line " pinMode(inputPins, OUTPUT);//pinMode(outputPins, OUTPUT); " is highlighted and there's a message as " invalid conversion from 'int*' to 'uint8_t' "
I cannot understand the error messages, because your code seems ok. If I click "Upload" button, the result is the same.
What is wrong? I'm looking forward your reply.
P.S. The title name of the file is "MusicIntrument_Keyboard.ino" I use Arduino Uno R2 and I use Windows XP. Board and Serial port( Com4 ) is correctly setup on Arduino 1.01.
|
|
|
|
|
Logged
|
|
|
|
|
Dubai, UAE
Offline
Edison Member
Karma: 20
Posts: 1627
|
 |
« Reply #5 on: October 22, 2012, 11:03:52 pm » |
Hi, inputPins is an array but the array access operator is missing throughout the pasted code. To fix this, whereever you see inputPins replace it with inputsPins[i] this will access specific members of the array rather than the array base pointer. If none of that makes sense search the web for C Array or read this - http://www.arduino.cc/en/Reference/ArrayDuane B rcarduino.blogspot.com
|
|
|
|
« Last Edit: October 23, 2012, 07:05:56 am by DuaneB »
|
Logged
|
|
|
|
|
Gosport, UK
Offline
Faraday Member
Karma: 19
Posts: 3117
|
 |
« Reply #6 on: October 23, 2012, 08:21:17 am » |
inputPins is an array but the array access operator is missing throughout the pasted code. This is why we have code tags. It stops the forum software converting array indexes into italic tags.
|
|
|
|
|
Logged
|
|
|
|
|
Dubai, UAE
Offline
Edison Member
Karma: 20
Posts: 1627
|
 |
« Reply #7 on: October 23, 2012, 01:29:12 pm » |
This is why we have code tags. It stops the forum software converting array indexes into italic tags. Oops. I only added code tags after rereading my own response and seeing no 's didn't occur to me that I had put them in and that they were the reason for the italics, same for the OP I guess.
Back on topic -
I have been messing around with my hacked keyboard, its still monophonic but by racing through the active tones at varying speeds I get a basic chord effect or arppegio's either way the monophonic version is much more interesting than I expected.
I will share the schematic and code shortly, the code should be easy enough to adapt to another instrument if the OP wants to experiment.
Duane B
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 7
|
 |
« Reply #8 on: October 23, 2012, 09:10:28 pm » |
Thank you very much for your comment. I replaced inputsPins with inputsPins.
The number of errors has decreased. But still there were 6 error messages as I post the image-1 here.
For example, In the void loop()
The line buttonState = digitalRead(inputPins); is highlighted and there's a message as " incompatible types in assignment of 'int' to 'int[9]' "
So I also added to all "buttonState" and "lastButtonState"
The number of errors has decreased further. But still there were 3 error messages as I post the image-2 here.
For example, In the void loop()
if (buttonState == HIGH) { noteOn(0,note,100);
The line noteOn(0,note,100); is highlighted and there's a message as " invalid conversion from 'int' to 'byte' "
In my understanding, talkMIDI() is a message with 3 bytes. How do you define the data type of noteOn()?
I feel I'm getting better with your help.
I'm looking forward your reply. Thank you very much.
|
|
|
|
|
Logged
|
|
|
|
|
Dubai, UAE
Offline
Edison Member
Karma: 20
Posts: 1627
|
 |
« Reply #9 on: October 24, 2012, 02:29:56 am » |
Why not post your code and using the code tag, its the # on the menu above, it stops the forum software from replacing your array index with italics (thanks dxw00d for point this out) ? Duane B rcarduino.blogspot.com
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 7
|
 |
« Reply #10 on: October 24, 2012, 10:45:19 am » |
Very sorry. I could not understand how to use the code tag, # on the menu. I'll post in a day.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 7
|
 |
« Reply #11 on: October 25, 2012, 08:00:48 pm » |
This is a re-post with a code tag. This time is the first time to use code tags. If I'm wrong, please tell me. MusicIntrument_Keyboard Errors Thank you very much for your comment. I replaced "inputsPins" ,"buttonState" "lastButtonState" as follows. inputPins[i] buttonState[i] lastButtonState[i] The number of errors has decreased. But still there are 3 error messages. For example, In the void loop() if (buttonState[i] == HIGH) { noteOn(0,note,100);
The line noteOn(0,note,100); is highlighted and there are messages as " invalid conversion from 'int' to 'byte' " " initializing argument 2 of 'noteOn(byte,byte,byte)' " In my understanding, talkMIDI() is a message with 3 bytes. How do you define the data type of noteOn()? I feel I'm getting better with your help. I'm looking forward your reply. Thank you very much.
|
|
|
|
|
Logged
|
|
|
|
|
Dubai, UAE
Offline
Edison Member
Karma: 20
Posts: 1627
|
 |
« Reply #12 on: October 26, 2012, 11:52:39 am » |
Hi, I meant the whole code, its not possible to figure out from snippets of code.
Duane B
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 7
|
 |
« Reply #13 on: October 26, 2012, 07:52:32 pm » |
MusicIntrument_Keyboard Errors Sorry! I pasted this topic's first contributer's ( Plankton's ) code and added array suffixes to "inputsPins" ,"buttonState" "lastButtonState" The full code is as follows. //Music Instrument Shield_Keyboard renew //MusicIntrument_Keyboard // Music Instrument Shield_Keyboard
#include <SoftwareSerial.h> SoftwareSerial mySerial(2, 3); //Soft TX on 3, we don't use RX in this code
int inputPins[] = {5,6,7,8,9,10,11,12,13}; int note[]={72,74,76,77,79,81,83,84,86}; int pinCount = 9;
int buttonState[9]; int lastButtonState[9];
byte resetMIDI = 4; //Tied to VS1053 Reset line int instrument = 13;
void setup() {
//Setup soft serial for MIDI control mySerial.begin(31250); for(int i=0; i<pinCount; i++){ pinMode(inputPins[i], OUTPUT);//pinMode(outputPins, OUTPUT); digitalWrite(inputPins[i], LOW);// this enables the pull up resistors to reduce noise pinMode(inputPins[i], INPUT); }
//Reset the VS1053 digitalWrite(resetMIDI, LOW); delay(100); digitalWrite(resetMIDI, HIGH); delay(100); talkMIDI(0xB0, 0x07, 126); //0xB0 is channel message, set channel volume to near max (127) talkMIDI(0xB0, 0, 0x79); //Default bank GM1 talkMIDI(0xC0, instrument, 0); //Set instrument number. 0xC0 is a 1 data byte command
}
void loop() { for (int i=0; i<pinCount; i++){
buttonState[i] = digitalRead(inputPins[i]); delay(1); if (buttonState[i] != lastButtonState[i]) { if (buttonState[i] == HIGH) { noteOn(0,note,100); } }
lastButtonState[i] = buttonState[i]; } }
//Send a MIDI note-on message. Like Pressing a piano key void noteOn(byte channel, byte note, byte attack_velocity) { talkMIDI( (0x90 | channel), note, attack_velocity); }
//Send a MIDI note-off message. Like releasing a piano key void noteOff(byte channel, byte note, byte release_velocity) { talkMIDI( (0x80 | channel), note, release_velocity); }
//Plays a MIDI note. Doesn't check to see that cmd is greater than 127, or that data values are less than 127 void talkMIDI(byte cmd, byte data1, byte data2) { mySerial.write(cmd); mySerial.write(data1);
//Some commands only have one data byte. All cmds less than 0xBn have 2 data bytes //(sort of: http://253.ccarh.org/handout/midiprotocol/) if( (cmd & 0xF0) <= 0xB0) mySerial.write(data2);
}
Thank you very much for your comments and am looking forward to them.
|
|
|
|
|
Logged
|
|
|
|
|
Dubai, UAE
Offline
Edison Member
Karma: 20
Posts: 1627
|
 |
« Reply #14 on: October 27, 2012, 01:50:41 am » |
Hi, I wanted to see the full code to make sure there are no values that would not fit into a byte (values > 255). There aren't any so you can change - int inputPins[] = {5,6,7,8,9,10,11,12,13}; int note[]={72,74,76,77,79,81,83,84,86};
to byte inputPins[] = {5,6,7,8,9,10,11,12,13}; byte note[]={72,74,76,77,79,81,83,84,86};
Duane B
|
|
|
|
|
Logged
|
|
|
|
|
|