drumduino_firmware.ino 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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. #ifndef cbi
  7. #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
  8. #endif
  9. #ifndef sbi
  10. #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
  11. #endif
  12. //=================================================================================
  13. // Prescaler
  14. //=================================================================================
  15. // Maximum sampling frequency // Resolution
  16. #define Prescaler_2 B00000000 // 16 MHz / 2 = 8 MHz //
  17. #define Prescaler_4 B00000010 // 16 MHz / 4 = 4 MHz // ~5.9
  18. #define Prescaler_8 B00000011 // 16 MHz / 8 = 2 MHz // ~7.4
  19. #define Prescaler_16 B00000100 // 16 MHz / 16 = 1 MHz // ~8.6
  20. #define Prescaler_32 B00000101 // 16 MHz / 32 = 500 kHz // ~8.9
  21. #define Prescaler_64 B00000110 // 16 MHz / 64 = 250 kHz // ~9.0
  22. #define Prescaler_128 B00000111 // 16 MHz / 128 = 125 kHz // ~9.1
  23. inline void setPrescaler(int prescaler)
  24. {
  25. ADCSRA &= B11111000;
  26. ADCSRA |= prescaler;
  27. }
  28. //=================================================================================
  29. // Adc Pin
  30. //=================================================================================
  31. #define AdPin_0 B00000000
  32. #define AdPin_1 B00000001
  33. #define AdPin_2 B00000010
  34. #define AdPin_3 B00000011
  35. #define AdPin_4 B00000100
  36. #define AdPin_5 B00000101
  37. #define AdPin_6 B00000110 // Bei Atmega8 nur in der Gehäusebauform TQFP und MLF verfügbar, nicht in PDIP
  38. #define AdPin_7 B00000111 // Bei Atmega8 nur in der Gehäusebauform TQFP und MLF verfügbar, nicht in PDIP
  39. #define AdPin_Vbg B00001110 // 1.23V
  40. #define AdPin_GND B00001111 // 0V
  41. inline void setAdPin(int adPin)
  42. {
  43. ADMUX &= B11110000;
  44. ADMUX |= adPin;
  45. }
  46. //=================================================================================
  47. // ADC Alignment
  48. //=================================================================================
  49. // Das Ergebnis wird in den Registern ADCH/ADCL linksbündig ausgerichtet.
  50. // Die 8 höchstwertigen Bits des Ergebnisses werden in ADCH abgelegt.
  51. // Die verbleibenden 2 niederwertigen Bits werden im Register ADCL in den Bits 6 und 7 abgelegt.
  52. #define ADAlignmentLeft B00100000
  53. #define ADAlignmentRight B00000000
  54. inline void setADAlignment(int align)
  55. {
  56. ADMUX &= ~B00100000;
  57. ADMUX |= align;
  58. }
  59. //=================================================================================
  60. inline void startADCConversion()
  61. {
  62. ADCSRA |= B01000000;
  63. }
  64. //=================================================================================
  65. inline void disableAnalogComparator()
  66. {
  67. ACSR = B10000000;
  68. }
  69. inline void multiplexSelectChan(uint8_t chan)
  70. {
  71. PORTD = B00011100 & (chan << 2);
  72. }
  73. struct SysexFrame {
  74. byte begin;
  75. byte manufacturer;
  76. unsigned long time1;
  77. unsigned long time2;
  78. byte values[CHAN_CNT* PORT_CNT];
  79. byte end;
  80. SysexFrame()
  81. : begin(0xf0)
  82. , manufacturer(42)
  83. , end(0xF7)
  84. {
  85. memset(values, 0, sizeof(values));
  86. }
  87. };
  88. SysexFrame _frame;
  89. void setup()
  90. {
  91. // Setup MultiplexSelection Pins
  92. pinMode(MULTIPLEX_PIN_A, OUTPUT);
  93. pinMode(MULTIPLEX_PIN_B, OUTPUT);
  94. pinMode(MULTIPLEX_PIN_C, OUTPUT);
  95. // Setup ADCs
  96. analogReference(DEFAULT);
  97. disableAnalogComparator();
  98. setPrescaler(Prescaler_8);
  99. //setADAlignment(ADAlignmentLeft);
  100. // Disable digital input buffers on all analog input pins
  101. DIDR0 = DIDR0 | B00111111;
  102. // Setup Serial
  103. //Serial.begin(115200);
  104. Serial.begin(2000000);
  105. Serial.flush();
  106. }
  107. inline void output()
  108. {
  109. _frame.time1 = micros();
  110. for(uint8_t chan = 0; chan < CHAN_CNT; ++chan) {
  111. multiplexSelectChan(chan);
  112. for(uint8_t port = 0; port < PORT_CNT; ++port) {
  113. int channelNumber = port * CHAN_CNT + chan;
  114. byte& value = *(_frame.values + channelNumber);
  115. value = byte(analogRead(port) >> 3);
  116. }
  117. }
  118. _frame.time2 = micros();
  119. Serial.write((byte*)&_frame, sizeof(_frame));
  120. }
  121. void loop()
  122. {
  123. //input();
  124. output();
  125. }