Contrôleur de multitouch musique (22 / 26 étapes)

Étape 22 : Firmware

Télécharger le firmware suivant au Conseil d’administration :

www.Monome.org www.Monome.org www.Monome.org www.Monome.org * * / / / affectations de PIN et le PORT / / si vous utilisez un matériel autre que le bouclier unsped, vous aurez envie de passer par cette partie du code, / / et modifier les codes pin et les PORTs d’atmega 168 que vous utilisez. Nous utilisons les affectations de PORT/broches ici, / / sorties pas le modèle de numéros pin de la carte arduino (p. ex. arduino de broche numérique 8 = port pin 1) / / Cependant, dans les commentaires ci-dessous, je donne les équivalents entre les numéros de broche numérique arduino et le / / atmega168 PORT/bit numérotation. IMPORTANT - vous aurez besoin pour vous assurer que vous avez défini les données suite à deux variables de registre de direction pour faire correspondre votre / / affectations des broches
. octet PORTD_Data_Direction = 0 x 02 ; //all entrées sauf pin 1 octet (TX) PORTB_Data_Direction = 0xFF ; //all sorties octets PORTC_Data_Direction = 0xFC ; //A2-A5 sont sorties, A0, A1 entrées //Connections à 595 Maj Registre //dataPin = A4 = PORTC, bit 4 //clockPin = A2 = PORTC, //latchPin bit 2 = A3 = PORTC, bit 3 #define DATA_PORT_595 (PORTC) octets dataPin595 = 4 ; dataPin595MaskHigh octets = 1 << dataPin595 ; dataPin595MaskLow octets = ~ dataPin595MaskHigh ; #define CLOCK_PORT_595 (PORTC) octets clockPin595 = 2 ; clockPin595MaskHigh octets = 1 << clockPin595 ; clockPin595MaskLow octets = ~ clockPin595MaskHigh ; #define LATCH_PORT_595 (PORTC) octets latchPin595 = 3 ; latchPin595MaskHigh octets = 1 << latchPin595 ; latchPin595MaskLow octets = ~ latchPin595MaskHigh ; Connexions vers le Max7219 (disques LEDS) / / dataIn = goupille d’arduino A5 = PORTC, bit 5 / / load = arduino broche 11 = PORTB bit 4 / / horloge = arduino pin 12 = PORTB, 5 #define LED_DATA_PORT (PORTC) octet MaxDataPin = 5 ; octet DataMaskHigh = 1 << MaxDataPin ; octet DataMaskLow = ~ DataMaskHigh ; octet de #define LED_CLOCK_PORT (PORTB) MaxClockPin = 5 ; octet ClockMaskHigh = 1 << MaxClockPin ; octet ClockMaskLow = ~ ClockMaskHigh ; octet de #define LED_LOAD_PORT (PORTB) MaxLoadPin = 4 ; octet LoadMaskHigh = 1 << MaxLoadPin ; octet LoadMaskLow = ~ LoadMaskHigh ; terminaisons au déplacement 165 Registre //use ceci pour corriger la mise en miroir de mirrorXLEDs boolean = true ; mirrorYLEDs booléen = false ; mirrorXButtons booléen = false ; mirrorYButtons booléen = false ; Tige d’extrémité et les affectations de PORT / /---/ / Global variables byte byte0, octet1 ; stockage pour entrant octet de données serial WaitingForAddress = 1 ; 1 quand nous attendons l’octet suivant série à être une valeur d’adresse, l’adresse 0 octets sinon = 0 x 00 ; octet d’ordures pour contenir l’adresse d’état de fonction octet = 0 x 00 ; octet d’ordures de tenir octet de valeur d’État x = 0 x 00 ; octet d’ordures de tenir position octet XY = 0 x 00 ; octet d’ordures s’y position octet z = 0 x 00 ; octet d’ordures pour itérer sur les boutons / / les variables suivantes sont utilisées pour stocker des indicateurs qui spécifient si nous avons reçu un message donné, / / la valeur des données dans ce message. par exemple IntensityChange = 0 ne == aucun message de changement d’intensité reçue, / / IntensityChange = 1 == un changement d’intensité message a été reçu, et sa valeur sera en IntensityVal / / le code qui finalement agit sur le message entrant réinitialisera la variable « Changer » à 0 une fois la / / le message a été géré. octet IntensityChange = 0 ; octet IntensityVal = 0 ; octet DisplayTestChange = 0 ; octet DisplayTestVal = 0 ; octet ShutdownModeChange = 0 ; octet ShutdownModeVal = 0 ; Ces variables sont utilisées pour gérer les messages de l’ADC et magasin quels ports sont actuellement activées, / / et qui ne le sont pas. octet ADCnum ; octet ADCstate ; octet ADCEnableState [4] ; ledmem Byte [8] ; mémoire pour LED États - 64 bits. octet j = 0 ; variable temporaire pour bouton boucle int i = 0 ; variable temporaire pour boucler id int etc. = 0 ; stockage temporaire pour les messages entrants ID octet firstRun = 1 ; 1 lorsque nous devons encore recevoir une commande de LED, 0 après cela. utilisé pour faire en sorte que notre mémoire d’État led est correctement initialisé lorsque nous recevons le premier message LED int kButtonUpDefaultDebounceCount = 12 ; Utilisé en bouton debouncing int kButtonNewEvent = 1 ; Utilisé pour stocker si l’état d’un bouton a changé ou non. octet t = 0 ; variable temporaire utilisé dans le traitement de bouton / * VARIABLES de tableau de bouton pour les États du bouton 1/0, utilisez 8 octets (64 bits) pour counter debounce bouton, utilisez tableau de 8 x 8 * / button_current byte [8] ; button_last Byte [8] ; button_state Byte [8] ; button_debounce_count Byte [8] [8] ; button_event Byte [8] ; / * FIN du bouton VARIABLES de tableau * / / * MAX 7219 adresses d’INSTRUCTION * / max7219_reg_noop octet = 0 x 00 ; définir max7219 registres (lire la doc tech pour explication) octets max7219_reg_digit0 = 0 x 01 ; max7219_reg_digit1 octet = 0 x 02 ; max7219_reg_digit2 octet = 0 x 03 ; max7219_reg_digit3 octet = 0 x 04 ; max7219_reg_digit4 octet = 0 x 05 ; max7219_reg_digit5 octet = 0 x 06 ; max7219_reg_digit6 octet = 0 x 07 ; max7219_reg_digit7 octet = 0 x 08 ; max7219_reg_decodeMode octet = 0 x 09 ; max7219_reg_intensity octets = 0x0a ; max7219_reg_scanLimit octets = 0x0b ; max7219_reg_shutdown octets = 0x0c ; max7219_reg_displayTest octets = 0x0f ; / * FIN des adresses d’INSTRUCTION MAX 7219 * / / / putByte - fonction d’assistance qui envoie un octet unique au MAX puce Sub putByte (données d’octets) {octets j’ai = 8; masque octets ; while(i > 0) {masque = 0 x 01 << (i - 1); / / obtenir le masque de bits si (données & masque) / / vérifier et envoyer la valeur de ce bit {LED_DATA_PORT | = DataMaskHigh;} else {LED_DATA_PORT & = DataMaskLow;} / / Pulse de l’horloge de MAX LED_CLOCK_PORT & = ClockMaskLow; / / digitalWrite (horloge FAIBLE) ; « tick » prepeare pour les bits d’entrée LED_CLOCK_PORT | = ClockMaskHigh; / / digitalWrite (horloge, haut) ; bit d’entrée « tock »--i ; //maxSingle passage à moindre bit}} est la fonction « facile » à utiliser pour un //dig unique max7219 est l’appel de la ligne et seg est la colonne appel creuser et seg référence aux noms de broche de tech doc maxSingle Sub (dig octet, octet seg) {LED_LOAD_PORT & = LoadMaskLow; / / digitalWrite (charge, LOW); / / commencer putByte(dig); / / préciser le registre putByte(seg); / / ((data & 0x01) * 256) + données >> 1) ; mettre les données LED_LOAD_PORT | = LoadMaskHigh ; digitalWrite(load,HIGH) ; } / / buttonInit - fonction d’assistance qui zéros le bouton États Sub buttonInit(void) {octets j’ai ; pour (i = 0; j’ai < 8; i ++) {button_current [i] = 0 x 00 ; button_last [i] = 0 x 00 ; button_state [i] = 0 x 00 ; button_event [i] = 0 x 00;}} / / buttonCheck - vérifie l’état d’un bouton donné. void buttonCheck (octets par ligne, index de l’octet) {si (((button_current [en ligne] ^ button_last[row]) & (1 << index)) & & / / si l’état de bouton physique actuelle est différente de la ((button_current [en ligne] ^ button_state[row]) & (1 << index))) {/ / dernier état du bouton physique et le courant debounced État si (button_current [en ligne] & (1 << index)) {/ / si l’état de bouton physique actuel est déprimé button_event [ligne] = kButtonNewEvent << index; / / un nouvel événement de touche en file d’attente immédiatement button_state [ligne] | = (1 << indice) ; et définir l’État debounced en bas. } else {button_debounce_count [ligne] [index] = kButtonUpDefaultDebounceCount;} / / dans le cas contraire le bouton était déjà déprimé et maintenant / / a été libéré, alors nous avons mis notre compteur debounce. } ElseIf (((button_current [en ligne] ^ button_last[row]) & (1 << index)) == 0 & & / / si l’état de bouton physique actuel est le même que (button_current [en ligne] ^ button_state[row]) & (1 << index)) {/ / physiques dernier bouton État mais la physique actuelle / / État du bouton est différente de l’actuelle debounce / / État... si (button_debounce_count [ligne] [index] > 0 & &--button_debounce_count [ligne] [index] == 0) {/ / si le comptoir debounce a / / été décrémenté à 0 (sens le / / le bouton a été pour / / kButtonUpDefaultDebounceCount / / itérations / / / button_event [en ligne] = kButtonNewEvent << index; / / un événement de changement d’État touche la queue si (button_current [ligne] & (1 << index)) {/ / et activer/désactiver les boutons debounce État. button_state [en ligne] | = (1 << index);} d’autre {button_state [ligne] & = ~ (1 << index);}}} } void buttonpress () {pour (j’ai = 0; j’ai < 8; i ++) {LATCH_PORT_595 & = latchPin595MaskLow; / / set goupille de verrouillage faible donc les sorties ne changent pas lors de l’envoi en bits pour (j = 0; j < 8; j ++) {CLOCK_PORT_595 & = clockPin595MaskLow;//digitalWrite(clockPin,LOW) ; if (j == j’ai) {courant égal de //if indice J’apprécie, mis bas DATA_PORT_595 & = dataPin595MaskLow;//digitalWrite(A4,LOW);} else {//set le reste des broches haute DATA_PORT_595 | = dataPin595MaskHigh ; //digitalWrite (A4 ÉLEVÉ) ; } CLOCK_PORT_595 | = clockPin595MaskHigh;//digitalWrite(clockPin,HIGH) ; } //set loquet broche haute-il envoie des données à sorties LATCH_PORT_595 | = latchPin595MaskHigh ; //digitalWrite (latchPin, HIGH) ; Ralentissement est mis ici pour perdre un peu de temps, en attendant que l’état de la sortie / / pins pour régler. Sans cette boucle de gaspillage de temps, un seul bouton se présenteraient comme / / deux presses (le bouton et sa voisine) volatile int ralentissement = 0 ; tandis que (ralentissement < 15) {ralentissement ++;} button_last [i] = button_current [i] ; pour (id = 0; id < 8; id ++) {switch (id) {case 0: t = digitalRead(A0) ; break ; case 1: t = digitalRead(A1) ; break ; case 2: t = digitalRead(2) ; break ; case 3: t = digitalRead(3) ; break ; case 4: t = digitalRead(4) ; break ; case 5: t = digitalRead(5) ; break ; case 6: t = digitalRead(6) ; break ; case 7: t = digitalRead(7) ; break;} t = (t == 0); //invert t if(t) {button_current [i] | = (1 << id);} else {button_current [i] & = ~ (1 << id);} buttonCheck (i, id) ; Si (button_event [i] & (1 << id)) {button_event [i] & = ~ (1 << id); //zero bouton événement si (button_state [i] & (1 << id)) {Serial.write(1);} else {Serial.write(byte(0));} si (mirrorXButtons) {id = id 7;} si (mirrorYButtons) {j’ai = 7-i;} Serial.Write(((ID) << 4) | (i)); //set}}} toutes les goupilles de 595 haute LATCH_PORT_595 & = latchPin595MaskLow; / / set goupille de verrouillage faible donc les sorties ne changent pas lors de l’envoi en bits pour (j = 0; j < 8; j ++) {CLOCK_PORT_595 & = clockPin595MaskLow;//digitalWrite(clockPin,LOW) ; DATA_PORT_595 | = dataPin595MaskHigh;//digitalWrite(A4,HIGH) ; CLOCK_PORT_595 | = clockPin595MaskHigh;//digitalWrite(clockPin,HIGH) ; } //set loquet broche haute-il envoie des données à sorties LATCH_PORT_595 | = latchPin595MaskHigh ; //digitalWrite (latchPin, HIGH) ; } ISR(TIMER2_COMPA_vect) {faire {si (Serial.available()) {si (WaitingForAddress == 1) {byte0 = Serial.read() ; adresse = byte0 >> 4 ; WaitingForAddress = 0 ; } / / fin si (WaitingForAddress == 1) ; Si (Serial.available()) {WaitingForAddress = 1; octet1 = Serial.read() ; switch(address) {case 2: état = byte0 & 15; x = octet1 >> 4; y = octet1 & 15 ; if (État == 0) {ledmem [7-y] & = ~ (1 << x);} else {ledmem [7-y] | = (1 << x);} break ; case 3: IntensityChange = 1 ; IntensityVal = octet1 & 15 ; rupture ; case 4: DisplayTestChange = 1 ; DisplayTestVal = octet1 & 15 ; rupture ; cas 5: état = octet1 & 0x0F ; ADCEnableState [(octet1 >> 4) & 0 x 03] = Etat ; rupture ; case 6: ShutdownModeChange = 1 ; ShutdownModeVal = octet1 & 15 ; rupture ; cas 7: si (firstRun == 1) {pour (x = 0; x < 8; x ++) {ledmem [x] = 0;} firstRun = 0;} x = ((byte0 & 15) & 0 x 7) ; masquer cette valeur, donc nous n’écrivent pas sur une adresse non valide. y = octet1 ; Si (mirrorYLEDs) {y = 7-y;} si (mirrorXLEDs) {x=flipByte(x);} ledmem [x] = y ; rupture ; cas 8: si (firstRun == 1) {pour (x = 0; x < 8; x ++) {ledmem [x] = 0;} firstRun = 0;} x = ((byte0 & 15) & 0 x 7) ; y = octet1 ; Si (mirrorYLEDs) {x = 7-x;} si (mirrorXLEDs) {y=flipByte(y);} pour (z = 0; z < 8; z ++) {si (y & (1 << z)) {ledmem [z] | = 1 << x;} else {ledmem [z] & = ~ (1 << x);}} break ; } / / fin switch(address)} / / fin si (Serial.available()} / / fin si (Serial.available();} / / fin while (Serial.available() > 16) ; } void whoosh(void) {/ / réactiver interruption de dépassement de capacité pour / / minuterie 1 - on en a besoin par delay(...) TIMSK0 | = (1 << TOIE0) ; pour (int j = 0; j < 9; j ++) {pour (int i = 0; j’ai < 8; i ++) {maxSingle (i + 1, 1 << j);} delay(125);} / / et éteindre l’interruption. TIMSK0 & = ~ (1 << TOIE0) ; } void configuration () {DDDR = PORTD_Data_Direction ; DDRB = PORTB_Data_Direction ; DDRC = PORTC_Data_Direction ; Serial.Begin(57600) ; buttonInit() ; initiation de la max 7219 maxSingle (max7219_reg_scanLimit, 0 x 07) ; maxSingle(max7219_reg_intensity,0x0F) ; maxSingle (max7219_reg_shutdown, 0 x 01) ; pas en arrêt mode maxSingle (max7219_reg_displayTest, 0 x 00) ; vider les registres, tourner toutes les LEDs arrêt h pour (j’ai = 1; j’ai < = 8; i ++) {maxSingle(i,0) ; ledmem [i-1] = 0;} cli (); //stop interruptions //set timer2 interrompre chaque TCCR2A 128us = 0; / / set ensemble TCCR2A Registre à 0 TCCR2B = 0; / / Idem pour TCCR2B TCNT2 = 0; //initialize valeur de compteur à 0 / / set compare match registre d’avancements d’échelon 7,8 khz OCR2A = 255; / / = (16 * 10 ^ 6) / (7812.5 * 8) - 1 (doit être < 256) / / activer le mode TCCR2A de la CCT | = (1 << WGM21) ; Set CS11 bit pour 8 Prédiviseur TCCR2B | = (1 << CS11) ; activer les interruptions de minuterie comparer TIMSK2 | = (1 << OCIE2A) ; SEI (); //allow interruptions / / / / mettre en place le compteur 8 bits 2, sortie comparer éteint, / / / / normal génération de forme d’onde (quoi que qui pourrait signifier) / / TCCR2A = 0 ; / / la valeur contraire être cadencé à 16Mhz/8 = 2 Mhz / / TCCR2B = 1 << CS21 ; / / / / set le masque d’interruption de sorte que nous obtenions une interruption / / / / le débordement du timer 2, c'est-à-dire après 256 cycles d’horloge. / / La routine d’interruption du timer 2 s’exécutera chaque / / / / 128 nous. TIMSK2 = 1 << TOIE2 ; / / / / NOTE : dans mes efforts pour essayer d’obtenir ceci / / / / code pour travailler avec fiabilité à 115200 bauds / / / / je suis allé sur la désactivation des minuteries inutilisés qui / / / / sont mis en place par le cadre de l’Arduino. / / Le cadre met en place les deux timer 2 et / / / / minuterie 1. Nous utilisons minuterie 2 au lecteur la / / / / serial interruption de lecture, donc on peut uniquement / / / / désactiver timer1 et son interruption. / / / / VRAIMENT IMPORTANT REMARQUE : Si vous souhaitez utiliser / / / / ANALOGWRITE / / / / / / timer de désactivation 1 arrête la minuterie / / / / utilisé pour PWM, qui sous-tend analogWrite. / / Si vous souhaitez utiliser analogWrite, supprimer / / / / les lignes ci-dessous. / / / / DÉSACTIVER PWM compteur / / TIMSK0 & = ~ (1 << TOIE0) ; / / TCCR1B & = ~ (1 << CS12) ; TCCR1B & = ~ (1 << CS11) ; TCCR1B & = ~ (1 << CS10) ; / / FIN DISABLE PWM compteur / / / / / /, désactiver les interruptions sur minuterie 0 / / / / vraiment IMPORTANT Remarque Si vous souhaitez à utiliser / / / / retard / / / / supprimer cette ligne et aussi regarder / / / / « whoosh », qui active et désactive ensuite / / / / l’intterupt minuterie 0. Vous aurez envie / / / / pour se débarrasser de ces lignes trop. TIMSK0 & = ~ (1 << TOIE0) ; modèle assez pour m’assurer que du firmware / / téléchargées correctement. whoosh() ; Veillez à éteindre les lumières. pour (int i = 0; i < 8; i ++) {maxSingle(i+1,0);}} void sendADC (int port, int valeur) {/ / Serial.write ((1 << 4) | ((port << 2) & 0x0C) | ((valeur >> 8) & 0 x 03)) ; Serial.Write (valeur & 0xFF) ; } / / //int actuel [4] ; int précédent [4] ; tolérance d’int = 7 ; void checkADCs() {/ / / / pour (int adcCounter = 0; adcCounter < 4; adcCounter ++) / / {/ / / / si (ADCEnableState [adcCounter]! = 0) / / {/ / courant [adcCounter] = analogRead(adcCounter); / / / / if (abs(previous[adcCounter]-current[adcCounter]) > tolérance) / / {/ / précédent [adcCounter] = courant [adcCounter]; / / sendADC(adcCounter,current[adcCounter]); / /} / / / /} / / / /} / /} flipByte octets (numToFlip octets) {miroir octet = 0; pour (int j = 0; j < 8; j ++) {copie octet = numToFlip ; miroir | = (copie >> j) & 1; si (j < 7) {miroir = miroir << 1;}} miroir retour;} void loop () {/ / envoyer les États de LED à la matrice de LED. pour (int j’ai = 0; j’ai < 8; i ++) {octet ledmemMirror = 0; si (mirrorXLEDs) {ledmemMirror=flipByte(ledmem[i]);} else {ledmemMirror = ledmem [i];} int y; if (mirrorYLEDs) {y =(7-i) + 1;} d’autre {y = i + 1;} maxSingle(y,ledmemMirror);} si (IntensityChange == 1) {IntensityChange = 0; maxSingle (max7219_reg_intensity, IntensityVal & 15);} si (DisplayTestChange == 1) {DisplayTestChange = 0; maxSingle (max7219_reg_displayTest, DisplayTestVal & 15);} si (ShutdownModeChange == 1) {ShutdownModeChange = 0; maxSingle (max7219_reg_shutdown ShutdownModeVal & 15) ; } / / check pour les bouton presses de buttonpress() ; / / vérifier l’état de l’ADCs / / checkADCs() ; }

