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 :)

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

Thank you for the help :)

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. 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 :)

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)
// 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;


#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;