Help needed to replace a button with a piezo

Hi
I am currently trying to build a drumkit that triggers sounds in pro tools. i have got it working using buttons. However I am now trying to find a way to replace the button with a piezo. Any help with this would be very apreciated.

Thanks :slight_smile:

The code below works with 8 buttons

// what midi channel we're sending on
// ranges from 0?15
#define drumchan 9 // Equates to MIDI Channel 10
// general midi drum notes
#define note_bassdrum 36
#define note_snaredrum 38
#define note_clap 39
#define note_hihat 42
#define note_rim 45
#define note_openhat 46
#define note_hattype 51
#define note_horn 43
// define the pins we use
#define switchAPin 10
#define switchBPin 9
#define switchCPin 8
#define switchDPin 7
#define switchEPin 6
#define switchFPin 5
#define switchGPin 4
#define switchHPin 3
#define ledPin 13 // for midi out status
int switchAState = LOW;
int switchBState = LOW;
int switchCState = LOW;
int switchDState = LOW;
int switchEState = LOW;
int switchFState = LOW;
int switchGState = LOW;
int switchHState = LOW;
int currentSwitchState = LOW;
int val,t;
void setup() {
pinMode(switchAPin, INPUT);
pinMode(switchBPin, INPUT);
pinMode(switchCPin, INPUT);
pinMode(switchDPin, INPUT);
pinMode(switchEPin, INPUT);
pinMode(switchFPin, INPUT);
pinMode(switchGPin, INPUT);
pinMode(switchHPin, INPUT);
digitalWrite(switchAPin, HIGH); // turn on internal pullup
digitalWrite(switchBPin, HIGH); // turn on internal pullup
digitalWrite(switchCPin, HIGH); // turn on internal pullup
digitalWrite(switchDPin, HIGH); // turn on internal pullup
digitalWrite(switchEPin, HIGH); // turn on internal pullup
digitalWrite(switchFPin, HIGH); // turn on internal pullup
digitalWrite(switchGPin, HIGH); // turn on internal pullup
digitalWrite(switchHPin, HIGH); // turn on internal pullup
pinMode(ledPin, OUTPUT);
Serial.begin(57600); // set MIDI baud rate
}
void loop() {
// deal with switchA
currentSwitchState = digitalRead(switchAPin);
if( currentSwitchState == LOW && switchAState == HIGH ) // push
noteOn(drumchan, note_bassdrum, 100);
if( currentSwitchState == HIGH && switchAState == LOW ) // release
noteOff(drumchan, note_bassdrum, 0);
switchAState = currentSwitchState;
// deal with switchB
currentSwitchState = digitalRead(switchBPin);
if( currentSwitchState == LOW && switchBState == HIGH ) // push
noteOn(drumchan, note_snaredrum, 100);
if( currentSwitchState == HIGH && switchBState == LOW ) // release
noteOff(drumchan, note_snaredrum, 0);
switchBState = currentSwitchState;
// deal with switchC
currentSwitchState = digitalRead(switchCPin);
if( currentSwitchState == LOW && switchCState == HIGH ) // push
noteOn(drumchan, note_clap, 100);
if( currentSwitchState == HIGH && switchCState == LOW ) // release
noteOff(drumchan, note_clap, 0);
switchCState = currentSwitchState;
// deal with switchD
currentSwitchState = digitalRead(switchDPin);
if( currentSwitchState == LOW && switchDState == HIGH ) // push
noteOn(drumchan, note_hihat, 100);
if( currentSwitchState == HIGH && switchDState == LOW ) // release
noteOff(drumchan, note_hihat, 0);
switchDState = currentSwitchState;
// deal with switchE
currentSwitchState = digitalRead(switchEPin);
if( currentSwitchState == LOW && switchEState == HIGH ) // push
noteOn(drumchan, note_rim, 100);
if( currentSwitchState == HIGH && switchEState == LOW ) // release
noteOff(drumchan, note_rim, 0);
switchEState = currentSwitchState;
// deal with switchF
currentSwitchState = digitalRead(switchFPin);
if( currentSwitchState == LOW && switchFState == HIGH ) // push
noteOn(drumchan, note_openhat, 100);
if( currentSwitchState == HIGH && switchFState == LOW ) // release
noteOff(drumchan, note_openhat, 0);
switchFState = currentSwitchState;
// deal with switchG
currentSwitchState = digitalRead(switchGPin);
if( currentSwitchState == LOW && switchGState == HIGH ) // push
noteOn(drumchan, note_hattype, 100);
if( currentSwitchState == HIGH && switchGState == LOW ) // release
noteOff(drumchan, note_hattype, 0);
switchGState = currentSwitchState;
// deal with switchH
currentSwitchState = digitalRead(switchHPin);
if( currentSwitchState == LOW && switchHState == HIGH ) // push
noteOn(drumchan, note_horn, 100);
if( currentSwitchState == HIGH && switchHState == LOW ) // release
noteOff(drumchan, note_horn, 0);
switchHState = currentSwitchState;
// Send a MIDI note on message. L ? ike pressing a piano key
// channel ranges from 0?15
}
void noteOn(byte channel, byte note, byte velocity) {
midiMsg( (0x90 | channel), note, velocity);
}
// Send a MIDI note?off message. Like releasing a piano key
void noteOff(byte channel, byte note, byte velocity) {
midiMsg( (0x80 | channel), note, velocity);
}
// Send a general MIDI message
void midiMsg(byte cmd, byte data1, byte data2) {
digitalWrite(ledPin,HIGH); // indicate we're sending MIDI data
Serial.write(byte(cmd));
Serial.write(byte(data1));
Serial.write(byte(data2));
digitalWrite(ledPin,LOW);
}

