DIY midi-faderbak met Arduino

OK OK dus als ik het goed begrijp hangt de outputpin van de 4051 aan analog in 0 van de atmega (pin 22). Output 9, 10 en 11 zijn dus de outputs, maar ik kan uit de code niet opmaken welke hier de 4051 aansturen en welke de midi maakt. Dat komt omdat ik echt bijna helemaal niks van dat coderen snap hoor. Zou je het kunnen uitleggen aan me welke welke zijn? te gek...
 
row = bin[count];
r0 = row & 0x01;
r1 = (row>>1) & 0x01;
r2 = (row>>2) & 0x01;
digitalWrite(s0, r0);
digitalWrite(s1, r1);
digitalWrite(s2, r2);

dit is de code die de outputs (9,10,11) bepaalt. "bin" is een array die de binaire waarden 1-8 bevat. met die binaire waarden communiceer je aan de 4051 naar welke input die moet luisteren.

wat mijn code doet is heel snel de acht inputs scannen, de waarden opslaan(in "memory") en de volgende keer kijken of de waarde is verandert. Als dat het geval is stuurt ie pas een midiCC.

void midiCC(char CC_data, char c_num, char c_val){
Serial.print(CC_data, BYTE);
Serial.print(c_num, BYTE);
Serial.print(c_val, BYTE);}

dit is de midiCC funktie die aangeroepen wordt als de waarde afwijkt.

Eigenlijk snap ik het zelf amper. de bitshifting code voor de output pins heb ik afgekeken van een voorbeeld. Zelf zou ik het misschien ook kunnen maken(zonder bitshifting), maar dan met veel meer code.
 
Ik vraag me af hoe de oorspronkelijke bitshift code eruitzag....

Want hier:
int bin [] = {000, 1, 10, 11, 100, 101, 110, 111}; //binary numbers for outputs
Wordt de array bin gevuld met de waarden 0 t/m 7..


