How to measure how long I pressed a button ?


+ Reply to Thread
Results 1 to 19 of 19

Hybrid View

  1. #1
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    579

    Default How to measure how long I pressed a button ?

    Howdy ! I'm back on the forum after some absence (I had some personal problems).
    I am trying to develop a project. I use a PIC12F675 with which I read the value of a group of 6 resistors, of different values, individually, to perform 6 specific tasks.
    I am attaching the diagram. I am also attaching the code used so far, by which I try, in the first phase, to read if a button was pressed briefly or long, in order to make two different decisions depending on the duration of the press.
    I wasted many hours with gemini/chatgpt, none of them managed to identify the problem of the code not working. I tried dozens of options, without any results.
    What proved to me, once more, that we are superior (still?) to artificial intelligence, at least in certain aspects.

    Can you help me identify and solve the problem? Thank you in advance !


    Code:
    @ __config _XT_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BODEN_ON & _CP_ON 
    
    DEFINE OSC  4
    INCLUDE "modedefs.bas"
    CMCON    = 7
    TRISIO   = %00001001
    INTCON   = 0 
    IOC      = 0
    GPIO     = 0
    ANSEL    = %00110001
    
    
    
    ' Constante
    longpress CON 5000 ' maximum press (5 sec)
    shortpress CON 100 ' minimum press
    
    ' Variabile
    
    durata 		var word
    PressStartTime 	var word
    overflow_counter_low var word
    T1CON = %00000110 ' Prescaler  1:64, activating Timer1
    TMR1H = 0 ' Resetam Timer1
    TMR1L = 0
    
    GPIO.2 = 0
    ADCON0 = %10000001
    PAUSEUS 100 
    
    Main:
    
        durata = 0
        overflow_counter_low = 0
    
    
        ADCON0.1 = 1
        While ADCON0.1 = 1 : Wend 
    
    
        DataW.HighByte = ADRESH 
        DataW.LowByte = ADRESL
    
    
    if DataW < 805 then
            if DataW > 50  AND DataW < 160 THEN b_level = 1
            if DataW > 180 AND DataW < 270 THEN b_level = 2
            if DataW > 290 AND DataW < 380 THEN b_level = 3
            if DataW > 400 AND DataW < 500 THEN b_level = 4
            if DataW > 540 AND DataW < 650 THEN b_level = 5
            if DataW > 690 AND DataW < 800 THEN b_level = 6
    
    
            if b_level <> 0 then
                TMR1H = 0
                TMR1L = 0
                PressStartTime = TMR1L
    
    	while durata < longpress
        		if T1CON.0 == 1 then
            	overflow_counter_low = overflow_counter_low + 1
            		if overflow_counter_low == 65535 then
                		overflow_counter_low = 0
                		durata = durata + 65535
            		endif
        		endif
        
        	durata = durata + (TMR1H * 256 + TMR1L)
    	wend
    
    	durata = durata - PressStartTime
            PAUSE 100
    	SEROUT GPIO.2, 2, ["Press for : ", #durata, " ms", 13, 10]
    
            endif
    
    endif
    
    
    GOTO Main
    Name:  schematic.BMP
Views: 278
Size:  36.2 KB
    Last edited by fratello; - 27th March 2024 at 16:55.

  2. #2
    Join Date
    May 2013
    Location
    australia
    Posts
    2,392


    Did you find this post helpful? Yes | No

    Default Re: How to measure how long I pressed a button ?

    in order to measure a buttons hold time you need to either note time button was pressed then the time button was released
    the duration is release time - when pressed time, or when button is pressed start a timer and then stop it when button released
    you are not doing either of these things
    you never start timer1, you never note when the button is released
    Warning I'm not a teacher

  3. #3
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    579


    Did you find this post helpful? Yes | No

    Default Re: How to measure how long I pressed a button ?

    Thanks for reply !
    T1CON = %00000110 ; this command does not start timer1?
    Or do I have to use the command: T1CON.0 = 1 'start Timer1 ?
    How to see if button is released ? IF DataW.... it's not enough ?
    Last edited by fratello; - 28th March 2024 at 09:19.

  4. #4
    Join Date
    May 2013
    Location
    australia
    Posts
    2,392


    Did you find this post helpful? Yes | No

    Default Re: How to measure how long I pressed a button ?

    No it just sets it to use external clock

    Name:  TIMER1.jpg
Views: 272
Size:  155.9 KB
    Warning I'm not a teacher

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


    Did you find this post helpful? Yes | No

    Default Re: How to measure how long I pressed a button ?

    you have set timer1 to overflow every 16.38 mS , you never count the overflows
    also adding 65535 to a word var seems very odd do you actually intend to subtract 1


    i can't see how any of this can work, i makes no sense to me

    Code:
    while durata < longpress
        	if T1CON.0 == 1 then
            	overflow_counter_low = overflow_counter_low + 1
            	if overflow_counter_low == 65535 then
                		overflow_counter_low = 0
                		durata = durata + 65535
            	endif
        	endif    
        	durata = durata + (TMR1H * 256 + TMR1L)
    wend
    Warning I'm not a teacher

  6. #6
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    579


    Did you find this post helpful? Yes | No

    Default Re: How to measure how long I pressed a button ?

    Quote Originally Posted by richard View Post
    you have set timer1 to overflow every 16.38 mS , you never count the overflows
    also adding 65535 to a word var seems very odd do you actually intend to subtract 1
    ....
    i can't see how any of this can work, i makes no sense to me
    Gemini code !

  7. #7
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,523


    1 out of 1 members found this post helpful. Did you find this post helpful? Yes | No

    Default Re: How to measure how long I pressed a button ?

    What happens if more than one button is pressed at the same time?

    Anyway, this might serve as starting point. It compiles but it is not tested.
    Code:
    Long_Press CON 5000
    Short_Press con 100
    
    cnt VAR WORD
    b_level VAR BYTE
    DataW VAR WORD
    
    Main:
        GOSUB ReadButton
        
        IF b_level > 0 THEN
        	cnt = 0
            WHILE b_level > 0  
        	   cnt = cnt + 10  
        	   if cnt > Long_Press THEN EXIT
        	   PAUSE 10
        	   GOSUB ReadButton
        	WEND
        	
        	SEROUT GPIO.2, 2, ["You pressed button ", #b_level, " for ", #cnt, "ms", 13, 10]
        endif
    Goto Main	
    
    
    ReadButton:
        ADCON0.1 = 1
    	While ADCON0.1 = 1 : Wend 
    	
        DataW.HighByte = ADRESH 
        DataW.LowByte = ADRESL
    
    	b_level = 0
    	if DataW < 805 then
            	if DataW > 50  AND DataW < 160 THEN b_level = 1
            	if DataW > 180 AND DataW < 270 THEN b_level = 2
            	if DataW > 290 AND DataW < 380 THEN b_level = 3
            	if DataW > 400 AND DataW < 500 THEN b_level = 4
            	if DataW > 540 AND DataW < 650 THEN b_level = 5
            	if DataW > 690 AND DataW < 800 THEN b_level = 6
    	ENDIF
    RETURN

  8. #8
    Join Date
    May 2013
    Location
    australia
    Posts
    2,392


    Did you find this post helpful? Yes | No

    Default Re: How to measure how long I pressed a button ?

    Quote Originally Posted by fratello View Post
    How to see if button is released ? IF DataW.... it's not enough ?
    i possibly could be enough but you never reevaluate it until the whole timing mess has long completed
    Warning I'm not a teacher

  9. #9


    Did you find this post helpful? Yes | No

    Default Re: How to measure how long I pressed a button ?

    I would think tighten up the adc values comparisons to fill in the gaps so reading doesn't fall off........ <160 next to >161, etc

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


    Did you find this post helpful? Yes | No

    Default Re: How to measure how long I pressed a button ?

    In the initial software, I use a procedure to check the pressed button; if 10 presses have the same ADC as a result, then I validate the button press. I tried to complete the code proposed above with this verification procedure. But, although the results APPEAR to be correct, on the breadboard the assembly does not work at all, none of the 6 commands are executed (of course, I commented Serout instruction and uncomment the other instruction) . Please, could you identify what exactly I did wrong?

    Main:
    apasat=0
    adcvalue=0

    GOSUB ReadButton

    IF b_level > 0 THEN
    cnt = 0
    WHILE b_level > 0
    cnt = cnt + 10
    if cnt > Long_Press THEN
    actiune = 1
    EXIT
    endif
    PAUSE 5
    GOSUB ReadButton
    WEND
    b_level = 0
    if b_act = 1 then gosub comenzi ; if button pressed is OK, no error
    ENDIF
    Goto Main


    ReadButton:
    ADCON0.1 = 1
    While ADCON0.1 = 1 : Wend

    DataW.HighByte = ADRESH
    DataW.LowByte = ADRESL
    b_level = 0
    actiune = 0
    IF DataW < 805 then
    if DataW > 50 AND DataW < 160 THEN b_level = 1
    if DataW > 180 AND DataW < 270 THEN b_level = 2
    if DataW > 290 AND DataW < 380 THEN b_level = 3
    if DataW > 400 AND DataW < 500 THEN b_level = 4
    if DataW > 540 AND DataW < 650 THEN b_level = 5
    if DataW > 690 AND DataW < 800 THEN b_level = 6

    apasat = b_level
    adcvalue=DataW

    if apasat=last_b_level then ; procedure for cheking pressed button
    b_cnt=b_cnt+1
    pauseus 200
    if b_cnt > 10 then b_act = 1 ; button pressed is OK
    endif

    last_b_level=apasat
    ENDIF

    RETURN

    ;================================================= ===========================

    comenzi:
    SEROUT GPIO.2, 2, ["You pressed button ", #apasat, " for ", #cnt, " ms", " ACTIUNE: ", #actiune, " ok ? ", #b_act, 13, 10]
    ;IF b_level=1 THEN gosub comand1
    ;IF b_level=2 THEN gosub comand2
    ;IF b_level=3 THEN gosub comand3
    ;IF b_level=4 THEN
    ; if actiune = 1 then
    ; gosub comand1
    ; else
    ; gosub comand 4
    ; endif
    ;ENDIF
    ;IF b_level=5 THEN gosub comand5
    ;IF b_level=6 THEN gosub comand6


    last_b_level=0
    b_cnt=0
    Return
    Last edited by fratello; - 2nd April 2024 at 08:34.

Similar Threads

  1. TMR1 & Button - long delay (1 min) before starting
    By flotulopex in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 14th March 2017, 13:03
  2. Long / short press button...but reading ADC
    By fratello in forum mel PIC BASIC Pro
    Replies: 37
    Last Post: - 10th July 2016, 08:37
  3. Replies: 5
    Last Post: - 26th February 2011, 05:51
  4. Replies: 1
    Last Post: - 14th October 2010, 18:33
  5. Button pressed time control
    By tanero in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 15th August 2005, 15:17

Members who have read this thread : 19

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