test code for piezo

I don't understand the connection to the 3v positive from board, all the examples I've seen are just analog inputs and gnd.
If you're referring to Paul's circuit for the piezo, the diode to 3v3 is used "clamp" the voltage from the piezo to < 4 volts, preventing damage to the teensy analog port.

the monitor output attachment in your post #75 is NOT from the sketch in post #23????? the sketch in post #23 prints two columns of numbers, DAC output and A0 input.
 
I just ran it again freshly copied from #23 same result, 1 column printing rapidly 328 or so. I replaced the diodes and rebooted and now-
nd1.PNG
 
Last edited:
those numbers look promising, though in post #69 I indicated I was interested particularly in the high end numbers (4000 ... 4032). Is English not your first language?

The sketch that was printing out 328 (presumably A0 values) is a mystery. That you couldn't get a fresh copy of sketch #23 to load and run is a mystery. That you had to reboot and replace diodes is a mystery. T3.6 damaged? poorly soldered?

I fear I am out of ideas ... hopefully, others will have some fresh insights.
 
I'm also running out of ideas here. The build in message #51 looks correct. The waveform in message #62 looks right, but at only 1/100th the correct amplitude. Wrong resistors are the main reason I can imagine it would be "working" but the signal far too low. But the resistors are measured as the right values, so I just can not know why it is not giving a strong enough signal.

Maybe the piezo was damaged? Did you solder the wires on the piezo? They are very temperature sensitive. Maybe if it got too hot the material may have been damaged.

If you buy another piezo, I highly recommend getting one which already has the wires connected.
 
I'm also running out of ideas here.
Well, I found it very unusual to have a piezo connected 'directly' (i.e. without any impedance transformation (FET or transformer)) to an ADC. It may only work for very slow sampling rates.

If you buy another piezo, I highly recommend getting one which already has the wires connected.
Agree,
any piezo where the soldering iron is on for more than 1 or two seconds, may not work properly. The polarisation within the piezo is destroyed by excessive heat and the piezo does nor work anymore properly.
 
I have at least 30 extra piezos all with wires, first thing I checked. When I connect one to+A0 and gnd. using Manitou's sketch in#55 I get exactly those numbers, 900-1100 with a tap and then flat line at 0. I have yet to see 1 example of a piezo triggering a midi note with the T3.6. It's time to cut my losses and move on. I have tested every connection on the board tried 1/2 dozen sketches that work with Arduinos but not with T3.6 The buttons sketch still works so maybe I'll find a use for the board sometime. Thanks for trying.
 
I have at least 30 extra piezos all with wires, first thing I checked. When I connect one to+A0 and gnd. using Manitou's sketch in#55 I get exactly those numbers, 900-1100 with a tap and then flat line at 0. I have yet to see 1 example of a piezo triggering a midi note with the T3.6.

If you already get that beautiful 900-1100 peak, you are only a few lines of code away from triggering midi notes. Why then being so desperate? You aren’t really expecting others to do your work and to write the code for you?
 
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.

I'm using the suggested protection setup on my piezo analog inputs in to a Teensy 3.6 as Paul describes in post #9 and it's working with the code. The downside is I need to get the sensitivity up quite substantially on my diy midi marimba. With that in mind is there an upper limit when swapping out the 10K resistor suggested? 27k is heading in the right direction but with only minor sensitivity increase. I would love some guidance before proceeding higher up the values please!
 
Paulstoffregen, hello! I use ARDUINO NANO as a preliminary data device on the power of the Piezo sensor. In other words, Piezo sensor is connected to Arduino Nano. The data is then transmitted by radio channel (NRF24L01) for Teensy 3.2. Everything works wonderful! But your scheme looks even more promising! Thresholdmin = 12 VS 60. But on Arduino Nano there is no out to 3.3V. Can I use 5V out? I am sure you understand what I mean! Paul, I will be very presented for you. Tell me, please, how to act.
 
So, I have a strange situation in which the Knock example doesn't ever turn off the LED, apparently seeing it above the threshhold at every single measurement, pulsing here with the rhythm of the delay(200)

Code:
/*
  Knock Sensor

  This sketch reads a piezo element to detect a knocking sound.
  It reads an analog pin and compares the result to a set threshold.
  If the result is greater than the threshold, it writes "knock" to the serial
  port, and toggles the LED on pin 13.

  The circuit:
	- positive connection of the piezo attached to analog in 0
	- negative connection of the piezo attached to ground
	- 1 megohm resistor attached from analog in 0 to ground

  created 25 Mar 2007
  by David Cuartielles <http://www.0j0.org>
  modified 30 Aug 2011
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Knock
*/


