I’m trying to get a super simple piezo sensor working. It’s a Korg CM-300BK. It works but the analog read values don’t surpass even 50 (of the 1024 range); and that’s when I knock quite hard. I feel like I’m missing something because all knock example codes have a threshold set at 100.
That microphone would put out a few hundred mills to maybe a volt tops, that is a guess as I do not have the data sheet. You will need an amplifier to front end the A/D or chose a different sensor.
That microphone would put out a few hundred mills to maybe a volt tops, that is a guess as I do not have the data sheet. You will need an amplifier to front end the A/D or chose a different sensor.
I googled about putting a preamp in but all I could find was that it's not needed and something (I could not figure out) about limiting the analog input to 1V. Is there a amp design you could recommend?
If it's indeed a microphone, be aware that they produce an AC signal. I'm not that much of an electronic engineer to advise on the opamp design but if you amplify AC, you'll have to make sure that you filter the negative halves out.
Of course it depends on what's "knocking" it... What happens if you tap it directly with your fingernail or drop it on a hard surface?
And I assume you have a pull-down resistor or the analog input would be floating to a higher "random" value. For maximum voltage, the resistor should be 1-10 megohms. The lower the resistance the lower the signal.
And there is an additional possible issue - analogRead() or digitalRead() on reads for an instant, once every time through the loop. You are likely to miss the peak voltage, and the odds of hitting the peak, or picking-up some ringing are lower if you doing other things in the loop (like printing every time through the loop). The more the program is doing, the less-frequently you are reading.
If you can get a high-enough voltage for digital reading, you can use an interrupt and you won't miss the knock.
I'll respond per paragraph, super thanks for your response in advance.
I have secured (or clipped) the piezo to a hard object (table for now) and knocking the table. Also tried securing it to a thinner object and knocking the bottom of said object directly under the piezo.
I have put a 1mOhm pull down resistor, but I'll get a 10 meg then!
That is a very good point, but also problematic for my usecase. I absolutely need the peaks because the intensity of the knock is the information I'm trying to capture. I am using analogRead now, I presume I need more voltage for a digital reading? Can I use interrupts with analog reads as well? I have never used the function so I'll read up.
Show your setup, and code.
The knock sensor project I once did with a common 1" piezo with 1Megohm resistor across had no problem detecting a pin dropping on the desk where the piezo was lying on.
Leo..
Edit: I think I used this sketch for testing (on an Uno R3).
// 1" Piezo with 1Megohm resistor across, connected to A0 and ground
int threshold = 100; // alarm threshold from 1 (very sensitive) to 1023
int alarmDuration = 100; // alarm duration in milliseconds
const byte piezoPin = A0;
int rawValue; // raw A/D readings
int piezoValue; // peak value
const byte ledPin = 13; // onboard LED and/or buzzer on pin 13
void setup() {
analogReference(INTERNAL); // remove this line if too sensitive
Serial.begin(115200); // set serial monitor to this baud rate
pinMode (ledPin, OUTPUT);
}
void loop() {
piezoValue = 0; // reset
for (int x = 0; x < 250; x++) { // multiple A/D readings
rawValue = analogRead(piezoPin);
if (rawValue > piezoValue) {
piezoValue = rawValue; // store peaks
}
}
if (piezoValue) { // if > 0
Serial.print(F("Piezo value is "));
Serial.println(piezoValue);
if (piezoValue >= threshold) {
Serial.print(F("Knock was over the threshold of "));
Serial.println(threshold);
digitalWrite (ledPin, HIGH);
delay(alarmDuration);
digitalWrite (ledPin, LOW);
}
}
}
The last code I used was this one, but 100% written for testing. It'll have to run on a D1 mini and send the captured information over 2.4ghz (espNOW) to a second D1 mini. I printed i to keep track of the amount of serial prints, and lastSensorValue + sensorValue in combination with the mils variables so higher values would be printed to keep track of the peaks (but as was already pointed out I obviously miss the moments between the reads, especially with a delay in there).
int i = 0;
int lastSensorValue = 0;
int mils = 0;
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
analogReference(INTERNAL);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A1);
if(sensorValue > 10){
if(sensorValue>lastSensorValue){
Serial.print(sensorValue);
Serial.print(" ");
Serial.println(i);
i++;
lastSensorValue = sensorValue;
mils = 0;
}
if(mils > 300){
lastSensorValue = 0;
}
}
mils++;
delay(1);
}
Hardware is super simple, an Uno, black wire connected to ground, red to A1 and a 1 meg resistor and a diode in parallel. I don't have access to the hardware anymore, but I suppose it's so simple an explanation will do.
While I can't speak for any other piezo devices you may have your Korg CM-300BK looks to have been designed using a Mic Line signal level and designed for use with their amplifiers. The signal level of a microphone, or mic level, is usually between 0.001 volts (1 millivolt) and 0.01 volts (10 millivolts), or -60 dBV to -40 dBV. Of the four main types of audio signals, mic level is the weakest and requires a pre-amplifier to bring it up to line level. Microphone levelis usually specified **between -60 and -40 dBu . (dBu and dBV are decibel measurements relative to voltage.)
While I'm not familiar with the electrical engineering side I am familiar with the different signal types. It's a Hi-Z signal, very similar to what comes out of a guitar, both electric and acoustic with a pickup EDIT both the electric and acoustic parts are called picksups actually, but electric guitars use an electromagnetic pickup and acoustic guitars use a piezo pickup (which just converts vibration into voltage, like all piezo elements). Pickups are often simply piezo elements, just like the clip I have is, and you could replace them with the familiar disk piezo. That's where my knowledge ends, so I guess I'll have to find a schematic for a Hi-Z amp that lifts it up to 1v peak and then block AC (but am I correct in saying that's simply a zener diode parallel between signal and ground?). Thanks for your response!
You don't want to block the AC but rather offset the AC so it does not go below 0.0 volts. A normal AC varies above and below 0.0 volts so we just offset it using circuits like those shown. Only because the Arduino uC cannot handle a signal level below 0.0 volts.
Anyway, yes, I see a preamp in your future. You may be able to find an off the shelf flavor.
I have used plain cheap piezo disks and 4 diodes (full wave rectifier) to make green leds flash, added a cap and got the led to stay lit between taps.
That's a 3V forward voltage driven by a finger tapped ~10 cent disk (price per in a 10 disk bag shipped, before 2015) so maybe look for bare audio pickups?
When I connected to Uno pins my scare was overvolting.
Simply google for microphone amplifier. They can range from a few dollars to over a grand depending on what you want. Then take your choice. As far as worrying about two much voltage place a 20K or so resistor in series with input. that will limit the current. For example if you apply 100V only 2mA will be placed on the input, well below the input protection rating. If you have the gain to high it will clip and sound horrible but that does not hurt anything.
I found this simple circuit, discard anything to the right of the resistor divider. Feed your AC in at Vin, the 100K resistors will center bias the input to 1/2 VCC or about 2.5Volts. You can then swing plus or minus 2.5V without worry. You may have to play with the resistor values. Your output is the input to the base of the transistor, you can put your input resistor between the port pin and the junction of the two resistors and cap. Vcc can be 5V.