1
1

drumduino_firmware.ino 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #define PORT_CNT 6
  2. #define CHAN_CNT 8
  3. #define MULTIPLEX_PIN_A 2
  4. #define MULTIPLEX_PIN_B 3
  5. #define MULTIPLEX_PIN_C 4
  6. inline void setPrescalers(byte i)
  7. {
  8. i = i % 7;
  9. const byte prescalers[] = {
  10. B00000000, // PS_2
  11. B00000010, // PS_4
  12. B00000011, // PS_8
  13. B00000100, // PS_16
  14. B00000101, // PS_32
  15. B00000110, // PS_64
  16. B00000111, // PS_128
  17. };
  18. ADCSRA &= ~prescalers[6];
  19. ADCSRA |= prescalers[0];
  20. }
  21. inline void multiplexSelectChan(uint8_t chan)
  22. {
  23. PORTD = B00011100 & (chan << 2);
  24. }
  25. struct SysexFrame {
  26. byte begin;
  27. byte manufacturer;
  28. byte values[CHAN_CNT* PORT_CNT];
  29. byte end;
  30. SysexFrame()
  31. : begin(0xf0)
  32. , manufacturer(42)
  33. , end(0xF7)
  34. {
  35. memset(values, 0, sizeof(values));
  36. }
  37. };
  38. SysexFrame _frame;
  39. byte _throttle = 1;
  40. byte _cnt = 0;
  41. void setup()
  42. {
  43. // Setup MultiplexSelection Pins
  44. pinMode(MULTIPLEX_PIN_A, OUTPUT);
  45. pinMode(MULTIPLEX_PIN_B, OUTPUT);
  46. pinMode(MULTIPLEX_PIN_C, OUTPUT);
  47. // Setup AD Pins
  48. analogReference(DEFAULT);
  49. // Setup Serial
  50. Serial.begin(115200);
  51. Serial.flush();
  52. //Configure Prescaler
  53. setPrescalers(2);
  54. }
  55. inline void handleMessage(byte* msg, byte length)
  56. {
  57. switch(msg[0] && length == 3) {
  58. case 0xff: {
  59. setPrescalers(msg[1]);
  60. _throttle = msg[2] != 0 ? msg[2] : 1;
  61. }
  62. }
  63. }
  64. inline void input()
  65. {
  66. //read until we receive a sysex
  67. while(Serial.peek() >= 0 && Serial.peek() != 0xF0) {
  68. Serial.read();
  69. }
  70. if(Serial.available() >= 6) {
  71. byte start = Serial.read();
  72. byte manufacturerId = Serial.read();
  73. byte deviceId = Serial.read();
  74. byte length = Serial.read();
  75. byte value[128];
  76. if(length > 0) {
  77. Serial.readBytes(value, length);
  78. handleMessage(value, length);
  79. }
  80. }
  81. }
  82. inline void output()
  83. {
  84. for(uint8_t chan = 0; chan < CHAN_CNT; ++chan) {
  85. multiplexSelectChan(chan);
  86. for(uint8_t port = 0; port < PORT_CNT; ++port) {
  87. int channelNumber = port * CHAN_CNT + chan;
  88. byte& value = *(_frame.values + channelNumber);
  89. byte v = byte(analogRead(port) >> 3); //map [0..1023] -> [0..127]
  90. value = (value > v) ? value : v;
  91. }
  92. }
  93. if(_cnt % _throttle == 0) {
  94. Serial.write((byte*)&_frame, sizeof(_frame));
  95. memset(_frame.values, 0, sizeof(_frame.values));
  96. }
  97. ++_cnt;
  98. }
  99. void loop()
  100. {
  101. input();
  102. output();
  103. }