author
1Instructables11,966Views66CommentsOrlando area, Florida, USA (Disney World, etc !)Joined September 16th, 2011
Retired electro-optical engineer. Education:M.S. in Physics. Married 56 years.(same woman!)

Achievements

10K+ Views Earned a bronze medal
  • dick55 commented on awall99's instructable DIY Anemometer With Hall-Sensor5 weeks ago
    DIY Anemometer With Hall-Sensor

    Wish you had completed the project, with code and results.

    View Instructable »
  • dick55 commented on cfleis1's instructable Build a Hover Craft in Less Than an Hour!6 weeks ago
    Build a Hover Craft in Less Than an Hour!

    What was the maximum weight successfully tested?

    View Instructable »
  • dick55 commented on 19aleonardi's instructable Robotic Arm Controlled by Glove6 weeks ago
    Robotic Arm Controlled by Glove

    Almost $100 for the flex sensors!

    View Instructable »
  • dick55 commented on Poly3DPrinter's instructable Poly 3D Printer6 weeks ago
  • dick55 commented on Core3D's instructable 3D Printer Cantilever 2.0 C3Dt/c2 months ago
    3D Printer Cantilever 2.0 C3Dt/c

    Bravo! Beautiful design and implementation. Actually, a work of art. Can't imagine the man-hours that went into this, especially considering the numerous prototypes you mention.

    View Instructable »
  • dick55 commented on Creativity Buzz's instructable Homework Writing Machine5 months ago
    Homework Writing Machine

    GREAT Instructable! Great design. You have made it so easy to implement, especially using the excellent video. At first I thought it was going to involve a 3D printer, but then you did it with flat cutouts and glue! Your liberal and quick use of super glue was very instructive. The resolution of this device is impressive! I have definitely voted for you in the contest.

    View Instructable »
  • dick55 commented on dick55's instructable Arduino Knock-Knock Treasure Box5 months ago
    Arduino Knock-Knock Treasure Box

    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 --------------------------//---Libraries-----#include <Servo.h>#include <EEPROM.h>//-----Variables, Typed and Defined-----/* int: Integer, 8 bits, 0-255unsigned short: Integer, 16 bits, 0-65,535float: 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 analo...

    see more »

    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 --------------------------//---Libraries-----#include <Servo.h>#include <EEPROM.h>//-----Variables, Typed and Defined-----/* int: Integer, 8 bits, 0-255unsigned short: Integer, 16 bits, 0-65,535float: 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 counterint BlinkTime = 100;    //LED on/off times, msecint BlinkNumber = 15;   //Number of times LED blinks when flashingint 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 A1Servo 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 pushbuttonchar BatteryMonitor = A1; //Analog input port for voltage dividerint BlueLED = 8;          //Digital output port for Blue LED 5V driveint RedLED = 9;           //Digital output port for Red LED 5V driveint GreenLED = 10;        //Digital output port for Green LED 5V driveint ServoLock = 11;       //Digital output port for servo commandint LidSwitch = 12;       //Digital Input port for lid Open/Closed (HIGH/LOW) stateint LEDPort;              //Sets to GreenLED in Program Mode and RedLED in Operate Mode//----------------------SetUp---------------------------/* 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(GreenLED,OUTPUT);  pinMode(BlueLED,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() {  ClosureCheck:   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; }    }    /*Delete:    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),a);    EEPROM.write((2*N)+1,b); }}//----------------------void GetSecretKnock() {   SecretKnockNumber = EEPROM.read(0);  for(N = 1; N <= SecretKnockNumber; N++) {    int a = EEPROM.read(2*N);    int b = EEPROM.read((2*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    digitalWrite(LEDPort,LOW);    delay(BlinkTime);    digitalWrite(LEDPort,HIGH);    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);      delay(100);      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      ProgramMode:     //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 */   ReadyToProgram:     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;  OperateMode:   //Initiate settings  Latch.write(Lock);              //Lock servo  digitalWrite(GreenLED,LOW);     //Green LED off  digitalWrite(RedLED, HIGH);     //Red LED on  LEDPort = RedLED;              StartKnocking:  GetKnock();                     //See function above  if (ErrorFlag == 1) {    FlashLED();    goto StartKnocking; }         //Can then enter a different knock  CompareKnocks();                //See function above  if (ErrorFlag == 1) {    FlashLED();    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.

    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 the Arduino IDE. This sketch is a modified version of KnockKnockTreasureBox_9, substituting a pushbutton for the microphone board, and showing code deleted and code added. //--------------------------- PushbuttonTreasureBox_9 -------------------------- //---Libraries----- #include #include //-----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 am...

    see more »

    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 the Arduino IDE. This sketch is a modified version of KnockKnockTreasureBox_9, substituting a pushbutton for the microphone board, and showing code deleted and code added. //--------------------------- PushbuttonTreasureBox_9 -------------------------- //---Libraries----- #include #include //-----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 //----------------------SetUp--------------------------- /* 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(GreenLED,OUTPUT); pinMode(BlueLED,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() { ClosureCheck: 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; } } /*Delete: 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),a); EEPROM.write((2*N)+1,b); } } //---------------------- void GetSecretKnock() { SecretKnockNumber = EEPROM.read(0); for(N = 1; N <= SecretKnockNumber; N++) { int a = EEPROM.read(2*N); int b = EEPROM.read((2*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 digitalWrite(LEDPort,LOW); delay(BlinkTime); digitalWrite(LEDPort,HIGH); 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); delay(100); 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 ProgramMode: //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 */ ReadyToProgram: 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; OperateMode: //Initiate settings Latch.write(Lock); //Lock servo digitalWrite(GreenLED,LOW); //Green LED off digitalWrite(RedLED, HIGH); //Red LED on LEDPort = RedLED; StartKnocking: GetKnock(); //See function above if (ErrorFlag == 1) { FlashLED(); goto StartKnocking; } //Can then enter a different knock CompareKnocks(); //See function above if (ErrorFlag == 1) { FlashLED(); 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, irrespective 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 loaded this sketch in my Box and have not implemented D7 switching. (However, if I can find the time and get motivated, I will give it a try.

    View Instructable »
  • dick55 commented on Sayandeep Nayak's instructable How to Program an Arduino on Android9 months ago
    How to Program an Arduino on Android

    Why would anybody want to use an Android device to load Arduino code?Like you, I would think that anybody interested in Arduino would have a laptop or desktop computer.

    View Instructable »
  • dick55 commented on Hiyadudez's instructable Hidden Chair Compartment9 months ago
    Hidden Chair Compartment

    User a very strong magnet I also like the velcro idea below.

    View Instructable »
  • dick55 commented on MarcoT87's instructable Portable Electrocardiogram9 months ago
    Portable Electrocardiogram

    An electro-cardiogram requires waveform display and the knowledge to interpret it.

    View Instructable »
  • dick55 commented on JoseBarreiros's instructable Raspberry Pi Video Streaming1 year ago
    Raspberry Pi Video Streaming

    I just came across this Instructable because I am looking at ways to implement web streaming. The procedure looks pretty straight forward.But I was struck by the fact that neither the author nor other Pi fanatics had responded to the questions asked. As one who has asked help from a number of forums, and usually received much appreciated help, I am sensitive to this subject and can't help but find fault here.Wish I could help, but i haven't even sampled the Pi yet :-)

    View Instructable »
  • Build a Raspberry Pi-Powered Amazon Echo

    Yes! A beautiful parts list. And an excellent Instructable. I give it an A+.

    View Instructable »
  • "With U Smart Sole" DIY GPS Embedded Smart Shoe sole #MITBetterWorld

    Impressive project.But will probably have false alarms when accidentally crossing feet.Can eliminate this problem by requiring two fairly quick crossings. Give only a vibration warning at first crossing to alert the user.

    View Instructable »
  • dick55 commented on KJMagnetics's instructable World's Simplest Electric Train1 year ago
    World's Simplest Electric Train

    DA6 magnets really stick together! I couldn't slip one off the other. So I made a simple tool to make it easier. I drilled a 5/8 inch hole, slightly less than 3/8 inch deep, centered in the long side of a piece of 2x4 wood. This supports one magnet while pushing firmly down on the other and makes it easy to separate it at the bottom of the slide.I also verified that it is easy for them to give you a bloody pinch if you are not very careful !

    I've been thinking about using a table saw to cut a length-wise slit in "1/2 inch" PVC pipe, then using steel spring wire on the magnets to maintain contact with a coil wound around the outside of the pipe. The inner diameter of 1/2 inch (normal-pressure Schedule 40) PVC pipe averages 0.622 inch, which is almost exactly the stated diameter of the 5/8 (0.625) inch DA6 magnets. Actually, my magnets measure less than 5/8 inch diameter. I took my battery/magnet assembly and dropped it into 1/2 inch pipe and it passed easily through a 3 foot length. I haven't researched conductive spring wire (or other ferrous-type material) which should lightly drag on the coil and contact more than one coil at a time.Minimum wall thickness of the pipe is 0.109 inch, so the coil diameter is large...

    see more »

    I've been thinking about using a table saw to cut a length-wise slit in "1/2 inch" PVC pipe, then using steel spring wire on the magnets to maintain contact with a coil wound around the outside of the pipe. The inner diameter of 1/2 inch (normal-pressure Schedule 40) PVC pipe averages 0.622 inch, which is almost exactly the stated diameter of the 5/8 (0.625) inch DA6 magnets. Actually, my magnets measure less than 5/8 inch diameter. I took my battery/magnet assembly and dropped it into 1/2 inch pipe and it passed easily through a 3 foot length. I haven't researched conductive spring wire (or other ferrous-type material) which should lightly drag on the coil and contact more than one coil at a time.Minimum wall thickness of the pipe is 0.109 inch, so the coil diameter is larger than one wound on a 5/8 inch dowel. However, the magnetic field strength at coil center is not a function of diameter; it only depends on current and number of turns. Also, the PVC wall material should not affect the field.

    View Instructable »
  • dick55 commented on KJMagnetics's instructable World's Simplest Electric Train1 year ago
    World's Simplest Electric Train

    Actually this is a self-powered solenoid.

    View Instructable »
  • dick55 commented on perrytsao's instructable Fly a mini-drone with your computer!2 years ago
    Fly a mini-drone with your computer!

    Impressive project. There is a lot to learn here: using OpenCV2 to track the drone with camera input to a PC; communicating with the drone's receiver using a compatible transmitter and understanding the command format; and closed loop control dynamics. Not a simple undertaking.

    View Instructable »
  • Multi-DIY Humidity Sensor + Irrigating System

    For a moisture sensor I used thin copper tubes available in 12" lengths at Ace Hardware. Attaching wire is easy; just insert bare wire in end of tube and hammer shut. I used mine buried in the lawn to control a sprinkler system. I applied voltage only when making a measurement. Keeping the current flowing continuously can speed up corrosion.

    View Instructable »
  • dick55 commented on AlexGyver's instructable DIY vacuum chamber for experiments2 years ago
    DIY vacuum chamber for experiments

    A really nice Instructable!Will save this for future fun.

    View Instructable »
  • dick55 commented on DrewPaulDesigns's instructable Free Energy from Thin Air!2 years ago
    Free Energy from Thin Air!

    You can drive a speaker with an RF-powered crystal set:http://www.rfcafe.com/references/popular-electronics-high-power-crystal-set-august-1960-popular-electronics.htmYou can add an RF-powered amplifier:www.bentongue.com/xtalset/25AmpXS/25AmpXS.html

    View Instructable »
  • dick55 commented on Eric Brouwer's instructable Arduino UNO nRF24L01+ Shield2 years ago
    Arduino UNO nRF24L01+ Shield

    Nice Instructable and application. I'm sure your friend appreciates his "robot."It is interesting that the existing wheelchair controller had an interface that worked with servo-type commands.

    View Instructable »