Pages: [1]   Go Down
Author Topic: Changing DrumKit Sketch to Only Read One Hit at a Time  (Read 2143 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
//  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]
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 637
Posts: 34581
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: May 28, 2014, 01:05:48 am by AeonSair » Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 637
Posts: 34581
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Try this then:-
Code:
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.
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 637
Posts: 34581
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Offline Offline
Newbie
*
Karma: 1
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 637
Posts: 34581
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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;
      }
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.


* Screen Shot 2014-05-28 at 6.59.12 PM.png (48.95 KB, 639x408 - viewed 29 times.)
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 637
Posts: 34581
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Try this then
Code:
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;
      }
}

Logged

Pages: [1]   Go Up
Jump to: