Search code examples
c++inputswitch-statementmbednucleo

Creating a switch statement with multiple digital inputs? (c++, mbed, nucleo)


I am trying to compile a switch statement to create a combination lock of sorts from a nucleo board. At first I tried to tackle using multiple digital inputs in a switch statement by creating a bit mask and assigning integers, this seems to have gone alright however when I try to get my switch statement running it is stuck on case 0.

For a start case 0 should be no buttons pressed however it only activates once I press switch 1. My second problem is that no other cases in my statement will activate at all.

I have no access to a debugger as mbed is not compatible with my nucleo board and I cannot get Keil Studio working so I am pretty stumped. Does anyone what is wrong with my statement or if there is an alternate way to refer to my digital inputs within the switch statement that may make it easier?

I am a coding n00b and have struggled to find much reference to my problem, any sample code I have looked at seems to work no problem and I cannot see where I have deviated from that code.

Code is below:

// You are to use these ojects to read the switch inputs
DigitalIn SW1(USER_BUTTON);
DigitalIn SW2(BTN1_PIN);
DigitalIn SW3(BTN2_PIN);
DigitalInOut SW4(BTN3_PIN, PIN_INPUT, PullDown, 0);
DigitalInOut SW5(BTN4_PIN, PIN_INPUT, PullDown, 0);

// You are to use this object to control the LEDs
BusOut leds(TRAF_RED1_PIN, TRAF_YEL1_PIN, TRAF_GRN1_PIN);

// Use this to sound an error
Buzzer alarm;

int main()
{

    

    while (true)
    {
        leds = 0;

        // Beep
        alarm.playTone("A", Buzzer::HIGHER_OCTAVE);
        wait_us(250000);
        alarm.rest();

        // Wait for the blue button using a while loop
        while (SW1==0) { };
             
            

        // For full marks, debounce the switches with suitable delays

        // This is a "combination lock" activity. Write some code to detect the following sequence of press-and-release inputs
        // SW1, SW2, SW5, SW3 and SW4, SW2 and SW3
        // If the full sequence is entered, correctly, the green LED should flash 3 times
        // If a sequence of inputs was entered incorrectly, the red LED should light and the buzzer should sound for 5 seconds
        // For full marks, debounce the switches and use flow control structures and arrays to avoid deep nesting of code

        

        // ***** MODIFY THE CODE BELOW HERE *****

        // ***** MODIFY THE CODE ABOVE HERE *****
       
       int Inputs = (SW1==0) << 0 | (SW2==1) << 1 | (SW3==1) << 2 | (SW4==1) << 3 | (SW5==1) << 4;
       int i;

       switch (Inputs) {

        case 0:
        printf("Please Enter Combination\n");

        if (false) {
            alarm.playTone("A", Buzzer::HIGHER_OCTAVE);
        wait_us(250000);
        alarm.rest();
        leds = 4;
        wait_us(5000000);
        leds = 0;
        }

        break;
       
        case 1:
        printf("Input 1 is Correct\n");

         if (false) {
            alarm.playTone("A", Buzzer::HIGHER_OCTAVE);
        wait_us(250000);
        alarm.rest();
        leds = 4;
        wait_us(5000000);
        leds = 0;
        }

        break;

        case 2:
        printf("Input 2 is Correct\n");

         if (false) {
            alarm.playTone("A", Buzzer::HIGHER_OCTAVE);
        wait_us(250000);
        alarm.rest();
        leds = 4;
        wait_us(5000000);
        leds = 0;
        }

        break;
       
        case 16:
        printf("Input 3 is Correct\n");

         if (false) {
            alarm.playTone("A", Buzzer::HIGHER_OCTAVE);
        wait_us(250000);
        alarm.rest();
        leds = 4;
        wait_us(5000000);
        leds = 0;
        }

        break;

        case 12:
        printf("Input 4 is Correct\n");

         if (false) {
            alarm.playTone("A", Buzzer::HIGHER_OCTAVE);
        wait_us(250000);
        alarm.rest();
        leds = 4;
        wait_us(5000000);
        leds = 0;
        }

        break;

        case 6:
        printf("Combination is Correct!\n");
        for (int i = 0; i < 3; i = i +1)
        {
             leds = 1;
             wait_us(1000000);
             leds = 0;
             wait_us(1000000);
        }

         if (false) {
            alarm.playTone("A", Buzzer::HIGHER_OCTAVE);
        wait_us(250000);
        alarm.rest();
        leds = 4;
        wait_us(5000000);
        leds = 0;
        }


Solution

  • You can make a bitmask integer where each bit corresponds to the state of one button like this:

    unsigned int inputs = (SW1==0) << 0 | (SW2==0) << 1 | (SW3==0) << 2 | (SW4==0) << 3 | (SW5==0) << 4;
    

    If you haven't seen those operators before, << is a left shift operator and | is a logical OR operator and you can look them up in any decent C++ book or introductory resource.

    Your switch statement might look like this:

    switch(inputs) {
    case 0:  // No buttons pressed
      break;
    case 1:  // SW1 pressed (bit 0 is 1)
      break;
    case 2:  // SW2 pressed (bit 1 is 1)
      break;
    case 4:  // SW3 pressed (bit 2 is 1)
      break;
    case 6:  // SW2 and SW3 pressed
      break;
    case 8:  // SW4 pressed (bit 4 is 1)
      break;
      // ...
    case 31:  // All switches pressed
      break;
    }