Record Length of Button Push - How?

Thread Starter

mwh624

Joined Nov 6, 2009
28
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.
 

spinnaker

Joined Oct 29, 2009
7,830
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.
 

MMcLaren

Joined Feb 14, 2010
861
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...

Rich (BB code):
  char swnew = 0;               // switch state logic
  char swold = 0;               // switch state latch
  char flags = 0;               // 
  
  int tag[] = { 0,0,0,0,0,0,0,0,0,0 };

  #define recsw flags.1         // rec switch on RA1
  #define runsw flags.2         // run switch on RA2
Rich (BB code):
  while(1)                      //
  { delay_ms(25);               // 25-msec debounce interval
/*
 *  swnew  ___---___---___---___   sample active lo switches
 *  swold  ____---___---___---__   switch state latch
 *  swnew  ___-__-__-__-__-__-__   changes, press or release
 *  swnew  ___-_____-_____-_____   filter out 'release' bits
 *  flags  ___------______------   toggle flag bits for main
 */
    swnew = ~porta;             // sample active lo switches
    swnew ^= swold;             // changes, press or release
    swold ^= swnew;             // update switch state latch
    swnew &= swold;             // filter out 'release' bits
    flags ^= swnew;             // toggle "rec" & "run" flags
/*
 *  record loop
 */
    if(recsw)                   // if "recsw" toggled "on"
    { char ndx = 0;             // reset array index
      int timer = 0;            // reset 25-msec timer
      porta.4 = 0;              // default motor off
      do                        //
      { delay_ms(25);           // 25-msec debounce interval
        swnew = ~porta;         // sample active lo switches
        swnew ^= swold;         // changes, press or release
        swold ^= swnew;         // update switch state latch
        if(swnew.0)             // if new SW0 (RA0) "change"
        { porta.4 ^= 1;         // toggle motor output (RA4)
          tag[ndx++] = timer;   // record interval, bump ndx
        }                       //
        swnew &= swold;         // filter out 'release' bits
        flags ^= swnew;         // refresh "recsw" flag
        timer++;                // increment 25-msec "timer"
      } while((ndx<10) & (recsw));
      porta.4 = 0;              // turn motor off
      recsw = 0;                //
    }                           //
 
Last edited:

Thread Starter

mwh624

Joined Nov 6, 2009
28
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?
 

MMcLaren

Joined Feb 14, 2010
861
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?
That's basically correct. It's a (single dimension) ten element array which you would access using indices of 0 through 9.

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

Am I on the right track?
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.

Rich (BB code):
  while(1)                      //
  { delay_ms(25);               // 25-msec debounce interval
/*
 *  swnew  ___---___---___---___   sample active lo switches
 *  swold  ____---___---___---__   switch state latch
 *  swnew  ___-__-__-__-__-__-__   changes, press or release
 *  swnew  ___-_____-_____-_____   filter out 'release' bits
 *  flags  ___------______------   toggle flag bits for main
 */
    swnew = ~porta;             // sample active lo switches
    swnew ^= swold;             // changes, press or release
    swold ^= swnew;             // update switch state latch
    swnew &= swold;             // filter out 'release' bits
    flags ^= swnew;             // toggle "rec" & "run" flags
/*
 *  record loop
 */
    if(recsw)                   // if "recsw" toggled "on"
    { char ndx = 0;             // reset array index
      int timer = 0;            // reset 25-msec timer
      porta.4 = 0;              // default motor off
      do                        //
      { delay_ms(25);           // 25-msec debounce interval
        swnew = ~porta;         // sample active lo switches
        swnew ^= swold;         // changes, press or release
        swold ^= swnew;         // update switch state latch
        if(swnew.0)             // if new SW0 (RA0) "change"
        { porta.4 ^= 1;         // toggle motor output (RA4)
          tag[ndx++] = timer;   // record interval, bump ndx
        }                       //
        swnew &= swold;         // filter out 'release' bits
        flags ^= swnew;         // refresh "recsw" flag
        timer++;                // increment 25-msec "timer"
      } while((ndx<10) & (recsw));
      porta.4 = 0;              // turn motor off
      recsw = 0;                //
    }                           //
/*
 *  run loop
 */
    if(runsw)                   // if "runsw" toggled "on"
    { char ndx = 0;             // reset array index
      int timer = 0;            // reset 25-msec timer
      porta.4 = 0;              // default motor off
      do                        //
      { delay_ms(25);           // 25-msec debounce interval
        if(tag[ndx] == timer)   // if interval match
        { porta.4 ^= 1;         // toggle motor output (RA4)
          ndx++;                // increment index
        }                       //
        timer++;                // increment 25-msec "timer"
        swnew = ~porta;         // sample active lo switches
        swnew ^= swold;         // changes, press or release
        swold ^= swnew;         // update switch state latch
        swnew &= swold;         // filter out 'release' bits
        flags ^= swnew;         // refresh "runsw" flag
      } while((ndx<10) & (runsw));
      porta.4 = 0;              // turn motor off
      runsw = 0;                //
    }                           //
  }                             //
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

Joined Jul 5, 2008
2,072
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
 
Top