Pic16 interrupt on change...

Discussion in 'Embedded Systems and Microcontrollers' started by dtv, Jan 25, 2015.

  1. dtv

    Thread Starter New Member

    Jan 25, 2015
    3
    0
    Hi. I have a project which I will need to detect both high and low changes. Furthermore, I will need to detect the length of time which the button is held high or low; i.e. if button is pressed and hold within 2 seconds do task1; else if button is press and hold for more than 2 seconds do task2.
    I have tried using PIC16 interrupt on change and set it up to detect both high and low edge change. This gave me intermittent detection result.

    However, if use interrupt on change only on HI or LO detect then how can I detect the other edge change?

    The challenge for me here is to do the proper edge detection. I can use a simple delay or Timer roll-over to debounce. Once I am certain of the "edge", the task1 or task2 is simple.

    Please advise.
    Thanks.
     
  2. MrChips

    Moderator

    Oct 2, 2009
    12,429
    3,360
    Firstly, you have to tell us which PIC you are using (full part number) and which I/O pin you are planning on using for the push button.
    Not all input pins have Schmitt trigger inputs.
     
  3. dtv

    Thread Starter New Member

    Jan 25, 2015
    3
    0
    I am using the PIC16LF1708-I/ML (20 pin QFN), and interrupt on change is an active low through internal weak pullup on pin RC4.

    I have tried

    void IOC_Init()
    {
    INTCONbits.IOCIE = 1;
    IOCCPbits.IOCCP4 = 1;
    IOCCPbits.IOCCN4 = 1;
    }
    When I ran this by using a simple LED as feedback, at some point, the LED appeared to have reversed its polarity. When the above code was shared with other programmers, this was viewed as an absolute "no, no"...to do both HI and LO edge detect at the same time.

    Please advise.
     
    Last edited: Jan 25, 2015
  4. joeyd999

    AAC Fanatic!

    Jun 6, 2011
    2,675
    2,723
    IOC is really the wrong way to go about it. Here is one of my switch processing functions.
     
  5. John P

    AAC Fanatic!

    Oct 14, 2008
    1,632
    224
    Assembly language, ain't gonna read that.

    But Joey is right: an interrupt-on-change is a really bad way to read a pushbutton. It would be better to read the button in a timer interrupt, where the interval between tests is enough to get past the bouncing time of the switch contacts, maybe as slow as 50msec. Then all you have to do is count the number of consecutive times the switch is found to be pressed. When the switch is found NOT to be pressed, you look at the count of times-pressed, and if it's nonzero, make the determination of which action to take, and before ending the routine, set the count to zero.
     
  6. dtv

    Thread Starter New Member

    Jan 25, 2015
    3
    0
    Hi all. I am sorry for not being more clear.
    The requirement is that the system goes to sleep if no button is pressed. To wake the system out of sleep, interrupt on change is used to accomplish this. However, once an "edge" is detected, debouncing is done per Timer0; i.e. every time a bouncy button edge is detected, the IOC isr fires and Timer0 counter gets reset to zero. Once the button has settled, the IOC isr will no longer gets fired thereby allowing the (8-bit) Timer0 counter to count from 0xFF to 0x00...to cause a Timer0 interrupt. My Timer0 interrupt is set to timed-out at 32mS. Summary: The interrupt on change ISR is not used for debouncing but only for edge detection. The actual debouncing is done in Timer0. Back to my original original issue. Seems like when I did this (I think this might be the problem):

    code:
    IOCCPbits.IOCCP4 = 1;
    IOCCPbits.IOCCN4 = 1;

    ...for IOC interrupt to detect both Hi to LO and Lo to Hi edges. At some intermittent time, the edge gets detected wrong. I know since a Hi to LO turns on a test LED and a LO to Hi turns OFF the LED. At some undetermined time, I noticed that a Hi to LO edge turns the LED OFF and the Lo to Hi edge (now) turned the LED ON. This is the opposite.

    One more thing. This only occurs if I press as fast as I humanly can. However, if I press at a rate of about 3 presses per second or slower, no error occurs.

    Please advise. Thank you.
     
    Last edited: Jan 25, 2015
Loading...