Arduino Knock-Knock Treasure Box




Introduction: Arduino Knock-Knock Treasure Box

About: Retired electro-optical engineer. Education:M.S. in Physics. Married 60 years.(same woman!)

This is my first Arduino project and Instructable. I made it for my three young grandchildren who have enjoyed it greatly. I purchased the box from Jo-Ann Fabric and Craft Store and installed an Arduino system. I put treats in the box and program a secret knock by knocking on the box. When they visit they immediately rush to the Treasure Box and work at finding the correct knock. When successful, the box lid springs open and they retrieve their treats.

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1: Design Overview

Refer to the photos.

The box has a power switch and a red/green/blue (RGB) LED on the front.

Internally, an Arduino Uno on box bottom and a circuit board on box front are hidden and protected by two covers: a false bottom and a front (circuit board) cover.

The modules interconnect with three ribbon cables.

The front cover slips over the circuit board. The false bottom presses into the box and against the front cover to hold it in place; i.e. no screws are required for the cover and false bottom. A piece of fabric glued to the false bottom enables easy removal.

The circuit board has a 9V battery, microphone knock sensor, servo for locking, lid micro switch, resistor voltage divider for battery monitoring, and also carries the power switch and LED.

The voltage divider has two identical resistors in series. Battery 9V is attached to one end and ground to the other. Nominal center tap voltage is 4.5V and that is fed to one of Uno's analog ports, which are scaled to 5V.

The box works as follows.


The box will normally be left with lid ajar, held open by the spring action of the lid micro switch.

Flip the power switch on. The LED glows green. And , if not already unlocked, the servo will go to unlock position. This is Program mode, determined by the micro switch in open state.

The box will not lock in this mode and will not respond to knocking or lid closures less than 5 seconds (or other value specified), until the lid is held down for more than 5 seconds.

Press the lid to close it and keep it closed until the LED blinks after 5 seconds.

Then release the lid and Program mode is ready to receive your secret knock. If the lid is released too soon the box will show no LED indication but will accept another closure.

