Author Options:

Arduino knock sensor with a twist Answered

Hey there!

I live in a dorm and there's no preinstalled doorbell so i thought i'd do something funkier.
I've used the stock Arduino Knock code and modified it a bit so agitating the piezo will make
a connected buzzer beep.

The problem is that while the entire setup is working, the buzzer itself is very very quiet.
With a pure tone making script the buzzer will make a loud BEEEP, but combined with the
knock code it's extremely quiet.

I'm new to Arduino's so please bear with me when i show my code (most is copy/paste to fit):

/* 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:
    * + connection of the piezo attached to analog in 0
    * - 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 Jun 2009
   by Tom Igoe


// these constants won't change:
int speakerPin = 9;
int ledpin = 13;
const int ledPin = 12;      // led connected to digital pin 13
const int knockSensor = 1;  // the piezo is connected to analog pin 0
const int threshold = 10;  // 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

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);
    buzz(9, 2500, 500); // buzz the buzzer on pin 4 at 2500Hz for 1000 milliseconds
    // delay to avoid overloading the serial port buffer

void buzz(int targetPin, long frequency, long length) {
  long delayValue = 1000000/frequency/2; // calculate the delay value between transitions
  //// 1 second's worth of microseconds, divided by the frequency, then split in half since
  //// there are two phases to each cycle
  long numCycles = frequency * length/ 1000; // calculate the number of cycles for proper timing
  //// multiply frequency, which is really cycles per second, by the number of seconds to
  //// get the total number of cycles to produce
 for (long i=0; i < numCycles; i++){ // for the calculated length of time...
    digitalWrite(targetPin,HIGH); // write the buzzer pin high to push out the diaphram
    delayMicroseconds(delayValue); // wait for the calculated delay value
    digitalWrite(targetPin,LOW); // write the buzzer pin low to pull back the diaphram
    delayMicroseconds(delayValue); // wait againf or the calculated delay value

If i get this working i'll see if i can make an instructable out of it (and make a "secret knock identifier").

I ended up using this code:
which works (code can be found by following the links)

And it works! I'm still wondering what was wrong with my (pasted) code though.