Vous devriez voir vos leds s’allument en une seule colonne à la fois et le défilement à l’écran lorsque le firmware est terminé Téléchargement :


Si votre LED n’est pas câblées correctement vers le haut, les fixe maintenant avant de passer à l’étape suivante.

Articles Liés

Contrôleur de musique RGB avec AGC

Contrôleur de musique RGB avec AGC

Ici, je vais vous montrer comment créer un contrôleur RGB musique, qui illumine les leds RGB de la musique. J'ai aussi ajouté un AGC (Automatic gain control), ce qui maintient la tension au même niveau. Ceci est très utile, car vous jouez souvent la
Contrôleur de MIDI personnalisé construit

Contrôleur de MIDI personnalisé construit

Im entrant dans cette jnstructable au concours d'instruments de musique, si vous l'aimez s'il vous plaît votez pour moi cos j'aimerais bien un nouveau synthé ! Comme un producteur de musique électronique/interprète, j'ai rassemblé quelques contrôleur
Contrôleur MIDI avec claviers

Contrôleur MIDI avec claviers

Aujourd'hui, nous construisons la touche 400 contrôleur MIDI à l'aide d'un Arduino et ordinateur claviers !Pour les producteurs de musique consciente budget là-bas, ce projet est un excellent moyen de construire un peu coûteux de contrôle des stupéfi
Contrôleur DJ USB bricolage

