Forum Rule: Always post complete source code & details to reproduce any issue!
Page 3 of 3 FirstFirst 1 2 3
Results 51 to 68 of 68

Thread: piezo velocity

  1. #51
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    Still trying to get pin A0 to change the notes of pin A1,

    Code:
    #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 < 10) { 
          noteOn(0, 36, 127); 
          MidiUSB.flush(); 
          while (analogRead(A0) < 10) { }
          noteOff(0, 36, 127);
          MidiUSB.flush(); 
        } 
        
      }
        int val;
      val = analogRead(A1);
      if (val > 400) {
        if (A0 val > 300); {
          send note 38
        }
        else if (A0 val > 50 < 300) {
          send note 39
        }
        else if (A0 val < 50) {
          send note 40
          velocity = map (val, 300, 1023, 30, 127);
          noteOn(0, 51, velocity);
          MidiUSB.flush();
          while (analogRead(A1) > 400) { }
          noteOff(0, 51, 127);
          MidiUSB.flush();
        }
      }]

  2. #52
    Junior Member
    Join Date
    Oct 2018
    Posts
    10
    This is my first post to the forum and I signed up specifically to thank Oddson for his code in post #36!! It's much appreciated It works really well and the comments in the code explain things enough for me to understand it.

    I have limited coding knowledge but I can always learn just enough to help me achieve most of what I set out to do. This code will be used to make an vibraphone midi controller with a Teensy 3.6.

    Paul's reoccurring advice to get the basics working one step at a time has also been invaluable!

    Thanks everyone

  3. #53
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,166
    Hey Thanx for the shout out...

    I've wondered if active filters with low cutoff frequencies would allow much shorter scanning windows that would reduce latency and improve accuracy when many signals are read via multiplexers.

    The current settings in the code gives 12 ms of latency and effectively limit double stops to 32 ms apart which seems very limiting for a percussion instrument.

    A proxy envelop signal (rectified and low passed) should allow shorter scan and 'ignore' windows but I don't know if decent performance can be had without resorting to all that circuitry.

  4. #54
    Junior Member
    Join Date
    Oct 2018
    Posts
    10
    Quote Originally Posted by oddson View Post
    Hey Thanx for the shout out...

    I've wondered if active filters with low cutoff frequencies would allow much shorter scanning windows that would reduce latency and improve accuracy when many signals are read via multiplexers.

    The current settings in the code gives 12 ms of latency and effectively limit double stops to 32 ms apart which seems very limiting for a percussion instrument.

    A proxy envelop signal (rectified and low passed) should allow shorter scan and 'ignore' windows but I don't know if decent performance can be had without resorting to all that circuitry.
    It makes sense to me that analogue filtering could create a shorter note so that the coding could run faster.

    I also had the idea of a matrix... Iíve opened enough keyboards (of both varieties) to understand how the hardware works, if not the coding yet. The plan would be to use two piezos per wooden note. Velocity could be calculated either combined or prioritize one of the piezos. The cost of the extra hardware works out extremely cheap.

    Is there anything glaringly dumb you would foresee in that setup?

  5. #55
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,166
    Quote Originally Posted by d.watson08 View Post
    It makes sense to me that analogue filtering could create a shorter note so that the coding could run faster.
    The idea is to produce something like an envelop signal so that intensity is read directly without requiring multiple reads to happen across a peak in the signal.

    I was more than a little vague but I was assuming the signal would be rectified and then filtered.

    I'm not sure what you mean by 'shorter' notes unless you are talking about removing potential re-triggers from the signal tail, which filtering should do.



    I also had the idea of a matrix... Iíve opened enough keyboards (of both varieties) to understand how the hardware works, if not the coding yet. The plan would be to use two piezos per wooden note. Velocity could be calculated either combined or prioritize one of the piezos. The cost of the extra hardware works out extremely cheap.
    Keyboards use two offset switches to measure the time difference which is inversely proportional to the speed of the key as it travels between the offsets of the switches.

    I can't see what a second piezo would do for you.

  6. #56
    Junior Member
    Join Date
    Oct 2018
    Posts
    10
    Ye, with Ďshorterí notes I was referring to signal tail. Essentially clean up the analogue input to reduce code run time.

    Our wires are definitely crossed with the matrix idea

    From what I understand a matrix reduces the input pin requirements. A1 A2 A3 A4 A5 A6 A7 A8 A9 can become A1 A2 A3 B1 B2 B3 C1 C2 C3 and will reduce 9 inputs to 6.

    The use of two piezos would only to trigger two inputs (eg A and 1 or B and 3) of the matrix NOT read velocity like the tradition two contact approach under a keyboard keybed. Velocity would be read as per your piezo input code in this post.

    Hope that clarifies? Iím away from my Teensy for this week but itís something Iím more than happy to dive into when I get back to see if I can prove the concept to myself

  7. #57
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,166
    No...you still don't have me.

    I get the matrix thing but not what two sensors per bar will do for you.

  8. #58
    Junior Member
    Join Date
    Oct 2018
    Posts
    10
    Could I wire the piezos in a matrix system with one per bar? I thought I needed to trigger two inputs per note in a matrix system and have them connected to ground.

    Maybe Iím being really dumb and I can simply split the signal of one piezo to the two correct inputs and ground!?

    Iím not sure how polyphony would work either in a matrix. But this is along way down the road from where I currently stand in my project! Iíve only just finished learning your code for two inputs which I will scale to 20ish. Baby steps!

  9. #59
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,166
    Quote Originally Posted by d.watson08 View Post
    Could I wire the piezos in a matrix system with one per bar?
    I'm no expert but the matrix configuration is only a means of scanning multiple signals (usually HIGH and LOW from pull down switches).

    (What follows assumes you are polling rather than using interupts https://www.pjrc.com/teensy/interrupts.html
    I don't know how interrupts would work with mux or with a matrix)

    I thought I needed to trigger two inputs per note in a matrix system and have them connected to ground.
    There typically are two but it's unrelated to the concept of a scanning matrix and is only about calculating velocity from time differences.


    Maybe I’m being really dumb and I can simply split the signal of one piezo to the two correct inputs and ground!?
    ...unless I'm sorely mistaken there is no reason to do this.

    I’m not sure how polyphony would work either in a matrix.
    Speed and diodes.... you are scanning each input in sequence but tracking the signals of all sensors across time. Even with digital switches there is something similar going on with contact bounce. The diodes prevent the signals from travelling thru alternate routes but limit the signal to a single polarity, so you would need to bias the signal.

    The key is speed. You scan at a rate sufficient to capture the shape of all the signal envelopes without any external trigger.



    But this is along way down the road from where I currently stand in my project! I’ve only just finished learning your code for two inputs which I will scale to 20ish. Baby steps!
    I would skip the matrix and use multiple mux instead even though it should work with a biased and conditioned signal.


    With the setup Paul outlines you only add one pin for each new mux... (see the mux section here: https://www.pjrc.com/teensy/td_midi.html)

    With 16 channel mux you can double the count with just one extra control pin.

    This post links to some hopefully relevant threads for when you get to that point.
    https://forum.pjrc.com/threads/52856...l=1#post181888

  10. #60
    Junior Member
    Join Date
    Oct 2018
    Posts
    10
    Thanks for the reply and links Oddson! Iíve skim read Pauls page before but will give it a deeper read to try understand mux. I get the basic concept of using extra hardware to read extra inputs through one on the Teensy.

  11. #61
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,166
    There are also GPIO extender chips that communicate via protocols like I2C but I personally don't feel it's worth the overhead when index loops with multiplexers extends array-based code so readily.

    Also while writing my last post it occurred to me how something like what you are suggesting could be done using interrupt programming instead of sequential polling (hence the caveat).

    You still would not require a second sensor, rather an analog comparitor could trigger a flip-flop to set an interrupt flag when some threshold is crossed so that when the interrupt routine is run it would read only the relevant pin(s).

    E.g. you could poll by a row or column in the matrix based on your external interrupt.

    You may have been thinking along these sorts of lines but there is still no point to two piezo sensors per bar.

    Logically their signals would be nearly identical and any differences would be unpredictable and therefore of no use (unless maybe as audio signals).

    Good luck in your endevours
    Last edited by oddson; 10-10-2018 at 02:48 PM. Reason: GPIO, bloody autocorrect

  12. #62
    Junior Member
    Join Date
    Oct 2018
    Posts
    10
    Having loads of fun with this project! It's running really smooth and I've managed to add my own octave/transpose coding with IF Else so I can use the same kind of piezo inputs instead of regular push buttons. It's mega useful as I don't have to swap from mallets to fingers during a performance. Pure assumption but I imagine that would also keep the code loop time efficient.

    I'm looking to move on to multiplexing with the 74HC4051 but I have two questions...

    1) I have a Teensy 3.6 that is 3.3v but all the info I've read suggests a 5v supply. Will 3.3v be ok or are there any simple routes to supply 5v?

    2) I have protection with two diodes & two resistors on each input... will I need to keep that on all piezos to multiplexers (x8 per mux) OR can I put one between the multiplexer and Teensy to cover those 8 inputs?

    I'm guessing simple answers for both but unlike coding I'm not keen on experimenting too much with the risk of frying an awesome Teensy!

  13. #63
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,166
    Teensy 3.6 uses 3.3 v for signals but you can still power MUX from the 5 v pin from the USB supply. Some mux only need 3.3 supply.

    Not sure about having no voltage protection for the mux... they are much more robust so it may be ok.

  14. #64
    Junior Member
    Join Date
    Oct 2018
    Posts
    10
    Ah sorry Oddson, the USB host 5v... I completely overlooked that on my reference card. My (basic) mistake! Thanks.

    Iíve done a lot of searching in regards to protection on every input PRE mux or one set POST mux between itself and the Teensy but still drawing a blank. Iím learning a lot in a short space of time but the vast majority of whatís found in data sheets still looks alien to me unfortunately. I guess it all depends on how the mux handles the potential peak voltage sent from the piezo?

    ...the good thing is Iíve really taken time to try understand you original code in detail. The use of Ďií had me stumped for a while but once I got over that the logical flow isnít too hard to follow and modify.

  15. #65
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,166
    A mux will have a supply voltage range and if your peaks are not wildly outside of that (since it's a low impedence transient) it's very unlikely to fry the mux. (Even if you're only powered at 3.3v.)

    But I'm not an EE so no guarantee from me.

    Arrays and incremented loop variables add a bit of abstraction but simplify things greatly when the signal count climbs.

  16. #66
    Junior Member
    Join Date
    Oct 2018
    Posts
    10
    My 74hc4051 breakout boards arrived and Iíve had a few successes with mux coding but mainly through copying pre-made codes online.

    When Iíve tried to modify the code below to include multiple mux piezo inputs I quickly find myself in a huge mess. Iíve tried for a few weeks now and appreciate folk on this forum want us to mainly find our own way... BUT Iím at a point where I really needed some guidance. If thereís such a thing Iíve read way too much from mixed sources and become brain tangled!

    To me the basic idea is I need to modify the analogPin array to read the mux inputs. Listing analog inputs was very easy to understand with this baseline code... but adding the correct mux addressing is where I come unstuck.

    I understand how to connect multiple 74hc4051s correctly confirmed with demo codes found online and Iíve successfully modified this code to include octave switching, sustain pedals etc so Iím not completely beyond help!

    Any advice and direction would be very much appreciated! Iíve learnt a lot in a relatively short space of time but this is currently beyond me 😒

    Oddsons original code Iím using below for quick reference!

    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
          }
      }
    }

  17. #67
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,166
    ...Oddsons original code ....
    I only did the extention to multiple input.

    What specifically are you trying to achieve right now and what is the final goal?

    The first step should be to read from one mux.

    For that your index variable 'i' needs to increment to the number of mux channels (8) instead of 'PINS'.

    Then you need to set the control pins for the mux based on the current value of i.

    The control bits are set from the binary values of the least-three bits

    0 = b000
    1 = b001
    2 = b010
    ...
    7 = b111

    This post includes links to other mux extentions as well as a further bit of explanation....
    https://forum.pjrc.com/threads/52856...l=1#post181888


    Once you can get data via a single mux you can perhaps start a new thread in project advice on how best to achieve your full project.

  18. #68
    Junior Member
    Join Date
    Oct 2018
    Posts
    10
    My only goal right now is to change this...

    Piezo -> protection circuit -> teensy (works fantastic with the code posted above!)

    To this...

    Piezo -> protection circuit -> MUX 74hc4051 -> teensy.

    The physical connections I have no issue wiring correctly (including all empty mux inputs to ground) but pointing the code to the right place via mux is my struggle.

    Iíll spend some time trying to absorb your advice above and will probably need to post a follow up if thatís ok.

    Thanks again Oddson!

Posting Permissions

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