(The 5 second lid closure requirement for entry to Program mode is a safeguard against possible lockout. The 5 second requirement helps to avoid unwanted Program mode entry due to accidental lid bumps or kid fiddling, and therefore guards against accidental programming and your inability to perform an unknown secret code to open a locked box. The lack of LED flashing to show error for early release is deliberate to reduce kid's interest in fiddling.)

Open the lid and perform a secret knock by knocking on the front cover.

The LED blinks for each knock detected.

There is a pause while knock data is stored in Uno EEPROM.

Then the LED blinks to verify data store.

Before locking the box it is a good idea to test the knock.

To do this I use one of the kid's lollipop sticks to briefly depress the lid micro switch (simulated lid closure) while flipping the power switch off then on, causing the servo to go to lock position and the LED to go red. (This is Operate mode.) I then enter my knock on the front cover. If the knock is correct the servo will go to unlock and the LED will go green.

Flip the power switch off. Then hold the lid own while switching power back on.

The box locks and the LED glows red. The box is now in Operate mode and ready for the kids.

(Assuming that treats have been placed in it!)

Flip the power switch off.


The kid flips the power switch on and the LED glows red.

He tries a knock. The LED blinks for each knock detected.

If the knock does not match the secret knock (within a defined tolerance) the LED flashes rapidly for a few seconds and the box will then accept another knock

If the knock does match, the LED goes green, the servo unlocks, the lid springs open, and the kids retrieve their treat.

The box will not respond to further knocks or lid closures until the power switch is cycled.

The kids can set up the box so that one of the others can take a try at the same secret knock.This is done simply by holding the lid closed while flipping the power switch on.

If you get locked out of the box I have provided a way to unlock it: just knock 10 times within the 5 second allowed time and the box will open. It is unlikely that a kid will do this.


When the power switch is flipped on, Uno reads battery voltage (divided by two).

If that corresponds to less than the 7 volts specified for Uno, the LED goes blue and blinks rapidly.

If that happens the box will not go to Program or Operate mode until the battery is replaced.


The circuit board is a perfboard holding all of the electrical components listed above. Wiring is point-to-point on board back.

Except for the power switch and LED, all circuit board components mount to the board with double-sided foam tape. This is especially convenient for servo and micro switch positioning.

The power switch and LED float so that they can be pushed through their holes in box front.

The circuit board is a standalone module that can be operated out of the box when connected to Uno.

The lid micro switch depressor is a wood dowel mounted in a small block of wood in the lid. The dowel passes through the hole in the front cover to engage the switch.

The lid latch is an aluminum L-bend. It passes through a slot in the front cover to engage the servo, whose arm swings over it
to lock the lid.

The latch screws to the lid with screws inserted from the outside. This enables easy latch removal to gain entry to the box in case of lockout due to forgotten secret knock, dead battery, or electrical failure.

Step 2: Parts, Material, and Tools


Box - Available at Jo-Ann. $6 with coupon.

Uno - You probably have the Uno. If not, it is available at Radio Shack or online at Sparkfun, Jameco, etc, for $28-$35.

Microphone board – Online at DealExtreme 135533 (only $2.80 with free shipping).

Servo – I had a Hitec HS-55. You can buy one for $10 or gamble on Chinese quality for less.

Micro switch – Sparkfun COM-09506 $1.50

RGB LED - Radio Shack has one for $1.

Power switch – Jameco 76523 $1.49 (This was the only one I could find that had sufficient thread length to pass through the 1/4 inch box front and use the nut.)

9V battery – Also get a snap connector.

Ribbon cables(3) – Sparkfun 12 inch:

   5-pin PRT-10375 $1.95

   4-pin PRT-10374 $1.95

   2-pin PRT-10372 $1.95


   One 1,000 ohm (current limiter for my bright LED)

   Two 10,000 ohm (for the voltage divider)

    All can be 1/8W.


Perf Board - Radio Shack 6 x 8 inch board 276-1396 $3.49

Tape – Scotch Permanent Mounting Tape (double-sided foam tape).

Stranded Hookup Wire

Heat Shrink Tubing – 1/4 inch and 1/16 inch diameter.

Nylon standoffs (3) – 1/4 inch high to mount Uno. I got mine at Ace Hardware.

Wood – 1/8 inch thick x 24 inch long bassboard from Jo-Ann. One 3 inch width and one 4 inch width.

Wood Dowel – One each I/8 inch diameter and 1/4 inch square.

Glue – I like Aleene's Tacky Glue. Holds parts in place while drying, dries in a few hours, sticks to about anything, and holds well.

Aluminum – I had a .032 inch aluminum sheet that I got at Home Depot. I cut the latch from that. You could use the aluminum top from a $3 Radio Shack project box, part # 270-1801.


   Two #4 x 1/2 inch sheet metal screws to attach the latch.

   Two #4 x 3/8 inch screws to hold the circuit board in place.

   Three #4-40 x 1/2 inch machine screws and nuts to mount Uno.


Wire cutter

Wire stripper

Soldering iron and solder

Fine-toothed Saw for the wood - If you don't have a table saw, you may be able to use a hacksaw

Coping saw (for notching)

Hacksaw for aluminum

Drill and bits

Vise – Nice to have for for holding material while cutting.

Step 3: Make the Circuit Board

Cut out the perfboard. The 6 inch dimension of the Radio Shack perfboard works as-is for width, clearing the 1/8 inch sides of the cover. Cut a piece off the 8 inch dimension that equals the interior box depth, less 3/16 inch to clear the top of the cover, which is flush with the box top lip.

Mark drill points on the box outside front face, horizontally centered, for the power switch and LED.

Center the perfboard in the box and drill pilot holes through box and board.

Enlarge holes to fit the switch and LED.

Using the coping saw, enlarge the perfboard switch hole to a rectangle that passes the switch.

Also cut a 1/2 inch wide x 1/4 inch tall notch at board top center. This allows clearance for the aluminum latch and servo arm.

Cut four basswood strips equal to perfboard height. Glue these together to make two 1/4 inch thick mounts for the perfboard.. These will provide space for the wiring.
Position the mounts on perfboard left and right edges and drill a pilot hole at mount center through perfboard and basswood.
Screw the perfboard to the mounts, apply glue to the mount exposed side, and stick it to box front, keeping the perfboard centered.
Let dry, then unscrew perfboard.
This leaves nice spacers and avoids trying to make pilot holes in the cramped confines of the box interior.

Now tape the micro switch, servo, microphone board, and battery to the perfboard, referring to the photo. Also place the voltage divider resistors on board. The servo arm in lock position should be where the lid latch will be, centered left/right on the box.

I enclosed my LED in 1/4 inch diameter heat shrink and slipped 1/16 inch diameter heat shrink over two of the four leads to insulate them all from each other. The only heat shrinking I did was around the LED glass bulb to hold the LED firmly. Length of the larger heat shrink was 1.25 inch to equal box thickness and spacer thickness, plus protrusion from the perfboard. I made 90 deg bends in the four leads, preparatory to soldering.

Cut one connector off each ribbon cable.

Break headers off the 40-pin breakaway male header strip and plug them into the remaining three female connectors. They will plug into Uno's female headers.

Step 4: Wire the Circuit Board

Decide where Uno will mount, considering front cover depth (1.25 inch; see Step 5) and leaving room to plug in the USB cable.

With ribbon cables plugged into Uno, determine the length needed from mounted perfboard bottom to Uno and peel the ribbon wires apart to that point.

Enlarge the perfboard holes to permit feeding the wires through. Pass the wires through the holes, trim as necessary, strip the ends and solder to the circuit board components. Wiring data is given below.


Component Connection           Uno Port

      Blue LED Anode                       8

      Red LED Anode                        9

     Green LED Anode                    10

     Servo Angle Cmd                     11
         (yellow wire)

       Micro Switch                           12
  (normally closed lug)


Component Connection           Uno Port

              5V input                           5V

              Ground                            Gnd

                 NC                                Gnd

       Switch 9V output                     Vin


 Component Connection          Uno Port

      Microphone Board                   A0

        Voltage Divider                       A1

Additional wiring is:

Wire battery 9V to switch input.

Wire 5V from Uno to servo (red wire) and microphone board “+” pin.
These three wires can be twisted together, soldered, and covered with heat shrink.

Wire all component grounds to Common Ground:

     Battery (black wire)

     Microphone board (“G” pin)

     Servo (black wire)

     Micro switch lower lug

     LED cathode resistor

These wires can also be twisted together, soldered, and covered with heat shrink.

Note that all wiring is done on the back of the board. Wires to components pass through enlarged holes where necessary. The LED cathode resistor is soldered to that pin and passes through a standard hole to the ground connection below.

Step 5: Make the Front Cover and False Bottom


Cut the sides, top, and back from the 3 inch wide basssboard using the following measurements:

     Sides height equal to interior box depth minus 1/8 inch . This leaves the cover top flush with the box front top.
     Width of 1.125 inch, which should leave sufficient room for the circuit board.

     Top length equal to box interior width.
     Width equal to sides plus 1/8 inch to overhang the back.

     Back length equal to top.
     The 3 inch board width can be used as is. It leaves a gap at the bottom for the ribbon cables.

Cut two lengths of the 1/4 inch square dowel equal to the length of the sides.

Referring to the photos, glue the sides to the back, flush with back sides and top.  Glue in the square dowels for reinforcement.

Glue the top to the sides and back.


Cut four false bottom supports from basswood. These glue together in pairs to provide two 1/4 inch wide supports that glue to box sides.
Length is arbitrary but height must allow the false bottom to clear the ribbon cables when plugged into Uno.

Cut the false bottom from the 4 inch basswood.
Dimensions equal box interior dimensions, minus the 1.25 inch occupied by the front cover.

If necessary to achieve a press fit to the front cover, cut a narrow length of basswood equal to box width and glue it to the rear of the false bottom while it is in the box, pressing the strip against the box back. (See the photos.) You can use wax paper to assure no gluing to the box. 

Step 6: Install the Circuit Board and Uno

Screw the circuit board to the spacers using the two #4 x 1/4 inch screws.

Position Uno on box bottom so that the ribbon cables easily plug in, and leave room for the USB cable.
Mark three mounting holes (the fourth is hard to use) and drill for the machine screws.
Use the three machine screws, nuts, and nylon spacers to mount Uno.

Stick four felt pads to box bottom to provide clearance for the protruding screws and nuts.

Step 7: Make and Install the Lid Parts


Cut a strip of aluminum 1/4 inch wide and 1.5 inches long.
Make a 90 deg bend extending about 3/8 inch.

Remove the box latch.

Install the aluminum latch with two screws in the following manner:

   Hold the latch inside the lid at lid center and drill one pilot hole through lid and latch for a screw.

   Enlarge lid hole for screw shaft.

   Screw the latch on, lining it up vertically.

   Repeat for second screw.

Adjust the servo as necessary to align the latch as close as possible with the top of the servo arm.

(The best way is to make careful measurements since vision is limited. Final adjustment can be done by bending the latch until there is just a little play in the lid when locked.)


Make a 3/8 inch thick block of wood to go in the corner of the lid with a 1/8 inch center hole to hold the dowel. The dowel must be centered on the micro switch plunger when lid closes; final adjustment can be done by positioning the switch. Glue the block in place.

Cut a 3/4 inch piece off the dowel.

Slide the dowel nearly all the way into the block hole; enlarge hole diameter as necessary.

Dab glue on dowel end and close the lid to mark the cover hole position.

Drill the hole.

Push the dowel partly out of the block and adjust length while listening to the switch click.

Mark where the dowel enters the wood block.

Pull it out, apply glue, then glue it back in.

Do a final micro switch adjustment if necessary to approximately align switch plunger with the cover hole.

Step 8: Download the Sketch File and Move It to Your Sketchbook

The sketch file is on Dropbox. It is named KnockKnockTreasureBox_9.ino This is a copy of the same file that is in my Sketchbook.
Use this link to download:
Copy or move this file from your Download folder to your Sketchbook.
In the Arduino IDE click on Sketchbook. Then click on KnockKnockTreasureBox_9 to view it.

The sketch is heavily commented and designed for easy reading by anyone familiar with Arduino coding.

It uses two libraries: Servo.h and EEPROM.h

In most places a variable name is used rather than the value I used. Thus the value may easily be changed where the variables are typed and defined. For example, Uno ports are named rather than numbered in the code.

It makes strong use of Functions. This keeps the main program [loop()] simple because it calls up functions which are clearly named and in which the details of the sketch are accomplished.

The main program listing follows. It is not for compilation but is presented in nearly that form for your understanding. The Functions are bold font for easy recognition and are described following the main program listing.

MAIN PROGRAM: Void loop() {

CheckBattery()    / /Flashes blue if battery needs replacing and will not proceed.

[If lid switch open go to ProgramMode]

Else goto OperateMode


[Unlock the servo and light the green LED]

AwaitGoAhead()    //Waiting for user to press lid for 5 sec to enable more secure programming.

ReadyToProgram:   //A goto address

GetKnock()    //Wait for user knocks, determine number and time between each, test for legality,

If ErrorFlag == 1   //Set flag if illegal,

FlashLED()    //Flash LED.

     goto ReadyToProgram    //Try again

StoreSecretKnock()   //Store secret knock data in EEPROM

BlinkLED()    //Blink LED to show data was stored .

ProgramDwell: //Disable box response to further lid closures and knocks.

goto ProgramDwell


[Lock the box and light the red LED]


If ErrorFlag == 1


     goto OperateMode

GetSecretKnock()    //Retrieve data from EEPROM

CompareKnocks()    //Compare knock number and spacings for user's knock vs secret knock.

If ErrorFlag == 1     //Set flag if different, and flash LED.


     goto OperateMode //Try again

[Else, light the green LED and unlock the box]

Dwell: //Disable box response to further knocks or lid closures.

goto Dwell


CheckBattery() reads the 0-1023 reading of analog port A1 and converts it to volts.

If voltage is less than 7V it starts flashing the blue LED and freezes the program in this state until power is turned off. However, If voltage is less than 5V the box is being USB-powered, so blue flashing is disabled.

AwaitGoAhead() senses lid closure, waits for 5 seconds, blinks the LED,  waits for lid to open, then returns to main program.

GetKnock() is called in both Program and Operate modes. It computes and saves the time interval between each knock. It also determines if the time allowed for knocking or the maximum number of knocks allowed has been violated, in which case it sets an ErrorFlag.

It waits until a knock amplitude on analog port A0 exceeds set Threshold.

When the first knock (N = 0) occurs it reads clock time and saves it in the Time[N] array as Time[0]. It also blinks the LED.

Clock time is constantly being read and ElapsedTime computed
as Clock – Time[0].

If elapsed time exceeds the allowed time for trying knocks, and only one pulse has been detected, the ErrorFlag is set and the function returns. Otherwise the function returns with no set ErrorFlag.

For each knock (N) detected after the first knock, ElapsedTime is saved as Time[N], and the LED is blinked.

If the number of knocks exceeds the maximum allowed (10), the ErrorFlag is set and the function returns.

If there are no errors, each knock interval (Time[N] – Time[N-1]) is saved in array KnockInterval[N], and when allowed ElapsedTime is reached the function returns.

StoreSecretKnock() is called in ProgramMode. It stores in EEPROM each KnockInterval[N] saved in GetKnock(), as well as total KnockNumber. These are stored as SecretKnockInterval[N] and SecretKnockNumber.

GetSecretKnock() is called in OperateMode. It retrieves each SecretKnockInterval[N] and SecretKnockNumber saved in EEPROM.

CompareKnocks() first determines if the KnockNnumber saved in GetKnock() equals the MaxKnockNumber allowed (10); if so, the box will open. This is a way to open a box when you are locked out.

Next, this function determines if KnockNumber from GetKnock equals the SecretKnockNumber retieved from EEPROM. If not, the ErrorFlag is set and the function returns.

If OK, the function compares each KnockInterval saved in GetKnock() to each SecretKnockInterval retrieved from EEPROM. If not equal, to within the Tolerance set in Delta, the ErrorFlag is set; otherwise the function returns with no ErrorFlag set.

BlinkLED() and FlashLED() are simple, short routines that do just what they say.

Step 9: Compile and Upload the Sketch; Then Test Your Box

Compile and upload the sketch to Uno using your USB cable.

Unplug the USB cable and flip the power switch on to operate on the box battery (a good one!).

The LED should be green.

Hold the lid down for less than 5 seconds.

When you release the lid nothing should happen; the box is waiting for more than 5 seconds hold-down to minimize the chance of unwanted secret knock entry.

Now hold the lid down until the LED blinks.

The box is now ready for you to enter a secret knock.

Open the lid

Program a secret knock by tapping on the front cover.

The LED should blink for each knock and blink again when the knock is saved.

(If you enter only one knock or too many knocks in the allotted time (5 seconds) the LED will flash.
You can then enter another secret knock.
Go ahead and test this now.)

Now, remember to test your secret knock before locking the box!

Test as follows.

     Flip the power switch off.

     Depress the lid micro switch with whatever is handy and flip the power switch back on.
     This simulates locking the box and going into Operate mode.

     The servo should “lock” and the LED should now be red.

     Enter the secret knock by tapping on the front cover.

     The LED should blink for each knock.

      After a short wait the LED should go green and the box should unlock.

Now try knocking. Nothing should happen.
Try closing the lid
Nothing you do should have any effect.
Box operation is deliberately disabled after successful unlocking to discourage kid fiddling.

However, the power switch can be cycled to start the process again.
If the lid is held down while power is turned on the box should start up in Operate mode with the previously stored secret knock.
This is useful when one kid has opened the box and another wants to try his luck.
Go ahead and do this.

You can enter repeated knocks as long as you want.
Exercise box error response by entering other than the secret knock. The LED should blink for each knock, and after a short wait the LED should flash rapidly to tell you that was not a good knock.
Enter some illegal knocks. Try: a single rap; taking more time than allowed while knocking; using more than the allowed number of raps. Each illegal knock should get the LED flash response.

Perform the secret knock and the box should spring open.

Lock the box again by flipping the power off, holding the lid down, and flipping the power back on.
Knock 10 times rapidly (within 5 seconds).
The box should open.
This is the emergency open command.

The easiest way to test battery monitoring is to clip leads from a variable voltage bench power supply to the battery connector, being careful about polarity and clip attachment. However, if you've got a used battery with a little less than 7V, that is much safer.
The box LED should flash blue when voltage drops below 7V.

Step 10: Some Concluding Notes

I made two different boxes.

Old Box

This box had Uno mounted in the bottom, jumper-wired to a small breadboard in the bottom.

The knock sensor was a piezoelectric in the lid. The LED was also in the lid.
This meant having a ribbon cable snaking down to the breadboard.

The servo was a standard (larger) servo screwed to a sturdy wood mount extending from box bottom
with Its standard 3-pin cable plugged into the breadboard.

A smaller micro switch was glued to the box front. I also used this for awhile on the new box until it failed.

(You may have wondered about the star sticker over the hole on the front cover of the new box pictured in this Instructable. It hides the ugly hole necessary for the new micro switch! The second star just balances the first.)

One ribbon cable served the micro switch and power switch. It too plugged into the breadboard.

The 9V battery was taped to box bottom and cabled to the breadboard.

Lastly, a “hidden” 3-position slide switch was screwed into the outer bottom of the box and operated by reaching under the box. It was ribbon cable connected to the breadboard.
This switch selected three modes: Program, Operate, and Open.
The last function allowed the box to be opened at any time.

This switching function worked well, but eventually the kids discovered it and could then open the box at will. Also, there was the possibility that they could put in their own secret knock, although it wasn't really a problem since I could select Open or select Program to change the secret knock.

In the new box I tried using a stereo jack and plug to achieve a “dongle” that would allow box Open.
That's why there is yet another star on the box bottom covering the required hole.
The dongle worked but was a little clumsy. I eventually decided on the security approaches described herein.

Battery monitoring was not included in the first box.

A surprise using it in the new box was the fact that it triggered the blue flashing when USB was plugged in, and box operation was disabled. Fortunately, a simple one line of code fixed the problem.

New Box

The old box had 5 ribbon cables, Uno, breadboard, and battery in box bottom. The exposed servo, micro switch, LED, and power switch were mounted on box front. This created a product that was very messy and somewhat difficult to install and work on.

That is what motivated the design of the new box:

     Hide everything

     Eliminate screws

     Eliminate the breadboard interface

     Minimize number of cables

     Go to a single removable module (circuit card) for everything but Uno.

I didn't quite achieve the no-screws criteria.

My intent was to use magnets to hold the circuit board in place; four magnets glued to box front and four ferrous metal plates on circuit board back. However, locally obtainable magnets proved to be too weak. So I used two screws. If you look close you may see that I kept the glued-on magnets as spacers and didn't take the plates off the board. If I had taken the time to find and procure the right magnets, I'm sure this would be a good design. The spacer approach I described will avoid the problem of driving screws in the box front.

I had some trouble keeping the micro switch taped on, so I added two screws.
I could probably avoid screws by gluing but I took the easy no-risk way out.

I plan to replace Uno with an Arduino Pro Mini 328 board that will mount in the unused space seen in the lower left corner of the circuit board. This will serve to eliminate the false bottom, increase treat space, and further streamline the design. Perhaps then I can also magnetically mount the board and the cover and glue the micro switch. So far the foam tape is doing a fine job of holding the servo, microphone board, and battery.

3 People Made This Project!


  • Tiny Speed Challenge

    Tiny Speed Challenge
  • Clocks Contest

    Clocks Contest
  • PCB Design Challenge

    PCB Design Challenge

25 Discussions


2 years ago

Certainly. Connect one lead of your (normally open) pushbutton to Uno pin D7, and the other lead to ground. Leave Uno pin A0 (microphone) unconnected.

Copy the following sketch and paste it in your Arduino IDE.

//--------------------------- PushbuttonTreasureBox_9 --------------------------


#include <Servo.h>

#include <EEPROM.h>

//-----Variables, Typed and Defined-----

/* int: Integer, 8 bits, 0-255

unsigned short: Integer, 16 bits, 0-65,535

float: Floating point (decimal) number */

//Add this:

int Knock = 1; // Knock now means "Pushbutton click" ; 1(switch open) or 0(switch closed)

/* Delete this:

int KnockAmp;           //Knock amplitude from the microphone board, an analog output read by Uno's 10 bit analog port: value = 0-1023.

int Threshold = 150;    /* Knock acceptance threshold: Voltage = (Threshold/1023) * 5V, or

                           0.73V for Threshold = 150, which gave reliable operation. */

int N;                  //Knock counter. First knock is N = 0. In the following I set a limit of N = 9 (10 knocks total, 9 intervals).

int KnockNumber;        //Number of knocks detected after first knock in Operate mode.

int MaxKnockNumber = 9; //Max N is 9, max number of knocks is 10.  This is also used as a code to unlock the box at any time.

int KnockInterval[9];   //An array of 1 to 9 intervals, msec.

int SecretKnockNumber;  //Number of knocks detected (after first knock) in Program mode.

int SecretInterval[9];  //An array of 1 to 9 intervals, msec.

unsigned long Time[10]; //Puts each knock time in a 10 element array (0-9).

int ErrorFlag;          /* Normally zero; otherwise unity(1)if any one of the following conditions occurred:

                             Knock entry does not match secret knock in Operate mode.

                             Only one knock detected in Program mode(must have at least two).

                             More than MaxKnockNumber of knocks in either mode.

                             Knock entry took too long in either mode. */

int LidSense;           /* Senses lid open (HIGH) or closed (LOW).

                           Note: LOW and HIGH are interpreted as legitimate integers (0 and 1) */

int K;                  //A counter

int BlinkTime = 100;    //LED on/off times, msec

int BlinkNumber = 15;   //Number of times LED blinks when flashing

int SwitchBounce = 500; //Time allowed for switch contact bounce, msec    

unsigned long Clock;          /* Time since power-up, millisec

                                  "unsigned int" is only two bytes, allowing only 65,655 msec (one minute) of operation.

                                  "unsigned long" is four bytes and allows 50 days! */

unsigned int CloseTime = 4500; //Required lid closure time (less SwitchBounce) to enter Program mode, msec.

unsigned int ElapsedTime;     //Time since first knock, msec.

unsigned int MaxTime = 5000;  //Maximum elapsed time allowed for a knock sequence, msec.

float Delta = 0.5;            /* Knock interval tolerance(1.0 +/- Delta).

                                 For example, if Delta = 0.5, must knock to within 50 to 150% of Secret Interval */

float ScaleFactor = 2.02;     //Battery voltage = ScaleFactor x voltage reading on port A1

Servo Latch;                  //Latch is the servo angle command, deg.

int Lock = 70;                //Servo lock command, 70 deg in my box.

int Unlock = 165;             //Servo unlock command, 165 deg in my box.

//-----Uno Port Assignments-----

//These are labled according to which hardware the numbered port is connected.

/* Delete this:

char KnockSensor = A0;     //Analog input port for microphone board's analog output */

// Add this:

int Pushbutton = 7;       //Digital input port for pushbutton

char BatteryMonitor = A1; //Analog input port for voltage divider

int BlueLED = 8;          //Digital output port for Blue LED 5V drive

int RedLED = 9;           //Digital output port for Red LED 5V drive

int GreenLED = 10;        //Digital output port for Green LED 5V drive

int ServoLock = 11;       //Digital output port for servo command

int LidSwitch = 12;       //Digital Input port for lid Open/Closed (HIGH/LOW) state

int LEDPort;              //Sets to GreenLED in Program Mode and RedLED in Operate Mode


/* Note: Each block of program code in Arduino starts with "void Name()" unless the block is returning data;

"void" means there are no data names in the ( ) bracket. */

// "void setup()" is a required first block of code; it is where you set up Uno to perform the "void loop()" program.

void setup(){

  //Port Setup: (Note: Ports default to INPUT at power-up.)

  //Add this:

  pinMode(Pushbutton, INPUT);         // set pin D7 to input

  digitalWrite(Pushbutton, HIGH);     // turn on Uno's internal pullup resistor

  pinMode(RedLED,OUTPUT);           //Set the LED ports to Output.



  pinMode(LidSwitch, INPUT_PULLUP);

  digitalWrite(LidSwitch, HIGH);    //Activate pullup resistor on this port.

  Latch.attach(ServoLock);          //Defines "Latch" as the servo angle command variable assigned to the Servo port.

  //Communication Setup for Debug:

  Serial.begin(9600);               //Activates serial output to PC at 9600 baud (bits/sec)


//------------------------Functions----(Must be placed before Main Program for reliable compiling)--------------------------

void AwaitGoAhead() {


  do {                                     //Wait for lid to close

    LidSense = digitalRead(LidSwitch); }

  while(LidSense == HIGH);

  Time[0] = millis();                      //Read time

  delay(500);                              //Allow for switch contact bounce

  do {                                     //Wait for lid to open 

    LidSense = digitalRead(LidSwitch);

    Time[1] = millis();                    //Read time

    if ((LidSense == HIGH) && ((Time[1] - Time[0]) < CloseTime)) goto ClosureCheck;  //If lid opened too soon blink never occurs and must do again

    if ((Time[1] - Time[0]) > CloseTime) { //When lid closed for required time,

      BlinkLED();                          //blink LED, and

      return; }                            //return with implied approval to go ahead


  while (LidSense == HIGH);

}   //End of function


void BlinkLED() {

  digitalWrite(LEDPort,LOW);   //LED off,

  delay(BlinkTime);            //for blink time,

  digitalWrite(LEDPort,HIGH);  //then back on.



void GetKnock() {  /* Detects each knock, blinks the LED, and reads clock time.

                      Determines elapsed time from first knock, and returns to main program when MaxTime exceeded (whether you are done knocking or not!)

                      Determines the intervals (time between each knock), and saves them in an array.

                      Sets the ErrorFlag if the number of knocks is only one or if they are more than allowed; I have set a fixed limit of 10 knocks. */

  N = 0;  // First knock

/*  Remove this:

  do  {

    KnockAmp = analogRead(KnockSensor); }    //Wait for a knock amplitude that exceeds threshold

  while(KnockAmp < Threshold); */

  //Add this:

  do  {

    Knock = digitalRead(Pushbutton); }    //Wait for knock = 0

  while(Knock = 1);

  Time[0] = millis();                        //Save T-zero

  BlinkLED();                                //See function above.

  // Get Subsequent Knocks:

  ErrorFlag = 0;

  //Do the following for each knock, while elapsed time from first knock < MaxTime and number of knocks < MaxKnockNumber

  do {          

    /* Delete this: do {                                 //Wait for a knock amplitude that exceeds threshold

       KnockAmp = analogRead(KnockSensor); */

      //Add this:

      Knock = digitalRead(Pushbutton);

      Clock = millis();                     //Read clock time

      ElapsedTime = Clock - Time[0];

      if(ElapsedTime > MaxTime) {           //Time's up!

        if(N == 0) ErrorFlag = 1;           //A viable knock sequence must have at least two knocks (one interval)

        return; }



    while(KnockAmp < Threshold); */

    // Add:

    while(Knock = 1);

  do { 

    N = N + 1;

    if (N == 10) {                          //Signal an error if too many knocks/intervals and return to main program

      ErrorFlag = 1;

      return; }

    BlinkLED();                             //Blink for each acceptable knock

    Time[N] = millis();                     //Read time of knock

    KnockInterval[N] = Time[N] - Time[N-1]; //Save time (interval) since previous knock

    KnockNumber = N;                        //Save number of intervals detected


   while(N < 10);

  return;        //Return to main program

}  //End of function


void StoreSecretKnock() {

  EEPROM.write(0, KnockNumber);        //Put KnockNumer in first EEPROM location

  for(N = 1; N <= KnockNumber; N++) {  //For each knock store interval time in next two locations

    int Interval = KnockInterval[N];   //In milliseconds

    int a = Interval/256;              //EEPROM can store only one byte in each location (0 to 255 msec)

                                       // a = number of 255 msec bytes

    int b = Interval % 256;            // b = residual msec in remaining byte


    EEPROM.write((2*N)+1,b); }



void GetSecretKnock() {

  SecretKnockNumber =;

  for(N = 1; N <= SecretKnockNumber; N++) {

    int a =*N);

    int b =*N)+1);

    SecretInterval[N] = (256*a) + b; }



void CompareKnocks() {

  if (KnockNumber == MaxKnockNumber)  return;  //This is a secret code to be used to unlock the box in case of accidental lockout.

  GetSecretKnock();  //See function above

  ErrorFlag = 0;

  if (KnockNumber != SecretKnockNumber) {    //Tests the two variables for non-equality,

    ErrorFlag = 1;                           //  sets ErrorFlag if not equal,

    return; }                                //  and immediately returns to Operating

  for(N = 1; N < (SecretKnockNumber + 1); N++) {  //For N = 1 to SecretKnockNumber, stepping 1 at a time

    if ( (KnockInterval[N] < ((1 - Delta) * SecretInterval[N])) || (KnockInterval[N] > ((1 + Delta) * SecretInterval[N])) )    ErrorFlag = 1; }

                                             //The above test is an OR statement that allows, for instance,

                                             //  +/- 50% tolerance in knock timing if Delta = 0.50



void FlashLED() {                     //Long flashing to signal operator of wrong knock and knock disabling                                                         

  for(K = 0; K < BlinkNumber; K++) {  //Flash BlinkNumber times




    delay(BlinkTime); }



void CheckBattery() {

  float V1;

  float Volts;

  digitalWrite(RedLED, LOW);

  digitalWrite(GreenLED, LOW);

  K = 1; //Used below to make an unending do-loop

  V1 = .00489 * analogRead(BatteryMonitor);  //Analog ports have a 0-1023 reading for 0 - 5V; thus,the port scale factor is 5/1023 = .00489 V/bit.

  Volts = ScaleFactor * V1;                  //Multiplying by the 2.02 resistive divider yields an overall scale factor of .00987 V/bit

  if (Volts < 5.0) return;      /* When Uno is powered by USB, Vin is < 5V and the voltage divider cuts that in half; so that tells the program

                                  to ignore battery monitoring, and blue blinking is eliminated */

  if (Volts < 7.0) {           // 7V is the recommended minimum battery voltage for Uno

    do {                       // Blink Blue LED to signal need for battery change

      digitalWrite(BlueLED, HIGH);


      digitalWrite(BlueLED, LOW);

      delay(100); }

    while(K == 1); }          //Stays in this do-loop. Will not allow box operation when battery is low at power-up.


//--------------------------End Functions---------------------------

//-----------The Main Program-------------

/* "void loop()" is a required second block of code; it is where the main program resides.

   It norminally runs as a repeating loop, but it does not have to. */

//The main program calls on functions defined above. This makes the code easier to read.

void loop() {

  Latch.write(Unlock);           //At power-up unlock the servo to avoid possible damage to the servo or latch by lid closure

  CheckBattery();                //See function above

  LidSense = digitalRead(LidSwitch);      //Read lid state at power up

  if(LidSense == HIGH) goto ProgramMode;  //If lid is open, box goes into Program mode

  else goto OperateMode;                  //If the lid is closed it goes into Operate mode


   //Initiate settings

   Latch.write(Unlock);           //Unlock servo

   digitalWrite(RedLED,LOW);      //Red LED off

   digitalWrite(GreenLED, HIGH);  //Green LED on

   LEDPort = GreenLED;            //All LED commands in ProgramMode are Green

   AwaitGoAhead();                /* See function above. This assures a deliberate secret code entry;

                                     i.e. the operator must close the lid for the required lid CloseTime before entering the secret knock */


   GetKnock();                     //See function above

     if (ErrorFlag == 1) {         //Flag is 1 if illegal knocks are performed.

       FlashLED();                 //See function below

       goto ReadyToProgram; } 

   StoreSecretKnock();            //See function above

   BlinkLED();                    //Show that data has been stored

   ProgramDwell:                  //Freeze box operation

   goto ProgramDwell;


  //Initiate settings

  Latch.write(Lock);              //Lock servo

  digitalWrite(GreenLED,LOW);     //Green LED off

  digitalWrite(RedLED, HIGH);     //Red LED on

  LEDPort = RedLED;           


  GetKnock();                     //See function above

  if (ErrorFlag == 1) {


    goto StartKnocking; }         //Can then enter a different knock

  CompareKnocks();                //See function above

  if (ErrorFlag == 1) {


    goto StartKnocking;  }        //Can then enter a different knock

  else {                         

    digitalWrite(RedLED, LOW);

    digitalWrite(GreenLED, HIGH); //Green LED on

    Latch.write(Unlock); }        //Unlock servo

  OperateDwell:                   //Freeze box operation

  goto OperateDwell;

}  // End of Loop

-------------------------------- End Sketch -------------------------------------------

Note in SetUp that I have activated Uno's internal pullup resistor on pin D7, so the pin input is HIGH (1)  until pushing the pushbutton makes it go LOW (0).

I have noted where I have deleted code and where I have added code. This modification of my original KnockKnockTreasureBox sketch retains all capability of the original. If you really just want to use only pulse number coding, irrespectiyve of time between pulses, delete the last statement in the CompareKnocks() function:

for(N = 1; N < (SecretKnockNumber + 1); N++) {

    if ( (KnockInterval[N] < ((1 - Delta) * SecretInterval[N])) || (KnockInterval[N] > ((1 +

   Delta) * SecretInterval[N])) )    ErrorFlag = 1; }

Please note that I have not implemented D7 switching and have not loaded this sketch in my Box. However, if you are interested enough to continue, load the compiled sketch into your Uno, hook up the peripherals (pushbutton, RGB LED, servo, and lid switch) and debug as necessary. I will supply LIMITED help if necessary.


2 years ago

Is it possible to use a push button instead of a microphone? So a certain number of pulses would open the lock?


4 years ago on Introduction

It is hard to see your plug-ins to the Uno board but you seem to have a LED anode plugged into D10 (Green) and a "micro" switch into D12, all of which is correct.

Have you tried stepping through the program to see where the problem occurs?

The first step would be to make a long delay like "delay(10000);" just after the point where the green LED lights up in Program mode. Apply power and the LED should stay on with no blinking for 10 seconds.

If good, proceed similarly to another point in the program.

ismail khopdi
ismail khopdi

Reply 4 years ago

same problem occurs now also . after giving delay the delay occurs between rapid blink n slow blink .

sir i m using sound sensor FC-04 which i think gives digital o/p and you give microphone output to A0(which is analog pin)

what is your microphone model no. ?


Reply 4 years ago on Introduction

I found a FC-04 sound sensor. The image is below. Is this your sensor?

The blue potentiometer (variable resistor) is the detection threshold adjust. Based on my sensor, I am guessing it has only digital output. Have you tried adjusting the threshold to see if your problem goes away?

ismail khopdi
ismail khopdi

Reply 4 years ago

yes i adjusted the pot of the sensor .
the problem i think is i m using sound sensor whose output is digital .
so today i m going to buy ur's microphone and let you the problem is solved or not.
Is there any way through which i can send u video so that u can easily understand my problem.

And i m very thankful to u sir that u r helping me out of this !!


Reply 4 years ago on Introduction

You say you adjusted the pot but do not say if the problem went away. By the tone of your message I am guessing that it did not.

You can see if it is digital output by putting a "Serial.println(KnockAmp)" command in the GetKnock() function. Assuming that the sensor Vcc = 5V, you should see 5V knock amplitude on the serial monitor for each knock no matter how soft or hard you knock. Actually you may see many pulses for a single knock. That was the case for my box. I think it's reverberation in the box. It's not a problem as long as the reverbs go away before the next knock.

There is no reason that you can not use a digital output, if the sensor's threshold function is working properly. You would not need the software threshold function but it would not hurt anything. (A threshold is necessary to avoid false detections of sensor noise or any other source.

I'm sorry I am having trouble with your English. It's not that bad, but it's hard enough doing online troubleshooting with a native English speaker! (Unfortunately I'm not familiar with how to provide video online.)

After going back through your messages here is what I understand:

1. Power up. You are getting the steady Green LED.

2. Press and hold the switch. You say that after 5 seconds the Green LED does not blink once but begins blinking rapidly. (I do not understand what you are trying to say in the message from several days ago: "4. without giving input through mic it blink with freq of 0.5sec ( toggle) slower then indication blink." )

Apparently the detection threshold is at least one of your problems. To test this I changed my threshold to zero. And guess what? After the 5 second wait to program the Green LED blinks fast and slow alternatively!! I see now that is what you were trying to tell me!

So, see if you can make your sound sensor work by increasing the threshold. If not you should order the one I have (hope they still have them). Mine really works well.

ismail khopdi
ismail khopdi

Reply 4 years ago

yes sir you understood my problem correctly(alternate rapid and slow blink after pressing the switch for 5sec).
I'm working on it and i also order keyes microphone.
thank you so much from the bottom of my heart .
If I'll get it i will let you know first.


Reply 4 years ago on Introduction

Glad to help. Hope everything else goes well.

It would be interesting to know who I have been talking with. I would like to know what country you are in and how old you are. Also anything else you would like to add. You can look at my profile to learn about me.

ismail khopdi
ismail khopdi

Reply 4 years ago

I m from India. Currently pursuing engg degree in EXTC from mumbai university . i m in 3rd yr
I m 20yrs old.
You are from florida ?!!! My college MHSSCOE team went there for competion, Team Aerosouls participated in the Advance class & Micro Class of SAE Aero Design East 2015, held at Lakeland, Florida, USA, and secured 2nd position in the world for Advance class design and 3rd position in the world for Micro class Design.


Reply 4 years ago on Introduction

Thanks for the info. I looked up EXTC and MHSSCOE to learn the meaning. MHSSCOE certainly did well at the SAE affair. You say that MHSSCOE is/was your college and Mumbai is your university. I assume that means your engineering education is a two step process.

ismail khopdi
ismail khopdi

Reply 4 years ago

EXTC means i m doing Electronics and telecommunication engineering its a 4yr (8 semester) degree course and i completed my 6semesters.
MHSSCOE(M h saboo siddik college of engineering) in which i m studying now .
my college is under the control of university of mumbai (like your country has university of southern California)

ismail khopdi
ismail khopdi

Reply 4 years ago

about to complete my 6th semester

ismail khopdi
ismail khopdi

Reply 4 years ago is my email Id.
can i have yours so that i can share my future projects with you


Reply 4 years ago on Introduction

Thanks for the clarification about your schools.

I sent you a private message with my email address.


Reply 4 years ago on Introduction

The image did not show. Go to


Reply 4 years ago on Introduction

As stated in Step 2 of this Instructable: "Microphone board – Online at DealExtreme 135533 (only $2.80 with free shipping). There is no model number. There is a name ("Keyes") but I don't know if that is the manufacturer. My sensor provides both analog and digital output; I am using analog and creating a detection threshold in software. The sensor has a pot to provide an adjustable threshold for digital output.

Your description of the results of stepping through the sketch is not clear to me. If you want further help, you must answer my questions for at least the two steps I described. Please take time to fully explain what you do and what you see.

ismail khopdi
ismail khopdi

Reply 4 years ago

but sir in programing mode the green led stand still unless i press micro switch to program my knock it goes like this-
1. i power it on
2. green led glow
3. i press micro switch n after 5sec it blink very rapidly(which indicate that to give input)
4. without giving input through mic it blink with freq of 0.5sec ( toggle) slower then indication blink.

then what i did i remove Vcc of mic it (green ) stop blinking then i removed GND of mic it again start blinking (which is wierd)
in my ardunio all the ports have some current o/p as well i/p including analog one
is there is some thing wrg (reverse current should i give mic input A0 via diode)with my ardunio
i copy and pasted ur program same

i will try ur suggestion of giving delay(10sec)

n another que is, is it imp to use microphone same as urs?


Reply 4 years ago on Introduction

Put the delay after the AwaitGoAhead() function in Program mode. Did you get the quick blink signifying entry to Program mode?

If so, put the delay in the GetKnock() function after the BlinkLED() function call (and before the " // Get Subsequent Knocks: " comment. Then (when in Program mode), knock once. Did you get the quick blink?

If so, put the delay just before the "return" command at the end of the GetKnock() function. Knock twice. Did you just get two blinks?

Continue stepping through the sketch like this until you isolate the problem area.