Long / short press button...but reading ADC


Closed Thread
Results 1 to 38 of 38
  1. #1
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    574

    Default Long / short press button...but reading ADC

    Hi !
    I need again for your help ! I tried to build one simple schematic ; I used 12F675 for reading ADC. Works fine.
    But ... I have no clue how to "find" if the button is pressed short (let's say under 1 sec) or long ( > 1 sec) ...for having different commands.
    Can someone point me into the right direction ?
    Thanks in advance ! Have a nice day and weekend !

    Code:
    @ __config _XT_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BODEN_ON 
    
    DEFINE OSC  4
    
    CMCON    = 7
    TRISIO   = %00001001
    INTCON   = 0 
    IOC      = 0
    GPIO     = 0
    ANSEL    = %00110001
    ADCON0.7 = 1
    
    DataW    var WORD		' Just a WORD Temporary working variable
    
    Main:
    ADCON0 = %10000001
    	Pauseus 50		' Wait for channel to setup
    	ADCON0.1 = 1		' Start conversion
    	While ADCON0.1=1:Wend	' Wait for conversion
    DataW.HighByte=ADRESH		' Read variable from ADC and save
    DataW.LowByte=ADRESL
    
    If DataW > 0 AND DataW < 1023 then GPIO.2 = 1
    Pause 1000
    GPIO.2 = 0
    Goto Main
    Attached Images Attached Images  

  2. #2
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    Fratello, fiest I would change the value of R4 to say... 100 Ohms. That way you are giving the port something less than 1/2 vcc to be seen as a low. Next I would on the trailing edge of the button press, start a loop counter and count some number of time the button is in the down state. When the button is released check the time against a constant of your choosing and see if it longer or shorter than that.
    Dave Purola,
    N8NTA
    EN82fn

  3. #3
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    don't see this working
    won't your adc reading always be > 0 and it can never be higher than 1023

    If DataW > 0 AND DataW < 1023 then GPIO.2 = 1

    as dave says something like this

    Code:
    @ __config _XT_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BODEN_ON 
    DEFINE OSC  4
    long_press_threshold con 20   ;2 sec
    press_threshold      con 10   ;1 sec
    trigger_thresshold   con 600  ; adc reading must fall below this to countr as pressed
    CMCON    = 7
    TRISIO   = %00001001
    INTCON   = 0 
    IOC      = 0
    GPIO     = 0
    ANSEL    = %00110001
    ADCON0.7 = 1
    DataW    var WORD  ' Just a WORD Temporary working variable
    b_cnt    var byte
    b_ACT    var byte      ;0 not pressed ,1 pressed for 1 sec ,2 pressed for 2 sec
    clear
    Main:
        gosub chk_sw
        Pause 100
        if b_ACT then
            if b_ACT ==1 then
               GPIO.2 = 0
            else
                GPIO.2 = 1
            endif
            b_ACT=0
            b_cnt=0
        endif
    Goto Main
    
    chk_sw:
    ADCON0 = %10000001 ;ch0
    Pauseus 50  ' Wait for channel to setup
    ADCON0.1 = 1  ' Start conversion
    While ADCON0.1=1:Wend ' Wait for conversion
    DataW.HighByte=ADRESH  ' Read variable from ADC and save
    DataW.LowByte=ADRESL
       if DataW < trigger_thresshold  then
          b_cnt=b_cnt+1   ;if btn is active add to count
          IF  b_cnt > long_press_threshold THEN b_ACT= 2  
       ELSE    ;button released
            if b_cnt > press_threshold THEN   ;press_threshold met
                IF  b_cnt > long_press_threshold THEN
                   b_ACT= 2           ;LONG press >2 SEC
                ELSE
                   b_ACT= 1
                ENDIF
            ELSE       ;press_threshold not met
            b_ACT= 0
            b_cnt=0    ;reset count
            ENDIF
       endif
    return
    Last edited by richard; - 1st April 2016 at 13:17. Reason: timing

  4. #4
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    574


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    Thank you both for such fast reply !
    Very good info !!! I will test and search for help again if something going wrong...

    LE : If DataW > 0 AND DataW < 1023 then GPIO.2 = 1
    DataW, with R3=R4=1k, it's "512", don't ?

  5. #5
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    I set the
    trigger_thresshold con 600 ; adc reading must fall below this to countr as pressed
    to 600 to allow a little safety margin
    ooops
    note I edited my post to fix timing Pause 100 instead of 50 but I forgot to press the save button till now sorry

  6. #6
    Join Date
    Aug 2011
    Posts
    408


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    I suppose there's some good reason for using the ADC to detect the keypress vs just looking for a digital high/low on the pin?

  7. #7
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    574


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    Yes, I NEED to use ADC instead "usual" button(s).

  8. #8
    Join Date
    Jan 2005
    Location
    France
    Posts
    97


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    just my two cents ..
    remove the Quartz and capacitors
    an use the internal oscillator if you don't need a precison time ..
    I love to use those small 12F675 ..
    Take care at programmation time you have datas (2 bytes) at the end of the eprom.
    read it before programming
    Francois

  9. #9


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    I have used 'for loop' to test for switch press duration as such....you would use your adc reading instead of GPIO check

    Code:
    if GPIO.1= 1 then start	       ' gpio is 1 for no press, 0 for pressed....or do 1 adc read and check ..about 100 microseconds
    
    FOR B5= 1 TO 100        '1 SECOND FOR TIMER
     PAUSE 10
     if GPIO.1= 1 then start	'or do 1 adc read and check ..about 100 microseconds
     NEXT B5
     
     '''' switch still pressed ...continue to 2 second press check
     
     FOR B5 = 1 TO 100       '2 SECONDS FOR 6 HR
     PAUSE 10
     if GPIO.1=1 then TIMER     'press is greater than 1 second in this loop... up to 2 second
     NEXT B5
      
    continuing here if switch still pressed !!!!

  10. #10
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    574


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    Thank you all for the support !

  11. #11
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    574


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    Code from Mr.Richard (Thanks !), see post #3, works just fine.
    But now I'm stuck again ...
    For accurate reading of ADC I use bubble-sort algoritm, how it's presented on this forum.
    Code:
    Main: 
    nr=1	
    for nr = 1 to 2
    For CounterA=0 to 8
    ADCON0 = %10000001
    		Pauseus 50			' Wait for channel to setup
    	        ADCON0.1 = 1			' Start conversion
    		While ADCON0.1=1:Wend		' Wait for conversion
    		DataW.HighByte=ADRESH		' Read variable from ADC and save
    		DataW.LowByte=ADRESL
    		RawData(CounterA)=DataW
    Next CounterA
    CounterA=0 
    Gosub Getsort
    next nr
    if adca=adcb then gosub efectuez		
    goto main
    
    
                             
    ;============================================================================
    GetSort:
    	If RawData(CounterA+1) < RawData(CounterA) then
    		DataW=RawData(CounterA)
    		RawData(CounterA)=RawData(CounterA+1)
    		RawData(CounterA+1)=DataW
    		If CounterA>0 then CounterA=CounterA-2
    		endif
    	CounterA=CounterA+1
    	If CounterA<9 then goto GetSort
    
    
    	DataW=0
    	For CounterA=3 to 6 
    		DataW=DataW+RawData(CounterA)
    		Next CounterA
    	ADCValue=DataW>>2
    if nr = 1 then 
    adca = adcvalue
    else
    adcb = adcvalue		
    endif
    Return
    ;============================================================================
    The code works amazing, almost no error ... for different value of ADC, I can do different tasks.
    BUT ... I can not figure out how to use the procedure of short/long press in this code... since even a short press makes the code to jump to "efectuez" (where I have different commands defined).
    I tried to use the same procedure as in post #3 ; I tried to put it into different places of the code, but without result ! Whatever I do, it's like pressing the button for a short time.

  12. #12
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    can you explain what you are trying to achieve , and maybe another schematic .
    at this stage I can't see how an array sorting routine is useful for detecting button presses long or short .
    post the code for what have you tried

  13. #13
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    574


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    In the schematic posted in #1, R4 have different values ... for different commands.
    The code above is for reading accurate ADC ; works very, very fine.
    Tried to read short/long press of button ... but no succes. No matter what I do, I always have same result, as pressed "short".
    Sorry for my poor english, I use g...translate for many words.

  14. #14
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    i'm assuming you have multiple buttons each with a different R4 so that in this example ---- with b1 pressed adc read is < 600,b2 pressed adc read is < 500,b3 pressed adc read is < 400.

    this pretty much the same as my first example but it keeps track of which button of the three is pressed and for how long.

    untested
    Code:
    @ __config _XT_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BODEN_ON 
    DEFINE OSC  4
    long_press_threshold con 40   ;2 sec
    press_threshold      con 8   ;.4 sec
    trigger_thresshold_1   con 600  ; adc reading must fall below this to count  as a pressed button 1
    trigger_thresshold_2   con 500  ; adc reading pressed button 2
    trigger_thresshold_3   con 400  ; adc reading pressed button 3
    CMCON    = 7
    TRISIO   = %00001001
    INTCON   = 0 
    IOC      = 0
    GPIO     = 0
    ANSEL    = %00110001
    ADCON0.7 = 1
    last_b_level  var byte      ;   last button 
    b_level       var byte      ;   which button
    DataW         var WORD  '  WORD Temporary working variable
    b_cnt         var byte
    b_ACT         var byte      ;0 not pressed ,1 pressed for 1 sec ,2 pressed for 2 sec
    clear
    Main:
        gosub chk_sw
        Pause 50
        if b_ACT then
        if b_level==2 then        ;button 2
            if b_ACT ==1 then
               GPIO.2 = 0
            else
                GPIO.2 = 1
            endif
            b_ACT=0
            b_cnt=0
            b_level=0
        endif
        endif
    Goto Main    
        
    
    chk_sw:
    ADCON0 = %10000001 ;ch0
    Pauseus 50  ' Wait for channel to setup
    ADCON0.1 = 1  ' Start conversion
    While ADCON0.1=1:Wend ' Wait for conversion
    DataW.HighByte=ADRESH  ' Read variable from ADC and save
    DataW.LowByte=ADRESL
       if DataW <  trigger_thresshold_1     then
          b_level =1
       elseif  DataW < trigger_thresshold_2 then
          b_level =2
       else  DataW < trigger_thresshold_3   then
          b_level =3
       endif
       if   b_cnt==0 then  last_b_level= b_level  ;first press begin
       if b_level= last_b_level then      ; same  btn is active add to count
          
          b_cnt=b_cnt+1   ;if btn is active add to count
          IF  b_cnt > long_press_threshold THEN b_ACT= 2  
       ELSE    ;button released
            if b_cnt > press_threshold THEN   ;press_threshold met
                IF  b_cnt > long_press_threshold THEN
                   b_ACT= 2           ;LONG press >2 SEC
                ELSE
                   b_ACT= 1
                ENDIF
            ELSE       ;press_threshold not met
            b_ACT= 0
            b_cnt=0    ;reset count
            b_level=0
            ENDIF
       endif
    return

  15. #15
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    574


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    Thanks again for support !
    Unfortunately I can not solved this ... because "For accurate reading of ADC I use bubble-sort algoritm, how it's presented on this forum."
    No matter what I tried ; it's available ONLY short press.
    Regards !

  16. #16
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    What if you start a timer?

    DT's routines could tell you how long a button is pressed.

    Robert
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

  17. #17
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    574


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    Thanks !
    I thought about this ... Should I use this ?
    I don't think I have "space" ...

  18. #18
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    can you explain what you are trying to achieve ?
    do you in fact have multiple buttons each with a different R4 ?
    did you try my second example ? is it even relevant if not what needs to happen differently ?

    at this stage I still can't see how an array sorting routine is in any way useful for detecting button presses long or short .
    why not post the code for what have you tried

    dt_elapsed will not run on a12f675

  19. #19
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    Fratello,

    I would suggest downloading and looking at the original for 18F PICs here:

    http://www.picbasic.co.uk/forum/show...271#post130271

    Robert
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

  20. #20
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    574


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    Tried hard to solve this problem, using a timer ... but without succes .
    Any advice will be very appreciated !


    Code:
    @ __config _XT_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BODEN_ON 
    
    DEFINE OSC  4
    
    CMCON    = 7
    TRISIO   = %00001011
    INTCON   = 0 
    IOC      = 0
    GPIO     = 0
    ANSEL    = %00110001
    ADCON0.7 = 1
    
    nr        var word
    adca 	  var word
    adcb	  var word
    
    ADCValue  var WORD		' Final ADC Result
    CounterA  var BYTE		' Just a BYTE Temporary working variable
    DataW     var WORD		' Just a WORD Temporary working variable
    RawData   var word [10]		' Array holding ADC Result
    TIP_press VAR BIT
    
    j  VAR word
    
    GPIO.2 = 0
    GIE VAR INTCON.7
    GPIE VAR INTCON.3
    GPIF VAR INTCON.0
    Timer1  var word EXT :@Timer1 = TMR1L
    TMR1ON  VAR T1CON.0
    TMR1IF  VAR PIR1.0
    LONGPRESS   VAR BIT
    T1CON =  %00110100
    T1COUNT VAR BYTE
    GIE =0
    GPIE=0
    IOC.0 = 1
    ok var bit
    
    ;============================================================================
    Main: 
    ok=0
    tip_press=0
    TIMER1 =3037
    T1COUNT=0
    LONGPRESS=0
    nr=1
    
    ADCON0 = %10000001
    		Pauseus 50			
    	        ADCON0.1 = 1			
    		While ADCON0.1=1:Wend		
    		DataW.HighByte=ADRESH		
    		DataW.LowByte=ADRESL
    
    	if dataw < 631 then
        		TMR1ON=1
        		pause 1
    
    	    	WHILE dataw < 631
        	    	T1COUNT=T1COUNT + 1
                	CALL CHECK
                	WEND
    
        		IF LONGPRESS = 1 THEN
        		TIP_press = 1
        		ELSE
        		TIP_press = 0
        		ENDIF
    
        		T1COUNT = 0
        		pause 1
    		call achizitie
    	endif
    
    gosub efectuez
    gpif = 0
    GOTO MAIN
    
    
    achizitie:
    for nr = 1 to 2
    For CounterA=0 to 9
    ADCON0 = %10000001
    		Pauseus 50			' Wait for channel to setup
    	        ADCON0.1 = 1			' Start conversion
    		While ADCON0.1=1:Wend		' Wait for conversion
    		DataW.HighByte=ADRESH		' Read variable from ADC and save
    		DataW.LowByte=ADRESL
    		RawData(CounterA)=DataW
    		Next CounterA
    CounterA=0 
    Gosub Getsort
    next nr
    return
    
    CHECK: 
      IF TMR1IF then
          TMR1IF  = 0
          Timer1  = 3037
          T1Count = T1Count + 1
          if T1Count = 2 then 
            TMR1ON = 0
            T1Count = 0
            LongPress = 1
          endif
      ENDIF
    RETURN
                             
    ;============================================================================
    GetSort:
    	If RawData(CounterA+1) < RawData(CounterA) then
    		DataW=RawData(CounterA)
    		RawData(CounterA)=RawData(CounterA+1)
    		RawData(CounterA+1)=DataW
    		If CounterA>0 then CounterA=CounterA-2
    		endif
    	CounterA=CounterA+1
    	If CounterA<10 then goto GetSort
    
    
    	DataW=0
    	For CounterA=4 to 7 
    		DataW=DataW+RawData(CounterA)
    		Next CounterA
    	ADCValue=DataW>>2
    if nr = 1 then 
    adca = adcvalue
    else
    adcb = adcvalue		
    endif
    
    if adcb=adca then ok = 1
    
    Return
    ;============================================================================
    efectuez:
    if ok=1 then
          IF adcb > 300 AND adcb < 350 THEN 
    			if tip_press = 1 then 
    				gpio.2 = 1 : pause 2000 : gpio.2 = 0
    			else
    				gpio.2 = 1 : pause 500 : gpio.2 = 0
    			endif
          endif
    endif
    Return
    ;============================================================================
    Name:  press_test.jpg
Views: 1544
Size:  180.9 KB

  21. #21
    Join Date
    Aug 2011
    Posts
    408


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    Why do you insist on sorting the ADC readings? What problem is that trying to solve?

    I'd get rid of the "bubble sort" and try starting with Richard's code.

  22. #22
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    574


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    The schematic is working into "hard" environment ... I tried different variants before this. THIS is the only way to have accurate readings of ADC.

  23. #23
    Join Date
    Aug 2011
    Posts
    408


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    I see now... the code isn't just a bubble sort. It sorts a set of adc readings and then averages the "inner most" set of them which would tend to exclude the outliers.

    What if you take this portion of Richard's code
    Code:
    chk_sw:
    ADCON0 = %10000001 ;ch0
    Pauseus 50  ' Wait for channel to setup
    ADCON0.1 = 1  ' Start conversion
    While ADCON0.1=1:Wend ' Wait for conversion
    DataW.HighByte=ADRESH  ' Read variable from ADC and save
    DataW.LowByte=ADRESL
    and replace that with the result of your existing sort/average routine?

  24. #24
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    574


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    Already tried ... it's act like I always press SHORT !

  25. #25
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    the dataset you are trying to infer information from consists of two pieces of data
    1. the adc reading
    2. the timestamp of the reading
    The periods you are interested in are between .2 and 1 sec. if you sample the input volts at 200 times / sec (5mS)
    then you need to store at least 200 samples and their timestamps . when you have those samples you could analyse the dataset
    for press/longpress data. you need to understand that if you sort the data on the adc value then the time stamp value needs to be included in the sort otherwise the data becomes useless [all the time info is lost].
    If the data is so noisey that my method fails the the above method could work but it would not be possible on a 12f675 [insufficient ram]
    lowering the input impedence, altering the sample rate or increasing the "pressed"/"not pressed" tolorance may help.
    Write a pgm to capture and print the adc reading at a 5mS sample rate .then you can examine the data statistically for a fundamental noise frequency that may be possible to filter out or maybe some other ways to mitigate the noise problem. without real data i'm just speculating.
    my method could also be turned around to count the number of "valid" reads in a period rather than the number of "periods" of valid reads ,
    which may perform better in noisy environments

  26. #26
    Join Date
    Aug 2011
    Posts
    408


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    One thing I will say is that with the code from post #14 you need to rearrange the threshold levels
    or the order of tests so that they go from the lowest value to the highest.

    Right now the code is
    Code:
    trigger_thresshold_1   con 600  ; adc reading must fall below this to count  as a pressed button 1
    trigger_thresshold_2   con 500  ; adc reading pressed button 2
    trigger_thresshold_3   con 400  ; adc reading pressed button 3
    
    if DataW <  trigger_thresshold_1 then
        b_level =1
    elseif  DataW < trigger_thresshold_2 then
        b_level =2
    else  DataW < trigger_thresshold_3   then
        b_level =3
    endif
    For that to work it needs to check from lowest value to highest value...
    Code:
    trigger_thresshold_1   con 400  ; adc reading must fall below this to count  as a pressed button 1
    trigger_thresshold_2   con 500  ; adc reading pressed button 2
    trigger_thresshold_3   con 600  ; adc reading pressed button 3
    Otherwise everything will look like button 1

  27. #27
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    your correct tumbleweed , I think there is another issue there with that code too but fratello has not indicated that multiple buttons actually are on the agenda so I left it as is.
    if anyone is interested I do have a multiple button version that is complete and works .i'm quite surprised just how well the idea actually works so I developed it a bit further .its a good option if pins are limited.
    I would be interested to see fratellos raw data and see if noise is really the issue
    Attached Images Attached Images    

  28. #28
    Join Date
    Aug 2011
    Posts
    408


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    Another thing that the sort and average routine in post #11 does is to perform the routine twice and compare the two resulting averages before declaring "I see a valid key" (if adca=adcb then gosub efectuez).

    That could be adapted to fit into the "check_sw" portion of your code by changing some of the post#11 averaging variables around and only
    changing the "result" DataW on a match...
    Code:
    if adca=adcb then
      DataW = adca
    endif
    return
    How well all that works depends on the noise, how many switches (and how far apart the values are), etc, but I could see where it'd be better than just using a single adc value for sure.


    if anyone is interested I do have a multiple button version that is complete and works
    Sure. Love to see it.

  29. #29
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    its on a 12f683
    the interrupt use is unnecessary , i left it in for experimenting with
    Attached Files Attached Files

  30. #30
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    574


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    Thank you all for support !
    Very interesting suggestions and points-of-view ...
    @Richard :
    if anyone is interested I do have a multiple button version that is complete and works ...
    Of course !!!

  31. #31
    Join Date
    Nov 2007
    Location
    West Covina, CA
    Posts
    219


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    I could be wrong but I have to ask about using "CALL" instead of GOSUB for the sub routines CHECK and achizitie.

    From the MCS Help section:
    CALL Label

    Execute the assembly language subroutine named Label. GOSUB is normally used to execute a PicBasic subroutine. The main difference between GOSUB and CALL is that with CALL, the existence of Label is not checked until assembly time. Using CALL, a Label in an assembly language section can be accessed that is otherwise inaccessible to PicBasic.

    Example

    CALL pass ' Execute assembly language subroutine named _pass
    I've never used it in place of GOSUB so don't know if a RETURN works the same in this case.
    Louie

  32. #32


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    I've done multi-button with long press (and timed no-button auto-backout) on a '88 using ADC to save pins, and it worked fine, but field EMF noise can wreak absolute havoc on your results (fluorescent lights much?) if you're not using twisted, and preferably shielded wire. That could be what's throwing you out of your "consistent" results needed to qualify for a long-press. Ceradiodes or double-zeners can bleed off freak transients, and a capacitor at the chip A/D input pin would help smooth things out.

  33. #33
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    574


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    @Mr.Richard : Tried to figure out how your soft work ... But in Proteus nothing happens.
    I do something wrong ? I "addapted" the "elseif" command, since is not present in PBP 2.6 (?).
    Thanks in advance for support !
    Code:
    ;pic12f683
    
    DEFINE OSC  8
    include "dt_ints-14.bas"
    include "REENTERPBP.bas"
    
    @timer1 =TMR1L
    wsave   VAR BYTE    $20     SYSTEM      ' location for W if in bank0
    wsave1  VAR BYTE    $A0     SYSTEM      ' location for W if in bank1
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,           Type,   ResetFlag?
            INT_Handler   TMR1_INT,   _chk_sw,      PBP,  yes
         endm
        INT_CREATE      
    ENDASM     
    
    long_press_threshold   con 200   ;1 sec       200*5( time const)=1000mS
    short_press_threshold  con 5 
    btn_tol                con 25   ;ADC READING TOLORACE
    number_of_buttons      con 3    ;MAX 7       
    ;4K7 TO 5V                                         
    '                               3k3            /  
    '                         ___  /\  /\  /\  ___/ ^____ btn1
    '                        |   \/  \/  \/  \/          |
    '   5v     4k7           |       2k2           /     |
    '    ___  /\  /\  /\  ___!___  /\  /\  /\  ___/ ^____!btn2
    '       \/  \/  \/  \/   |   \/  \/  \/  \/          |
    '                        |       1k            /     |
    '    ____________________!___  /\  /\  /\  ___/ ^____!btn3
    '    an3  gpio4              \/  \/  \/  \/          |
    '                                                    |
    '    ________________________________________________! 
    '    gnd                                             |
    '    ___________|\|__led_____________________________|
    '    gpio2      |/|
    
    OSCCON=$70
    CMCON0    = 7
    TRISIO   = %111011
    ANSEL    = %01011000        ;fosc/16 ,an3
    btn_adc var word[number_of_buttons]
    b_cnt   var byte[number_of_buttons]
    b_state var byte[number_of_buttons]     ;0 not pressed ,1 short ,2 long
    button_index  var byte      ;which button
    led           var gpio.2    ;led
    btn_flg       var byte 
    abp           var BIT  
    adcr          var WORD 	    ;adc reading
    timer1        VAR WORD EXT
    tmp           var word     
    FLASH_ON      VAR WORD      ;led
    FLASH_OFF     VAR WORD      ;led
    FLASH_DUTY    VAR WORD      ;led
    led = 0 
    clear
    
    btn_adc[0]=209           ;adc read for buttons
    btn_adc[1]=327           ;adc read for buttons
    btn_adc[2]=422           ;adc read for buttons
    
    timer1=55543             ;5mS  time const
    T1CON=1
    @ INT_ENABLE  TMR1_INT
    
    FLASH_OFF=200
    FLASH_On=0
    ADCON0 = %10001101     ;warm up the adc  ,right shift   ,an3
    ADCON0.1 = 1            ' Start a conversion
    
    Main:
       Pause 5   ;loop time const  
        IF ABP THEN 
           button_index= 0
           tmp=20
          
           while abp     
               if  B_STATE[button_index]=2 then
                   FLASH_OFF= tmp
                   abp=0
                   led=0
                   FLASH_DUTY=0
               else 
                   if   B_STATE[button_index]=1 then
                   FLASH_On=tmp
                   abp=0
                   led=0
                   FLASH_DUTY=0   
                   endif
               endif
               tmp=tmp+100
               B_STATE[button_index]=0
               button_index=button_index+1
               if  button_index= number_of_buttons then abp=0  ;clr error  if req 
            wend          
        ENDIF  
         IF  FLASH_ON THEN
           IF FLASH_DUTY=0 THEN
           led = ! LED     ; flash led
            	IF LED THEN
             	FLASH_DUTY = FLASH_ON
            	ELSE
             	FLASH_DUTY = FLASH_OFF
            	ENDIF
           ELSE
           FLASH_DUTY=FLASH_DUTY-1
           ENDIF       
         ENDIF        
        
    Goto Main     
       
    chk_sw:
        T1CON.0=0
        timer1=timer1+55543 
        T1CON.0=1
        ;ADCON0 = %10001101 ; NO NEED since ch never changes and ADC is left ON 
        ;Pauseus 50		'  aqusition  time  if req
        ;ADCON0.1 = 1		' Start conversion
        ;While ADCON0.1=1:Wend	' Wait for conversion
        adcr.HighByte = ADRESH	' Read variable from ADC 
        adcr.LowByte  = ADRESL
        FOR button_index = 0 TO 2
              if ! B_STATE[button_index] then
                  IF    abs (adcr- btn_adc[button_index] )< btn_tol  then
                       if  btn_flg.0[button_index]  THEN
                            IF b_cnt[button_index] < 250 THEN  b_cnt[button_index]=b_cnt[button_index]+1   
                            ELSE   ;FIRST PRESS  FOR  THIS BUTTON 
                            b_cnt[button_index]=0
                            btn_flg.0[button_index]=1
                            ENDIF            
                       ELSE
                       IF   btn_flg.0[button_index]  THEN    ;  HAD   THIS BUTTON  BEEN PRESSED  ?
                           IF   b_cnt[button_index] > long_press_threshold THEN                                           
                           B_STATE[button_index]=2
                           abp=1 
                           ELSE
                           IF   b_cnt[button_index] > short_press_threshold THEN  
                           B_STATE[button_index] =1
                           abp=1
                           ENDIF 
                       endif
                       btn_flg.0[button_index]=0   
                  ENDIF
              ENDIF
              endif
        next 
        ADCON0.1 = 1     ' Start conversion  for next pass
    @ INT_RETURN
    Name:  TEST.jpg
Views: 1398
Size:  119.3 KB

  34. #34
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    Tried to figure out how your soft work ... But in Proteus nothing happens
    did you try it on a real chip ?
    Warning I'm not a teacher

  35. #35
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    the led should have a series resistor to limit current , I assumed that would be obvious and omitted it from the sketch
    @ 5v try 180 ohm for a yellow led
    Warning I'm not a teacher

  36. #36
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    574


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    Thanks for reply ! Proteus work fine even without resistor for LED ... I wonder if my "adaptations" of code are corect.

  37. #37
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Smile Re: Long / short press button...but reading ADC

    your adaptation works fine when complied with pbp3 [on a real chip , none of this simulator nonsense ], can't vouch for pbp2.6
    would recommend an upgrade
    Warning I'm not a teacher

  38. #38
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    574


    Did you find this post helpful? Yes | No

    Default Re: Long / short press button...but reading ADC

    I see ... Thank you !
    LE : Please, can share asm & hex file, as results of PBP3 compiled ?

Similar Threads

  1. Replies: 5
    Last Post: - 26th February 2011, 06:51
  2. Button press or not
    By lerameur in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 24th November 2010, 21:37
  3. 4 Bytes one button press
    By Dennis in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 15th January 2010, 23:36
  4. Sleep until button press?
    By kevj in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 9th October 2007, 04:47
  5. Button press and press & hold how to ?
    By GrandPa in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 22nd August 2007, 04:37

Members who have read this thread : 3

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts