#include <Adafruit_NeoPixel.h>
// ------------------------- CONSTANTS ----------------------------//
//Drums
#define PIN_DRUM_1 A0
#define PIN_LED_1 2
#define PIN_DRUM_2 A1
#define PIN_LED_2 3
#define DRUM_COUNT 2
#define DRUM_SENS 350
#define DELAY_BETWEEN_HIT 100
#define DELAY_LENGTH_HIT 20
//Midi
#define SERIAL_MIDI Serial
#define MIDI_NOTE_ON 0x90
#define NOTE_DRUM_1 60
#define NOTE_DRUM_2 61
#define NOTE_LENGTH 1000
//Led
#define LED_NUM 16
#define LED_R 255
#define LED_G 255
#define LED_B 255
// ------------------------- END CONSTANTS ----------------------------//
// ------------------------- START DRUMS CLASS ----------------------------//
class Drum{
public:
Drum();
Drum(uint8_t _pinDrum, uint8_t _pinLed, uint8_t _note);
void init();
boolean checkHit();
void play();
void stop();
boolean Drum::isNeedToStop();
uint8_t pinDrum;
uint8_t pinLed;
uint8_t note;
int mid;
long timer;
Adafruit_NeoPixel strip;
boolean isOn;
};
Drum::Drum(){}
Drum::Drum(uint8_t _pinDrum, uint8_t _pinLed, uint8_t _note){
pinDrum = _pinDrum;
pinLed = _pinLed;
note = _note;
pinMode(pinLed, OUTPUT);
strip = Adafruit_NeoPixel(LED_NUM, pinLed, NEO_GRB + NEO_KHZ800);
isOn = false;
}
void Drum::init(){ // Drums initialisation
strip.begin(); // led init
uint8_t n = 5; // count averange
for(uint8_t i=0; i<n; i++ ){
mid = analogRead(pinDrum);
}
mid = mid/n;
}
boolean Drum::checkHit(){ // Check hitting
if(abs(analogRead(pinDrum)-mid)>DRUM_SENS){
delay(DELAY_LENGTH_HIT);
if(abs(analogRead(pinDrum)-mid)>DRUM_SENS){
return true;
}
}
return false;
}
void Drum::play(){ // Start midi and led
// Send play midi
SERIAL_MIDI.write(MIDI_NOTE_ON); // command code midi
SERIAL_MIDI.write(note); // midi note
SERIAL_MIDI.write(127); // velosity
// Send show LED
for(int i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, strip.Color(LED_R,LED_G,LED_B));
}
strip.show();
isOn = true;
timer = millis();
}
void Drum::stop(){ // Stop midi and led
// Send play midi
SERIAL_MIDI.write(MIDI_NOTE_ON); // command code midi
SERIAL_MIDI.write(note); // midi note
SERIAL_MIDI.write(0); // velosity
// Send show LED
for(int i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, strip.Color(0,0,0));
}
strip.show();
isOn = false;
}
boolean Drum::isNeedToStop(){ // Check time to stop
if(((millis()-timer)) > NOTE_LENGTH){
return true;
}
return false;
}
// ------------------------- END DRUMS CLASS ----------------------------//
// ------------------------- GLOBAL VAR ----------------------------//
Drum drums[DRUM_COUNT];
// ------------------------- ENDGLOBAL VAR ----------------------------//
// ------------------------- SETUP ---------------------------------//
void setup() {
SERIAL_MIDI.begin(9600);
drums[0] = Drum(PIN_DRUM_1,PIN_LED_1,NOTE_DRUM_1);
drums[1] = Drum(PIN_DRUM_2,PIN_LED_2,NOTE_DRUM_2);
for(uint8_t i=0; i<8; i++)
drums[i].init();
}
// ------------------------- END SETUP ---------------------------------//
// ------------------------- MAIN LOOP ---------------------------------//
void loop(){
// loop for ceck hit and start play
for(uint8_t i=0; i<DRUM_COUNT; i++){
if(drums[i].checkHit()){
drums[i].play();
}
}
// loop for finish time and stop play
for(uint8_t i=0; i<DRUM_COUNT; i++){
if(drums[i].isOn){
if(drums[i].isNeedToStop()){
drums[i].stop();
}
}
}
delay(DELAY_BETWEEN_HIT);
}
// ------------------------- END MAIN LOOP ---------------------------------//