Knock Block




Knock Block: a modern knocking framework

Man has long wrestled with Time. Also, with knocking on things and not getting the time of day. We propose a knocking platform through which these fundamental needs are met. This is illustrated with the Knock Block KUI and accompanying Clock Knock Block application. The Knock Block possesses realistic knocking action with a human-like variation in frequency and amplitude of knocks.

Just knock on the Knock Block, or even the surface on which it's resting, and it will knock back the time to you. First it will knock the number of hours, and then the quarter hours.

If you knock several times, the Mock Knock Block application will take over, and repeat back your knocking pattern.


Step 1: Inside the Knock Block

What's inside that rich mahogany exterior? An Arduino that reads vibrations from a piezoelectric sensor and relays back information with a solenoid tapping against the resonant lid of the block. It's all powered by one or two 9V batteries.

Parts list:
- any Arduino can handle this
- a TIP31C high current transistor for the switch
- the exotically named Jameco 191172-001 solenoid, prized for its low price ($3!) and current
- a Measurement Specialties DT-series piezo film element (pretty sure that's the model)
- a 1M ohm resistor (your mileage may vary)
- 9V battery
- block case of your choice

Step 2: Choose Your Block

Exactly how you make your case is up to you, but ours was carved from a block of mahogany by a ShopBot CNC machine. Our design was simple so we made a 2D file and just set depths for the machine to cut (our DXF file is attached below). After routing, we handsanded the whole thing, but especially the edges to make them nice and rounded.We designed the lid to pressfit onto the body so there are no fasteners.

As long as it's hard and has some space to allow the knocking to reverbrate through the body, you're fine. We also cut an acrylic bracket that holds the parts (especially the solenoid) in place and away from the sides where they might dampen the sound.

We gave it a tongue for a nice tone, with the idea that we could make several blocks each with a different size tongue for a variety of tones.

Step 3: Wire the Circuit (piezo)

Tape the piezo at the base to something hard, so it can vibrate more freely. A cheap substitute for the piezo element is an old speaker, which also can produce voltage in response to vibrations.

Schematic for wiring to an Arduino is attached.

Step 4: Wire the Circuit (solenoid)

You'll need to get a high-current transistor (we used a TIP31C) to act as a switch for the solenoid - if it's connected directly to the Arduino it may reset the whole thing every time it activates, since it draws too much current for the Arduino to supply. Then the Arduino is only turning the base on and off, and the collector/emitter circuit is sourced by the 9V directly. The solenoid we used was designed for 12V but it has some tolerance for lower voltage at the cost of knocking volume.

Schematic and board overview attached. Notes:
- We wired the battery right into the Vin and GND pins on the Arduino (right under the resistor).
- The middle pin of the transistor is bent out so it's not in the Arduino, and is only connected to the solenoid via the blue wire.

Step 5: The Arduino Code

// Arduino code for Knock Block
// 2009: ReeD Martin, Ned Burns, Jon Ward, John Kestner
// constants:
const int ledPin = 12; // the solenoid circuit is connected to digital pin 12
const int knockSensor = 0; // the piezo is connected to analog pin 0
const int threshold = 20; // threshold value to decide when the detected sound is a knock or not;
// change this to adjust sensitivity on your own block

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

// Current Time
int current_millis_value = 0;
int previous_millis_value = 0;
int m = 0;
int seconds = 0;
int minutes = 45; // manually set the minutes it starts from when turned on
int hours = 6; // manually set the hours it starts from when turned on

// Initialize Knock-Tracking Variables
long lastKnock = 0;
long curKnock = 0;
int lastIntensity = 0;
int shouldKnock = 0;
long knockSpaces[100];

void setup() {
pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
pinMode(knockSensor, INPUT);
Serial.begin(9600); // use the serial port
Serial.println("Welcome to the Knock Clock Block!");

void loop() {
// Manage time
current_millis_value = millis();
m += current_millis_value - previous_millis_value;
seconds += m / 1000;
m = m % 1000;
minutes += seconds / 60;
seconds = seconds % 60;
hours += minutes / 60;
minutes = minutes % 60;
hours = hours % 24;
previous_millis_value = current_millis_value;

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

curKnock = millis();

// if the sensor reading is greater than the threshold, count it as a knock
if (sensorReading >= threshold) {

if((curKnock - lastKnock) < 1000) {
knockSpaces[shouldKnock] = (curKnock - lastKnock);

lastKnock = curKnock;
lastIntensity = sensorReading;

delay(150); // avoid accidentally triggering more than once

// if it isn't, check to see if 1000 ms has elapsed, and begin knocking:
} else if((curKnock - lastKnock) > 1000 && shouldKnock >= 1) {

if(shouldKnock < 5) {

// Reset Knocks
shouldKnock = 0;
lastKnock = 0;
lastIntensity = 0;

// Knock Hours
for (int y = 0; y < hours; y++) {
Serial.println("Knock! (Hours)");
knockOut(round((max(sensorReading,lastIntensity) / 50)*18));
delay(200 + random(90));


// Knock Minutes (15 min increments)
for (int y = 0; y < floor(minutes / 15); y++) {
Serial.println("Knock! (Minutes)");
knockOut(round((max(sensorReading,lastIntensity) / 50)*18));
delay(900 + random(200));

} else {

// Knock Back
for (int y = 0; y < shouldKnock; y++) {
Serial.println("Knock! (Fun!)");
delay((knockSpaces[y] - 20));

// Reset Knocks
shouldKnock = 0;
lastKnock = 0;
lastIntensity = 0;


delay(150); // avoid accidentally triggering more than once

delay(100); // avoid accidentally triggering more than once

// Perform a knock
void knockOut(int tVolume) {
ledState = HIGH;
digitalWrite(ledPin, ledState);
delay(20 + random(tVolume)); // Randomize intensity
ledState = LOW;
digitalWrite(ledPin, ledState);

Step 6: Stock Your Block

Here you can see the battery resting on one side of the acrylic bracket, the Arduino on the other side with the transistor for the solenoid sticking in it at an angle, and the solenoid in the middle - screwed into a block of MDF to hold it steady - and the piezo sensor taped to the MDF block. Some calibration was necessary to make sure the solenoid hit the tongue of the lid well, and we put a piece of felt under the solenoid hammer to keep it at the right height.

Step 7: Put the Lid On

... and enjoy your Knock Block.



    • Pets Challenge

      Pets Challenge
    • Frozen Treats Challenge

      Frozen Treats Challenge
    • Colors of the Rainbow Contest

      Colors of the Rainbow Contest

    35 Discussions

    Hey, great project! Very simple idea but a rich human-computer interaction.

    I am having a big problem using a piezo sensor in a project I am working on. I just cant get it to sense anything practically. If I hold it and flick it I get a big spike of course, but once I tape it to a surface I can knock all I want and I get almost nothing, maybe 5-6 out of the 1023 of the analog sensing range from the arduino.

    Can you explain how you're attaching it a little better. I just dont know what I'm doing wrong. Thanks for your help.

    2 replies

    Ours is just taped to a hard surface inside. In the Knock Block, we only need to sense whether or not it was knocked, not how hard, so dynamic range doesn't matter much. We set the threshold at 20 and that filtered out false positives.

    Keep in mind that the Arduino's sampling rate may be too low to capture the high-frequency waveform produced by knocking a piezo. Our rich mahogany case probably helped deepen it. You could try smoothing out the sharp waves with a capacitor, if it is just a sampling-rate issue.


    My gut tells me that the sampling rate isnt the issue as when I clamped the piezo into some helping hands it managed to get the vibration into the right part of the sensor because it seemed nice and sensitive then.

    The capacitor sounds interesting. What rating would you recommend and how would you recommend I connect it?



    Reply 9 years ago on Introduction

    Actually, one of the team is working on a $100 CNC router. But of course, it can be just as fun to experiment with found containers.


    Reply 9 years ago on Introduction

    Ah, you spotted the weakness! Right now, you have to set the starting time in the source code so that when you upload the code, you start at the right time. Not optimal if your battery dies. An improvement would be to write a setup function that's called at power-up to set the hour, and then the minute. With knocking, of course.


    9 years ago on Introduction

    You may be interested in my take on the Knock Block.
    (PLEASE don't call it a schlock mock knock block ;¬)


    9 years ago on Introduction

    This is such an awesome project. 

    How long does the battery last in it? I can't imagine it would drain them too quickly. Also, would it be possible make a plug on it to plug it into say a USB port for charging only?


    9 years ago on Step 4

    This is a great idea! The only suggestion I can make is that you may want to put a reverse-biased diode across the solenoid, to keep the back EMF from destroying the transistor. Apparently the particular transistor that you are using can handle it, but a less robust one might not.