Howdie guys and girls,
With the help of the arduino community, I have been able to accomplish our school project of the laserharp.
The construction is not the most beatiful, but with the lack of materials this is the result!
What you can do with it:
- Play 5 different tones
- Change between 2 channels (instruments) with buttons.
- Change the sound tone with a potentiometer
Next project is to build an other midi instrument, a midi fighter. And the third project will be to build a quadcopter, that will have an autopilot function.
Just wait 10 years and Ill be done with the midi fighter, stay tuned!
Cheers!
Edit:
I thought I could upload the code of the laserharp 2 ![]()
Ive tried to shorten it down as much as possible with arrays and for loops.
#define AntalLDR 5
#define AntalInstr 2
int ValdKanal = 144;
int PitchBend = 5;
int AnalogArray[AntalLDR] = {0,1,2,3,4};
int PotVal[AntalLDR] = {0,0,0,0,0};
int State[AntalLDR] = {LOW, LOW, LOW, LOW, LOW};
int DigState[AntalLDR] = {LOW, LOW, LOW ,LOW, LOW};
int Noter[AntalLDR] = {63,62,60,59,58};
int InstrVal[AntalInstr] = {8,9};
int Kanal[AntalInstr] = {144, 145};
int InstrState[AntalInstr] = {LOW, LOW};
int ledPin[AntalInstr] = {10, 11};
void setup() {
Serial.begin(57600);
pinMode(ledPin[0], OUTPUT);
pinMode(ledPin[1], OUTPUT);
}
void loop() {
//Väljer instrument/kanal
for(int i = 0; i < AntalInstr; i++){ // En for-loop för att skanna igenom samtliga knappar (Varje knapp = Instrument val)
int buttonState = digitalRead(InstrVal[i]); // Värdet på själva knappen registreras i en variabel
if(InstrState[i] != buttonState){ // Om värdet på knappen är förändrat från det förra tillstånde, då går den in i nästa IF state
if(buttonState == HIGH){ // Om värdet är HÖGT, går den i IF funktionen
digitalWrite(ledPin[0], LOW); // Släcker lampa 1
digitalWrite(ledPin[1], LOW); // Släcker lampa 2
digitalWrite(ledPin[i], HIGH); // Den knappen som blev intryckt, tänds motsvarande lampa på
ValdKanal = Kanal[i]; // Eftersom att varje knapp har en bestämd kanal, så lägger vi in den kanalen i ValkdKanal
}
InstrState[i] = !InstrState[i]; // Eftersom att tillståndet förändrats, så måste vi lägga till det nuvarande tillståndet.
}
}
//Spelar upp toner
for(int i= 0; i < AntalLDR; i++){ // Går in i en for-loop för att kolla igenom samtliga sensorer
PotVal[i] = analogRead(AnalogArray[i]); // Lägger in värdet på LDRn i PotVal
if(PotVal[i] > 500){ // Överstiger värdet på PotVal 700, då betyder det att laser strålen fortfarande är på
DigState[i] = LOW; // Eftersom att strålen inte är blockerad (över 700), så lägger vi LDR tillståndet som LÅG
}
else {
DigState[i] = HIGH; // Om värdet är lägre än 700, så lägger vi LDR tillståndet som HÖG
}
if(DigState[i] != State[i]){ // Nu kollar vi ifall det är någon skillnad från förra tillståndet på den specifika LDRn, om det finns skillnad gå till nästa IF
if(DigState[i] == HIGH) // Är värdet HÖGT, alltså att lasern blivit blockerad, går vi in i funktionen. Annars går vi till else-satsen
{
int value = analogRead(PitchBend)/8; // Här registrerar vi värdet på potentiometern (Pitch Bend) i en variabel
noteOn(0xE1, value, value); // Pitch värdet läggs in i kanal 1
noteOn(0xE0, value, value); // Pitch värdet läggs in i kanal 2
Serial.println(PotVal[i]);
noteOn(ValdKanal, Noter[i], 0x7F); // Här skickas dessa värdena in i en funktion som skickar iväg dessa värden till datorn
// ValdKanal = Den bestämda kanalen, Noter[i] = Den specifika tonen för varje LDR, 0x7F = Högsta volym
}
else{
delay(200); // Vi väntar en viss tid
noteOn(ValdKanal, Noter[i], 0x00); // Här stänger vi av ljudet
}
State[i] = !State[i]; //Nu ändrar vi tillståndet till det nuvarande.
}
}
}
void noteOn(int cmd, int pitch, int velocity) {
Serial.write(cmd);
Serial.write(pitch);
Serial.write(velocity);
}