here full sketch
/*
MIDI ударная установка
sslobodyan@ya.ru 2017
*/
#define LED 13
#define PIEZ_CNT 8 // количество датчиков
#define DRUM_CHANEL 8
#define ANOTHER_MUTE_PIN_
#define SHOW_
#define CRASH 0 // номер пьезо на котором тарелка
// #define CRASHC 54
#define PIN_CRASH_STOP 9 // кнопка на крэше
#define OPEN_HAT 42 //нота открытого хэта
//#define OPENING_HAT 21 //звук педали хэта
#define KANAL_HAT 1 // номер пьезо на котором хэт
#define KNOPKA_HAT 10 // педаль хэт
// пороговый уровень датчика
int kick_treshold[PIEZ_CNT]={50,150,150,150,150,150,150,150};
// время на остановку колебаний
long kick_mute_time[PIEZ_CNT]={60000,50000,50000,50000,50000,50000,50000,50000};
// ноты на каналах
byte kick_note[PIEZ_CNT]={49,46,51,36,33,50,47,43};
// канал молчит
bool mute[PIEZ_CNT]={1,1,1,1,1,1,1,1};
// ножка датчика
const uint8_t kick_pin[PIEZ_CNT]={A0,A1,A2,A3,A4,A5,A5,A5};
#ifdef ANOTHER_MUTE_PIN
const uint8_t stop_pin[PIEZ_CNT]={A0,A1,A2,A3,A4,A5,A5,A5};
#endif
int kick_val[PIEZ_CNT]; // предыдущее значение датчика
int velocity;
uint32_t tm[PIEZ_CNT], tm_led;
byte cnt=0, piez_idx=0;
void noteOn(int chan, int note, int velocity) {
Serial.write( (0x90 | chan) );
Serial.write(note);
Serial.write(velocity);
}
void noteOff(int chan, int note, int velocity) {
Serial.write( (0x80 | chan) );
Serial.write(note);
Serial.write(velocity);
}
void channelVolume(int chan, int velocity) {
Serial.write( (0xb0 | chan) );
Serial.write( 0x07 );
Serial.write(velocity);
}
void channelPan(int chan, int pan) {
Serial.write( (0xb0 | chan) );
Serial.write( 0x0a );
Serial.write(pan);
}
void channelBank(int chan, int dat) {
Serial.write( (0xB0 | chan) );
Serial.write( 0x00 );
Serial.write( dat );
}
void channelInstrum(int chan, int dat) {
Serial.write( (0xC0 | chan) );
Serial.write( dat );
}
void setup() {
Serial.begin(115200); // эмулятор МИДИ на компе
//Serial.begin(31250); // реальный МИДИ
pinMode(LED, OUTPUT);
pinMode(PIN_CRASH_STOP, INPUT);
pinMode(KNOPKA_HAT, INPUT);
digitalWrite(LED, LOW);
for (byte i=0; i<PIEZ_CNT; i++) {
digitalWrite(kick_pin[i], LOW);
pinMode(kick_pin[i], INPUT);
#ifdef ANOTHER_MUTE_PIN
digitalWrite(stop_pin[i], LOW);
pinMode(stop_pin[i], INPUT);
#endif
}
channelBank(1, 0);
channelInstrum(1, DRUM_CHANEL);
channelVolume(1, 70);
// делитель 16 - частота опроса 1МГц разрешение 8 бит
ADCSRA |= (1 << ADPS2); //Биту ADPS2 присваиваем единицу
ADCSRA &= ~ ((1 << ADPS1) | (1 << ADPS0)); //Битам ADPS1 и ADPS0 присваиваем нули
}
void loop(){
if (mute[CRASH] == false) { //если щас играет крэш
if (digitalRead[PIN_CRASH_STOP] == LOW) { // и при этом нажали кнопку
noteOn (DRUM_CHANEL,kick_note[CRASH],0); // глуши тарелку
//noteOn (DRUM_CHANEL,kick_note[CRASHC],127); // звук резко заглушенной тарелки
}
}
if(piez_idx>0) piez_idx--; else piez_idx=PIEZ_CNT-1; // выбор следующего датчика
int adc = analogRead(kick_pin[piez_idx]);
if (adc > kick_treshold[piez_idx]) {
if ( tm[piez_idx] == 0 ){
tm[piez_idx] = micros() + 2000;
kick_val[piez_idx] = 0;
digitalWrite(LED, HIGH);
tm_led = millis()+10;
}
}
if (tm_led > 0) {
if (millis() > tm_led) {
tm_led = 0;
digitalWrite(LED, LOW);
}
}
if ( tm[piez_idx] > 0 ) {
if ( micros() > tm[piez_idx] ) {
if ( mute[piez_idx] ) {
mute[piez_idx] = false;
velocity = map(kick_val[piez_idx], kick_treshold[piez_idx], 1023, 1, 127);
if (velocity > 127) velocity = 127;
if (piez_idx == KANAL_HAT){
if (digitalRead(KNOPKA_HAT) == LOW ){ // если кнопка нажата
// noteOn(DRUM_CHANEL,OPENING_HAT,velocity);
noteOn(DRUM_CHANEL,OPEN_HAT,velocity); //играем открытый хэт
}
else {
noteOn(DRUM_CHANEL,kick_note[piez_idx],velocity); //играем ноту из масива закрытый хэт
}
}
else {
noteOn(DRUM_CHANEL, kick_note[piez_idx], velocity); // играем остальные ноты из масива
}
tm[piez_idx] += kick_mute_time[piez_idx];
#ifdef ANOTHER_MUTE_PIN
pinMode(stop_pin[piez_idx], OUTPUT); // разряжаем кондер
#else
pinMode(kick_pin[piez_idx], OUTPUT); // разряжаем кондер
#endif
#ifdef SHOW
cnt++;
velocity = kick_val[piez_idx];
Serial.print("IDX="); Serial.print(piez_idx);
Serial.print(" Vel="); Serial.print(velocity);
Serial.print(" cnt="); Serial.println(cnt);
#endif
}
}
if ( kick_val[piez_idx] < adc ) {
kick_val[piez_idx] = adc; // ищем максимум сигнала от датчика
}
if ( micros() > tm[piez_idx] ) {
// закончили сканирование одного удара
tm[piez_idx] = 0;
mute[piez_idx] = true;
// отключаем разрядку кондера
#ifdef ANOTHER_MUTE_PIN
pinMode(stop_pin[piez_idx], INPUT);
#else
pinMode(kick_pin[piez_idx], INPUT);
#endif
}
}
}