|
|
@@ -5,16 +5,48 @@
|
|
|
#define MULTIPLEX_PIN_B 3
|
|
|
#define MULTIPLEX_PIN_C 4
|
|
|
|
|
|
-void multiplexSelectChan(uint8_t chan)
|
|
|
+
|
|
|
+
|
|
|
+inline void setPrescalers(byte i)
|
|
|
+{
|
|
|
+ i = i % 7;
|
|
|
+ const byte prescalers[] = {
|
|
|
+ B00000000, // PS_2
|
|
|
+ B00000010, // PS_4
|
|
|
+ B00000011, // PS_8
|
|
|
+ B00000100, // PS_16
|
|
|
+ B00000101, // PS_32
|
|
|
+ B00000110, // PS_64
|
|
|
+ B00000111, // PS_128
|
|
|
+ };
|
|
|
+
|
|
|
+ ADCSRA &= ~prescalers[6];
|
|
|
+ ADCSRA |= prescalers[0];
|
|
|
+}
|
|
|
+
|
|
|
+inline void multiplexSelectChan(uint8_t chan)
|
|
|
{
|
|
|
- digitalWrite(MULTIPLEX_PIN_A, chan & 0x1);
|
|
|
- digitalWrite(MULTIPLEX_PIN_B, chan & 0x2);
|
|
|
- digitalWrite(MULTIPLEX_PIN_C, chan & 0x4);
|
|
|
+ PORTD = B00011100 & (chan << 2);
|
|
|
}
|
|
|
|
|
|
+struct SysexFrame {
|
|
|
+ byte begin;
|
|
|
+ byte manufacturer;
|
|
|
+ byte values[CHAN_CNT* PORT_CNT];
|
|
|
+ byte end;
|
|
|
|
|
|
-byte valueFrame[1 + CHAN_CNT* PORT_CNT] = {0xff, 0};
|
|
|
+ SysexFrame()
|
|
|
+ : begin(0xf0)
|
|
|
+ , manufacturer(42)
|
|
|
+ , end(0xF7)
|
|
|
+ {
|
|
|
+ memset(values, 0, sizeof(values));
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
+SysexFrame _frame;
|
|
|
+byte _throttle = 1;
|
|
|
+byte _cnt = 0;
|
|
|
|
|
|
void setup()
|
|
|
{
|
|
|
@@ -29,21 +61,70 @@ void setup()
|
|
|
// Setup Serial
|
|
|
Serial.begin(115200);
|
|
|
Serial.flush();
|
|
|
+
|
|
|
+ //Configure Prescaler
|
|
|
+ setPrescalers(2);
|
|
|
}
|
|
|
|
|
|
-void loop()
|
|
|
+inline void handleMessage(byte* msg, byte length)
|
|
|
+{
|
|
|
+ switch(msg[0] && length == 3) {
|
|
|
+ case 0xff: {
|
|
|
+ setPrescalers(msg[1]);
|
|
|
+ _throttle = msg[2] != 0 ? msg[2] : 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+inline void input()
|
|
|
+{
|
|
|
+ //read until we receive a sysex
|
|
|
+ while(Serial.peek() >= 0 && Serial.peek() != 0xF0) {
|
|
|
+ Serial.read();
|
|
|
+ }
|
|
|
+
|
|
|
+ if(Serial.available() >= 6) {
|
|
|
+ byte start = Serial.read();
|
|
|
+ byte manufacturerId = Serial.read();
|
|
|
+ byte deviceId = Serial.read();
|
|
|
+ byte length = Serial.read();
|
|
|
+ byte value[128];
|
|
|
+
|
|
|
+ if(length > 0) {
|
|
|
+ Serial.readBytes(value, length);
|
|
|
+ handleMessage(value, length);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+inline void output()
|
|
|
{
|
|
|
for(uint8_t chan = 0; chan < CHAN_CNT; ++chan) {
|
|
|
multiplexSelectChan(chan);
|
|
|
|
|
|
for(uint8_t port = 0; port < PORT_CNT; ++port) {
|
|
|
+
|
|
|
int channelNumber = port * CHAN_CNT + chan;
|
|
|
|
|
|
- byte& value = *(valueFrame + 1 + channelNumber);
|
|
|
+ byte& value = *(_frame.values + channelNumber);
|
|
|
|
|
|
- value = byte(analogRead(port) / 8); //map [0..1023] -> [0..127]
|
|
|
+ byte v = byte(analogRead(port) >> 3); //map [0..1023] -> [0..127]
|
|
|
+
|
|
|
+ value = (value > v) ? value : v;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- Serial.write(valueFrame, sizeof(valueFrame));
|
|
|
+ if(_cnt % _throttle == 0) {
|
|
|
+ Serial.write((byte*)&_frame, sizeof(_frame));
|
|
|
+ memset(_frame.values, 0, sizeof(_frame.values));
|
|
|
+ }
|
|
|
+
|
|
|
+ ++_cnt;
|
|
|
+}
|
|
|
+
|
|
|
+void loop()
|
|
|
+{
|
|
|
+ input();
|
|
|
+ output();
|
|
|
}
|