Air Drums

Обсуждаем Arduino, Raspberry Pi и другие электронные компоненты и проекты DIY
Ответить
stan
Сообщения: 3
Зарегистрирован: 26 фев 2013, 20:00

Air Drums

Сообщение stan »

Привет!

Помогите мне пожалуйста интегрировать код Debounce в мою программу!
Я уже собрал проект по типу "Arduino Air Drums" http://www.youtube.com/watch?feature=pl ... jvy_jzGlAQ by mmigdal и http://blimp12.blogspot.ru/2012/01/ardu ... art-1.html by Bhargav. Но их коды у меня не работали и я взял как базу более простой код отсюда: http://itp.nyu.edu/physcomp/Labs/MIDIOutput

Проблема в том что акселерометры при каждом малейшем движении сигналят. Я пытался использовать код с http://playground.arduino.cc/Learning/SoftwareDebounce но он даже не компилировался. Код отсюда бесконечно повторял сигнал http://www.arduino.cc/en/Tutorial/Switch

Я не знаю что ещё можно сделать. Может кто-то подскажет?

Код: Выделить всё

#include <SoftwareSerial.h>
SoftwareSerial midiSerial(2, 3);   // digital pins for soft serial RX & TX

#define hatOpen  0x36              // LDR switches between two MIDI notes, 
#define hatClosed  0x5a            // used in HIHAT SETTINGS

 // Variables:
  int LEDpin = 13;            // MIDI signal light indicator
 
  int kickPin = A3;           // Kick Pedal sensor
  int lastKickPinState = 0;
  int currentKickPinState = 0;
  
  int snarePin = A5;          // Snare Stick sensor
  int lastSnarePinState = 1;    
  int currentSnarePinState = 1;
  
  int hatPin = A4;          // HiHat Stick sensor
  int lastHatPinState = 1;    
  int currentHatPinState = 1;
  int HH;
  
  int pedalPin = A2;          // HiHat Pedal sensor
  int lastPedalPinState = 0;    
  int currentPedalPinState = 0;

  void setup() 
  {
    Serial.begin(9600);
      midiSerial.begin(31250);
      pinMode(LEDpin, OUTPUT);
      pinMode(kickPin, INPUT);
      pinMode(snarePin, INPUT);
      pinMode(hatPin, INPUT);
      pinMode(pedalPin, INPUT);
  }


  void loop() {
    
 /* KICK SETTINGS BELOW*/

    currentKickPinState = digitalRead(kickPin);
    // Check to see that the switch is pressed:
    if (currentKickPinState == 1) {
      //  check to see that the switch wasn't pressed last time through the main loop
      if (lastKickPinState == 0) {
        noteOn(0x90, 0x24, 0x40);
        // save the note we played, so we can turn it off:
        digitalWrite(LEDpin, HIGH);
      }
    }
    else {   // if the switch is not pressed but the switch was pressed last time through the main loop:
      if (lastKickPinState == 1) {
        //  stop the last note played:
        noteOn(0x90, 0x24, 0x00);
        digitalWrite(LEDpin, LOW);
      }
    }
    //  save the state of the switch for next time through the main loop:
    lastKickPinState = currentKickPinState;


/* SNARE SETTINGS BELOW*/

currentSnarePinState = digitalRead(snarePin);
    if (currentSnarePinState == 0) {
      if (lastSnarePinState == 1) {
        noteOn(0x90, 0x26, 0x40);
        digitalWrite(LEDpin, HIGH);
      }
    }
    else {
      if (lastSnarePinState == 0) {
        noteOn(0x90, 0x26, 0x00);
        digitalWrite(LEDpin, LOW);
      }
    }
    lastSnarePinState = currentSnarePinState;


/* HIHAT SETTINGS BELOW*/

    currentHatPinState = digitalRead(hatPin);
    if (currentHatPinState == 0) {
      if (lastHatPinState == 1) {
        noteOn(0x90, HH, 0x40);
        digitalWrite(LEDpin, HIGH);
      }
    }
    else {  
      if (lastHatPinState == 0) {
        noteOn(0x90, HH, 0x00);
        digitalWrite(LEDpin, LOW);
      }
    }
    lastHatPinState = currentHatPinState;

{
if (analogRead(A2)>25)    // HiHat Pedal switches HiHat Open or Closed
{
  HH=hatOpen;
}
else
{
  HH=hatClosed;
}
}

  }


  //  plays a MIDI note
  void noteOn(byte cmd, byte data1, byte data2) { 
    midiSerial.write(cmd);
    midiSerial.write(data1);
    midiSerial.write(data2);

   //prints the values in Serial Monitor
    Serial.print("cmd: ");
    Serial.print(cmd);
    Serial.print(", data1: ");
    Serial.print(data1);
    Serial.print(", data2: ");
    Serial.println(data2);

  }
Hardware:
- Arduino Leonardo
- Piezo (Kick pedal)
- Accelerometer MMA7361 (Snare stick, HiHat stick)
- LDR (HiHat pedal)
- MIDI OUT circuit
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1020
Зарегистрирован: 22 окт 2010, 23:57