Contrôleur DJ USB bricolage

Beaucoup de gens se lancent dans DJing ces jours-ci, que ce soit comme un moyen d'expression de soi ou un moyen de gagner de l'argent supplémentaire. J'aime DJing puisqu'il fournit une expérience plus intéressante, impliquée et interactive-écoute de
Contrôleur MIDI contrôlé la flamme

Contrôleur MIDI contrôlé la flamme

Un énorme problème dans le monde de la production musicale numérique garde cette chaleur analogique (qui a résonné de tubes et systèmes de bobine à bobine) en musique numérique moderne. Beaucoup jurent que les systèmes analogiques ont un son qui ne p
Comment faire un contrôleur d’youtube USB

Comment faire un contrôleur d’youtube USB

il s'agit d'un contrôleur simple youtube qui « agit » comme son pressage J, K ou LÉtape 1: Ce que vous devez-A clavier inutile-Un outil de soudage-Colle-Verre loupe (recommandé)Étape 2: Mappage des touches mettre le clavier pcb oh haut du clavier et
Nintendo contrôleur MP3, Version 2.0

Nintendo contrôleur MP3, Version 2.0

tout d'abord, je vous offre la reconnaissance à Morte_Moya pour son instructable « NDA contrôleur MP3 Player ». J'ai construit une suite à son instructable et il fonctionnait très bien !Je laisse mon imagination aller sur une deuxième génération. J'a
(PART1) Comment faire pour faire AN AWSOME DIY ableton contrôleur

