Thread: One button to have two values.

  1. #1
    Registered User
    Join Date
    Dec 2012
    Posts
    37

    One button to have two values.

    Hi everyone. Im very much new to this forum and would really appreciate to have help all around.

    Im doing a project with C language to control a radio using a remote control. I generally have 5 buttons on the remote of which 1 of the buttons need to have a single press (mute function) and a long press (turn ON/OFF) as well.

    The problem that I am currently facing is that although I've tried to do several ways, such as for loops, while loops, if else etc.. but non works.

    It seems that it always goes into the else if loop instead of if and/or else, even though the counter is set at the correct number.
    Code:
    void construct(void)
    {
    #if 1    
            //assuming all variables are properly declared in unsigned char
        {    
            if ((key > 205) && (key < 235))                //button 1
            {
                count++;
                if ((count > 1) && (count <= 51))        //short press
                {
                    d1 = 0xXX;                        
                    d2 = 0xYY;
                }
                else if ((count > 51) && (count <=255))    //long press
                {
                    d1 = 0xXX;                        
                    d2 = 0xYY;
                }
                else
                {
                }
            }
            else if ((key > 155) && (key < 173))        //button 2
            {
                d1 = 0xXX;                        
                d2 = 0xYY;        
            }
            else if ((key > 80) && (key < 141))            //button 3
            {
                d1 = 0xXX;                        
                d2 = 0xYY;                             
            }
            else if ((key > 47) && (key < 78))            //button 4
            {
                d1 = 0xXX;                        
                d2 = 0xYY;                                 
            }
            else if ((key >= 0) && (key < 15))            //button 5
            {
                d1 = 0xXX;                        
                d2 = 0xYY;                             
            }
            else
            {    
            }
        }
            
    #endif
    }
    [ATTACH]12369


    Could anyone please help and see if there is anything that I missed?

    gumasumnida.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    You need key-down and key-up events if you want to distinguish short-press from long-press.

    Where are you getting key presses from?

    Which OS/Compiler are you using?

    Is this being run on your desktop development machine, or some kind of dev board?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2012
    Posts
    37
    Hi Salem,

    key presses are obtained from ADC conversion (the key value ranges are the converted values). Im using Microchip pic 10F222 running on MPLAB IDE v8.87.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    So what value is stored in key when the key is up?

    How is construct() called? Is it in a loop in your main(), or is it called directly as a result of a completed ADC conversion event?

    Finite-state machine - Wikipedia, the free encyclopedia
    Basically, you have two events, key-press and key-release
    You also have two states key-up and key-down
    So state=key-up and event=key-press takes you to state key-down.

    In state key-down, you increment your counter (at some rate).

    On the key-release event, you look at the key and the counter, and decide what it all means.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by kim15 View Post
    It seems that it always goes into the else if loop instead of if and/or else, even though the counter is set at the correct number.
    Just from the code you provided, it's probably impossible to give an accurate answer. For example, where are you initializing count? Do you ever reset count back to 0?

    Run the code using a debugger and set a breakpoint right after the "count++" line. Then observe if your supposition is correct.

  6. #6
    Registered User
    Join Date
    Dec 2012
    Posts
    37
    Basically, you have two events, key-press and key-release
    You also have two states key-up and key-down
    So state=key-up and event=key-press takes you to state key-down.
    How exactly do u do a key state events?

    Thanks

  7. #7
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Quote Originally Posted by kim15 View Post
    How exactly do u do a key state events?

    Thanks
    The easiest way of doing this is with a switch statement

    Code:
    switch (state)
    {
      case 0:
        if (button_pressed)
        {
          count += (count < 100);
          if (count == 100)
          {
            count = 0;
            state = 1;
          }
          else if (count > 100)
          {
            count = 0;
          }
        }
        else
        {
          count = 0;
        }
    
        break;
    
      case 1:
        if (!button_pressed)
        {
          count += (count < 100);
          if (count == 100)
          {
            count = 0;
            state = 0;
          }
        }
        else
        {
          count = 0;
        }
    
        break;
        
    }
    Also noticed that I do not take the reading straight away -> I wait for 100 positive readings in a row before I change state.
    Last edited by Click_here; 12-19-2012 at 09:58 PM.
    Fact - Beethoven wrote his first symphony in C

  8. #8
    Registered User
    Join Date
    Dec 2012
    Posts
    37
    Thanks Click_Here! It was really helpful.

    I managed the key state events as above. However, I seem to notice that my key state never enters case 1 for high (mine is low trigger) even pressing the key multiple times. Is there a reason why?

    Thanks in advance

  9. #9
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Do you have a pull up resister on the port, or have you enabled the weak pull ups?

    Do you have an output LED which you could use for debugging? - i.e. Turn output on when entering the 'if' statement. I'd check to see if the port is set up by temporarily putting something like this in the code

    Code:
    for(;;)
    {
      if(input_latch == 0)
      {
        LED_output_pin == 1;
      }
      else
      {
        LED_output_pin == 0;    
      }
    }
    It will loop there forever, changing the output the same as the button -> If this doesn't work, you have a set-up problem

    Have you correctly set-up the tristate register for input (TRISGPIO)?

    What GPIO are you using? For digital mode on the 10F222 for each pin, you need to make sure other peripherals are not turned on -
    GP0 - ANS0 needs to be cleared
    GP1 - ANS1 needs to be cleared
    GP2 - FOSC4 and T0CS need to be cleared
    GP3 - MCLRE needs to be cleared

    What actual compiler are you using? C18/HI-TECH/CCS/...
    Fact - Beethoven wrote his first symphony in C

  10. #10
    Registered User
    Join Date
    Dec 2012
    Posts
    37
    Initially my input is configured as analog (obtained from the analog key) then is converted into digitial via ADC. Im not sure entirely what you mean by clear the pins.

    My input pin is : GP0
    Output pin (digital): GP1
    My GP2 isnt connected (not using, I assume it should be 0 at this point?)
    On my GP3, i use it as my pull-up resistor with 100k ohm.

    For the TRISGPIO, yes, I have set it up correctly, because before the hacking, the remote is successfully working..


    Appreciate all the help. Thanks in advance.

  11. #11
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    I reread your post an saw that you are dealing with an analogue input - I am imagining something like this Save Pic Pins with a 1 pin analog hex keypad but simpler.

    OK, so...

    Have you tested the analogue input with a variable resister input? You can still use an LED for debugging...

    What signal conditioning are you doing on the input? (Have you got an RC circuit, or are you taking the average input, ect...) - You shouldn't trust the first value you get from your analogue input. Don't forget about rise time considerations with the input signal.

    Have you considered using something like the MCP23X08? http://ww1.microchip.com/downloads/e...tes/00972a.pdf
    Fact - Beethoven wrote his first symphony in C

  12. #12
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    I might comment on the states that you might have as well...

    state 0
    - If input detected, state = 1

    state 1
    - Input is detected. If input stays in this range for, say, 1000 readings, output = key1, state = 6
    If input voltage is larger than the voltage range for key1, state = 2
    If input voltage is smaller than this voltage range for key1, state = 0

    state 2
    - If input stays in this range for, say, 1000 readings, output = key2, state = 6
    If input voltage is larger than the voltage range for key2, state = 3
    If input voltage is smaller than this voltage range for key2, state = 1

    state 3
    - If input stays in this range for, say, 1000 readings, output = key3, state = 6
    If input voltage is larger than the voltage range for key3, state = 4
    If input voltage is smaller than this voltage range for key3, state = 2

    state 4
    - If input stays in this range for, say, 1000 readings, output = key4, state = 6
    If input voltage is larger than the voltage range for key4, state = 5
    If input voltage is smaller than this voltage range for key4, state = 3

    state 5
    - If input stays in this range for, say, 1000 readings, output = key5, state = 6
    If input voltage is smaller than this voltage range for key3, state =

    state 6
    - Print output key
    State = 7

    state 7
    - If input voltage 0 again, state = 0
    Fact - Beethoven wrote his first symphony in C

  13. #13
    Registered User
    Join Date
    Dec 2012
    Posts
    37
    Quote Originally Posted by Click_here View Post
    Have you tested the analogue input with a variable resister input? You can still use an LED for debugging...

    What signal conditioning are you doing on the input? (Have you got an RC circuit, or are you taking the average input, ect...) - You shouldn't trust the first value you get from your analogue input. Don't forget about rise time considerations with the input signal.

    Have you considered using something like the MCP23X08? http://ww1.microchip.com/downloads/e...tes/00972a.pdf
    Hey, thanks for the quick response.

    Im not so sure where I am to start, so I'll just start from beginning. So... The remote has 5 different buttons that have different values for the resistors. after converting it, i get the ranges for the key (that is obtained from ADC). I gave about 10 percent tolerance for each key pressed. After reading and determining which key was pressed, it will then start to send out the data 8bit by 8bit.

    Tried it out, and the remote works fine. It does what it basically supposed to do with the values for each d1 and d2. Then a situation comes where I need to make one of the buttons (button one) to have 2 types of presses; short press and long press, which has 2 different set of values for d1 and d2.

    Now, I have tried using if else. Sometimes it works, sometimes it doesnt. But that isnt the point; the point is that in order for me to access the long press, i first must access to the short press. Which is inconvenient since I dont want the button to be sending the data d1 and d2 for the short press while intending for the long press.

    Then when Salem suggested to use key state, and by using the method that you gave (switch case) I wrote the code just a little different. That is by using the states for the key states to determine the short and long press.

    key_state == 0 means it is short press (not pressing after several count) and key_state == 1 means long press (still pressing after several count)

    But the output seems to only detect the key_state == 0 and never the key_state == 1. Even when I had first initialized the value to be 1 instead of the norm 0.

    I've included the key state events that you suggested. Did I miss something else?

    Please advise.

    Thanks

  14. #14
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Looking at the states I gave before, what you could do is is key0 has been pressed, don't send output right away -> Go to a new state that increments a variable while button is pushed down. When the button's release is detected, see how many cycles have occurred -> If the number of cycles is larger than 'n', output = key0a, otherwise, output = key0b. state = 7 to print. I would then switch the release/print order like this:

    state 0
    - If input detected, state = 1


    state 1
    - Input is detected. If input stays in this range for, say, 1000 readings, state = 8
    If input voltage is larger than the voltage range for key1, state = 2
    If input voltage is smaller than this voltage range for key1, state = 0


    state 2
    - If input stays in this range for, say, 1000 readings, output = key2, state = 6
    If input voltage is larger than the voltage range for key2, state = 3
    If input voltage is smaller than this voltage range for key2, state = 1


    state 3
    - If input stays in this range for, say, 1000 readings, output = key3, state = 6
    If input voltage is larger than the voltage range for key3, state = 4
    If input voltage is smaller than this voltage range for key3, state = 2


    state 4
    - If input stays in this range for, say, 1000 readings, output = key4, state = 6
    If input voltage is larger than the voltage range for key4, state = 5
    If input voltage is smaller than this voltage range for key4, state = 3


    state 5
    - If input stays in this range for, say, 1000 readings, output = key5, state = 6
    If input voltage is smaller than this voltage range for key3, state = 4


    state 6
    - If input voltage 0 again, state = 0
    State = 8


    state 7
    if voltage not 0, increment a variable.
    if voltage is 0 -> if variable > 1000000, output = key0a, else output = key0b, state = 8

    state 8
    - Print output key
    - state = 0
    Fact - Beethoven wrote his first symphony in C

  15. #15
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by Click_here View Post
    What signal conditioning are you doing on the input? (Have you got an RC circuit, or are you taking the average input, ect...) - You shouldn't trust the first value you get from your analogue input. Don't forget about rise time considerations with the input signal.
    You can trust analog input as long as the ADC polling rate is slow enough. The ADC will poll the analog signal, and average it for a short time before setting the output register. So there isn't necessarily a need for digital averaging.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. write() and read() int values from socket returning wrong values.
    By Premjith P S in forum Linux Programming
    Replies: 8
    Last Post: 11-29-2012, 02:59 PM
  2. passing int values and *double values through message queues
    By Hyp3rTension in forum C Programming
    Replies: 11
    Last Post: 05-11-2012, 05:04 AM
  3. Replies: 100
    Last Post: 06-21-2010, 02:22 AM
  4. Replies: 2
    Last Post: 06-28-2008, 08:30 PM
  5. Scroll button values!
    By pran1 in forum Windows Programming
    Replies: 2
    Last Post: 03-30-2004, 09:35 AM