Re: Air Drums

Сообщение Mr.Kubikus »

Привет!

Может быть проблема в том, что в программе вы пытаетесь работать с аналоговыми(0..1023) датчиками как с цифровыми (0..1) ?
С уважением, Григорий
GitHub FB ВК
stan
Сообщения: 3
Зарегистрирован: 26 фев 2013, 20:00

Re: Air Drums

Сообщение stan »

Я тоже так думал и хотел уменьшить чувствительность командой, допустим
if ( analogRead(snarePin) < 100 ); (т.к. в неподвижном сост. сигнал 1023, а рывок читает как 0)
then..


Но я не разобрался как его правильно прописать, т.к. сейчас в коде есть простой дебаунсер "currentPinState / lastPinState" ответы которым либо да либо нет (1/0).
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1020
Зарегистрирован: 22 окт 2010, 23:57

Re: Air Drums

Сообщение Mr.Kubikus »

Я думаю, в вашем случае поможет НЧ фильтрация сигналов от акселерометров. С помощью фильтров можно уменьшить чувствительность этих датчиков.

Пример реализации НЧ фильтра для Arduino:

http://playground.arduino.cc/main/smooth

Код: Выделить всё

int sensVal;           // for raw sensor values 
float filterVal;       // this determines smoothness  - .0001 is max  1 is off (no smoothing)
float smoothedVal;     // this holds the last loop value just use a unique variable for every different sensor that needs smoothing

float smoothedVal2;   // this would be the buffer value for another sensor if you needed to smooth two different sensors - not used in this sketch


int i, j;              // loop counters or demo     

void setup()
{
  Serial.begin(9600);
  Serial.println("start ");
}

/* the main loop is a test of the smooth function. It generates a simulated square wave and then 
 switches in four different smoothing values. Watch the numbers scroll by as the filter value
 slows down the response.  */


void loop()
{ 
  for (i = 0; i < 7; i++){    // substitute some different filter values
    filterVal = i * .15; 


    for (j = 0; j< 60; j++){      

      if (j < 30){            // generate a simulated square wave
        sensVal = 1023;
      }
      else
      {
        sensVal = 0; 
      }

      // sensVal = analogRead(0);   this is what one would do normally
      smoothedVal =  smooth(sensVal, filterVal, smoothedVal);   // second parameter determines smoothness  - 0 is off,  .9999 is max smooth 

      Serial.print(sensVal);
      Serial.print("   ");
      Serial.print(smoothedVal, DEC);
      Serial.print("      ");
      Serial.print("filterValue * 100 =  ");   // print doesn't work with floats
      Serial.println(filterVal * 100, DEC);
      delay(30); 
    }
  }
}

int smooth(int data, float filterVal, float smoothedVal){


  if (filterVal > 1){      // check to make sure param's are within range
    filterVal = .99;
  }
  else if (filterVal <= 0){
    filterVal = 0;
  }

  smoothedVal = (data * (1 - filterVal)) + (smoothedVal  *  filterVal);

  return (int)smoothedVal;
}
С уважением, Григорий
GitHub FB ВК
stan
Сообщения: 3
Зарегистрирован: 26 фев 2013, 20:00

Re: Air Drums

Сообщение stan »

Для меня этот код слишком сложный чтобы понять как с его помощью контролировать MIDI note on/off и LED on/off.
noteOn(0x90, 0x26, 0x40);
digitalWrite(LEDpin, HIGH);

Я вижу analogRead(0) но в сэмпле его значение ничего не контролирует?
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1020
Зарегистрирован: 22 окт 2010, 23:57

Re: Air Drums

Сообщение Mr.Kubikus »

приведу пример для для HiHat:

Дополнительные переменные:
int sensHiHat = 0; // Значение из АЦП.
float smoothHiHat = 0.0; // Сглаженное значение.
float paramKFHiHat = 0.1; // Коэффициент НЧ фильтра [0.001..1.0]. Чем меньше KF, тем более сглаженным будет сигнал на выходе.
float limHiHat = 512.0; //Порог сигнала, превышение которого посылает команду MIDI. Уточняется в процессе настройки.

1. Сначала вам надо получить значение сигнала в цифровой форме:

sensHiHat = analogRead(hatPin);

2. Затем пропускаем сигнал через фильтр:

smoothHiHat = smooth(sensHiHat, paramKFHiHat, smoothHiHat);

4. Теперь сравниваем сглаженный сигнал с пороговым значением и формируем соответствующую команду MIDI:

Код: Выделить всё

if (smoothHiHat > limHiHat) {
  currentHatPinState = 1;
} 
else {
  currentHatPinState = 0;
}

if (currentHatPinState == 1) {
  if (lastHatPinState == 0) {
    noteOn(0x90, HH, 0x40);
    digitalWrite(LEDpin, HIGH);
  }
}
else { 
  if (lastHatPinState == 1) {
    noteOn(0x90, HH, 0x00);
    digitalWrite(LEDpin, LOW);
  }
}
lastHatPinState = currentHatPinState;
С уважением, Григорий
GitHub FB ВК
Ответить