(PART1) Comment faire pour faire AN AWSOME DIY ableton contrôleur

Salut, avez-vous jamais regardé un gars jouer de la musique via un ordinateur en appuyant sur les boutons ? Et vous dites à vous-même... « Je pouvais faire un de ces instruments fantaisies moi-même », et vous venez de commencer twinkering certaines c
Convertir un jouet secouru un contrôleur MIDI

Convertir un jouet secouru un contrôleur MIDI

dans ce Instructable, je vous guidera dans le processus de conversion de jouet d'enfant secouru faire du bruit en un instrument de musique vraiment utile à l'aide de MIDI ! Prenez un moment pour juste coup d'oeil sur les titres des étapes de ce Instr
Week-end maison contrôleur (Work in progress) Smart

Week-end maison contrôleur (Work in progress) Smart

Remarque : Cette instructable est encore travaux en cours (WIP), puisque je n'ai pas beaucoup de temps à cause de l'école et j'ai des problèmes avec Edison. Et parce que je suis perfectionniste, tandis que l'instructable est en état de travaux en cou
Comment faire un contrôleur de jeu personnalisé

Comment faire un contrôleur de jeu personnalisé

j'ai fait un tapis de danse une fois avant pour le PC - à utiliser avec Stepmania. Cette fois-ci, bien que j'ai voulu faire un contrôleur pour Frets on Fire ou Freetar (simulateur de Guitar Hero) et de la pensée de partager comment tout cela fonction
Un contrôleur de bande de LED en réseau avec Arduino et Android

Un contrôleur de bande de LED en réseau avec Arduino et Android

je suis fascinant de l'effet de lumières depuis enfant et une fois trouvé sur Ebay un bon marché LED multicolore bande j'ai commencé à la recherche comment il, vous cherchez un Ethernet activé control qui fait les bandes un ensemble d'objet en réseau
Faire votre propre clavier ou contrôleur MIDI USB pas cher

Faire votre propre clavier ou contrôleur MIDI USB pas cher

Je cherchais un périphérique contrôleur USB MIDI (ou interface) pour les applications de musique comme le clavier de piano ou orgue ou pédalier. Après quelques recherches, j'ai voulu aller vers une solution plus « fait maison ». Mon choix a été final
Midi simple flûte/enregistreur contrôleur (EWI)

Midi simple flûte/enregistreur contrôleur (EWI)

Comme un enfant (il y a environ 30 ans), j'ai commencé mes cours de musique à la flûte (un enregistreur pour être précis) et maintenant je veux une version électronique moderne de cet instrument (un Instrument à vent électronique telle qu'elle est ap