Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 4 1 2 3 ... LastLast
Results 1 to 25 of 82

Thread: test code for piezo

  1. #1

    test code for piezo

    Why won't this code work with teensy 3.6? It just goes berserk when I open the serial monitor even with nothing connected. I copied the code from the spark fun Piezo Drum Kit Quickstart Guide and connected everything the same. What do I need to do to get 1 piezo working and trigger a note or something-anything?

    #define DRUM1 0 // Our analog pin

    byte val = 0; // Initializing the variable for the voltage value

    void setup()
    {
    Serial.begin(9600); // Initializing the serial port at 9600 baud
    }

    void loop()
    {
    val = analogRead(DRUM1); // Read the voltage
    Serial.println(val, DEC); // Print the voltage to the terminal
    }

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    5,184
    Unrestrained printing is most likely what you are seeing.

    Also analogRead will return larger than 8 bit value on Teensy. Untested edits shown below.

    Code:
    uint16_t val = 0; // Initializing the variable for the voltage value
    uint16_t last_val = 0; // Initializing the variable for the voltage value
    void loop()
    {
      val = analogRead(DRUM1); // Read the voltage
      if ( val != last_val ) {
        Serial.println(val, DEC); // Print the voltage to the terminal
        last_val = val;
        delay( 40 );
      }
    }

  3. #3
    Thanks for responding, I tried your sketch, it says

    'DRUM1' was not declared in this scope.
    I tried several sketches for piezo drum pads but still can't get any to trigger a note.

  4. #4
    Senior Member
    Join Date
    Apr 2013
    Posts
    1,580
    defragster wrote it to match your sketch, either graft his loop into yours, or add
    #define DRUM1 0 // Our analog pin
    In either case you probably also need to add
    pinMode(DRUM!,INPUT);
    to the setup function.

  5. #5
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    5,184
    GremlinWrangler has it right - except for redefining 'val' - I expected the upper part with setup() and #define to persist.

    As an Analog input the pinMode may be wrong to add.

  6. #6
    Please bare with me, I'm new at this. Is this what you mean?

    #define DRUM1 0 // Our analog pin

    byte val = 0; // Initializing the variable for the voltage value

    void setup()
    {
    Serial.begin(9600); // Initializing the serial port at 9600 baud
    }

    void loop()
    {
    val = analogRead(DRUM1); // Read the voltage
    Serial.println(val, DEC); // Print the voltage to the terminal
    }
    uint16_t val = 0; // Initializing the variable for the voltage value
    uint16_t last_val = 0; // Initializing the variable for the voltage value
    void loop()
    {
    val = analogRead(DRUM1); // Read the voltage
    if ( val != last_val ) {
    Serial.println(val, DEC); // Print the voltage to the terminal
    last_val = val;
    delay( 40 );
    }

  7. #7
    Senior Member
    Join Date
    Jul 2014
    Posts
    1,544
    Quote Originally Posted by seayaker View Post
    Please bare with me, I'm new at this.
    only one loop() function and one declaration

    Code:
    #define DRUM1 0    // Our analog pin
    
    void setup()
    {
      Serial.begin(9600);  // Initializing the serial port at 9600 baud
    }
    
    uint16_t val = 0; // Initializing the variable for the voltage value
    uint16_t last_val = 0; // Initializing the variable for the voltage value
    void loop()
    {
      val = analogRead(DRUM1); // Read the voltage
      if ( val != last_val ) {
        Serial.println(val, DEC); // Print the voltage to the terminal
        last_val = val;
        delay( 40 );
      }

  8. #8
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    5,184
    @seayaker - hopefully the more complete post from WMXZ gets you started better. If you click the "#" hashtag icon it adds HTML markers in the post to inset and format the code as shown in above posts to be more readable.

    That delay(40); is just a guess to slow down the prints. There are better ways than delay() - Teensy comes with elapsedMicros and elapsedMillis that make tracking time very easy and keep from halting code execution as you get more going on. The Analog value may vary +/- 1 or more, and without that delay it could still end up printing every loop. That should be good enough though to see that it works for this demo purpose.

    Because Teensy uses on-chip hardware USB it goes away during programming - and takes the computer a couple hundred milliseconds to re-attach. Which can leave some early print()'s lost. Sometimes things like this will be used to have setup() wait a short time - in this case up to 4 seconds for the connection to be made before continuing so all the output can be captured to the Serial Monitor:
    Code:
    void setup()
    {
      Serial.begin(9600);  // Initializing the serial port at 9600 baud
      while ( !Serial && millis() < 4000 ) ;
      Serial.println( "Hello World!" );
    }
    Last edited by defragster; 12-10-2017 at 08:27 AM.

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    16,287
    Before talking about code, I'd like to recommend using 2 resistors (470 and 10K) and 2 signal diodes (1N4148 or 1N914 or similar).

    Click image for larger version. 

Name:	DSC_0860_web.jpg 
Views:	22 
Size:	153.1 KB 
ID:	12225

    The piezo sensor positive should connect to the 470 ohm resistor, and the 2 diodes should connect from the 470 resistor to GND and to 3.3V.

    Click image for larger version. 

Name:	DSC_0862_zoom.JPG 
Views:	13 
Size:	72.8 KB 
ID:	12226

    This arrangement will limit the voltage, keeping your Teensy safe. These piezo sensors can create rather high voltage spikes, especially if struck with a lot of force by a hard object.

    The other resistor connects to GND, in parallel with one of the diodes. This 10K resistor gives the piezo a load to drive. The result is much lower noise at the analog pin. In this test I used 10K, but you can adjust this resistor for more or less sensitivity.

    Before you go any further, I highly recommend building this circuit with these 4 parts. It will protect your Teensy and give you a much better signal.

  10. #10
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    5,184
    Nice detail Paul - Thx. I only looked at the code as reading a safe analog value of course. But I have something I might want to test a piezo for detecting a louder noise and saw a note go by about a single large resistor solution. Then I was wondering if I could still have the Piezo make a beep sound for me?

  11. #11
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    16,287
    Now for the code part. To properly capture this signal requires work in the code. First, here's what the signal actually looks like at the analog pin, after the effect of those 2 resistors and 2 diodes.

    Click image for larger version. 

Name:	file.png 
Views:	16 
Size:	28.3 KB 
ID:	12228
    (click for full size)

    To proper capture this requires making many measurements during the first portion of the waveforms. Your first measurement that shows a signal won't be the peak. It'll very likely be somewhere along the rising slope. A timer is needed, to keep making measurements for the entire expected duration of the first peak. In this waveform it lasts about 3 milliseconds, but on others it could be slightly longer. During this time, every measurement must be checked and the highest value kept.

    After the initial peak comes lasting aftershock and vibration. How long this lasts and how large it is depends on how the piezo is mounted. It it's sitting loose on a table, vibrations can last time quite some time. The code needs to ignore all readings for that amount of time. Then it can begin waiting for another reading, and start looking for the next peak.

    With those ideas in mind, here's a quick program I wrote as an example. I tested it with the circuit shown above. It works well. Hopefully this helps?

    Code:
    const int thresholdMin = 12;  // minimum reading, avoid "noise"
    const int aftershockMillis = 60; // time of aftershocks & vibration
    
    int state=0; // 0=idle, 1=looking for peak, 2=ignore aftershocks
    int peak;    // remember the highest reading
    elapsedMillis msec; // timer to end states 1 and 2
    
    void setup() {
      Serial.begin(115200);
      //pinMode(A0, INPUT_DISABLE);
      while (!Serial && millis() < 2500) /* wait for serial monitor */ ;
      Serial.println("Piezo Peak Capture");
    }
    
    void loop() {
      int piezo = analogRead(A0);
    
      if (state == 0) {
        // IDLE state: if any reading is above a threshold, begin peak
        if (piezo > thresholdMin) {
          //Serial.println("begin state 1");
          state = 1;
          peak = piezo;
          msec = 0;
        }
      } else if (state == 1) {
        // Peak Tracking state: for 10 ms, capture largest reading
        if (piezo > peak) {
          peak = piezo;
        }
        if (msec >= 10) {
          Serial.print("peak = ");
          Serial.println(peak);
          //Serial.println("begin state 2");
          state = 2;
          msec = 0;
        }
      } else {
        // Ignore Aftershock state: wait for things to be quiet again
        if (piezo > thresholdMin) {
          msec = 0; // keep resetting timer if above threshold
        } else if (msec > 30) {
          //Serial.println("begin state 0");
          state = 0; // go back to idle after 30 ms below threshold
        }
      }
      
    }

  12. #12
    OK, now hopefully we're getting somewhere, I will get the components, is there a chance the teensy is damaged already? if so how could I test it? The blink and the buttons programs still work. I only have an ohm meter and when I squeeze and tap the piezo as hard as I can I get little more than 1 volt. I have my unit built which is just 20 pads, bass drum and hi hat pedals and a few buttons and pots for controlling midi functions. Is this doable with the 3.6? I have the usb type set at serial+midi correct? For now my goal is to get 1 piezo to trigger a midi note with velocity sense. Thanks for helping.
    Last edited by seayaker; 12-10-2017 at 05:05 PM.

  13. #13
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    5,184
    Yes, Paul posted a very nice application specific example sketch!

    Not sure if there is a better way but each affected input exposed to direct Piezo input could be careful connected to GND and 3.3V in turn running Paul's Sketch and watch for full range values - or attach the wiper part of a POT and run it through some range testing.

    Typical Ohmmeter does relatively slow repeat samples and perhaps averaging so it won't generally show the real time peaks generated.

  14. #14
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    16,287
    Quote Originally Posted by seayaker View Post
    is there a chance the teensy is damaged already?
    Yes, there is a chance your Teensy may be damaged. But the total energy from those piezos is pretty small, so odds are probably in your favor. Hopefully you'll get lucky and have it working fine.

    if so how could I test it?
    You could use a pot or resistors to create known voltage, and then compare the result of analogRead().

    I have my unit built which is just 20 pads, bass drum and hi hat pedals and a few buttons and pots for controlling midi functions. Is this doable with the 3.6?
    Maybe. The hard part is you'll need to do 20 analogRead to capture all the inputs, which is 20X slower than just 1 input. If the peak is very narrow, you might end of reading slight before or after the actual peak.

  15. #15
    I tried your code but no response with a piezo, the serial monitor says- piezo peak capture, peak = 507. this value changes when I hit the button on the board and it reboots but nothing happens when I tap the piezo. I have it connected +to analog 0 and - to analog ground with a 1m ohm between. I have yet to get any response from the piezo Any suggestions? I still just want to get 1 piezo to trigger a note or do something that tells me its working or not. I've tested the piezo itself and all connections Is this not the right board for what I'm trying to do?
    Last edited by seayaker; 12-10-2017 at 10:15 PM.

  16. #16
    Senior Member manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,265
    recent piezo discussion at https://forum.pjrc.com/threads/48100...inMode-problem

    you could try the knock sketch

  17. #17
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    16,287
    Quote Originally Posted by seayaker View Post
    I have it connected +to analog 0 and - to analog ground with a 1m ohm between.
    That doesn't sound anything like the circuit I recommended.

    In fact, I don't even know what "with a 1m ohm between" means. You really need to be more precise in words, or post photos showing the wiring clearly. I highly recommend using photos, even if you believe the words are clear. There are so many opportunities for misunderstanding. That's why I gave you pictures of the circuitry I tested yesterday.

  18. #18
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    5,184
    No it is not - I think it relates to this on SparkFun or a tutorial like it I saw mentioned recently : Piezo Drum Kit Quickstart Guide
    > Oddly enough the analog DRUM1 test sketch is there ...

  19. #19
    I tried to upload a photo but it fails, anyway if you look at this link there are photos, I did exactly the same thing except with the teensy. https://www.sparkfun.com/tutorials/330. What I meant was the pull down resistor between the+and the-. I don't have the components to make your circuit yet, I assumed the diodes and resisters in your circuit were for protection and that if i taped lightly on the piezo I could at least get a response. If that were going to damage the board then it's damaged already because i tried this before you recommended the circuit. At this point I just want to make sure the board is ok and why I can't get the piezo to do anything. If it turns out I damaged it and I had to buy another so be it. If you say the only way to test it is with that circuit than I'll have to get the components.

  20. #20
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    5,184
    The piezo if working will generate a voltage - but should be used in a controlled circuit as provided. Until then if you want to test the Teensy see notes posts #13 and #14 above - set up a POT or use known resistor values that should give consistent readings from 3.3V - or carefully GND the pin and then test again with 3.3V carefully attached on what ever analog pin is under test.

    I'd do this with the revised post #7 sketch to test function so the values are not filtered. You could expand that code to read all the pins you want to in turn. With indication of the pins to be tested and your desire to do so - somebody might even provide working tested code - but showing your start and success on at least one pin with simple tests and that sketch would be good practice.

    <edit> : Photo Limit is near 1MB for JPG or PNG
    Last edited by defragster; 12-11-2017 at 09:37 AM.

  21. #21
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    1,155
    Quote Originally Posted by seayaker View Post
    I don't have the components to make your circuit yet, I assumed the diodes and resisters in your circuit were for protection and that if i taped lightly on the piezo I could at least get a response. If that were going to damage the board then it's damaged already because i tried this before you recommended the circuit. At this point I just want to make sure the board is ok and why I can't get the piezo to do anything. If it turns out I damaged it and I had to buy another so be it. If you say the only way to test it is with that circuit than I'll have to get the components.
    Just for my understanding... You just took a piezo and connected it to the Teensy without studying the piezo's and the Teensy's data sheets before to make sure that the voltage levels would match and that no harm would be done to either of these?

    That would be a highly non-scientific approach! Please don't take it as personal critics, but I think it is important to mention here for all Teensy newbies:

    Always solve a problem (be it circuit design or code) first in theory, studying data sheets, doing the needed analysis, calculus, and verifications, for example checking sub circuits with an oscilloscope to make sure that everything will run within safe boundaries before connecting things together and powering these. On the code side, know first what input your code will need, how to capture/interface it, which output you expect, and draw a flow diagram first. Then translate the flow diagram blocks into code one after another, and write test code to verify your code blocks individually before merging everything together into a large program.

  22. #22
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    16,287
    Sparkfun's piezo tutorial is horrible.

    As defragster suggested, use a pot (not the piezo) to test if your board is still working and able to read analog voltage.

  23. #23
    Senior Member manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,265
    To test your analog port you could also jumper DAC0 (A21) to A0 and run this little sketch
    Code:
    void setup() {
      Serial.begin(9600);
      analogWriteResolution(12);
      analogReadResolution(12);
    }
    
    void loop() {
      for (int i = 0; i < 4095; i += 32) {
        analogWrite(A21, i);    // DAC
        delayMicroseconds(10);   // DAC settle time
        Serial.print(i); Serial.print(" ");
        Serial.println(analogRead(A0));
        delay(500);  // regulate output speed
      }
    }
    other piezo test circuits i've seen use a zener diode (e.g. 3v3) to clamp voltage.
    Click image for larger version. 

Name:	piezocircuit.png 
Views:	9 
Size:	14.2 KB 
ID:	12242

    T3.2 with just 1 Mohm and then with 5.1v zener
    Click image for larger version. 

Name:	piezo.png 
Views:	13 
Size:	36.6 KB 
ID:	12243Click image for larger version. 

Name:	piezoz.png 
Views:	11 
Size:	34.3 KB 
ID:	12244

    T3.6 is NOT 5v tolerant, so you would want a 3.3v zener diode for T3.6
    Last edited by manitou; 12-11-2017 at 07:04 PM.

  24. #24
    Thanks, I appreciate your help, I tried the first test connecting A21 to A0 and running your code The serial monitor just keeps printing 2 rows of 4 digit numbers, It makes no difference when I disconnect the jumper. fried?

  25. #25
    Senior Member manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,265
    well, the two columns should be close in value
    Code:
    0 1
    32 31
    64 62
    96 94
    128 126
    160 159
    192 190
    ...
    1376 1377
    1408 1408
    1440 1441
    1472 1472
    1504 1505
    while it`s running if you remove the jumper from the DAC and plug it into GND, the 2nd column should go to 0 (or 1 ish)

    with no jumper, you get random numbers in the 2nd column from the unconnected/floating A0. the first column is just the DAC value (i) counting from 0 to 4095 by 32

    as noted photos of your setup would be helpful, try converting photos to .png or reducing size, (forum won't upload "big" photos). or take a photo with your smartphone and select a small size to save. is your T3.6 soldered to its header pins?
    Last edited by manitou; 12-11-2017 at 06:54 PM.

Posting Permissions

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