Record Length of Button Push - How?

Discussion in 'Embedded Systems and Microcontrollers' started by mwh624, Feb 16, 2012.

  1. mwh624

    Thread Starter New Member

    Nov 6, 2009
    28
    0
    Trying to figure out how I'd go about doing this. I am going to be using a pic12f675 using HI-TECH C. I am trying to create a program that will record the sequence of a single push button and then output that sequence to run a dc motor where the motor will run when the button was pushed in and stop when the button was not engaged. There will be up to 5 ON-OFF cycles with the ON portions being 1-10 seconds and the OFF portions being 1-10 seconds.

    The problem is I am not 100% sure how to record the length of time the button is pushed in.

    Does anyone know of any examples I can look at?

    Thanks for your input.
     
  2. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,866
    988
    Check your data sheet. Some of your digital input pins should have an interrupt on change. That interrupt could start a timer. The timer would have an interrupt that when 10 seconds is reached it will turn your device on / off.
     
  3. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,866
    988
    I downloaded that datasheet. Look at TMR0 Overflow Interrupt, GP2/INT INTERRUPT and GPIO Change Interrupts.
     
  4. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    off the top of my head (using free/lite BoostC compiler)... after pressing the "rec" switch you'll be in the record loop until you press the "rec" switch again or until you fill the ten element array... using 25-msec intervals and an integer array allows recording on/off push button intervals up to 27 minutes in duration... untested code excerpts below...

    Code ( (Unknown Language)):
    1.   char swnew = 0;               // switch state logic
    2.   char swold = 0;               // switch state latch
    3.   char flags = 0;               //
    4.  
    5.   int tag[] = { 0,0,0,0,0,0,0,0,0,0 };
    6.  
    7.   #define recsw flags.1         // rec switch on RA1
    8.   #define runsw flags.2         // run switch on RA2
    9.  
    Code ( (Unknown Language)):
    1.  
    2.  
    3.   while(1)                      //
    4.   { delay_ms(25);               // 25-msec debounce interval
    5. /*
    6.  *  swnew  ___---___---___---___   sample active lo switches
    7.  *  swold  ____---___---___---__   switch state latch
    8.  *  swnew  ___-__-__-__-__-__-__   changes, press or release
    9.  *  swnew  ___-_____-_____-_____   filter out 'release' bits
    10.  *  flags  ___------______------   toggle flag bits for main
    11.  */
    12.     swnew = ~porta;             // sample active lo switches
    13.     swnew ^= swold;             // changes, press or release
    14.     swold ^= swnew;             // update switch state latch
    15.     swnew &= swold;             // filter out 'release' bits
    16.     flags ^= swnew;             // toggle "rec" & "run" flags
    17. /*
    18.  *  record loop
    19.  */
    20.     if(recsw)                   // if "recsw" toggled "on"
    21.     { char ndx = 0;             // reset array index
    22.       int timer = 0;            // reset 25-msec timer
    23.       porta.4 = 0;              // default motor off
    24.       do                        //
    25.       { delay_ms(25);           // 25-msec debounce interval
    26.         swnew = ~porta;         // sample active lo switches
    27.         swnew ^= swold;         // changes, press or release
    28.         swold ^= swnew;         // update switch state latch
    29.         if(swnew.0)             // if new SW0 (RA0) "change"
    30.         { porta.4 ^= 1;         // toggle motor output (RA4)
    31.           tag[ndx++] = timer;   // record interval, bump ndx
    32.         }                       //
    33.         swnew &= swold;         // filter out 'release' bits
    34.         flags ^= swnew;         // refresh "recsw" flag
    35.         timer++;                // increment 25-msec "timer"
    36.       } while((ndx<10) & (recsw));
    37.       porta.4 = 0;              // turn motor off
    38.       recsw = 0;                //
    39.     }                           //
    40.  
     
    Last edited: Feb 18, 2012
    mwh624 and Eric007 like this.
  5. mwh624

    Thread Starter New Member

    Nov 6, 2009
    28
    0
    MMcLaren,
    Many thanks. Just want to make sure I understand the overall concept of your code.

    Tag, a 1 X 10 matrix holds the on and off durations with columns 1,3,5,7 and 9 being ON times and columns 2,4,6,8 and 10 being OFF times?

    timer is the number of 25-msec blocks of time for an ON or OFF segment.

    Am I on the right track?
     
  6. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    That's basically correct. It's a (single dimension) ten element array which you would access using indices of 0 through 9.

    Yes, that's correct.

    Also worth mentioning, if you haven't figured it out already, is the use of a switch state latch and parallel switch state logic to detect switch state changes. Using an exclusive-or instruction instead or an 'or' instruction on the flag bits, after filtering out the 'release' bits, allows your "rec" and "run" push button switches to behave like toggle switches (push to toggle a flag from on-to-off or from off-to-on).

    Your "run" loop would use a similar 25-msec loop time to "play back" the motor on/off sequences at the same intervals that you recorded in the tag[] array.

    Code ( (Unknown Language)):
    1.  
    2.   while(1)                      //
    3.   { delay_ms(25);               // 25-msec debounce interval
    4. /*
    5.  *  swnew  ___---___---___---___   sample active lo switches
    6.  *  swold  ____---___---___---__   switch state latch
    7.  *  swnew  ___-__-__-__-__-__-__   changes, press or release
    8.  *  swnew  ___-_____-_____-_____   filter out 'release' bits
    9.  *  flags  ___------______------   toggle flag bits for main
    10.  */
    11.     swnew = ~porta;             // sample active lo switches
    12.     swnew ^= swold;             // changes, press or release
    13.     swold ^= swnew;             // update switch state latch
    14.     swnew &= swold;             // filter out 'release' bits
    15.     flags ^= swnew;             // toggle "rec" & "run" flags
    16. /*
    17.  *  record loop
    18.  */
    19.     if(recsw)                   // if "recsw" toggled "on"
    20.     { char ndx = 0;             // reset array index
    21.       int timer = 0;            // reset 25-msec timer
    22.       porta.4 = 0;              // default motor off
    23.       do                        //
    24.       { delay_ms(25);           // 25-msec debounce interval
    25.         swnew = ~porta;         // sample active lo switches
    26.         swnew ^= swold;         // changes, press or release
    27.         swold ^= swnew;         // update switch state latch
    28.         if(swnew.0)             // if new SW0 (RA0) "change"
    29.         { porta.4 ^= 1;         // toggle motor output (RA4)
    30.           tag[ndx++] = timer;   // record interval, bump ndx
    31.         }                       //
    32.         swnew &= swold;         // filter out 'release' bits
    33.         flags ^= swnew;         // refresh "recsw" flag
    34.         timer++;                // increment 25-msec "timer"
    35.       } while((ndx<10) & (recsw));
    36.       porta.4 = 0;              // turn motor off
    37.       recsw = 0;                //
    38.     }                           //
    39. /*
    40.  *  run loop
    41.  */
    42.     if(runsw)                   // if "runsw" toggled "on"
    43.     { char ndx = 0;             // reset array index
    44.       int timer = 0;            // reset 25-msec timer
    45.       porta.4 = 0;              // default motor off
    46.       do                        //
    47.       { delay_ms(25);           // 25-msec debounce interval
    48.         if(tag[ndx] == timer)   // if interval match
    49.         { porta.4 ^= 1;         // toggle motor output (RA4)
    50.           ndx++;                // increment index
    51.         }                       //
    52.         timer++;                // increment 25-msec "timer"
    53.         swnew = ~porta;         // sample active lo switches
    54.         swnew ^= swold;         // changes, press or release
    55.         swold ^= swnew;         // update switch state latch
    56.         swnew &= swold;         // filter out 'release' bits
    57.         flags ^= swnew;         // refresh "runsw" flag
    58.       } while((ndx<10) & (runsw));
    59.       porta.4 = 0;              // turn motor off
    60.       runsw = 0;                //
    61.     }                           //
    62.   }                             //
    63.  
    I hope this example is similar enough to what you're trying to do to be helpful. There are many many different ways to come up with a similar solution.

    Good luck on your project...

    Cheerful regards, Mike
     
    be80be likes this.
  7. be80be

    Senior Member

    Jul 5, 2008
    431
    57
    There one thing that the OP needs to think about the counting can only begin after the switch is latched and no more bounce is found. And the bounce of a button switch can be short uS to a mS long even with a button switch of the same type. I read report where over 400 types of switches where tested and the bounce times was unreal. Even with the same kind of buttons.

    That's why when we use the tv remote it some times jumps a channel lol

    Oh and Mike that is a great piece of code
     
Loading...