Have you looked at this?

... and these
http://leucos.lstilde.org/wp/2009/06/piezo-transducer-signal-conditioning/

Thank you for the help :slight_smile:

Hi again
Thanks for the links, i am still really struggling to work out how to replace the code that uses the button to trigger pro tools with the piezo. I have connected the piezo and connected it the same as this link you kindly supplied. http://www.arduino.cc/en/Tutorial/KnockSensor. I have it working so that the light goes bright when you tap the piezo, and i am able to monitor the values that are triggered from the piezo via the monitor window. The main thing i am struggling with now is, how do i change the code so that the piezo signal replaces the button. Any advice in regard to this would be a great help. I have been reading up on the code as well as following the tutorials and have no idea what to try now.

The main difference is the piezo returns an analog value instead of a digital, so you will need to deal with values that are 0-1023 rather than HIGH/LOW.

One approch may be to use a threshold value (x) that over which you treat it as HIGH and below which it is LOW. That means you can reduce the number of changes to your current code.

Alternatively, you can use the additional information from a piezo to include 'loudness' of the drum. In this case you could use the value 0-1023 as an indication of how hard the drum is hit and, therefore, how loud it would be.

I would suggest you experiment with one piezo and the serial monitor, printing the values, to get a feel for what hitting the piezo does.

I will give it a go. Thanks :slight_smile:

A couple of other suggestions:

  • Your code has a lot of repetition in it. This means that you should be able to define a functin to do one drum (passing in the right parameters) and then call it with different parameters to do the other drums. This will make maintaining the code easier (eg, to change the way all drums work you only need to change the one function).
  • Consider using arrays to store repetitive data and implify processing your code (see below for an example)
    From
// define the pins we use
#define switchAPin 10
#define switchBPin 9
#define switchCPin 8
#define switchDPin 7
#define switchEPin 6
#define switchFPin 5
#define switchGPin 4
#define switchHPin 3
int switchAState = LOW;
int switchBState = LOW;
int switchCState = LOW;
int switchDState = LOW;
int switchEState = LOW;
int switchFState = LOW;
int switchGState = LOW;
int switchHState = LOW;

to

#define NUMNOTES 8
const uint8_t switchPin[NUMNOTES] = { 10, 9, 8, 7, 6, 5, 4, 3 };
int switchState[NUMNOTES] = { LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW };

Get the idea? You can do the same with the drum notes. The you can go through the whole lot using a 'for' loop in a few statements, as long as the array indices (ie, the 0, 1, etc) for the arrays are congruent for all arrays.

for (uint8_t i=0; i<NUM_NOTES; i++)
{
  currentSwitchState = digitalRead(switchPin[i]);
  if( currentSwitchState == LOW && switchState[i] == HIGH ) // push
    noteOn(drumchan, note_drum[i], 100);
  else if( currentSwitchState == HIGH && switchState[i] == LOW ) // release
    noteOff(drumchan, note_drum[i], 0);
  switchState[i] = currentSwitchState;
}