BTW, here is the code for what the 2560 is working on right now for these LED VU meters... Strictly midi library stuff, so I need to figure out how to take rotary encoder data and convert that back to my program.
#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>
MIDI_CREATE_INSTANCE(HardwareSerial, Serial3, controller);
MIDI_CREATE_INSTANCE(HardwareSerial, Serial, pt);
byte lastChannel = 0;
byte pp[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
// Meter pins per channel:
// - Latch pin connected to ST_CP of 74HC595
// - Clock pin connected to SH_CP of 74HC595
// - Data pin connected to DS of 74HC595
#define CHANNELS 8
typedef enum { LATCH = 0, CLOCK = 1, DATA = 2, METER = 3, PEAK = 4, CLIP = 5 } channel_index_t;
// LEFT:
//{ LATCH, CLOCK, DATA, METER, PEAK, CLIP } ***DO NOT USE 0,1,13,14,15***`
byte meter_left[CHANNELS][6] = {
{ 2, 3, 4, 0, 0, 0 },
{ 6, 3, 8, 0, 0, 0 },
{ 9, 3, 12, 0, 0, 0 },
{ 11, 3, 19, 0, 0, 0 },
{ 17, 3, 23, 0, 0, 0 },
{ 20, 3, 27, 0, 0, 0 },
{ 22, 3, 28, 0, 0, 0 },
{ 25, 3, 29, 0, 0, 0 }
};
// RIGHT:
//{ LATCH, CLOCK, DATA, METER, PEAK, CLIP } ***DO NOT USE 0,1,13,14,15***
byte meter_right[CHANNELS][6] = {
{ 5, 3, 4, 0, 0, 0 },
{ 7, 3, 8, 0, 0, 0 },
{ 10, 3, 12, 0, 0, 0 },
{ 16, 3, 19, 0, 0, 0 },
{ 18, 3, 23, 0, 0, 0 },
{ 21, 3, 27, 0, 0, 0 },
{ 24, 3, 28, 0, 0, 0 },
{ 26, 3, 29, 0, 0, 0 }
};
void PTHandleAfterTouchPoly(byte channel, byte note, byte pressure)
{
/*
0xA00ysv
[0xA0]
0xA_ : AfterTouchPoly
0x_0 : channel #1
[0x0y] -> note
y = channel (0..7)
[0xsv] -> pressure
s : side (left/right)
s = 0 : side = left; meter
s = 1 : side = right; meter
s = 2 : side = left; peak hold
s = 3 : side = right; peak hold
s = 4 : side = left; meter & clip
s = 5 : side = right; meter & clip
s = 6 : side = left; peak hold & clip
s = 7 : side = right; peak hold & clip
v : value (0..b)
v = b : signal >= -2dB; yellow
v = a : signal >= -4dB; yellow
v = 9 : signal >= -6dB; yellow
v = 8 : signal >= -8dB; green
v = 7 : signal >= -10dB; green
v = 6 : signal >= -14dB; green
v = 5 : signal >= -20dB; green
v = 4 : signal >= -30dB; green
v = 3 : signal >= -40dB; green
v = 2 : signal >= -50dB; green
v = 1 : signal >= -60dB; green
v = 0 : signal < -60dB; all leds off
*/
// 0xA0
if (channel == 1) {
int huv_channel = (note & 0x0f);
int huv_code = (pressure & 0xf0) >> 4;
int huv_value = (pressure & 0x0f);
if (0 <= huv_channel && huv_channel < CHANNELS) {
// Right or left channel
byte *meter = (huv_code & 0x1) ? meter_right[huv_channel] : meter_left[huv_channel];
switch (huv_code) {
case 0x0: // Left channel metering
case 0x1: // Right channel metering
meter[METER] = huv_value;
if (huv_value == 0x00) meter[CLIP] = 0x00;
break;
case 0x2: // Left channel peak hold
case 0x3: // Right channel peak hold
meter[PEAK] = huv_value;
break;
case 0x4: // Left channel metering with Clip LED #12
case 0x5: // Right channel metering with Clip LED #12
meter[METER] = huv_value;
meter[CLIP] = 0x0c;
break;
case 0x6: // Left channel peak hold with Clip LED #12
case 0x7: // Right channel peak hold with Clip LED #12
meter[PEAK] = huv_value;
meter[CLIP] = 0x0c;
break;
default:
// we do not support any other commands
return;
}
shiftMeter(meter[LATCH], meter[DATA], meter[CLOCK], meter[METER], meter[PEAK], meter[CLIP]);
}
return;
}
controller.sendPolyPressure(note, pressure, channel);
}
void PTHandleAfterTouchChannel(byte channel, byte pressure)
{
controller.sendAfterTouch(pressure, channel);
}
void ControllerHandleAfterTouchPoly(byte channel, byte note, byte pressure)
{
pt.sendPolyPressure(note, pressure, channel);
}
void shiftMeter(byte latchPin, byte myDataPin, byte myClockPin, byte meter, byte peak, byte clip) {
int pinState;
pinMode(latchPin, OUTPUT);
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, OUTPUT);
//ground latchPin and hold low for as long as you are transmitting
digitalWrite(latchPin, 0);
//clear everything out just in case to
//prepare shift register for bit shifting
digitalWrite(myDataPin, 0);
digitalWrite(myClockPin, 0);
int i;
for (i = 15; i >= 0; i--) {
digitalWrite(myClockPin, 0);
pinState = ((i < meter) ||
(peak != 0 && i == (peak - 1)) ||
(clip != 0 && i == (clip - 1))) ? 1 : 0;
//Sets the pin to HIGH or LOW depending on pinState
digitalWrite(myDataPin, pinState);
//register shifts bits on upstroke of clock pin
digitalWrite(myClockPin, 1);
//zero the data pin after shift to prevent bleed through
digitalWrite(myDataPin, 0);
}
//stop shifting
digitalWrite(myClockPin, 0);
//return the latch pin high to signal chip that it
//no longer needs to listen for information
digitalWrite(latchPin, 1);
}
void setup()
{
// Initiate MIDI communications, listen to all channels
controller.begin(MIDI_CHANNEL_OMNI);
pt.begin(MIDI_CHANNEL_OMNI);
Serial3.begin(38400);
controller.setThruFilterMode(midi::Off);
pt.setThruFilterMode(midi::Off);
pt.setHandleAfterTouchPoly(PTHandleAfterTouchPoly);
controller.setHandleAfterTouchPoly(ControllerHandleAfterTouchPoly);
}
void loop()
{
controller.read();
pt.read();
}