OK, I'm starting to look at DPM and bitwise operations now. The code I put up before would work conceptually, but using digitalRead and digitalWrite will most likely be too slow.
Which means I have to think about how to best implement this.
I have a basic understanding of how to use DPM to activate pins (pretty straightforward), but I'm trying to get my head around how to use the incoming MIDI data combined with reading the input pins to update e.g., PORTD.
PieterP:
Take a look at direct port manipulation, for example and use (pin change) interrupts on the 8 select lines.
You'll probably have to write your own MIDI in function: if the byte you read from the Serial port has a 1 as MSB, it's a status byte (the start of a MIDI message). This byte contains the message type (note on or off) and the channel (you could probably ignore this).
OK, so the first byte will be e.g., 1001---- (note on and whatever channel number). This will be followed by two more bytes, the note number (0-127), and then the velocity (0-127).
The next byte should have a 0 as MSB, and contains the note number. Use this data to update an 8-byte array with note states (using some bitwise operations and logic). In most cases, you can probably ignore the third byte, it's the velocity. However, some MIDI devices send a note on with velocity = 0 instead of a note off. This can be very frustrating.
I'll ignore velocity and concentrate just on note on/off for now.
I'm confused a little bit here, though. Why would I need an 8 byte array? There are 6 data lines and 8 select lines. I'll be 'monitoring' the select lines using DPM and the 6 data lines will be activated based on the MIDI data and the select line activity. Would I need a 6 byte array in that case (for note states)?
So an example of my array would be:
dataPins[] = {B00000001, B00000010, B00000100, B00001000, B00010000, B00100000}
selectPins[] = {B00000001, B00000010, B00000100, B00001000, B00010000, B00100000, B01000000, B10000000}
I would also need to monitor the select lines. I could use an 8 byte array for this. However, because there may only be 6 bits per byte, I'd have to use two port registers in this array. I'm unsure how to achieve this...
In your ISR (interrupt service routine, the piece of code that executes when one of the 8 select lines changes state), use direct port manipulation to determine which one of the 8 lines (0-7) is high or low, and use that number as the index of your note states array. Then output the contents of the byte to the right pins. If you use clever wiring, you can output 6 bits at once, using direct port manipulation. Using bitshifts and bitmasks, you can get the right bits to the proper output register. It would be convenient if the Uno had 8-bit output registers, but only PORTD has 8 bits, but you can't use pin 0 and 1, because you're already using them for Serial (MIDI) communication.
I'm unsure how I would go about using the note byte data to update the appropriate byte in the array above. Let's say I receive middle C or note number 60, which is 00111100. Let''s presume that PORTD is the output and PORTC is the input. In this case, when select line 3 is active (PORTC = B00000100), and I receive middle C (00111100), in the array above, I want:
PORTD = dataPins[6];
So something like:
if (PORTC == selectPins[6] && note == 60) {
PORTD = dataPins[6];
}
I could of course do this for all possible notes, but it's going to be a loooot of code. I'd also have to do the same for note off messages. I could also use a 2D array of midi notes, each array being 6 bytes to correspond to the dataPins[] array. I could then do a nested for loop.
However, because I'm hoping to be able to use polyphony, I'd have to be able to combine the dataPins[] array bytes somehow, probably using | logic. In this case I'd need to store and update a variable which contains the current byte being output to the register.
You mention bitwise operations and logic. I'm not sure how I'd go about this in this situation though.
Sorry, this post has a lot of rubber ducking. I'd really appreciate any help though!