Forum Rule: Always post complete source code & details to reproduce any issue!
Page 2 of 3 FirstFirst 1 2 3 LastLast
Results 26 to 50 of 69

Thread: piezo velocity

  1. #26
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,326
    Very nearly but you have 23 elements in each rather than 21.

    The space between the array name and brackets is optional (turns out) but I prefer no space.

    Here is my utterly untested extension to multiple piezos:
    Code:
    /* Use a Piezo sensor (percussion / drum) to send USB MIDI note on
       messages, where the "velocity" represents how hard the Piezo was
       tapped.
    
       Connect a Pieze sensor to analog pin A0.  This example was tested
       with Murata 7BB-27-4L0.  Almost any piezo sensor (not a buzzer with
       built-in oscillator electronics) may be used.  However, Piezo
       sensors are easily damaged by excessive heat if soldering.  It
       is highly recommended to buy a Piezo with wires already attached!
    
       Use a 100K resistor between A0 to GND, to give the sensor a "load".
       The value of this resistor determines how "sensitive" the circuit is.
    
       A pair of 1N4148 diodes are recommended to protect the analog pin.
       The first diode connects to A0 with its stripe (cathode) and the other
       side to GND.  The other diode connects its non-stripe (anode) side to
       A0, and its stripe (cathode) side to 3.3V.
    
       Sensitivity may also be tuned with the map() function.  Uncomment
       the Serial.print lines to see the actual analog measurements in the
       Arduino Serial Monitor.
    
       You must select MIDI from the "Tools > USB Type" menu
    
       This example code is in the public domain.
       *multi-pad extension by oddson (untested)*
    */
    
    const int channel = 10;  // General MIDI: channel 10 = percussion sounds
    const int PINS = 22;     // number of signals incoming
    const int note[PINS] = {36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57};     // array of MIDI note values for read signals
    
    const int analogPin[PINS] = {A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20,A21}; //array of analog PINs 
    const int thresholdMin = 60;  // minimum reading, avoid noise and false starts
    const int peakTrackMillis = 12;
    const int aftershockMillis = 25; // aftershocks & vibration reject
      
    int state[PINS];  // 0=idle, 1=looking for peak, 2=ignore aftershocks
    int peak[PINS];   // remember the highest reading
    int piezo[PINS];
    elapsedMillis msec[PINS]; // timer to end states 1 and 2
    
    void setup() {
      Serial.begin(115200);
      while (!Serial && millis() < 2500) /* wait for serial monitor */ ;
      Serial.println("Piezo Peak Capture");
    }
    
    
    void loop() {
    
    
      for (int i=0;i<PINS;i++){
        piezo[i] = analogRead(analogPin[i]);
      
      int voltage=piezo[i];
      
        switch (state[i]) {
          // IDLE state: wait for any reading is above threshold.  Do not set
          // the threshold too low.  You don't want to be too sensitive to slight
          // vibration.
          case 0:
            if (voltage > thresholdMin) {
              //Serial.print("begin peak track ");
              //Serial.println(voltage);
              peak[i] = voltage;
              msec[i] = 0;
              state[i] = 1;
            }
            return;
      
          // Peak Tracking state: capture largest reading
          case 1:
            if (voltage > peak[i]) {
              peak[i] = voltage;     
            }
            if (msec[i] >= peakTrackMillis) {
              //Serial.print("peak = ");
              //Serial.println(peak);
              int velocity = map(peak[i], thresholdMin, 1023, 22, 127);
              usbMIDI.sendNoteOn(note[i], velocity, channel);
              msec[i] = 0;
              state[i] = 2;
            }
            return;
      
          // Ignore Aftershock state: wait for things to be quiet again.
          default:
            if (voltage > thresholdMin) {
              msec[i] = 0; // keep resetting timer if above threshold
            } else if (msec[i] > aftershockMillis) {
              usbMIDI.sendNoteOff(note[i], 0, channel);
              state[i] = 0; // go back to idle when
            }
        }
      }
      // Add other tasks to loop, but avoid using delay() or waiting.
      // You need loop() to keep running rapidly to detect Piezo peaks!
    
      // MIDI Controllers should discard incoming MIDI messages.
      // http://forum.pjrc.com/threads/24179-Teensy-3-Ableton-Analog-CC-causes-midi-crash
      while (usbMIDI.read()) {
        // ignore incoming messages
      }
    }
    
    
    void peakDetect(int voltage) {
    }
    I tried to keep to the old code a much as possible other than merging the peak detection into the main loop; even where I had issues with the existing code.

  2. #27
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    Wow Thank you! It would have taken me weeks to figure all that out, I have to wait till tomorrow to test it, I'm on a different computer. I will let you know as soon as I do. Thanks again!

  3. #28
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    Well, it just plays A0 the same as before, I tried several pins along with A0 but no sound. tested the pins with another sketch, they all work. I reduced the analog pins to 21 (A0-A20) I tried to change the no. of incoming pins to 21 and I get this error - too many initializers for 'const int [21]'. If I don't want to limit this to channel 10 can I just eliminate that line so it will use all channels?

  4. #29
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    I tried uncommenting the serial print and it also only prints from A0. any suggestions?

  5. #30
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,326
    same replacement as everywhere else should work

    peak becomes peak[i]

  6. #31
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,326
    Quote Originally Posted by edrummer View Post
    Well, it just plays A0 the same as before, I tried several pins along with A0 but no sound. tested the pins with another sketch, they all work. I reduced the analog pins to 21 (A0-A20) I tried to change the no. of incoming pins to 21 and I get this error - too many initializers for 'const int [21]'. If I don't want to limit this to channel 10 can I just eliminate that line so it will use all channels?
    Sorry... there's nothing magical about 21. I typed it instead of 22. You had a 23 entries in the array you had initialized to have 22 entries. I said 21 in error.

    It not working is to be expected frankly... I very rarely get this stuff right on the first go and so there is very likely some errors in my code and what is working and not working will hopefully let us find them together.

    For testing you may want to reduce N from 22 to 3 until you get it working.

    Note that in an array declaration the size declared inside the array cannot be smaller than the number of items you are putting into it. That's what that error meant, you can't put 22 items into 21 spots.

    If it only works on pin A0 that implies the problem is with getting the value into voltage.

    It looks like I accidentally declare the variable after it tries to assign peak[i] to it... I can't see that working at all (even on just A0) so lets get that fixed and try again.

    I've reduced PINS = 3 with pins A0,A1,A2 active.

    Code:
    /* Use a Piezo sensor (percussion / drum) to send USB MIDI note on
       messages, where the "velocity" represents how hard the Piezo was
       tapped.
    
       Connect a Pieze sensor to analog pin A0.  This example was tested
       with Murata 7BB-27-4L0.  Almost any piezo sensor (not a buzzer with
       built-in oscillator electronics) may be used.  However, Piezo
       sensors are easily damaged by excessive heat if soldering.  It
       is highly recommended to buy a Piezo with wires already attached!
    
       Use a 100K resistor between A0 to GND, to give the sensor a "load".
       The value of this resistor determines how "sensitive" the circuit is.
    
       A pair of 1N4148 diodes are recommended to protect the analog pin.
       The first diode connects to A0 with its stripe (cathode) and the other
       side to GND.  The other diode connects its non-stripe (anode) side to
       A0, and its stripe (cathode) side to 3.3V.
    
       Sensitivity may also be tuned with the map() function.  Uncomment
       the Serial.print lines to see the actual analog measurements in the
       Arduino Serial Monitor.
    
       You must select MIDI from the "Tools > USB Type" menu
    
       This example code is in the public domain.
       *multi-pad extension by oddson (untested)*
    */
    
    const int channel = 10;  // General MIDI: channel 10 = percussion sounds
    const int PINS = 3;     // number of signals incoming
    const int note[PINS] = {36,37,38};     // array of MIDI note values for read signals
    
    const int analogPin[PINS] = {A0,A1,A2}; //array of analog PINs 
    const int thresholdMin = 60;  // minimum reading, avoid noise and false starts
    const int peakTrackMillis = 12;
    const int aftershockMillis = 25; // aftershocks & vibration reject
      
    int state[PINS];  // 0=idle, 1=looking for peak, 2=ignore aftershocks
    int peak[PINS];   // remember the highest reading
    int piezo[PINS];
    elapsedMillis msec[PINS]; // timer to end states 1 and 2
    
    void setup() {
      Serial.begin(115200);
      while (!Serial && millis() < 2500) /* wait for serial monitor */ ;
      Serial.println("Piezo Peak Capture");
    }
    
    
    void loop() {
    
    
      for (int i=0;i<PINS;i++){
      
        int voltage=piezo[i];
        piezo[i] = analogRead(analogPin[i]);
      
        switch (state[i]) {
          // IDLE state: wait for any reading is above threshold.  Do not set
          // the threshold too low.  You don't want to be too sensitive to slight
          // vibration.
          case 0:
            if (voltage > thresholdMin) {
              Serial.print("begin peak track ");
              Serial.println(voltage);
              peak[i] = voltage;
              msec[i] = 0;
              state[i] = 1;
            }
            return;
      
          // Peak Tracking state: capture largest reading
          case 1:
            if (voltage > peak[i]) {
              peak[i] = voltage;     
            }
            if (msec[i] >= peakTrackMillis) {
              Serial.print("peak = ");
              Serial.println(peak[i]);
              int velocity = map(peak[i], thresholdMin, 1023, 22, 127);
              usbMIDI.sendNoteOn(note[i], velocity, channel);
              msec[i] = 0;
              state[i] = 2;
            }
            return;
      
          // Ignore Aftershock state: wait for things to be quiet again.
          default:
            if (voltage > thresholdMin) {
              msec[i] = 0; // keep resetting timer if above threshold
            } else if (msec[i] > aftershockMillis) {
              usbMIDI.sendNoteOff(note[i], 0, channel);
              state[i] = 0; // go back to idle when
            }
        }
      }
      // Add other tasks to loop, but avoid using delay() or waiting.
      // You need loop() to keep running rapidly to detect Piezo peaks!
    
      // MIDI Controllers should discard incoming MIDI messages.
      // http://forum.pjrc.com/threads/24179-Teensy-3-Ableton-Analog-CC-causes-midi-crash
      while (usbMIDI.read()) {
        // ignore incoming messages
      }
    }
    
    
    void peakDetect(int voltage) {
    }

  7. #32
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    Thanks Oddson, I rarely get things right the first time also but I'm persistent. So still just A0, I only have 2 piezos connected right now A0/A1, I'm afraid I can't be of much help here, if this has to do with the loop going back to A0 this is beyond anything I know

  8. #33
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,326
    ok... I'll have a look and will likely ask you to run another version, try an alternate setting or (hopefully) fix the obvious error that's eluded me so far.

  9. #34
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    I don't know if this will help but 3/4 down the page is a sketch
    http://www.instructables.com/id/Arduino-Xylophone/

  10. #35
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,326
    ...I completely misread how this code works...

    I may be a bit.
    Last edited by oddson; 02-25-2018 at 03:46 AM.

  11. #36
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,326
    Could you try this code?

    I decided the thing to do was make it more like the original and restore the function call once i realized global variables would work if I passed the index value instead of the reading itself and then just replaced voltage with 'piezo[i]'.

    I also realized I could do some minimal testing with a pullup wire and some resistors to keep the analog pins from floating. So a jolt of 3.3 volts mimics the piezo transient (once it increased all the timeframes by 10 fold).

    So this is a bit tested and it at least isn't pumping random garbage MIDI any more.

    Code:
    /* Use a Piezo sensor (percussion / drum) to send USB MIDI note on
       messages, where the "velocity" represents how hard the Piezo was
       tapped.
    
       Connect a Pieze sensor to analog pin A0.  This example was tested
       with Murata 7BB-27-4L0.  Almost any piezo sensor (not a buzzer with
       built-in oscillator electronics) may be used.  However, Piezo
       sensors are easily damaged by excessive heat if soldering.  It
       is highly recommended to buy a Piezo with wires already attached!
    
       Use a 100K resistor between A0 to GND, to give the sensor a "load".
       The value of this resistor determines how "sensitive" the circuit is.
    
       A pair of 1N4148 diodes are recommended to protect the analog pin.
       The first diode connects to A0 with its stripe (cathode) and the other
       side to GND.  The other diode connects its non-stripe (anode) side to
       A0, and its stripe (cathode) side to 3.3V.
    
       Sensitivity may also be tuned with the map() function.  Uncomment
       the Serial.print lines to see the actual analog measurements in the
       Arduino Serial Monitor.
    
       You must select MIDI from the "Tools > USB Type" menu
    
       This example code is in the public domain.
       *multi-pad extension by oddson (under-tested)*
    */
    
    const int channel = 10;  // General MIDI: channel 10 = percussion sounds
    const int PINS = 3;     // number of signals incoming
    
    const int note[PINS] = {36,37,38};     // array of MIDI note values for read signals
    
    const int analogPin[PINS] = {A0,A1,A3}; //array of analog PINs 
    const int thresholdMin = 60;  // minimum reading, avoid noise and false starts
    const int peakTrackMillis = 12;
    const int aftershockMillis = 25; // aftershocks & vibration reject
    
    int state[PINS];  // 0=idle, 1=looking for peak, 2=ignore aftershocks
    int peak[PINS];   // remember the highest reading
    int piezo[PINS];
    elapsedMillis msec[PINS]; // timers to end states 1 and 2
    
    void setup() {
      Serial.begin(115200);
      while (!Serial && millis() < 2500) /* wait for serial monitor */ ;
      Serial.println("Piezo Peak Capture");
    }
    
    
    void loop() {
      for (int i=0;i<PINS;i++){
        //delay(20);
        piezo[i] = analogRead(analogPin[i]);
     
      peakDetect(i);
      // Add other tasks to loop, but avoid using delay() or waiting.
      // You need loop() to keep running rapidly to detect Piezo peaks!
    
    }
      // MIDI Controllers should discard incoming MIDI messages.
      // http://forum.pjrc.com/threads/24179-Teensy-3-Ableton-Analog-CC-causes-midi-crash
      while (usbMIDI.read()) {
        // ignore incoming messages
      }
    }
    
    
    void peakDetect(int i) {
    
            //Serial.println(state[i]);
    
      switch (state[i]) {
        // IDLE state: wait for any reading is above threshold.  Do not set
        // the threshold too low.  You don't want to be too sensitive to slight
        // vibration.
        case 0:
          if (piezo[i] > thresholdMin) {
            //Serial.print("begin peak track ");
            //Serial.println(piezo[i]);
            peak[i] = piezo[i];
            msec[i] = 0;
            state[i] = 1;
          }
          return;
    
        // Peak Tracking state: capture largest reading
        case 1:
          if (piezo[i] > peak[i]) {
            peak[i] = piezo[i];     
          }
          if (msec[i] >= peakTrackMillis) {
            //Serial.print("peak = ");
            //Serial.println(peak);
            int velocity = map(peak[i], thresholdMin, 1023, 1, 127);
            usbMIDI.sendNoteOn(note[i], velocity, channel);
            msec[i] = 0;
            state[i] = 2;
          }
          return;
    
        // Ignore Aftershock state: wait for things to be quiet again.
        default:
          if (piezo[i] > thresholdMin) {
            msec[i] = 0; // keep resetting timer if above threshold
          } else if (msec[i] > aftershockMillis) {
            usbMIDI.sendNoteOff(note[i], 0, channel);
            state[i] = 0; // go back to idle when
          }
      }
    }

  12. #37
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    ha!!! it works!!

  13. #38
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    I new you could do it! I only have 2 piezos hooked up but they play 2 different notes with velocity. I can tell you there are many people still looking for a sketch like this. This can be used for several different instruments instead of just one. Ableton has some nice percussion instruments like brushed bells, marimba etc. I have 1 more thing i'd like to get with you about should be fairly simple but not tonight. Put your name on it, and thank you!!

  14. #39
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,326
    Glad it worked for you...

    You should know the accuracy of this system is potentially diminished as you scale N.

    It relies on getting enough readings from ADC that one of them will roughly correspond to the top of the signal's envelope and therefore represent it's loudness.

    But if you have a lot of pins to check, and in particular if you tried to extend further with multiplexers, then the number of usable samples goes down and potentially you're failing to find a representative peak value.

  15. #40
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    Will it be noticeable with 22 inputs or is there a better way, more than 1 board? My unit will have 21 piezos and 1 FSR which will be the hi hat pedal. I wanted to ask how I could control the notes played on a designated pad with the FSR pedal. Something like this?

    if value of A 22 > 300 A3 plays note #40
    if value of A 22 < 300 but > 50 A3 plays note #41
    if value of A 22 < 50 A3 plays note #42

  16. #41
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,326
    Beats me... T3.6 is wicked fast so it might be fine as is.

    If not there are software and, if necessary, hardware fixes to try.

  17. #42
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    Any idea how to do this? I don't know how to word it or where to put it, if it can be done.

    if value of A 22 > 300 A3 plays note #40
    if value of A 22 < 300 but > 50 A3 plays note #41
    if value of A 22 < 50 A3 plays note #42

  18. #43
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,326
    Quote Originally Posted by edrummer View Post
    ... I don't know how to word it...
    Knowing how to word it is 50% the way to knowing how to program it.

    If we're still talking peak detection what would this even mean since the events are highly unlikely to be simultaneous enough to interact directly.

    If you are thinking of a voltage divider (pot) that acts as a three way mode selector then this is relatively easy (although I'd recommend a more 'digital' selection method).

    Whatever it is you may want to master this code before looking to alter it dramatically. (Advice I should have been following above! )

  19. #44
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    Yes it would be the same as a pot, in fact some pedals use a pot. I had to order new resistors for the other piezos so I can't do anything else till they get here. (they work with 10k but not with 100k). I'm working with copy's so I may as well try to get this last thing going. The pedal itself has to trigger a note but I had that working with the other sketch.
    I really appreciate all your help!!

  20. #45
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    I just went through all the pins, they all work, I don't understand why this works, - const int PINS = 3; but when I have 23 pins /23 notes I have to change that no. to 24. It's not important I just don't understand.

  21. #46
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,326
    Array size and item count should match, but you had one too many for the 22 spots available in your earlier code.

    If you initialize the array larger than the item count it will still work. You just don't call on the zero values it fills in anyway...

    Still, count your values manually to double check

    But if you give it more values than you have sized it for you get the error you quoted

  22. #47
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    My bad the 0 got me again

  23. #48
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,559
    Yes, my inner mathematician confirms that zero is a number like the others...

  24. #49
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,326
    Alas it is the number unlike all others. Just try to divide by it.

  25. #50
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    Click image for larger version. 

Name:	screen shot.PNG 
Views:	67 
Size:	55.1 KB 
ID:	13072 doesn't enplane this though

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •