DIY Réalisation d'un Sugarcube MIDI Controller
- 3 réponses
- 2 participants
- 449 vues
- 5 followers
![Mat Martigan Mat Martigan](https://img.audiofanzine.com/img/user/avatar/6/5/657327.jpg?w=40&h=40&fm=pjpg&s=a7cc4baacdab6b4a0b74455bdbfae6e4)
Mat Martigan
105
![105 posts au compteur 105 posts au compteur](https://static.audiofanzine.com/images/audiofanzine/forum/avatars/new/3.png)
Posteur·euse AFfiné·e
Membre depuis 12 ans
Sujet de la discussion Posté le 31/10/2019 à 09:42:59DIY Réalisation d'un Sugarcube MIDI Controller
Bonjour a tous
J'essaye de réaliser un stepsequencer à base de matrice de led/button Sparkfun
https://www.sparkfun.com/products/7835
![bidouille-developpement-informatique-2783068.jpg bidouille-developpement-informatique-2783068.jpg](https://medias.audiofanzine.com/images/thumbs3/bidouille-developpement-informatique-2783068.jpg)
Pour ce fait je me base sur la création d'un Sugarcube Afin premièrement d'apprendre le fonctionnement des registre à décalage et deuxièmement d'avoir une base de programme sur laquelle je peux m'appuyer
https://www.instructables.com/id/Multiplexing-with-Arduino-and-the-74HC595/
https://www.instructables.com/id/Sugarcube-MIDI-Controller/
Le montage est effectué et j'ai pu effectuer les programmes test
Un exemple ici
avec ce programme j'ai 1 button = 1 led = 1 note Midi bref un clavier midi 16 note
C'est après que sa se gâte si je puis dire
Le programme complet compile
Le problème est que lorsque j'upload son programme complet c'est a dire son programme final il n'y a rien qui se passe
La programmatrice se sert d'un programme principal qui appelle plusieurs librairies
il n'y a pas de boucle principale ni de fonction delay car un timer est généré d’après ce que j'ai pu comprendre
J'ai checké toutes les soudures et les éventuelles faux contact ainsi que le schéma de câblage
Son programme est il erroné pour la version actuel de l’Arduino ? car le projet n'est pas récent
![bidouille-developpement-informatique-2783084.jpg bidouille-developpement-informatique-2783084.jpg](https://medias.audiofanzine.com/images/thumbs3/bidouille-developpement-informatique-2783084.jpg)
![bidouille-developpement-informatique-2783085.jpg bidouille-developpement-informatique-2783085.jpg](https://medias.audiofanzine.com/images/thumbs3/bidouille-developpement-informatique-2783085.jpg)
![bidouille-developpement-informatique-2783086.jpg bidouille-developpement-informatique-2783086.jpg](https://medias.audiofanzine.com/images/thumbs3/bidouille-developpement-informatique-2783086.jpg)
J'essaye de réaliser un stepsequencer à base de matrice de led/button Sparkfun
https://www.sparkfun.com/products/7835
![bidouille-developpement-informatique-2783068.jpg bidouille-developpement-informatique-2783068.jpg](https://medias.audiofanzine.com/images/thumbs3/bidouille-developpement-informatique-2783068.jpg)
Pour ce fait je me base sur la création d'un Sugarcube Afin premièrement d'apprendre le fonctionnement des registre à décalage et deuxièmement d'avoir une base de programme sur laquelle je peux m'appuyer
https://www.instructables.com/id/Multiplexing-with-Arduino-and-the-74HC595/
https://www.instructables.com/id/Sugarcube-MIDI-Controller/
Le montage est effectué et j'ai pu effectuer les programmes test
Un exemple ici
//BUTTON TEST w/ 74HC595 and 74HC165
//by Amanda Ghassaei 2012
//pin connections
int ledLatchPin = 6;
int ledClockPin = 5;
int ledDataPin = 7;
int buttonLatchPin = 4;
int buttonClockPin = 3;
int buttonDataPin = 2;
//looping variables
byte i;
byte j;
byte k;
//storage for led states, 4 bytes
byte ledData[] = {0, 0, 0, 0};
//storage for buttons, 4 bytes
byte buttonCurrent[] = {0,0,0,0};
byte buttonLast[] = {0,0,0,0};
byte buttonEvent[] = {0,0,0,0};
byte buttonState[] = {0,0,0,0};
//button debounce counter- 16 bytes
byte buttonDebounceCounter[4][4];
void setup() {
DDRD = 0xFA;//set pins D7-D4 as output, D2 as input
}
// buttonCheck - checks the state of a given button.
//this buttoncheck function is largely copied from the monome 40h firmware by brian crabtree and joe lake
void buttonCheck(byte row, byte index)
{
if (((buttonCurrent[row] ^ buttonLast[row]) & (1 << index)) && // if the current physical button state is different from the
((buttonCurrent[row] ^ buttonState[row]) & (1 << index))) { // last physical button state AND the current debounced state
if (buttonCurrent[row] & (1 << index)) { // if the current physical button state is depressed
buttonEvent[row] = 1 << index; // queue up a new button event immediately
buttonState[row] |= (1 << index); // and set the debounced state to down.
}
else{
buttonDebounceCounter[row][index] = 12;
} // otherwise the button was previously depressed and now
// has been released so we set our debounce counter.
}
else if (((buttonCurrent[row] ^ buttonLast[row]) & (1 << index)) == 0 && // if the current physical button state is the same as
(buttonCurrent[row] ^ buttonState[row]) & (1 << index)) { // the last physical button state but the current physical
// button state is different from the current debounce
// state...
if (buttonDebounceCounter[row][index] > 0 && --buttonDebounceCounter[row][index] == 0) { // if the the debounce counter has
// been decremented to 0 (meaning the
// the button has been up for
// kButtonUpDefaultDebounceCount
// iterations///
buttonEvent[row] = 1 << index; // queue up a button state change event
if (buttonCurrent[row] & (1 << index)){ // and toggle the buttons debounce state.
buttonState[row] |= (1 << index);
}
else{
buttonState[row] &= ~(1 << index);
}
}
}
}
void shift(){
for (i=0;i<4;i++){
buttonLast[i] = buttonCurrent[i];
byte dataToSend = (1 << (i+4)) | (15 & ~ledData[i]);
// set latch pin low so the LEDs don't change while sending in bits
digitalWrite(ledLatchPin, LOW);
// shift out the bits of dataToSend
shiftOut(ledDataPin, ledClockPin, LSBFIRST, dataToSend);
//set latch pin high so the LEDs will receive new data
digitalWrite(ledLatchPin, HIGH);
//once one row has been set high, receive data from buttons
//set latch pin high
digitalWrite(buttonLatchPin, HIGH);
//shift in data
buttonCurrent[i] = shiftIn(buttonDataPin, buttonClockPin, LSBFIRST) >> 3;
//latchpin low
digitalWrite(buttonLatchPin, LOW);
for (k=0;k<4;k++){
buttonCheck(i,k);
}
}
}
void updateLEDs(){ //update the leds to reflect hte state of the buttons
for (j=0;j<4;j++){
ledData[j] = buttonState[j];
}
}
void loop() {
shift();
updateLEDs();
}
avec ce programme j'ai 1 button = 1 led = 1 note Midi bref un clavier midi 16 note
C'est après que sa se gâte si je puis dire
Le programme complet compile
Le problème est que lorsque j'upload son programme complet c'est a dire son programme final il n'y a rien qui se passe
La programmatrice se sert d'un programme principal qui appelle plusieurs librairies
il n'y a pas de boucle principale ni de fonction delay car un timer est généré d’après ce que j'ai pu comprendre
J'ai checké toutes les soudures et les éventuelles faux contact ainsi que le schéma de câblage
Son programme est il erroné pour la version actuel de l’Arduino ? car le projet n'est pas récent
![bidouille-developpement-informatique-2783084.jpg bidouille-developpement-informatique-2783084.jpg](https://medias.audiofanzine.com/images/thumbs3/bidouille-developpement-informatique-2783084.jpg)
![bidouille-developpement-informatique-2783085.jpg bidouille-developpement-informatique-2783085.jpg](https://medias.audiofanzine.com/images/thumbs3/bidouille-developpement-informatique-2783085.jpg)
![bidouille-developpement-informatique-2783086.jpg bidouille-developpement-informatique-2783086.jpg](https://medias.audiofanzine.com/images/thumbs3/bidouille-developpement-informatique-2783086.jpg)
[ Dernière édition du message le 02/11/2019 à 20:46:34 ]
![Rémy M. (chimimic) Rémy M. (chimimic)](https://img.audiofanzine.com/img/user/avatar/5/7/5775.jpg?w=40&h=40&fm=pjpg&s=eb14dd2468c0b835d1966880e02541e0)
Rémy M. (chimimic)
14218
![14218 posts au compteur 14218 posts au compteur](https://static.audiofanzine.com/images/audiofanzine/forum/avatars/new/moderator_thematic.png)
Modérateur·trice thématique
Membre depuis 22 ans
2 Posté le 31/10/2019 à 10:47:23
Citation :
il n'y a pas de boucle principale
Or, tu as bien :
void loop() {
shift();
updateLEDs();
}
Ou alors, je ne comprends pas ce que tu veux dire.
Formateur en techniques sonores ; électronicien ; auteur @ sonelec-musique.com
[ Dernière édition du message le 31/10/2019 à 10:48:17 ]
![Mat Martigan Mat Martigan](https://img.audiofanzine.com/img/user/avatar/6/5/657327.jpg?w=40&h=40&fm=pjpg&s=a7cc4baacdab6b4a0b74455bdbfae6e4)
Mat Martigan
105
![105 posts au compteur 105 posts au compteur](https://static.audiofanzine.com/images/audiofanzine/forum/avatars/new/3.png)
Posteur·euse AFfiné·e
Membre depuis 12 ans
3 Posté le 31/10/2019 à 11:30:46
Citation :
Or, tu as bien :
void loop() {
shift();
updateLEDs();
}
oui pour le programme de test des notes Midi
Pour le programme principal ;
https://github.com/amandaghassaei/Sugarcube-Arduino-Library
#include "SugarCube.h"
SugarCube sugarcube;
void setup()
{
// default pin connections are given below:
// Analog
// 0 - Gyroscope Y (Y4.5)
// 1 - Potentiometer 1
// 2 - Gyroscope X (X4.5)
// 3 - Accelerometer Y (YAcc)
// 4 - Accelerometer X (XAcc)
// 5 - Potentiometer 2
// Digital
// 0 - serial in - this much remain unconnected
// 1 - serial out - this is hooked up to the MIDI output
// 2 - 74HC165 data pin (Q7)
// 3 - 74HC165 clock pin (CP)
// 4 - 74HC165 latch pin (PL)
// 5 - 74HC595 clock pin (SH_CP)
// 6 - 74HC595 latch pin (ST_CP)
// 7 - 74HC595 data pin (DS)
//
// set custom pin connections using the following commands, this must happen before sugarcube.init()
// leave digital pins 0 and 1 (RX/TX Serial pins) empty
sugarcube.setLedLatchPin(6);
sugarcube.setLedClockPin(5);
sugarcube.setLedDataPin(7);
sugarcube.setButtonLatchPin(4);
sugarcube.setButtonClockPin(3);
sugarcube.setButtonDataPin(2);
// sugarcube.setXAccPin(A4);
// sugarcube.setYAccPin(A3);
sugarcube.setPot1Pin(A1);
sugarcube.setPot2Pin(A5);
// sugarcube.setXGyroPin(A2);
// sugarcube.setYGyroPin(A0);
byte patchNum = sugarcube.init();
switch(patchNum) {
case 0:
{
StepSequencer stepSequencer;
sugarcube.setDelegate(&stepSequencer);
for (;[img alt=";)"]https://static.audiofanzine.com/images/audiofanzine/interface/smileys/icon_wink.gif[/img] {}
}
case 1:
{
Flin flin;
sugarcube.setDelegate(&flin);
for (;[img alt=";)"]https://static.audiofanzine.com/images/audiofanzine/interface/smileys/icon_wink.gif[/img] {}
}
case 2:
{
Boiing boiing;
sugarcube.setDelegate(&boiing);
for (;[img alt=";)"]https://static.audiofanzine.com/images/audiofanzine/interface/smileys/icon_wink.gif[/img] {}
}
case 3:
{
Arp arp;
sugarcube.setDelegate(&arp);
for (;[img alt=";)"]https://static.audiofanzine.com/images/audiofanzine/interface/smileys/icon_wink.gif[/img] {}
}
case 4:
{
SimpleMIDIKeyboard simpleMIDIKeyboard;
sugarcube.setDelegate(&simpleMIDIKeyboard);
for (;[img alt=";)"]https://static.audiofanzine.com/images/audiofanzine/interface/smileys/icon_wink.gif[/img] {}
}
case 5:
{
PixelTilt pixelTilt;
sugarcube.setDelegate(&pixelTilt);
for (;[img alt=";)"]https://static.audiofanzine.com/images/audiofanzine/interface/smileys/icon_wink.gif[/img] {}
}
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
{
SerialComm serialComm;
sugarcube.setDelegate(&serialComm);
for (;[img alt=";)"]https://static.audiofanzine.com/images/audiofanzine/interface/smileys/icon_wink.gif[/img] {}
}
break;
}
}
void loop()
{
}
//---------------------------------------------------------------------
//--------------------INTERRUPT ROUTINES-------------------------------
//---------------------------------------------------------------------
ISR(TIMER1_COMPA_vect)
{//time 1 interrupt, at freq of 1kHz
sugarcube.timer1Routine();
}
ISR(TIMER2_COMPA_vect)
{//timer 2 interupt, every 128us
sugarcube.timer2Routine();
}
![bidouille-developpement-informatique-2783191.png bidouille-developpement-informatique-2783191.png](https://medias.audiofanzine.com/images/thumbs3/bidouille-developpement-informatique-2783191.png)
![Mat Martigan Mat Martigan](https://img.audiofanzine.com/img/user/avatar/6/5/657327.jpg?w=40&h=40&fm=pjpg&s=a7cc4baacdab6b4a0b74455bdbfae6e4)
Mat Martigan
105
![105 posts au compteur 105 posts au compteur](https://static.audiofanzine.com/images/audiofanzine/forum/avatars/new/3.png)
Posteur·euse AFfiné·e
Membre depuis 12 ans
4 Posté le 07/11/2019 à 16:49:03
J'ai également pu tester ce programme qui intègre un timer et il fonctionne
C'est une fonction midi qui se trouve dans le Sugarcube
Une sorte de lecture de note va et vient sur chaque ligne et modifiable via un accéléromètre
Cela veut dire que mon montage est bon et que le programme principale sur Sugarcube ne marche pas c'est comme si je chargeais un programme vide.
Si Il y a quelque qui gère la programmation orienté objet afin de trouver une explication de se qui va pas de le code?
C'est une fonction midi qui se trouve dans le Sugarcube
Une sorte de lecture de note va et vient sur chaque ligne et modifiable via un accéléromètre
Cela veut dire que mon montage est bon et que le programme principale sur Sugarcube ne marche pas c'est comme si je chargeais un programme vide.
Si Il y a quelque qui gère la programmation orienté objet afin de trouver une explication de se qui va pas de le code?
//accelerometer test- bounce
//by Amanda Ghassaei 2012
//[url]https://www.instructables.com/id/Send-and-Receive-MIDI-with-Arduino/[/url]
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*/
//pin connections
//#define ledLatchPin 6
//#define ledClockPin 5
//#define ledDataPin 7
//#define buttonLatchPin 4
//#define buttonClockPin 3
//#define buttonDataPin 2
//setup varibles for Gyroscope/Accelerometer
int xGyroRAW;
int yGyroRAW;
int xAccRAW;
int yAccRAW;
int zAccRAW;
byte xGyro;
byte yGyro;
byte xAcc;
byte yAcc;
byte zAcc;
//looping variables
byte i;
byte j;
byte k;
//storage for led states, 4 bytes
byte ledData[] = {0, 0, 0, 0};
//storage for buttons, 4 bytes
byte buttonCurrent[] = {0,0,0,0};
byte buttonLast[] = {0,0,0,0};
byte buttonEvent[] = {0,0,0,0};
byte buttonState[] = {0,0,0,0};
//button debounce counter- 16 bytes
byte buttonDebounceCounter[4][4];
//variables for accelerometer pixel movement
boolean firstPress[] = {0, 0, 0, 0};
byte movingPixel[] = {0, 0, 0, 0};
byte xPosition[4];
int timeX[] = {0, 0, 0, 0};
boolean dirX;
boolean dirY;
boolean prevDirX = 0;
boolean bounceDirection[]= {0, 0, 0, 0};
boolean toggle[] = {1, 1, 1, 1};
byte peakHeight[4];
byte lastX = 4;
byte lastY = 4;
//MIDI variables
int velocity = 100;
int noteON = 144;
int MIDIoffset = 60;
byte currentX;
byte note[] = {60, 64, 67, 72};
void setup() {
DDRD = 0xFA;//set pins D7-D4 as output, D2 as input
Serial.begin(31250);//MIDI baud rate
cli();//stop interrupts
//set timer1 interrupt at 1kHz
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;//initialize counter value to 0;
// set timer count for 1khz increments
OCR1A = 1999;// = (16*10^6) / (1000*8) - 1
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS11 bit for 8 prescaler
TCCR1B |= (1 << CS11);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
sei();//allow interrupts
}
ISR(TIMER1_COMPA_vect) {//Interrupt at freq of 1kHz
for (byte a=0;a<4;a++){
timeX[a]++;//increment each element of timeX
}
shift();
}
// buttonCheck - checks the state of a given button.
//this buttoncheck function is largely copied from the monome 40h firmware by brian crabtree and joe lake
void buttonCheck(byte row, byte index)
{
if (((buttonCurrent[row] ^ buttonLast[row]) & (1 << index)) && // if the current physical button state is different from the
((buttonCurrent[row] ^ buttonState[row]) & (1 << index))) { // last physical button state AND the current debounced state
if (buttonCurrent[row] & (1 << index)) { // if the current physical button state is depressed
buttonEvent[row] = 1 << index; // queue up a new button event immediately
buttonState[row] |= (1 << index); // and set the debounced state to down.
}
else{
buttonDebounceCounter[row][index] = 12;
} // otherwise the button was previously depressed and now
// has been released so we set our debounce counter.
}
else if (((buttonCurrent[row] ^ buttonLast[row]) & (1 << index)) == 0 && // if the current physical button state is the same as
(buttonCurrent[row] ^ buttonState[row]) & (1 << index)) { // the last physical button state but the current physical
// button state is different from the current debounce
// state...
if (buttonDebounceCounter[row][index] > 0 && --buttonDebounceCounter[row][index] == 0) { // if the the debounce counter has
// been decremented to 0 (meaning the
// the button has been up for
// kButtonUpDefaultDebounceCount
// iterations///
buttonEvent[row] = 1 << index; // queue up a button state change event
if (buttonCurrent[row] & (1 << index)){ // and toggle the buttons debounce state.
buttonState[row] |= (1 << index);
}
else{
buttonState[row] &= ~(1 << index);
}
}
}
}
void shift(){
for (i=0;i<4;i++){
buttonLast[i] = buttonCurrent[i];
byte dataToSend = (1 << (i+4)) | (15 & ~ledData[i]);
// set latch pin low so the LEDs don't change while sending in bits
PORTD&=B10111111;//digitalWrite(ledLatchPin, LOW);
// shift out the bits of dataToSend
//shiftOut(ledDataPin, ledClockPin, LSBFIRST, dataToSend);
for (j=0;j<8;j++){
PORTD&=B11011111;//digitalWrite(ledClockPin,LOW);
//digitalWrite(ledDataPin,((dataToSend>>j)&1));
if ((dataToSend>>j)&1){
PORTD|=B10000000;
}
else{
PORTD&=B01111111;
}
PORTD|=B00100000;//digitalWrite(ledClockPin,HIGH);
}
//set latch pin high so the LEDs will receive new data
PORTD|=B01000000;//digitalWrite(ledLatchPin, HIGH);
// SlowDown is put in here to waste a little time while we wait for the state of the output
// pins to settle. Without this time wasting loop, a single button press would show up as
// two presses (the button and its neighbour)
volatile int SlowDown = 0;
while (SlowDown < 15)
{
SlowDown++;
}
//once one row has been set high, receive data from buttons
//set latch pin high
PORTD|=B00010000;//digitalWrite(buttonLatchPin, HIGH);
//shift in data
//buttonCurrent[i] = shiftIn(buttonDataPin, buttonClockPin, LSBFIRST) >> 3;
for (j=0;j<4;j++){
PORTD&=B11110111;//digitalWrite(buttonClockPin,LOW);
PORTD|=B00001000;//digitalWrite(buttonClockPin,HIGH);
}
for (j=0;j<4;j++){
PORTD&=B11110111;//digitalWrite(buttonClockPin,LOW);
if ((PIND>>2)&1){//digitalRead(buttonDataPin)
buttonCurrent[i]|=1<<j;
}
else{
buttonCurrent[i]&=~(1<<j);
}
PORTD|=B00001000;//digitalWrite(buttonClockPin,HIGH);
}
//latchpin low
PORTD&=B11101111;//digitalWrite(buttonLatchPin, LOW);
for (k=0;k<4;k++){
buttonCheck(i,k);
}
}
//turn off leds- this way one row does not appear brighter than the rest
// set latch pin low so the LEDs don't change while sending in bits
PORTD&=B10111111;//digitalWrite(ledLatchPin, LOW);
// shift out 0
//shiftOut(ledDataPin, ledClockPin, LSBFIRST, 0);
for (j=0;j<8;j++){
PORTD&=B11011111;//digitalWrite(ledClockPin,LOW);
PORTD&=B01111111;
PORTD|=B00100000;//digitalWrite(ledClockPin,HIGH);
}
//set latch pin high so the LEDs will receive new data
PORTD|=B01000000;//digitalWrite(ledLatchPin, HIGH);
}
void checkPress(byte Y){
if (buttonEvent[y]){
for (byte b=0;b<4;b++){
if (buttonState[y]&(1<<b)){
//toggle firstPress variable
firstPress[y] = 1;
//display pressed pixel
ledData[y] = (1<<b);
//store current position
xPosition[y] = (1<<b);
//store peak height
peakHeight[y] = (1<<b);
//reset timers
timeX[y] = 0;
return;
}
}
}
}
byte scaleAcc(int RAW){
if (RAW<=10 && RAW>=-10){
return 5;
}
else if (RAW<-10){
if (RAW<-50){
return 0;
}
else if (RAW<-40){
return 1;
}
else if (RAW<-30){
return 2;
}
else if (RAW<-20){
return 3;
}
else{
return 4;
}
}
else if (RAW>10){
if (RAW>50){
return 10;
}
else if (RAW>40){
return 9;
}
else if (RAW>30){
return 8;
}
else if (RAW>20){
return 7;
}
else{
return 6;
}
}
}
void checkAccelerometerGyro(){
//read values
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;
//convert to 0-10
xAcc = scaleAcc(xAccRAW);
yAcc = scaleAcc(yAccRAW);
if (xAccRAW>5){
dirX = 1;
}
else if (xAccRAW<5){
dirX = 0;
}
if (yAccRAW>5){
dirY = 1;
}
else if (yAccRAW>5){
dirY = 0;
}
}
int getTime(byte acceleration){
switch (acceleration){
case 0://max - acceleration
return 100;
break;
case 1:
return 100;
break;
case 2:
return 150;
break;
case 3:
return 200;
break;
case 4:
return 250;
break;
case 5://lying flat
return 0;
break;
case 6:
return 250;
break;
case 7:
return 200;
break;
case 8:
return 150;
break;
case 9:
return 100;
break;
case 10://max + acceleration
return 100;
break;
}
}
void moveXPixel(byte Y, int timeComp){
if (timeComp==0){
}
else{
if (timeX[y]>timeComp){
timeX[y] = 0;
if (dirX){
if (peakHeight[y]==8&&xPosition[y]==8){
if(toggle[y]){
MIDImessage(noteON,note[y],0);//send midi
toggle[y]=0;
ledData[y]=0;
}
else{
MIDImessage(noteON,note[y],velocity);
toggle[y]=1;
}
}
else{
toggle[y]=1;
if (xPosition[y]==peakHeight[y]){//if at peak
bounceDirection[y]=1;//falling
MIDImessage(noteON,note[y],0);//turn note off
}
if (xPosition[y]==8){//if hitting bottom
bounceDirection[y]=0;//rising
MIDImessage(noteON,note[y],velocity);//turn note on
}
if (xPosition[y]==1){
bounceDirection[y]=1;
}
if (bounceDirection[y]){
xPosition[y] = xPosition[y]<<1;
}
else{
xPosition[y] = xPosition[y]>>1;
}
}
}
else{
if (peakHeight[y]==1&&xPosition[y]==1){
if(toggle[y]){
MIDImessage(noteON,note[y],0);//send midi
toggle[y]=0;
ledData[y]=0;
}
else{
MIDImessage(noteON,note[y],velocity);
toggle[y]=1;
}
}
else{
toggle[y]=1;
if (xPosition[y]==peakHeight[y]){//if at peak
bounceDirection[y]=0;//falling
MIDImessage(noteON,note[y],0);//turn note off
}
if (xPosition[y]==8){
bounceDirection[y]=0;
}
if (xPosition[y]==1){//if hitting bottom
bounceDirection[y]=1;//rising
MIDImessage(noteON,note[y],velocity);//turn note on
}
if (bounceDirection[y]){
xPosition[y] = xPosition[y]<<1;
}
else{
xPosition[y] = xPosition[y]>>1;
}
}
}
}
}
}
void shake2Clear(){
if (abs(xGyroRAW)>300){
for (byte a=0;a<4;a++){
firstPress[a]=0;
ledData[a]=0;
}
}
}
void MIDImessage(int command, int MIDInote, int MIDIvelocity) {//send s a MIDI message
Serial.write(command);//send note on or note off command
Serial.write(MIDInote);//send pitch data
Serial.write(MIDIvelocity);//send velocity data
}
void loop() {
checkAccelerometerGyro();
shake2Clear();
for (byte column=0;column<4;column++){
checkPress(column);
if (firstPress[column]){
moveXPixel(column, getTime(xAcc));
if (toggle[column]){
ledData[column]= xPosition[column];
}
}
}
}
- < Liste des sujets
- Charte