// these constants won't change:
const int ledPin = LED_BUILTIN;      // LED connected to digital pin 13
const int knockSensor = A10; // the piezo is connected to analog pin A10 on a teensy 4.1, so pin 24
const int threshold = 40;  // threshold value to decide when the detected sound is a knock or not


// these variables will change:
int sensorReading = 0;      // variable to store the value read from the sensor pin
int ledState = LOW;         // variable used to store the last LED status, to toggle the light

void setup() {
  pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
  Serial.begin(9600);       // use the serial port
}

void loop() {
  // read the sensor and store it in the variable sensorReading:
  sensorReading = analogRead(knockSensor);

  // if the sensor reading is greater than the threshold:
  if (sensorReading >= threshold) {
    // toggle the status of the ledPin:
    ledState = !ledState;
    // update the LED pin itself:
    digitalWrite(ledPin, ledState);
    // send the string "Knock!" back to the computer, followed by newline
    Serial.println("Knock!");
  }
  delay(200);  // delay to avoid overloading the serial port buffer
}

The actual circuit is just as this piezo schematic:
PiezoSchematic.jpg

I will see if I can get a photo up if that's necessary/useful.

Maybe i misunderstand, but this piezo cannot self-oscillate in such a configuration or!?
The loop is obviously looping, as the delay shows in the LED blink speed, but then it always evaluates to above it's threshhold forever!?

Expected: LED to briefly toggle ON, perhaps on and off a few times before settling to OFF

Result: LED is OFF, then I strike the pieze, LED turns ON, and stays ON in a blinking on and off pattern with the pulse rate of the delay(200), (at 100 it is faster, at 500 is is slow)

loop apparently evaluates the analogRead(piezoPin) to be always higher than threshold...

Serial.println repetitively prints "KNOCK KNOCK KNOCK..." forever
 
One weird thing is that in Arduino Examples->Teensy->USB_MIDI->Piezo_Drum I see a steady stream of Note-On and Note-Off events:
Code:
^C[aaron@lilliput ~]$ aconnect -i
client 0: 'System' [type=kernel]
    0 'Timer           '
    1 'Announce        '
client 14: 'Midi Through' [type=kernel]
    0 'Midi Through Port-0'
client 20: 'Teensy MIDI' [type=kernel,card=1]
    0 'Teensy MIDI MIDI 1'
[aaron@lilliput ~]$ aseqdump -p 20
Waiting for data. Press Ctrl+C to end.
Source  Event                  Ch  Data
 20:0   Note on                 9, note 38, velocity 3
 20:0   Note off                9, note 38, velocity 0
 20:0   Note on                 9, note 38, velocity 126
 20:0   Note off                9, note 38, velocity 0
 20:0   Note on                 9, note 38, velocity 2
 20:0   Note off                9, note 38, velocity 0
 20:0   Note on                 9, note 38, velocity 7
 20:0   Note off                9, note 38, velocity 0
 20:0   Note on                 9, note 38, velocity 126
 20:0   Note off                9, note 38, velocity 0
 20:0   Note on                 9, note 38, velocity 126
 20:0   Note off                9, note 38, velocity 0
 20:0   Note on                 9, note 38, velocity 6
 20:0   Note off                9, note 38, velocity 0
 20:0   Note on                 9, note 38, velocity 10
 20:0   Note off                9, note 38, velocity 0
 20:0   Note on                 9, note 38, velocity 126


That example has a second threshold comparison in the run loop... as such

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.
*/

const int channel = 10;  // General MIDI: channel 10 = percussion sounds
const int note = 38;     // General MIDI: note 38 = acoustic snare

const int analogPin = A10;
const int thresholdMin = 60;  // minimum reading, avoid noise and false starts
const int peakTrackMillis = 12;
const int aftershockMillis = 25; // aftershocks & vibration reject


void setup() {
  Serial.begin(115200);
  while (!Serial && millis() < 2500) /* wait for serial monitor */ ;
  Serial.println("Piezo Peak Capture");
}