En vervolgens wordt hier:
void setup() {
for (int count = 0; count < 8; count++) {
row = bin[count]; // load binary for current input

Dus eigenlijk in de variable row een waarde van 0 tm 7 geplaatst waarna deze geshift wordt etc..
Vraag: Is die array "bin[]" daadwerkelijk nodig daar count ook van 0 tm 7 loopt...
Overhead in de code..

Verder is het bij midiCC mischien beter om expliciet een char unsigned te gebruiken om eventuele problemen met signed/unsigned te voorkomen (midi is altijd een unsigned char)

Ik wil trouwens niet zeggen dat mijn code altijd zo prefect is ;-)
 
de binaire waarden worden als bits gebruikt om met de 4051 inputs te communiceren. de decimale 0-7 waarden die met "count" en "row" worden gedefinieerd zijn pointers om de binaire waarden in de "bin" array op te halen.

..dacht ik.

als ik het goed begrijp is unsigned 0-255 ipv -127 tot 127. De faders zullen nooit negatieve waarden geven, maar ik zal het implementeren in de volgende versie.

dank voor het meedenken.
 
de binaire waarden worden als bits gebruikt om met de 4051 inputs te communiceren. de decimale 0-7 waarden die met "count" en "row" worden gedefinieerd zijn pointers om de binaire waarden in de "bin" array op te halen.

..dacht ik.
Maar in je array staan gewoon de waarden 0 tm 7 maar dan binair weergegeven.
Anders gezegd:
11 binair is
3 decimaal en ook
3 hexadecimaal

1011 binair is
11 decimaal en
0B hexadecimaal

Dus in jouw code is de stap met de array volgens mij overbodig
 
Je kan inderdaad ipv row = bin[count] direct count gebruiken en het hele array gebeuren weghalen. Dit doet hetzelfde en is efficiënter.

Nu we het toch over efficiëntie hebben, je gebruikt nu overal integers voor kleine waardes. De AVR is een 8-bit processor en in AVR C is een integer 16 bit. Dit betekend dat de compiler nu twee bytes voor iedere waarde reserveert en ook nog eens een hoop extra assembly code genereert om 16-bit berekeningen uit te voeren op een 8-bit core.

Beter is om, wanneer je toch geen waardes gebruikt hoger dan 255, om unsigned chars te gebruiken ipv int. Een unsigned char heeft een grootte van 1 byte en de AVR core kan hier direct efficiënt mee rekenen.

Dit gedeelte is overigens ook niet heel efficiënt:

r0 = row & 0x01; // tricky bitshifterism copy/pasted
r1 = (row>>1) & 0x01; // tricky bitshifterism copy/pasted
r2 = (row>>2) & 0x01; // tricky bitshifterism copy/pasted

De variabelen r0, r1 en r2 worden nu vooraf gedeclareerd (buiten de functie). Dit betekend dat ze nu ergens in SRAM komen te staan. De compiler genereert assembly code die steeds met behulp van een pointer de waarde in SRAM ophaalt, berekend en weer opslaat in SRAM. Werken met variabelen uit SRAM kosten veel meer CPU cycles dan variabelen in registers. Gezien je de variabelen niet buiten de functie gebruikt is het beter om r0, r1 en r2 niet buiten de functie maar binnen de functie zelf te declareren. De compiler gebruikt dan een register ipv een SRAM locatie. (tenzij de variabele als static in een functie wordt gedeclareerd, maar dat is een ander verhaal.)

de decimale 0-7 waarden die met "count" en "row" worden gedefinieerd zijn pointers om de binaire waarden in de "bin" array op te halen.

Soort van pointers inderdaad. Op assembly niveau zullen het wel pointers worden. In C praat men meer over index (of offset). Een 'echte' pointer naar een element in de array zou er ongeveer zo uit zien: unsigned char *myPointer = &myArray[someElement];

Hopelijk heb je iets aan deze info!
 
Laatst gewijzigd:
Ik wil ook een midi controller gaan maken, maar vroeg me het volgende af, ik wil meer dan 16 potmeters gebruiken om CC mee te verzenden, ik zit te denken aan deze Mega2560 processor, die heeft 16 analoge inputs en ik wil multiplexers gaan gebruiken, de 4051 om zo flink wat potmeters aan te kunnen sluiten.

Nu begrijp ik dat de multiplexers niet van 2 potmeters tegelijk de waarden kan uitlezen (voltages eigenlijk), maar max 1 tegelijk, betekent dit dat je problemen krijgt als je aan 2 potmeters tegelijk draait als deze op de zelfde multiplexer zitten?

Ik lasook dat je snel kan schrijven naar de multiplexer, betekent dit dat je toch aan 2 knoppen tegelijk kan draaien ' als je het maar niet te gek maakt ' met de draaibeweginen en dat de multiplexers de waarden toch kan verwerken? Iemand die hier ervaring mee heeft?

Of is het beter om knoppen waarvan je verwacht dat je er tegelijk aan zou willen draaien aan te sluiten op 2 verschillende multiplexers ?

http://www.arduino.cc/playground/Learning/4051
 
die van mij hangt met 8 faders aan 1 input en zoals je aan organix zn post kunt zien is de code verre van optimaal.
 
Maar kun jij 2 faders tegelijk bedienen, dus, bijv, langzaam open gooien?

Die code daar kom ik wel uit.. :D
 
vergeet niet dat het om 128 waardes midi gaat. de arduino registreert 1024 van de fader dus je bent daar al wat kwijt. de atmel scant de faders rete snel af. De menselijke brein is waarschijnlijk ook serieel, maar fokkin snel.
 
Leuk project.
Ik begrijp alleen dat gedoe met een 4051 niet als je met een Arduino Pro Mini reeds 8 analoge ingangen hebt en dat dat de hoeveelheid is die je nodig hebt. Dat ding kost minder dan een tientje.

Het stabiel krijgen van de potwaardes is makkelijk op te lossen met de software omdat de MIDI resolutie 128 is en de analoge lezing 1024. Een hysteresis waarde invoegen van b.v. 2.
Als de uit te lezen (Nieuwe) waarde van de pot groter+2 of kleiner-2 is dan de oude waarde, dan pas is er sprake van een nieuwe waarde die uitgezonden moet worden.

Een ontkoppel condensator plaatsen op de analoge ingang - eventueel met een kleine weerstand ervoor helpt niet omdat er glitches intern worden veroorzaakt door de multiplexer in de processorchip.
Natuurlijk is het van belang dat de spanning op de pots stabiel is. Vele arduino's hebben een 3V3 referentiespanning daarvoor. Anders kan er eenvoudig met een goedkope Voltage Reference (TL431) een stabiele referentiespanning gemaakt worden.

Voorbeeld van de pot en pot-old vergelijking met een hysteresis waarde

if (pot < potold-2 || pot > potold+2) {
.......action
}
 
Back
Top