Тел. (495) 972-27-12

Air Drums

Обсуждаем Arduino, Raspberry Pi и другие электронные компоненты и проекты DIY

Air Drums

Сообщение stan » 26 фев 2013, 20:48

Привет!

Помогите мне пожалуйста интегрировать код 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

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

Code: [Выделить всё] [Expand/Collapse]
#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);

  }
GeSHi © Codebox Plus


Hardware:
- Arduino Leonardo
- Piezo (Kick pedal)
- Accelerometer MMA7361 (Snare stick, HiHat stick)
- LDR (HiHat pedal)
- MIDI OUT circuit
stan
 
Сообщения: 3
Зарегистрирован: 26 фев 2013, 20:00

Re: Air Drums

Сообщение Mr.Kubikus » 26 фев 2013, 22:12

Привет!

Может быть проблема в том, что в программе вы пытаетесь работать с аналоговыми(0..1023) датчиками как с цифровыми (0..1) ?
С уважением, Григорий
GitHub FB ВК TW
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
 
Сообщения: 881
Изображения: 49
Зарегистрирован: 22 окт 2010, 23:57
Откуда: Москва

Re: Air Drums

Сообщение stan » 27 фев 2013, 00:43

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


Но я не разобрался как его правильно прописать, т.к. сейчас в коде есть простой дебаунсер "currentPinState / lastPinState" ответы которым либо да либо нет (1/0).
stan
 
Сообщения: 3
Зарегистрирован: 26 фев 2013, 20:00

Re: Air Drums

Сообщение Mr.Kubikus » 27 фев 2013, 01:29

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

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

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

Code: [Выделить всё] [Expand/Collapse]
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;
}
GeSHi © Codebox Plus
С уважением, Григорий
GitHub FB ВК TW
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
 
Сообщения: 881
Изображения: 49
Зарегистрирован: 22 окт 2010, 23:57
Откуда: Москва

Re: Air Drums

Сообщение stan » 27 фев 2013, 09:32

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

Я вижу analogRead(0) но в сэмпле его значение ничего не контролирует?
stan
 
Сообщения: 3
Зарегистрирован: 26 фев 2013, 20:00

Re: Air Drums

Сообщение Mr.Kubikus » 27 фев 2013, 18:11

приведу пример для для 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:
Code: [Выделить всё] [Expand/Collapse]
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;
GeSHi © Codebox Plus
С уважением, Григорий
GitHub FB ВК TW
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
 
Сообщения: 881
Изображения: 49
Зарегистрирован: 22 окт 2010, 23:57
Откуда: Москва


Вернуться в Arduino и Ко. ♥♥♥



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

cron