Corjan Veenema schreef:Dit is de code:
<.>
Als iemand interesse heeft in de bestanden van het PCB om het zelf te bestellen hoor ik het wel!
Dat ziet er heel professioneel uit Corjan! Ik heb zeker interesse in de PCB bestanden, op dit moment werkt mijn orgelpedaal met een doepfer ctm64. Die bestaat uit acht keer een Shift-and-Store Register (CD4094BE) en een PIC16F73 microprocessor. De ctm64 zit aan een roland UM1. Het lijkt me wel leuk om die te vervangen door iets zelfgemaakts. Zit nog te twijfelen tussen teensy en arduino. Met teensy kan ik direct usb-midi uitsturen en heb ik de roland niet meer nodig, maar met arduino kan ik van dit nette ontwerp gebruik maken en hoef ik niet zelf het wiel uit te vinden.
Hoe zit het met de latency? Stabiliteit?
Ik ben door de code heen gegaan en was benieuwd waarom je bepaalde keuzes maakt. Het is wel een boel tekst geworden.
Je verandert 64 keer de selectpins. Werkt het ook als je dat maar 8 keer doet?
- Code:
for(j=0; j<8; j++) // 8 combinaties voor de select pinnen
{
setSelectpins(j);
for(i=0; i<8; i++) // 8 digitale inputs afgaan
{
inputNieuw[i*8+j] = digitalRead(I1+i);
//Serial.print(inputNieuw[i*8+j]); // gebruik om te debuggen. Zet baudrate dan op 9600. ontcommentaar ook de Serial.println() aan het eind van de loop
}
}
Je verstuurt alleen note-on commando's en verandert het volume afhankelijk van de nieuwe status. (127 bij off, 0 bij on, dus indrukken van een toets zet het signaal laag?)
Wat gebeurt er als je note-on en note-off gebruikt?
- Code:
byte noteOn = kanaal | 144;
byte noteOff = kanaal | 128;
for(k=0; k<64; k++)
{
if(inputNieuw[k] != inputOud[k]) // alleen als de input is veranderd een MIDI transfer doen
{
if(inputNieuw[k] == LOW) MIDItransfer(noteOn, offset+k, 127);
else MIDItransfer(noteOff, offset+k, 127);
}
}
Kan je alles in 2 loops ipv 3 doen of wordt dat onstabiel?
- Code:
for(j=0; j<8; j++) // 8 combinaties voor de select pinnen
{
setSelectpins(j);
for(i=0; i<8; i++) // 8 digitale inputs afgaan
{
k=i*8+j
inputNieuw[k] = digitalRead(I1+i);
if(inputNieuw[k] != inputOud[k]) // alleen als de input is veranderd een MIDI transfer doen
{
if(inputNieuw[k] == LOW) MIDItransfer(144, offset+k, 127);
else MIDItransfer(128, offset+k, 127);
}
//Serial.print(inputNieuw[i*8+j]); // gebruik om te debuggen. Zet baudrate dan op 9600. ontcommentaar ook de Serial.println() aan het eind van de loop
}
}
Serial.write verwacht drie keer een byte, maar je geeft hem drie keer een int. Wat gebeurt er als je drie bytes in 1 keer naar de poort stuurt?
- Code:
byte command[3] = {0}; //ruimte reserveren
command[2] = 127; //volume verandert nergens
if(inputNieuw[k] != inputOud[k]) // alleen als de input is veranderd een MIDI transfer doen
{
command[1] = offset+k;
if(inputNieuw[k] == LOW)
{
command[0]=noteOn;
}
else
{
command[0]=noteOff;
}
Serial.write(command,3); // alle drie tegelijk om delay te minimaliseren
}
Ik blijf het apart vinden dat arduino een bij een digital read een 16 bits waarde teruggeeft ipv een bit of een byte, maar daar moeten we het maar mee doen. Betekent wel dat je per loop 16x meer informatie moet kopiëren dan strikt noodzakelijk.
Pin 2,3 en 4 zitten trouwens op dezelfde bus, dus je zou eventueel nog wat snelheid kunnen winnen door ze tegelijk te setten.
- Code:
void setSelectpins(int combinatie)
{
//PORTD bestuurt digital pin 0-7. Zie https://www.arduino.cc/en/Reference/PortManipulation
//om bijvoorbeeld digital pin 3 hoog te zetten en de rest laag zijn twee commandos nodig
//1) alles laag:
//PORTD = PORTD & B11100011; //we komen niet aan pin 0,1,5,6,7
//2) pin 3 hoog:
//PORTD = PORTD | B00001000; //we komen niet aan de overige pinnen
//nu zetten we de combinatie in twee commandos
PORTD = PORTD & B11100011; //we komen niet aan pin 0,1,5,6,7
PORTD = PORTD | (combinatie<<2) //shift de bitjes 2 naar links.
}