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 [PD] Piezo, trigger, Arduino these deal with shaping the signal by adding a capacitor , which I intend to do. I also read this post Arduino Forum 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.
* Arduino analog input 5 - I2C SCL
* Arduino analog input 4 - I2C SDA
* 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
currentState[i] = analogRead(mux1); // read mux1 in first 8 array locations
delay(1); // delay to allow sample & hold capictor to charge
currentState[i+8] = analogRead(mux2); // read mux2 in last 8 array locations
}
}
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;
int ledMask = 1;
for(int i=0; i<16; i++){
if(currentState[i] < threshold) ledVal |= ledMask; // add a 1 in
the position of sensors under threshold
ledMask = ledMask << 1;
}
if(lastLedVal != ledVal) { // something has changed
ledMask = 1;
for(int i=0; i<16; i++){
if((ledMask & ledVal) != (ledMask & lastLedVal)){
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);
}
}
ledMask = ledMask << 1;
}
// Update the trigger LEDs
gpio_writeByteInverse(ledAddress, ledVal, I2CregisterInput);
}
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
// I2C device addresses
#define ledAddress (0x20 | 0x0) // address of trigger LED
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:
Thank you in advance,
Caesar