Skicka och ta emot MIDI med Arduino (11 / 11 steg)
Steg 11: exempel
Jag byggde nyligen en MIDI-controller med en inbyggd accelerometer och gyroskop, samt 16 bakgrundsbelysta knappar. Jag kommer att lägga hela projektet snart (fortfarande behöver avsluta inhägnad och några andra saker), men jag har bifogat några exempelkod som visar hur jag fick MIDI upp och löpande. Här är en video av två program som jag har skrivit hittills:
Och här är koden för dessa program:
enstaka pixel flyttar, utlösa MIDI (använder bara x och y accelerometer):
< pre > //accelerometer test-singel pixel
Amanda Ghassaei 2012
/*
* Detta program är fri programvara; Du kan vidaredistribuera det och/eller ändra
* det enligt villkoren i GNU General Public License som offentliggjorts av
* den Free Software Foundation; antingen version 2 av licensen, eller
* (på ditt alternativ) någon senare version.
*
*/
PIN-anslutningar
#define ledLatchPin 6
#define ledClockPin 5
#define ledDataPin 7
#define buttonLatchPin 4
#define buttonClockPin 3
#define buttonDataPin 2
installationsprogrammet för varibles för gyroskop/Accelerometer
int xGyroRAW;
int yGyroRAW;
int xAccRAW;
int yAccRAW;
int zAccRAW;
byte xGyro;
byte yGyro;
byte xAcc;
byte yAcc;
byte zAcc;
looping variabler
byte i.
byte j;
byte k;
lagring för ledde staterna, 4 byte
byte ledData [] = {0, 0, 0, 0};
lagring för knappar, 4 byte
byte buttonCurrent [] = {0,0,0,0}.
byte buttonLast [] = {0,0,0,0}.
byte buttonEvent [] = {0,0,0,0}.
byte buttonState [] = {0,0,0,0}.
knappen Dämpningstid counter - 16 byte
byte buttonDebounceCounter [4] [4].
variabler för accelerometer pixel rörelse
booleska firstPress = 1;
byte movingPixel [] = {0, 0, 0, 0};
byte yPosition;
byte xPosition;
int timeX = 0;
int timeY = 0;
booleska dirX = 0;
booleska dirY = 0;
byte lastX = 4;
byte lastY = 4;
MIDI-variabler
int hastighet = 100;
int noteON = 144;
int MIDIoffset = 60.
byte AktuelltX;
void setup() {
DDRD = 0xFA; //set stift D7-D4 som D2 som indata-utdata
Serial.BEGIN (31250); //MIDI överföringshastighet
Serial.BEGIN(9600);
(CLI); //stop avbrott
Ställ in timer1 avbrott vid 1kHz
TCCR1A = 0; / / Ställ in hela TCCR1A register till 0
TCCR1B = 0; / / samma för TCCR1B
TCNT1 = 0, //initialize counter värde till 0.
ställa in timer räknas 1khz steg
OCR1A = 1999. / / = (16 * 10 ^ 6) / (1000 * 8) - 1
Aktivera CTC läge
TCCR1B | = (1 << WGM12);
Ange CS11 bit för 8 prescaler
TCCR1B | = (1 << CS11);
Aktivera timern jämför avbrott
TIMSK1 | = (1 << OCIE1A);
SEI (); //allow avbrott
}
ISR(TIMER1_COMPA_vect) {//Interrupt på freq 1 kHz
timeX ++; //increment timeX
timeY ++; //increment timeY
Skift (); //send data till lysdioder
}
buttonCheck - kontrollerar status för en viss knapp.
denna buttoncheck funktion är i stort sett kopierade från monome 40h firmware brian crabtree och joe sjö
void buttonCheck (byte rad, byte index)
{
om (((buttonCurrent [rad] ^ buttonLast[row]) & (1 << index)) & & / / om det aktuella fysiska knapp läget skiljer sig från den
((buttonCurrent [rad] ^ buttonState[row]) & (1 << index))) {/ / last fysisk knapp staten och nuvarande debounced staten
om (buttonCurrent [rad] & (1 << index)) {/ / om nuläget fysisk knapp trycks
buttonEvent [rad] = 1 << index; köa upp en ny knapp händelse omedelbart
buttonState [rad] | = (1 << index); och ställa in debounced ner.
}
annat {
buttonDebounceCounter [rad] [index] = 12.
} / / annars knappen tidigare var deprimerad och nu
har släppts så vi våra debounce counter.
}
annars om (((buttonCurrent [rad] ^ buttonLast[row]) & (1 << index)) == 0 & & / / om det aktuella fysiska knapp läget är samma som
(buttonCurrent [rad] ^ buttonState[row]) & (1 << index)) {/ / den senaste fysiskt knappen stat men den nuvarande fysiskt
knappläge skiljer sig från den nuvarande debounce
statliga...
om (buttonDebounceCounter [rad] [index] > 0 & &--buttonDebounceCounter [rad] [index] == 0) {/ / om den räknaren debounce har
varit minskas till 0 (menande den
knappen har varit upp i
kButtonUpDefaultDebounceCount
iterationer / / /
buttonEvent [rad] = 1 << index; köa en knapp staten change-händelse
om (buttonCurrent [rad] & (1 << index)) {/ / och växla knapparna debounce staten.
buttonState [rad] | = (1 << index);
}
annat {
buttonState [rad] & = ~ (1 << index);
}
}
}
}
{Ogiltig shift()
för (jag = 0; jag < 4; i ++) {
buttonLast [i] = buttonCurrent [i];
byte dataToSend = (1 << (jag + 4)) | (15 & ~ ledData[i]);
ställa in spärren pin låg så lysdioderna inte ändra samtidigt skickas i bitar
PORTD & = B10111111; //digitalWrite (ledLatchPin, låg);
flytta ut bitarna av dataToSend
shiftOut (ledDataPin, ledClockPin, LSBFIRST, dataToSend);
för (j = 0; j < 8; j ++) {
PORTD & = B11011111;//digitalWrite(ledClockPin,LOW);
digitalWrite (ledDataPin, ((dataToSend >> j) & 1));
om ((dataToSend >> j) & 1) {
PORTD| = B10000000;
}
annat {
PORTD & = B01111111;
}
PORTD|=B00100000;//digitalWrite(ledClockPin,High);
}
ställa in spärren pin hög så lysdioderna kommer att få nya uppgifter
PORTD| = B01000000; //digitalWrite (ledLatchPin, hög);
Avmattningen sätts i här slösa bort lite tid medan vi väntar på statligt av produktionen
Pins sedimentera. Utan denna tid slösa slinga, skulle en enda knapptryckning dyka upp som
två pressar (knappen och dess granne)
flyktiga int avmattning = 0;
medan (avmattning < 15)
{
Avmattningen ++;
}
När en rad har ställts in hög, ta emot data från knappar
ställa in spärren pin hög
PORTD| = B00010000; //digitalWrite (buttonLatchPin, hög);
skifta i data
buttonCurrent [i] = shiftIn (buttonDataPin, buttonClockPin, LSBFIRST) >> 3.
för (j = 0; j < 4; j ++) {
PORTD & = B11110111;//digitalWrite(buttonClockPin,LOW);
PORTD|=B00001000;//digitalWrite(buttonClockPin,High);
}
för (j = 0; j < 4; j ++) {
PORTD & = B11110111;//digitalWrite(buttonClockPin,LOW);
om ((PIND >> 2) & 1){//digitalRead(buttonDataPin)
buttonCurrent [i] | = 1 << j;
}
annat {
buttonCurrent [i] & = ~ (1 << j);
}
PORTD|=B00001000;//digitalWrite(buttonClockPin,High);
}
latchpin låg
PORTD & = B11101111; //digitalWrite (buttonLatchPin, låg);
för (k = 0; k < 4; k ++) {
buttonCheck(i,k);
}
}
stänga av lysdioder - detta sätt en rad inte visas ljusare än resten
ställa in spärren pin låg så lysdioderna inte ändra samtidigt skickas i bitar
PORTD & = B10111111; //digitalWrite (ledLatchPin, låg);
flytta ut 0
shiftOut (ledDataPin, ledClockPin, LSBFIRST, 0);
för (j = 0; j < 8; j ++) {
PORTD & = B11011111;//digitalWrite(ledClockPin,LOW);
PORTD & = B01111111;
PORTD|=B00100000;//digitalWrite(ledClockPin,High);
}
ställa in spärren pin hög så lysdioderna kommer att få nya uppgifter
PORTD| = B01000000; //digitalWrite (ledLatchPin, hög);
}
void checkFirstButton() {
för (byte en = 0; en < 4; a ++) {
om (buttonEvent[a]) {
för (byte b = 0; b < 4; b ++) {
om (buttonState [a] & (1 << b)) {
Växla firstPress variabel
firstPress = 0;
Visa nertryckta pixel
ledData [a] = buttonEvent [a];
lagra aktuell position
yPosition = a;
xPosition = 1 << b;
Återställ timers
timeX = 0;
timeY = 0;
hemkomst.
}
}
}
}
}
byte scaleAcc (int RAW) {
om (RAW < = 10 & & RAW > =-10) {
returnera 5.
}
annars om (RAW < -10) {
om (RAW < -50) {
Return 0;
}
annars om (RAW < -40) {
tillbaka 1.
}
annars om (RAW < -30) {
returnera 2.
}
annars om (RAW < -20) {
returnera 3.
}
annat {
returnera 4.
}
}
annars om (RAW > 10) {
om (RAW > 50) {
returnera 10.
}
annars om (RAW > 40) {
returnera 9.
}
annars om (RAW > 30) {
returnera 8.
}
annars om (RAW > 20) {
returnera 7.
}
annat {
returnera 6.
}
}
}
void checkAccelerometer() {
Läs värden
xGyroRAW = analogRead(A1);
yGyroRAW = analogRead(A0);
xAccRAW = analogRead(A4);
yAccRAW = analogRead(A3);
zAccRAW = analogRead(A2);
offset data
xGyroRAW = 317-xGyroRAW;
yGyroRAW = 183-yGyroRAW;
xAccRAW = 282-xAccRAW;
yAccRAW = 282-yAccRAW;
zAccRAW = 282-zAccRAW;
om (xAccRAW > 0) {
dirX = 1;
}
annat {
dirX = 0;
}
om (yAccRAW > 0) {
dirY = 1;
}
annat {
dirY = 0;
}
konvertera till 0-10
xAcc = scaleAcc(xAccRAW);
yAcc = scaleAcc(yAccRAW);
}
int getTime (byte acceleration) {
Växla (acceleration) {
fall 0: / / max - acceleration
returnera 25.
bryta;
fall 1:
returnera 25.
bryta;
fall 2:
gå tillbaka 50;
bryta;
fall 3:
gå tillbaka 100.
bryta;
fall 4:
returnera 150;
bryta;
fall 5: / / ligger platt
Return 0;
bryta;
fall 6:
returnera 150;
bryta;
fall 7:
gå tillbaka 100.
bryta;
mål 8:
gå tillbaka 50;
bryta;
mål 9:
returnera 25.
bryta;
mål 10: / / max + acceleration
returnera 25.
bryta;
}
}
void moveXPixel (int timeComp) {
om (timeComp == 0) {
}
annat {
om (timeX > timeComp) {
timeX = 0;
om (dirX) {
om (xPosition == 8) {
}
annat {
xPosition = xPosition << 1;
}
}
annat {
om (xPosition == 1) {
}
annat {
xPosition = xPosition >> 1;
}
}
}
}
}
void moveYPixel (int timeComp) {
om (timeComp == 0) {
}
annat {
om (timeY > timeComp) {
timeY = 0;
om (dirY) {
om (yPosition == 3) {
}
annat {
yPosition = yPosition + = 1;
}
}
annat {
om (yPosition == 0) {
}
annat {
yPosition = yPosition-= 1;
}
}
}
}
}
void checkMIDI() {
konvertera xPosition till decimal
växel (xPosition) {
fall 1:
AktuelltX = 0;
bryta;
fall 2:
AktuelltX = 1;
bryta;
fall 4:
AktuelltX = 2;
bryta;
mål 8:
AktuelltX = 3;
bryta;
}
om pixel har flyttat skicka midi
om (lastX! = AktuelltX || lastY! = yPosition) {
MIDImessage (noteON, (lastX + 5 * lastY + MIDIoffset), 0), //turn av sista anmärkning
MIDImessage (noteON, (AktuelltX + 5 * yPosition + MIDIoffset), velocity); //turn på nästa anteckning
}
lastX = AktuelltX;
lastY = yPosition;
}
void MIDImessage (int befalla, int MIDInote, int MIDIvelocity) {//send s ett MIDI-meddelande
Serial.write (kommandot); //send på eller av kommandot
Serial.write (MIDInote); //send pitch data
Serial.write (MIDIvelocity); //send hastighet data
}
void loop() {
om (firstPress) {
checkFirstButton();
}
annat {
för (byte pixel = 0; pixel < 4; pixel ++) {
om (pixel == yPosition) {
ledData [pixlar] = xPosition;
}
annat {
ledData [pixlar] = 0;
}
}
checkAccelerometer();
moveXPixel(getTime(xAcc));
moveYPixel(getTime(yAcc));
checkMIDI();
}
}
fyra pixlar studsande (använder bara x accelerometer, använder x gyro att rensa pixlar):
< pre > //accelerometer test-bounce
Amanda Ghassaei 2012
/*
* Detta program är fri programvara; Du kan vidaredistribuera det och/eller ändra
* det enligt villkoren i GNU General Public License som offentliggjorts av
* den Free Software Foundation; antingen version 2 av licensen, eller
* (på ditt alternativ) någon senare version.
*
*/
PIN-anslutningar
#define ledLatchPin 6
#define ledClockPin 5
#define ledDataPin 7
#define buttonLatchPin 4
#define buttonClockPin 3
#define buttonDataPin 2
installationsprogrammet för varibles för gyroskop/Accelerometer
int xGyroRAW;
int yGyroRAW;
int xAccRAW;
int yAccRAW;
int zAccRAW;
byte xGyro;
byte yGyro;
byte xAcc;
byte yAcc;
byte zAcc;
looping variabler
byte i.
byte j;
byte k;
lagring för ledde staterna, 4 byte
byte ledData [] = {0, 0, 0, 0};
lagring för knappar, 4 byte
byte buttonCurrent [] = {0,0,0,0}.
byte buttonLast [] = {0,0,0,0}.
byte buttonEvent [] = {0,0,0,0}.
byte buttonState [] = {0,0,0,0}.
knappen Dämpningstid counter - 16 byte
byte buttonDebounceCounter [4] [4].
variabler för accelerometer pixel rörelse
booleska firstPress [] = {0, 0, 0, 0};
byte movingPixel [] = {0, 0, 0, 0};
byte xPosition [4].
int timeX [] = {0, 0, 0, 0};
booleska dirX;
booleska dirY;
booleska prevDirX = 0;
booleska bounceDirection [] = {0, 0, 0, 0};
Boolean växla [] = {1, 1, 1, 1};
byte peakHeight [4].
byte lastX = 4;
byte lastY = 4;
MIDI-variabler
int hastighet = 100;
int noteON = 144;
int MIDIoffset = 60.
byte AktuelltX;
byte Observera [] = {60, 64, 67, 72};
void setup() {
DDRD = 0xFA; //set stift D7-D4 som D2 som indata-utdata
Serial.BEGIN (31250); //MIDI överföringshastighet
(CLI); //stop avbrott
Ställ in timer1 avbrott vid 1kHz
TCCR1A = 0; / / Ställ in hela TCCR1A register till 0
TCCR1B = 0; / / samma för TCCR1B
TCNT1 = 0, //initialize counter värde till 0.
ställa in timer räknas 1khz steg
OCR1A = 1999. / / = (16 * 10 ^ 6) / (1000 * 8) - 1
Aktivera CTC läge
TCCR1B | = (1 << WGM12);
Ange CS11 bit för 8 prescaler
TCCR1B | = (1 << CS11);
Aktivera timern jämför avbrott
TIMSK1 | = (1 << OCIE1A);
SEI (); //allow avbrott
}
ISR(TIMER1_COMPA_vect) {//Interrupt på freq 1 kHz
för (byte en = 0; en < 4; a ++) {
timeX [a] ++; //increment varje beståndsdel av timeX
}
Shift();
}
buttonCheck - kontrollerar status för en viss knapp.
denna buttoncheck funktion är i stort sett kopierade från monome 40h firmware brian crabtree och joe sjö
void buttonCheck (byte rad, byte index)
{
om (((buttonCurrent [rad] ^ buttonLast[row]) & (1 << index)) & & / / om det aktuella fysiska knapp läget skiljer sig från den
((buttonCurrent [rad] ^ buttonState[row]) & (1 << index))) {/ / last fysisk knapp staten och nuvarande debounced staten
om (buttonCurrent [rad] & (1 << index)) {/ / om nuläget fysisk knapp trycks
buttonEvent [rad] = 1 << index; köa upp en ny knapp händelse omedelbart
buttonState [rad] | = (1 << index); och ställa in debounced ner.
}
annat {
buttonDebounceCounter [rad] [index] = 12.
} / / annars knappen tidigare var deprimerad och nu
har släppts så vi våra debounce counter.
}
annars om (((buttonCurrent [rad] ^ buttonLast[row]) & (1 << index)) == 0 & & / / om det aktuella fysiska knapp läget är samma som
(buttonCurrent [rad] ^ buttonState[row]) & (1 << index)) {/ / den senaste fysiskt knappen stat men den nuvarande fysiskt
knappläge skiljer sig från den nuvarande debounce
statliga...
om (buttonDebounceCounter [rad] [index] > 0 & &--buttonDebounceCounter [rad] [index] == 0) {/ / om den räknaren debounce har
varit minskas till 0 (menande den
knappen har varit upp i
kButtonUpDefaultDebounceCount
iterationer / / /
buttonEvent [rad] = 1 << index; köa en knapp staten change-händelse
om (buttonCurrent [rad] & (1 << index)) {/ / och växla knapparna debounce staten.
buttonState [rad] | = (1 << index);
}
annat {
buttonState [rad] & = ~ (1 << index);
}
}
}
}
{Ogiltig shift()
för (jag = 0; jag < 4; i ++) {
buttonLast [i] = buttonCurrent [i];
byte dataToSend = (1 << (jag + 4)) | (15 & ~ ledData[i]);
ställa in spärren pin låg så lysdioderna inte ändra samtidigt skickas i bitar
PORTD & = B10111111; //digitalWrite (ledLatchPin, låg);
flytta ut bitarna av dataToSend
shiftOut (ledDataPin, ledClockPin, LSBFIRST, dataToSend);
för (j = 0; j < 8; j ++) {
PORTD & = B11011111;//digitalWrite(ledClockPin,LOW);
digitalWrite (ledDataPin, ((dataToSend >> j) & 1));
om ((dataToSend >> j) & 1) {
PORTD| = B10000000;
}
annat {
PORTD & = B01111111;
}
PORTD|=B00100000;//digitalWrite(ledClockPin,High);
}
ställa in spärren pin hög så lysdioderna kommer att få nya uppgifter
PORTD| = B01000000; //digitalWrite (ledLatchPin, hög);
Avmattningen sätts i här slösa bort lite tid medan vi väntar på statligt av produktionen
Pins sedimentera. Utan denna tid slösa slinga, skulle en enda knapptryckning dyka upp som
två pressar (knappen och dess granne)
flyktiga int avmattning = 0;
medan (avmattning < 15)
{
Avmattningen ++;
}
När en rad har ställts in hög, ta emot data från knappar
ställa in spärren pin hög
PORTD| = B00010000; //digitalWrite (buttonLatchPin, hög);
skifta i data
buttonCurrent [i] = shiftIn (buttonDataPin, buttonClockPin, LSBFIRST) >> 3.
för (j = 0; j < 4; j ++) {
PORTD & = B11110111;//digitalWrite(buttonClockPin,LOW);
PORTD|=B00001000;//digitalWrite(buttonClockPin,High);
}
för (j = 0; j < 4; j ++) {
PORTD & = B11110111;//digitalWrite(buttonClockPin,LOW);
om ((PIND >> 2) & 1){//digitalRead(buttonDataPin)
buttonCurrent [i] | = 1 << j;
}
annat {
buttonCurrent [i] & = ~ (1 << j);
}
PORTD|=B00001000;//digitalWrite(buttonClockPin,High);
}
latchpin låg
PORTD & = B11101111; //digitalWrite (buttonLatchPin, låg);
för (k = 0; k < 4; k ++) {
buttonCheck(i,k);
}
}
stänga av lysdioder - detta sätt en rad inte visas ljusare än resten
ställa in spärren pin låg så lysdioderna inte ändra samtidigt skickas i bitar
PORTD & = B10111111; //digitalWrite (ledLatchPin, låg);
flytta ut 0
shiftOut (ledDataPin, ledClockPin, LSBFIRST, 0);
för (j = 0; j < 8; j ++) {
PORTD & = B11011111;//digitalWrite(ledClockPin,LOW);
PORTD & = B01111111;
PORTD|=B00100000;//digitalWrite(ledClockPin,High);
}
ställa in spärren pin hög så lysdioderna kommer att få nya uppgifter
PORTD| = B01000000; //digitalWrite (ledLatchPin, hög);
}
void checkPress(byte Y) {
om (buttonEvent[Y]) {
för (byte b = 0; b < 4; b ++) {
om (buttonState [Y] & (1 << b)) {
Växla firstPress variabel
firstPress [Y] = 1;
Visa nertryckta pixel
ledData [Y] = (1 << b);
lagra aktuell position
xPosition [Y] = (1 << b);
lagra topphöjden
peakHeight [Y] = (1 << b);
Återställ timers
timeX [Y] = 0;
hemkomst.
}
}
}
}
byte scaleAcc (int RAW) {
om (RAW < = 10 & & RAW > =-10) {
returnera 5.
}
annars om (RAW < -10) {
om (RAW < -50) {
Return 0;
}
annars om (RAW < -40) {
tillbaka 1.
}
annars om (RAW < -30) {
returnera 2.
}
annars om (RAW < -20) {
returnera 3.
}
annat {
returnera 4.
}
}
annars om (RAW > 10) {
om (RAW > 50) {
returnera 10.
}
annars om (RAW > 40) {
returnera 9.
}
annars om (RAW > 30) {
returnera 8.
}
annars om (RAW > 20) {
returnera 7.
}
annat {
returnera 6.
}
}
}
void checkAccelerometerGyro() {
Läs värden
xGyroRAW = analogRead(A1);
yGyroRAW = analogRead(A0);
xAccRAW = analogRead(A4);
yAccRAW = analogRead(A3);
zAccRAW = analogRead(A2);
offset data
xGyroRAW = 317-xGyroRAW;
yGyroRAW = 183-yGyroRAW;
xAccRAW = 282-xAccRAW;
yAccRAW = 282-yAccRAW;
zAccRAW = 282-zAccRAW;
konvertera till 0-10
xAcc = scaleAcc(xAccRAW);
yAcc = scaleAcc(yAccRAW);
om (xAccRAW > 5) {
dirX = 1;
}
annars om (xAccRAW < 5) {
dirX = 0;
}
om (yAccRAW > 5) {
dirY = 1;
}
annars om (yAccRAW > 5) {
dirY = 0;
}
}
int getTime (byte acceleration) {
Växla (acceleration) {
fall 0: / / max - acceleration
gå tillbaka 100.
bryta;
fall 1:
gå tillbaka 100.
bryta;
fall 2:
returnera 150;
bryta;
fall 3:
returnera 200.
bryta;
fall 4:
returnera 250;
bryta;
fall 5: / / ligger platt
Return 0;
bryta;
fall 6:
returnera 250;
bryta;
fall 7:
returnera 200.
bryta;
mål 8:
returnera 150;
bryta;
mål 9:
gå tillbaka 100.
bryta;
mål 10: / / max + acceleration
gå tillbaka 100.
bryta;
}
}
void moveXPixel (byte Y, int timeComp) {
om (timeComp == 0) {
}
annat {
om (timeX [Y] > timeComp) {
timeX [Y] = 0;
om (dirX) {
om (peakHeight [Y] == 8 & & xPosition[Y]==8) {
IF(Toggle[Y]) {
MIDImessage (noteON, Obs [Y], 0); //send midi
växla mellan [Y] = 0;
ledData [Y] = 0;
}
annat {
MIDImessage(noteON,note[Y],velocity);
växla mellan [Y] = 1;
}
}
annat {
växla mellan [Y] = 1;
om (xPosition[Y]==peakHeight[Y]) {//if på topp
bounceDirection [Y] = 1; //falling
MIDImessage (noteON, Obs [Y], 0); //turn anmärkning av
}
om (xPosition[Y]==8) {//if slår botten
bounceDirection [Y] = 0; //rising
MIDImessage (noteON, Obs [Y], velocity); //turn anteckning på
}
om (xPosition[Y]==1) {
bounceDirection [Y] = 1;
}
om (bounceDirection[Y]) {
xPosition [Y] = xPosition [Y] << 1;
}
annat {
xPosition [Y] = xPosition [Y] >> 1;
}
}
}
annat {
om (peakHeight [Y] == 1 & & xPosition[Y]==1) {
IF(Toggle[Y]) {
MIDImessage (noteON, Obs [Y], 0); //send midi
växla mellan [Y] = 0;
ledData [Y] = 0;
}
annat {
MIDImessage(noteON,note[Y],velocity);
växla mellan [Y] = 1;
}
}
annat {
växla mellan [Y] = 1;
om (xPosition[Y]==peakHeight[Y]) {//if på topp
bounceDirection [Y] = 0; //falling
MIDImessage (noteON, Obs [Y], 0); //turn anmärkning av
}
om (xPosition[Y]==8) {
bounceDirection [Y] = 0;
}
om (xPosition[Y]==1) {//if slår botten
bounceDirection [Y] = 1; //rising
MIDImessage (noteON, Obs [Y], velocity); //turn anteckning på
}
om (bounceDirection[Y]) {
xPosition [Y] = xPosition [Y] << 1;
}
annat {
xPosition [Y] = xPosition [Y] >> 1;
}
}
}
}
}
}
void shake2Clear() {
om (abs(xGyroRAW) > 300) {
för (byte en = 0; en < 4; a ++) {
firstPress [a] = 0;
ledData [a] = 0;
}
}
}
void MIDImessage (int befalla, int MIDInote, int MIDIvelocity) {//send s ett MIDI-meddelande
Serial.write (kommandot); //send på eller av kommandot
Serial.write (MIDInote); //send pitch data
Serial.write (MIDIvelocity); //send hastighet data
}
void loop() {
checkAccelerometerGyro();
shake2Clear();
för (byte kolumn = 0; kolumnen < 4; kolumn ++) {
checkPress(column);
om (firstPress[column]) {
moveXPixel (kolumn, getTime(xAcc));
om (toggle[column]) {
ledData [kolumn] = xPosition [kolumn].
}
}
}
}