velocity sensitive code

Is there a way to make this code velocity sensitive? It works well but only at one volume.

void loop() {
  int val;
  val = analogRead(A0);
  if (val > 600) { // if it is greater than the threshold
    noteOn(0, 50, 127); // send a note on message the 68 is the pitch of the note 
    MidiUSB.flush(); // send the MIDI message
    while (analogRead(A0) > 600) { } // wait here until the signal has dropped
    noteOff(0, 50, 127); // send the note off message
    MidiUSB.flush(); // send the MIDI message
  }

Yes. Probably you want to change the 127 in the noteOn to some variable you set according to the velocity you want.

I guess that might have something to do with whatever value you're getting from A0 but with only that tiny code snippet and no description of what's connected to A0, what the noteON() function does or where you expect to get velocity from it is just a guess.

Steve

Thanks for responding, There are piezos connected to all pins, I used this snippet because I can focus on 1 pin. I can copy and paste this and change the pin and note # and it works. I've tried many other sketches and all are full of errors and bugs but this one works well with the Teensy 3.6 which transmits midi by USB. The serial monitor shows between 46 for a soft tap and 1030 for a hard tap is there a way to read the value and send it as velocity?

/*
   MIDIUSB_test.ino

   Created: 4/6/2015 10:47:08 AM
   Author: gurbrinder grewal
   Modified by Arduino LLC (2015) & Grumpy Mike
*/

#include "MIDIUSB.h"

// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void setup() {
  Serial.begin(115200);
}

// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).

void loop() {
  int val;
  val = analogRead(A0);
  if (val > 600) { // if it is greater than the threshold
    noteOn(0, 50, 127); // send a note on message the 68 is the pitch of the note 
    MidiUSB.flush(); // send the MIDI message
    while (analogRead(A0) > 600) { } // wait here until the signal has dropped
    noteOff(0, 50, 127); // send the note off message
    MidiUSB.flush(); // send the MIDI message
  }
  
  {

What exactly is the Serial monitor displaying when it shows 46 - 130? I can't see any use of Serial in your code. It's presumably not the value from the analogRead() because that apparently has to be >600 for any note to be produced.

Steve

sorry that should be 1030 I corrected that, I'm not sure what that represents.

midi m.PNG

Can you check the numbers again? If you are displaying the output from a read of the analog pin the value can never be higher than 1023. If you're really seeing 1030 then I have no idea what you might be looking at.

For now I'll guess it represents the varying voltages produced by the piezo when tapped which what the analogRead(A0) is reading. Currently the code is set up so that anything below 600 is ignored so you need a good hard tap or nothing happens. That's probably too high if you want velocity sensitivity, I'd try something like 300.

Then you need to map the value you're getting to MIDI velocities using a map() command. Something like

  int val; 
  int velocity;          //ADD this
  val = analogRead(A0);
  if (val > 300) { // if it is greater than the threshold
    velocity = map (val, 300, 1023, 30, 127);             //ADD this
    noteOn(0, 50, velocity); // send a note on message
    MidiUSB.flush(); // send the MIDI message
    while (analogRead(A0) > 300) { } // wait here until the signal has dropped
    noteOff(0, 50, 127); // send the note off message

So a lightish tap will give MIDI velocity 30 and a hard one gives 127 (maximum). Then you just stick that velocity value into the NoteOn in place of the constant 127. You can play with the threshold value and the velocity mapping to suit yourself when you have it going.

Give it a try. But most serious drum kit code is considerably more complicated than that, using different thresholds for different pads and doing some averaging of hit strength etc. I guess it depends exactly what you're trying to achieve.

Steve

Thanks, That makes sense, I'll try it. Sorry I'm not sure what the numbers were, I have several of those tests I guess I got confused. I really appreciate your help!

THANK YOU!!! it works! may need some tweeking but that's what I was after. I tried so many other sketches and they all have so many errors or will not work with the T3.6. What I like about this is now I have 1 block of code that I can use for all the pins (except the hi hat pedal). I will be using it for other instruments as well so if tune the code for a bass drum it won't be right for the vibes and so on. Plus I can make adjustments in the software Thanks again.

Glad to help. I guess you're on your way now. Good luck.

Steve

disreguard