CapTouchMIDIDrums.ino
  1  // SPDX-FileCopyrightText: 2020 Carter Nelson for Adafruit Industries
  2  //
  3  // SPDX-License-Identifier: MIT
  4  
  5  ////////////////////////////////////////////////////////////////////////////
  6  // Circuit Playground Capacitive Touch USB MIDI Drums
  7  //
  8  // Send MIDI percussion commands over USB.
  9  // https://www.arduino.cc/en/Reference/MIDIUSB
 10  // https://en.wikipedia.org/wiki/General_MIDI#Percussion
 11  //
 12  // Author: Carter Nelson
 13  // MIT License (https://opensource.org/licenses/MIT)
 14  
 15  #include <Adafruit_CircuitPlayground.h>
 16  #include "MIDIUSB.h"
 17  
 18  #define CAP_THRESHOLD   50
 19  #define DEBOUNCE        100
 20  
 21  uint8_t pads[] = {3, 2, 0, 1, 12, 6, 9, 10};
 22  uint8_t numberOfPads = sizeof(pads)/sizeof(uint8_t);
 23  
 24  ////////////////////////////////////////////////////////////////////////////
 25  void takeAction(uint8_t pad) {
 26    Serial.print("PAD "); Serial.print(pad); Serial.print(". Sending MIDI: ");
 27    switch (pad) {
 28      case 3:
 29        Serial.println("36");
 30        drumHit(36);
 31        break;
 32      case 2:
 33        Serial.println("37");
 34        drumHit(37);
 35        break;
 36      case 0:
 37        Serial.println("38");
 38        drumHit(38);
 39        break;
 40      case 1:
 41        Serial.println("39");
 42        drumHit(39);
 43        break;
 44      case 12:
 45        Serial.println("40");
 46        drumHit(40);
 47        break;
 48      case 6:
 49        Serial.println("41");
 50        drumHit(41);
 51        break;
 52      case 9:
 53        Serial.println("42");
 54        drumHit(42);
 55        break;
 56      case 10:
 57        Serial.println("43");
 58        drumHit(43);
 59        break;
 60      default:
 61        Serial.println("THIS SHOULD NEVER HAPPEN.");
 62    }
 63  }
 64  
 65  ////////////////////////////////////////////////////////////////////////////
 66  boolean capButton(uint8_t pad) {
 67    // Check if capacitive touch exceeds threshold.
 68    if (CircuitPlayground.readCap(pad) > CAP_THRESHOLD) {
 69      return true;  
 70    } else {
 71      return false;
 72    }
 73  }
 74  
 75  ////////////////////////////////////////////////////////////////////////////
 76  void noteOn(byte channel, byte pitch, byte velocity) {
 77    // Send a MIDI Note On command.
 78    midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
 79    MidiUSB.sendMIDI(noteOn);
 80  }
 81  
 82  ////////////////////////////////////////////////////////////////////////////
 83  void noteOff(byte channel, byte pitch, byte velocity) {
 84    // Send a MIDI Note Off command.
 85    midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
 86    MidiUSB.sendMIDI(noteOff);
 87  }
 88  
 89  ////////////////////////////////////////////////////////////////////////////
 90  void drumHit(byte drum) {
 91    // Send Note On/Off command for given drum (note) number.
 92    noteOn(9, drum, 125);
 93    MidiUSB.flush();
 94    noteOff(9, drum, 0);
 95    MidiUSB.flush();
 96  }
 97  
 98  ////////////////////////////////////////////////////////////////////////////
 99  void setup() {
100    // Initialize serial.
101    Serial.begin(9600); 
102    
103    // Initialize Circuit Playground library.
104    CircuitPlayground.begin();
105  }
106  
107  ////////////////////////////////////////////////////////////////////////////
108  void loop() {
109    // Loop over every pad.
110    for (int i=0; i<numberOfPads; i++) {
111      
112      // Check if pad is touched.
113      if (capButton(pads[i])) {
114        
115        // Do something.
116        takeAction(pads[i]);
117        
118        // But not too often.
119        delay(DEBOUNCE);
120      }
121    }
122  }