Go Down

Topic: How to convert byte of data to individual button presses? (Read 757 times) previous topic - next topic

orionsbelt0

So I am working on a big project and need help with one little roadblock I haven't had to do before.  I am using an MCP23017 (i2c general I/O expander) with its interrupt function to grab button presses very efficiently.  I have everything working with the chip.  However when the MCP23017 returns what button was pressed in comes in as a byte (10000000) with whichever 1 standing for which button was pressed.

How do I break that byte to use individually.  So I can then say "if button x was pressed do this".  I can take care of all the if statements and such just need to know how to break it apart.  Bit shifts???

Thanks!

#1
Feb 05, 2013, 09:51 pm Last Edit: Feb 05, 2013, 09:54 pm by TexasStingray Reason: 1
Can you just do something like this

switch (byte) {
case 10000000:
  ....
  ....
  break;
case 1000000:
  ....
  ....
  break;
case 100000:
  ....
  ....
  break;
case 10000:
  ....
  ....
  break;
case 1000:
  ....
  ....
  break;
case 100:
  ....
  ....
  break;
case 10:
  ....
  ....
  break;
case 1:
  ....
  ....
  break;
default:
  ....
  ....
  break;
}





orionsbelt0

*headdesk* found it.  Ill post for anyone else future reference.


Code: [Select]
b1 = bitRead(x,0);
b2 = bitRead(x,1);
b3 = bitRead(x,2);
b4 = bitRead(x,3);
b5 = bitRead(x,4);
b6 = bitRead(x,5);
b7 = bitRead(x,6);
b8 = bitRead(x,7);


where x is the byte and the b1-8 are the individual buttons.

That case thing would work but I think it would miss presses if they happen at the same time.

Delta_G

You don't need 255.  If you do it the smart way you only need 8.


You don't need 255.  If you do it the smart way you only need 8.


Which is what I have, you have to test with if then else logic anyways.

PeterH


That case thing would work but I think it would miss presses if they happen at the same time.


The 'best' design depends how much similarity there is between the code to handle the different button presses. If they're completely different, I'd use a loop to shift and mask bits out of the byte, and for each bit that was set I'd call a handler which used a switch statement to select the case corresponding to the bit number of the set bit. If the handlers were very similar, I'd define a function which accepted the bit number as an argument and call that for each set bit.

Either way, to cope with multiple simultaneous button presses you need to test each bit individually, and I'd use a loop to do that.

If you can safely assume only one button is pressed at a time, you can just switch on the original byte value and avoid all that fiddling.
I only provide help via the forum - please do not contact me for private consultancy.

I'm sure thats true, but he said "returns what button was pressed" not buttons were pressed.

PeterH

I'm sure that's true, but it may be that the significance of that subtle difference between 'button' and 'buttons' had not occurred to the OP.
I only provide help via the forum - please do not contact me for private consultancy.

Then he still has to code for ever combination of all possible combinations. Doesn't he?

PeterH


Then he still has to code for ever combination of all possible combinations. Doesn't he?


No; not for every combination.

If he knows that only one button will be pressed at a time, the simple solution is just to hard-code the eight possible one-bit values in a switch statement.

If they might possibly arrive in combinations, the simplest solution is to test each bit in turn and handle any bit that is set. This just needs a couple of extra lines over the previous case.
I only provide help via the forum - please do not contact me for private consultancy.

lloyddean

My 3 cents ...

Code: [Select]

#define ENTRIES(ARRAY)      (sizeof(ARRAY)/ sizeof(ARRAY[0]))

typedef void (*button_handler_ptr)(void);

void button_handler_8()    {}
void button_handler_7()    {}
void button_handler_6()    {}
void button_handler_5()    {}
void button_handler_4()    {}
void button_handler_3()    {}
void button_handler_2()    {}
void button_handler_1()    {}

button_handler_ptr button_handlers[] =
{
      button_handler_1
    , button_handler_2
    , button_handler_3
    , button_handler_4
    , button_handler_5
    , button_handler_6
    , button_handler_7
    , button_handler_8
};


void handle_buttons(byte button_bits)
{
    for ( uint8_t i = 0; i < ENTRIES(button_handlers); button_bits >>= 1, i++ )
    {
        if ( button_bits & 1 )
        {
            // ... dispatch to button handler function ...
           
            (*button_handlers[i])();
        }
    }
}

void loop()
{
    //  ... some code      ...

    handle_buttons(0b11011011);

    //  ... some more code ...
}

void setup()
{
    // ... some setup code ...
}


Go Up