Go Down

Topic: Changing DrumKit Sketch to Only Read One Hit at a Time (Read 2285 times) previous topic - next topic

AeonSair

Hi, I'm running a version of SpikenzieLab's DrumKitAI Sketch on an Arduino Duemilanove w/ATmega 328. The drum kit sketch is meant to be used with multiple piezo sensors that are mounted on separate pads/drums. However, for my project I am mounting all of my piezo sensors on a single piece of thin wood. I need to the sketch to only register one hit at a time so that there wont be any crosstalk between sensors. I was hoping someone could describe/show me how to change the sketch to only read the sensor with the highest vibration for each hit. Here is the code I am using:
[font=Verdana]
Code: [Select]
//  BY: MARK DEMERS Copywrite 2009
//  April. 2009
//  VERSION: 1.b
//
//  DESCRIPTION:
//  Arduino analog input used to sense piezo drum hits then sent serialy to processing.

//*******************************************************************************************************************
// User settable variables
//*******************************************************************************************************************

unsigned char PadNote[6] = {40,36,50,63,40,65};         // MIDI notes from 0 to 127 (Mid C = 60)

int PadCutOff[6] = {580,700,280,600,600,600};           // Minimum Analog value to cause a drum hit

int MaxPlayTime[6] = {90,120,70,90,90,90};               // Cycles before a 2nd hit is allowed

#define  midichannel 0;                              // MIDI channel from 0 to 15 (+1 in "real world")

boolean VelocityFlag  = true;                           // Velocity ON (true) or OFF (false)





//*******************************************************************************************************************
// Internal Use Variables
//*******************************************************************************************************************

boolean activePad[6] = {0,0,0,0,0,0};                   // Array of flags of pad currently playing
int PinPlayTime[6] = {0,0,0,0,0,0};                     // Counter since pad started to play

unsigned char status;

int pin = 0;     
int hitavg = 0;

//*******************************************************************************************************************
// Setup
//*******************************************************************************************************************

void setup()
{
  Serial.begin(57600);                                  // connect to the serial port 115200
}

//*******************************************************************************************************************
// Main Program
//*******************************************************************************************************************

void loop()
{
  for(int pin=0; pin < 6; pin++)
  {
    hitavg = analogRead(pin);                              // read the input pin

    if((hitavg > PadCutOff[pin]))
    {
      if((activePad[pin] == false))
      {
        if(VelocityFlag == true)
        {
  //        hitavg = 127 / ((1023 - PadCutOff[pin]) / (hitavg - PadCutOff[pin]));    // With full range (Too sensitive ?)
          hitavg = (hitavg / 8) -1 ;                                                 // Upper range
        }
        else
        {
          hitavg = 127;
        }

        MIDI_TX(144,PadNote[pin],hitavg);
        PinPlayTime[pin] = 0;
        activePad[pin] = true;
      }
      else
      {
        PinPlayTime[pin] = PinPlayTime[pin] + 1;
      }
    }
    else if((activePad[pin] == true))
    {
      PinPlayTime[pin] = PinPlayTime[pin] + 1;
     
      if(PinPlayTime[pin] > MaxPlayTime[pin])
      {
        activePad[pin] = false;
        MIDI_TX(128,PadNote[pin],127);
      }
    }
  }
}


//*******************************************************************************************************************
// Transmit MIDI Message
//*******************************************************************************************************************
void MIDI_TX(unsigned char MESSAGE, unsigned char PITCH, unsigned char VELOCITY)
{
  status = MESSAGE + midichannel;
  Serial.write(status);
  Serial.write(PITCH);
  Serial.write(VELOCITY);
}
[/size][/size][/size][/font]
/code]

Thank you for any help/suggestions![size=10pt][size=10pt][font=Verdana][size=10pt][/size][/font][/size][/size]

Grumpy_Mike

I don't think you can. If they are all on the same piece of wood they will all get the same hit and there is nothing you can do to distinguish between them as all the signals will look the same.

AeonSair

#2
May 28, 2014, 08:01 am Last Edit: May 28, 2014, 08:05 am by AeonSair Reason: 1
The Piezos are able to measure the velocity of each hit based on the amount of vibration. The sketch even allows me to create a minimum velocity needed to send a MIDI signal. It seems like the code should be able to be altered to only allow a single MIDI note to be registered at a time (the note from the piezo with the strongest signal/vibration). Or am I missing something?

I should also note that currently, using the filter already built into the code, hitting the piece of wood only sends a signal from the nearest coupled of piezos. I used the Arduino Serial Monitor and recorded the data from various hits. It appears to be constant that the piezo nearest the point of contact for each hit sends the greatest value for the Velocity variable.

Grumpy_Mike

Try this then:-
Code: [Select]

void loop()
{
  int pin = 0;
  boolean noHit = true;
  while(pin < 6 && noHit){
    hitavg = analogRead(pin);                              // read the input pin
    if((hitavg > PadCutOff[pin]))
    {
       MIDI_TX(144,PadNote[pin],hitavg);
        noHit = false;
      }
    }   
    delay(100); // adjust for length of time to play note
        MIDI_TX(128,PadNote[pin],127);
        noHit = true;
      }


Note:- completely untested because only you have the hardware. It does compile however.

AeonSair

I just tried it and only the signals from the first sensor are coming through. I tried changing the PadCutOff to the lowest value for all the other sensors while increasing the PadCutOff for the first one, but I still can't get any of the other pads to register a hit.

Grumpy_Mike

Sorry I missed out a
Code: [Select]
pin++;
From that.
It goes just before the closing brace of the while statement.

AeonSair

I'm having trouble understanding where to insert that. I don't know very much about programming, just what I've learned in the past week.

Grumpy_Mike

I could believe you are not trying. I said:-
Quote
It goes just before the closing brace of the while statement.


If you click on the opening brace the closing brace gets highlighted. Remember that, in the mean time:-
Code: [Select]

void loop()
{
  int pin = 0;
  boolean noHit = true;
  while(pin < 6 && noHit){
    hitavg = analogRead(pin);                              // read the input pin
    if((hitavg > PadCutOff[pin]))
    {
       MIDI_TX(144,PadNote[pin],hitavg);
        noHit = false;
      }
      pin++;
    }   
    delay(100); // adjust for length of time to play note
        MIDI_TX(128,PadNote[pin],127);
        noHit = true;
      }

AeonSair

Thank you. I just uploaded the new sketch but the readings are going crazy. It appears that after the first piezo is triggered, a loop is occurring and sending a "note off" MIDI message. I've attached a screenshot of my MIDI monitor. I also tried running the sketch with all the user variables set to the default value but the same thing is happening. After the loop starts it appears that none of the Piezos can be triggered.

Grumpy_Mike

Try this then
Code: [Select]

void loop()
{
  int pin = 0;
  boolean noHit = true;
  while(pin < 6 && noHit){
    hitavg = analogRead(pin);                              // read the input pin
    if((hitavg > PadCutOff[pin]))
    {
       MIDI_TX(144,PadNote[pin],hitavg);
        noHit = false;
      }
      pin++;
    }
   if(!noHit){   
    delay(100); // adjust for length of time to play note
        MIDI_TX(128,PadNote[pin],127);
        noHit = true;
      }
}


Go Up