# reading piezo for midi note velocity

Hi all, I’ve been working on a midi drum controller for some time now. At the moment I am able to trigger note on/pff messages using 16 piezos, however the notes all have a fixed velocity of max 127 or 0. How can I get velocity based on how hard or soft I hit the sensor? I’ve read a lot of posts on the topic including this one http://www.workinprogress.ca/projects/edubeat/source/ see original post http://lists.puredata.info/pipermail/pd-list/2011-06/089407.html these deal with shaping the signal by adding a capacitor , which I intend to do. I also read this post http://arduino.cc/forum/index.php?topic=65113.0 which deal with velocity like this

So what happens is, as soon as I strike the piezo, I hear a piano note
from my PC speakers…
I also modified the sketch so that instead of ‘127’ as the midi
velocity, I send the analog read value divided by 8 (max value from
analog read is 1023, and max midi velocity value is 127) to the
software
So now I’ve got the basic idea working with ‘velocity’ sensing

Can anyone help me implement velocity sensing like mentioned above or other in the sketch below

``````/* Midi Footsteps - Mike Cook Feb 2010
*
* -----------------
* send MIDI serial data, for multiplexed pressure pad sensors
*
*
###############################################################################################

HARDWARE NOTE:
The MIDI Socket is connected to arduino TX through a PNP transistor to
invert the MIDI signal.

*  Using 1 MCP23016 I2C expanders at addresses 0 to drive indicator LEDs
*  Two 8 to 1 multiplexers feeding A0 and A1 controlled by Pins 4, 5 & 6

*  Output MIDI CC values from 16 to 32 (depending on what sensor is triggered)
with a value of 0 or 127 depending if the sansor returns
a number greater than or less than that held in the threshold variable.

################################################################################################
*/
// Includes
#include <Wire.h>
#include <avr/pgmspace.h>
#include "Defines.h"
#include "pitches.h"
//#define MIDI_TEST   // un comment for a test to format the data for
the seril monitor
// notes to play, corresponding to the 12+ sensors:
int notes[] = { NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6,
NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5 };//soprano

// Start of code
void setup() {
//  set the states of the I/O pins to drive the sensor multiplexer:
pinMode(s0Pin, OUTPUT);
pinMode(s1Pin, OUTPUT);
pinMode(s2Pin, OUTPUT);
lastLedVal = 0;

// Setup I2C devices
Wire.begin();                      // start the I2C interface

doSensorScan();                                        // get initial states
saveCurrentState();

//  Setup serial / MIDI
#ifdef MIDI_TEST
Serial.begin(9600);    // Debug speed
#else
Serial.begin(31250);       // MIDI speed
#endif
}

//********************* MAIN LOOP ***********************************

void loop() {
doSensorScan();
lookForChange();
saveCurrentState();
//   delay(400);
} // end loop function

//********************* Functions ***********************************

void doSensorScan() {  // look at all the sensors
for(int i=0; i<8; i++){
// select multiplexer channel
digitalWrite(s0Pin, i & 0x1);
digitalWrite(s1Pin, (i>>1) & 0x1);
digitalWrite(s2Pin, (i>>2) & 0x1);
delay(1);            // delay to allow sample & hold capictor to charge
delay(1);            // delay to allow sample & hold capictor to charge
}
}

void saveCurrentState(){  // save the current state for next time
for(int i=0; i<16; i++){
lastState[i] = currentState[i];
}
}

void printCurrentSatae(){   // for debugging use
Serial.print(" one ");
for(int i=0; i<3; i++){
Serial.print(currentState[i], HEX);
Serial.print(" ");
}
Serial.println(" ");
Serial.print(" two ");
for(int i=0; i<3; i++){
Serial.print(currentState[i+8], HEX);
Serial.print(" ");
}
}

// the value of threshold determins the on / off point
void lookForChange(){
int ledVal = 0;
for(int i=0; i<16; i++){
the position of sensors under threshold
}
if(lastLedVal != ledVal) {   // something has changed
for(int i=0; i<16; i++){
if((ledMask & ledVal) == 0) {
// note off
controlSend(0x80, control[i], 0x00);   // turn off control message
noTone(8);
digitalWrite(ledPin,LOW);
}
else{
// note on
controlSend(0x90, control[i], 0x7f);  // turn on control message
tone(8, notes[i], 20);
digitalWrite (ledPin,HIGH);
}
}
}
// Update the trigger LEDs
}
lastLedVal = ledVal;        // record current state of LEDs and
MIDI notes / messages
digitalWrite(ledPin,LOW);
}

//  plays a MIDI note

#ifdef MIDI_TEST
// This is a test so format data for viewing in the serial monitor
void controlSend(char cmd, char data1, char data2) {
cmd = cmd | char(midiChannel);  // merge channel number
Serial.print(((cmd >> 4) & 0xf), HEX);  // to prevent leading Fs
being displayed
Serial.print((cmd & 0xf), HEX);
Serial.print(" ");
Serial.print(data1, HEX);
Serial.print(" ");
Serial.println(data2, HEX);

}

#else
// no test so send the stuff out to MIDI
void controlSend(char cmd, char data1, char data2) {
cmd = cmd | char(midiChannel);  // merge channel number
Serial.print(cmd, BYTE);
Serial.print(data1, BYTE);
Serial.print(data2, BYTE);
}
==========
new Tab
========
defines.h

// Defines
// I2C registers
#define I2CregisterInput 0
#define I2CregisterOutput 2
#define I2CregisterPolarity 4
#define I2CregisterConfig 6
#define I2CregisterInterrupt 8
#define I2CregisterExpander 10
indicators output
// Control Switch device bit masks
#define ddrTrigger 0x00000     // data direction register for trigger
indictor LEDs

// Arduino pin assignments

#define midiChannel (byte)0

// Define constants
const int s0Pin = 2;  // multiplexer select pins
const int s1Pin = 3;
const int s2Pin = 4;
const int mux1 = 0;   // analogue port multiplexer 1 is read on
const int mux2 = 1;   // analogue port multiplexer 2 is read on
#define ledPin     13  // for midi out status
// Variable definations
int currentState[16]; // current state of sensors
int lastState[16];    // the last state of the sensors
int threshold = 0x90;  // sets the threshold value in deciding if a
sensor is pressd.
int lastLedVal;
char control[16] = { 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75};
// notes to play, corresponding to the 16 sensors:
``````

Caesar

Replace this line:-

``````controlSend(0x90, control[i], 0x7f);  // turn on control message
``````

with

``````controlSend(0x90, control[i], currentState[i]>>3);  // turn on control message
``````

Thanks Mike!

from looking at the serial monitor I can see that I'm now getting varying velocity values. sweet. I had to double check bu the tone library docs says to control volume use a resistor. Again that would control all audio output at once. Can the tone command have a similar velocity variable? MY next post will be one adding a 12bit DAC for audio synth. but for now now my finale question has to do with polyphony. How many notes can I play simultaneously, as in chords, using an arduino board and multiplexers?

Can the tone command have a similar velocity variable?

No, there is no hardware to alter the amplitude is is just a digital output.