Thread: good way to simulate two push buttons?

  1. #1
    Registered User mc088's Avatar
    Join Date
    Jan 2017
    Posts
    19

    good way to simulate two push buttons?

    Let's say we have a control box with two buttons (button 1 and button 2) and there are three possible operations

    1. When the user presses button 1 and then releases it, the text "blue" should be displayed.

    2. When user presses button 2, and then releases it, the text "green" should be displayed.

    3. When user presses button 1, holds button 1, then presses button 2 then releases button 2, the text "red" should be displayed.

    To simulate the two pushbuttons, I have user enter 1 or 0, depending on whether a specific button (button 1 or button 2) is pressed / held or not pressed at all. But it feels clunky doing it that way, so any better ways to simulate the two push buttons so it's more realistic?

    My current code is included below (and yes, this is not homework of any sort) Thanks.

    Code:
    #include <stdio.h>
    #define  S0 0
    #define WS1 1
    #define WS2 2
    #define WS3 3
    
    
    void buttonFSM( int buttonPress[2]);
    int main()
    {
        int buttonArray[2] = {0};
        int i;
    
    
        while(1)
        {
            for (i = 0; i < 2; i++) 
            {
                printf("Button %d: ", i+1);
                scanf("%d", &buttonArray[i]);
            }
            
            if( (buttonArray[0] == -1))
            {
                break;
            }
    
    
            if( (buttonArray[0] != -1))
            {
                buttonFSM(buttonArray);
            }
            else
            {
                printf("Program End");
                break;
            }
    
    
            printf("\n");
        }
    
    
        printf("\n\n");
        return 0;
    }
    
    
    //*******************************
    
    
    void buttonFSM(int buttonPress[2])
    {
        static char fsm_state = S0;
        
        switch(fsm_state)
        {
            case(S0):
                if( (buttonPress[0] == 0 && buttonPress[1] == 0) || 
                    (buttonPress[0] == 1 && buttonPress[1] == 1) )
                {
                    fsm_state = S0;
                }
    
    
                else if (buttonPress[0] == 1 && buttonPress[1] == 0)
                {
                    fsm_state = WS1;
                }
    
    
                else if (buttonPress[0] == 0 && buttonPress[1] == 1)
                {
                    fsm_state = WS2;
                }
                break;
                
            case WS1:
                if( (buttonPress[0] == 0 && buttonPress[1] == 0) )
                {
                    fsm_state = S0;
                    printf("green\n");
                }
                else if (buttonPress[1] == 1 && buttonPress[1] == 1)
                {
                    fsm_state = WS3;
                }
                else
                {
                    fsm_state = S0;
                }
                break;
            
            case WS2:
                if( (buttonPress[0] == 0 && buttonPress[1] == 0) )
                {
                    fsm_state = S0;
                    printf("blue\n");
                }
                else
                {
                    fsm_state = S0;
                }
                break;
            
            case WS3:
                if( (buttonPress[0] == 1 && buttonPress[1] == 0) )
                {
                    fsm_state = S0;
                    printf("red\n");
                }
                else
                {
                    fsm_state = S0;
                }
                break;
    
    
            default: 
                break;
        }
    }
    Last edited by mc088; 01-23-2017 at 12:42 AM.

  2. #2
    Registered User
    Join Date
    Jun 2015
    Posts
    1,643
    I'm not sure what you mean by "any better ways to simulate the two push buttons".

    Your code could be improved quite a bit, though:
    Code:
    #include <stdio.h>
    
    enum { S0, WS1, WS2, WS3 };
    
    void buttonFSM(int buttons[]);
    
    int main() {
        int buttons[2] = {0};
        int i;
    
        while (1) {
            for (i = 0; i < 2; i++) {
                printf("Button %d: ", i+1);
                scanf("%d", &buttons[i]);
            }
             
            if (buttons[0] == -1)
                break;
     
            buttonFSM(buttons);
    
            printf("\n");
        }
     
        printf("Program End\n");
    
        return 0;
    }
    
    void buttonFSM(int buttons[]) {
        static char state = S0;
    
        switch (state) {
            case S0:
                if (buttons[0] == buttons[1])
                    state = S0;
                else if (buttons[0] && !buttons[1])
                    state = WS1;
                else if (!buttons[0] && buttons[1])
                    state = WS2;
                break;
                 
            case WS1:
                if (!buttons[0] && !buttons[1]) {
                    state = S0;
                    printf("green\n");
                }
                else if (buttons[1] && buttons[1])
                    state = WS3;
                else
                    state = S0;
                break;
             
            case WS2:
                if (!buttons[0] && !buttons[1]) {
                    state = S0;
                    printf("blue\n");
                }
                else
                    state = S0;
                break;
             
            case WS3:
                if (buttons[0] && !buttons[1]) {
                    state = S0;
                    printf("red\n");
                }
                else
                    state = S0;
                break;
        }
    }

  3. #3
    Registered User mc088's Avatar
    Join Date
    Jan 2017
    Posts
    19
    Quote Originally Posted by algorism View Post
    I'm not sure what you mean by "any better ways to simulate the two push buttons".
    I mean like is there any better way to simulate pressing a button besides just manually entering in 1 and 0 for the two buttons, and is there a better way to distinguish between just having pressed the button vs holding a button (like the 3rd operation to get 'red' to display requires)


    Thought about doing something like detecting keypresses by user on the keyboard but if I'm understanding correctly seems like that option is OS dependent and that seems a bit complicated to me at the moment I just way to stick to really simple stuff at the moment.


    Also thought of like manually editing values with debugger but that's probably not the way to go if I want things to happen normally (not having to use debugger to do that)

    Hope this makes more sense and there's a better idea of what I can be doing.



    Thank you
    Last edited by mc088; 01-23-2017 at 11:23 PM.

  4. #4
    Registered User mc088's Avatar
    Join Date
    Jan 2017
    Posts
    19
    Oh I probably should write a test program to supply the desired sequence of button presses instead of what I Was thinking in my previous post above, but how is best way to go about it? (sorry if i seem bit confused at times, still learning best ways to program)

    Thanks!

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,706
    Perhaps
    Code:
    #define ASIZE(x) (sizeof(x)/sizeof(x[0]))
    
    int buttonsequence[][2] = {
      { 0, 0 },
      { 1, 0 },
      { 0, 0 }, // b1 press and release
      { 0, 1 },
      { 0, 0 }, // b2 press and release
    };
    
    for ( i = 0 ; i < ASIZE(buttonsequence) ; i++ ) {
      buttonFSM(buttonsequence[i]);
    }
    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.

  6. #6
    Registered User mc088's Avatar
    Join Date
    Jan 2017
    Posts
    19
    Thank you. That works fine.

  7. #7
    Registered User mc088's Avatar
    Join Date
    Jan 2017
    Posts
    19
    Although I can get Salem's suggestion to work, I thought of changing the test program so that I could have all the predefined states of the state machine stored like in a table (look up table maybe? idk what you call it) so that you could do some like automated testing to check to be sure every possible path of the buttonFSM function would do what it's supposed to do. And what if you had like 4 or 5 buttons? Are you going to have to just make a long winded list of all possible states (use intbuttonsequence[][2] so many times) or is there a better strategy instead? Hopefully that makes sense of what I wanted to do.

    Was not sure how to start coding that, was thinking of using struct but not sure if that's the best way to go and how it would look.

    Thanks!!
    Last edited by mc088; 01-28-2017 at 02:22 PM.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,706
    If you're not already familiar, you should read up on Mealy and Moore.

    A lookup table is a good approach, as it allows you to identify every valid state and transition.
    Any illegal combination is therefore easy to spot, and can prompt either 'halt' or 'reset' as appropriate.

    Hand-crafted logic is vulnerable to obscure combinations which can lead to the kind of random behaviour which is hard to diagnose.
    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.

  9. #9
    Registered User mc088's Avatar
    Join Date
    Jan 2017
    Posts
    19
    Quote Originally Posted by Salem View Post

    A lookup table is a good approach, as it allows you to identify every valid state and transition.
    Any illegal combination is therefore easy to spot, and can prompt either 'halt' or 'reset' as appropriate.
    .
    Ok.

    Just for an example, if I were to just be looking at gray code, with the following sequence:

    input -> output
    0b000 0b000
    0b001 0b001
    0b010 0b011
    0b011 0b010
    0b100 0b110
    0b101 0b111
    0b110 0b101
    0b111 0b100

    I might just do a table as such:

    Code:
    const gray_code[8]={0b000,0b001,0b011,0b010,0b110,0b111,0b101,0b100};


    and get the desired value with the following code (assuming variables already properly declared and initialized prior):
    Code:
    desired value = gray_code[input];
    Now, back to push buttons:

    to make sure you have been through every button combination, in the code, would you just simply make a big huge array (similar to the one shown 4 posts before) and loop through all that and print out the appropriate messages that indicate that the proper state /transition has been passed through? Because how would it be best to know you've tested every possible path /state / transition in a good way without getting yourself confused? The button sequences are predefined, and I was thinking of sticking that into a table (lookup table perhaps)

    But if there's a better way to create the lookup table to make a good test program for this push button scenario, I'd like to know, maybe that template can be reused for future codes I write that I involve a state machine with.

    So in short: I guess I'd like to know what should the template of the lookup table look like in that case to be correct / make life easier so to speak?

    Hope that makes some more sense, sorry if reply seems long, I appreciate all the help Salem and thank you very much.
    Last edited by mc088; 01-29-2017 at 06:26 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Simulate Keypress
    By silentkarma in forum Windows Programming
    Replies: 4
    Last Post: 02-29-2008, 12:59 AM
  2. how can i get push buttons to look nice?
    By e66n06 in forum Windows Programming
    Replies: 2
    Last Post: 10-28-2007, 03:46 PM
  3. Simulate Start->Run->OK
    By caduardo21 in forum Windows Programming
    Replies: 2
    Last Post: 01-13-2006, 11:48 PM
  4. Optional Push-Buttons Around Frame :: MFC
    By kuphryn in forum Windows Programming
    Replies: 0
    Last Post: 05-09-2002, 03:18 PM

Tags for this Thread