void loop() {
  int piezo = analogRead(analogPin);
  peakDetect(piezo);
  // 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) {
  // "static" variables keep their numbers between each run of this function
  static int state;  // 0=idle, 1=looking for peak, 2=ignore aftershocks
  static int peak;   // remember the highest reading
  static elapsedMillis msec; // timer to end states 1 and 2

  switch (state) {
    // 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 = voltage;
        msec = 0;
        state = 1;
      }
      return;

    // Peak Tracking state: capture largest reading
    case 1:
      if (voltage > peak) {
        peak = voltage;     
      }
      if (msec >= peakTrackMillis) {
        //Serial.print("peak = ");
        //Serial.println(peak);
        int velocity = map(peak, thresholdMin, 1023, 1, 127);
        usbMIDI.sendNoteOn(note, velocity, channel);
        msec = 0;
        state = 2;
      }
      return;

    // Ignore Aftershock state: wait for things to be quiet again.
    default:
      if (voltage > thresholdMin) {
        msec = 0; // keep resetting timer if above threshold
      } else if (msec > aftershockMillis) {
        usbMIDI.sendNoteOff(note, 0, channel);
        state = 0; // go back to idle when
      }
  }
}

But I still don't understand what modifications I must make to a basic triggering code, like "knock" example, to make it only read above the threshold when it's actually above the threshold.
but we know my circuit and piezo work
 
Hello, and thank you, BriComp.
I do not note any behavioral difference after adding this line, unfortunately.

In the Knock example try adding pinMode(A10, INPUT_DISABLE); to the if statement
Code:
  if (sensorReading >= threshold) {
    // toggle the status of the ledPin:
    ledState = !ledState;
    // update the LED pin itself:
    digitalWrite(ledPin, ledState);
    // send the string "Knock!" back to the computer, followed by newline
    Serial.println("Knock!");
    [COLOR="#FF0000"]pinMode(knockSensor, INPUT_DISABLE);  [/COLOR]
  }

Tested T4.1 with Sparkfun piezo with 1Mohm resistor in parallel
 
Last edited:
Hello and thank you, Manitou.
I detect no change in the behavior yet.
Thank you for the tip to try the analog-pin access A10 vs 24, I did try both in both locations (in setup, and in the loop inside the if statement as you mention.

So, does the "Knock" example turn OFF the LED and stop printing "KNOCK!" at some point for you?
 
So,
1) I had bad connections (a loose ground and the piezo negative was a bad physical connection due to the thin leads and my bad soldering ...
2) it appears that the sketch itself recommends other circuit than a 1megaohm bridging + - on the piezo, what various "arduino knock" references on the web show in a simple schematic, rather as you describe. i tried it, and it worked wit the following sketch

Code:
/*
  Knock Sensor

  This sketch reads a piezo element to detect a knocking sound.
  It reads an analog pin and compares the result to a set threshold.
  If the result is greater than the threshold, it writes "knock" to the serial
  port, and toggles the LED on pin 13.

  The circuit:
	- positive connection of the piezo attached to analog in 0
	- negative connection of the piezo attached to ground
	- 1 megohm resistor attached from analog in 0 to ground

  created 25 Mar 2007
  by David Cuartielles <http://www.0j0.org>
  modified 30 Aug 2011
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Knock
*/


// these constants won't change:
const int ledPin = LED_BUILTIN;      // LED connected to digital pin 13
const int knockSensor = A11; // the piezo is connected to analog pin 0
const int threshold = 40;  // threshold value to decide when the detected sound is a knock or not


// these variables will change:
int sensorReading = 0;      // variable to store the value read from the sensor pin

void setup() {
  pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
  Serial.begin(9600);       // use the serial port
}

void loop() {
  sensorReading = 0;
  // read the sensor and store it in the variable sensorReading:
  sensorReading = analogRead(knockSensor);

  // if the sensor reading is greater than the threshold:
  if (sensorReading >= threshold) {
    digitalWrite(ledPin, HIGH);
    Serial.println("hit");
    Serial.println(sensorReading);
  } else {
    digitalWrite(ledPin, LOW);
    pinMode(knockSensor, INPUT_DISABLE);
  }
  delay(50);  // delay to avoid overloading the serial port buffer
}


So, then I was still getting very odd numbers and spikes, so I ran the piezo on the same pin but tried using it as an ADC in the audio library as such:
Code:
AudioInputAnalog         adc1(A11);
and when listening to the audio of the signal from the piezo, it makes more sense why there's these random seeming voltages, as the frequency response is all over the place!
there's this bassy thump when you touch the actual piezo disc, there's microphonics on the surface it's taped to, of course, and the frequency response seems to be rolling off lows and highs the further you get from the piezo... interesing.
I'm interested in learning more about the "personalities" of piezos, as clearly this is a complex signal and using it merely to switch/gate things seems more difficult than mere button debouncing, and less useful considering the dynamic signal here.

Are there guides to how to best use the secret powers of piezo transducers?
 
Back
Top