maxint-rd / TM16xx

Arduino TM16xx library for LED & KEY and LED Matrix modules based on TM1638, TM1637, TM1640 and similar chips. Simply use print() on 7-segment and use Adafruit GFX on matrix.
164 stars 34 forks source link

Button numbering question for TM1638 LED&KEY module (8 LEDS, 8 digits, 8 Buttons)? #48

Closed zapdogster closed 1 week ago

zapdogster commented 4 months ago

I am testing this library by running the TM16xxButtons_clicks.ino example. I was expecting the Button numbers to be reported as either 0 thru 7, or 1 thru 8. However this is what I see: ButtonPressed DisplayedValue fnClick Reported Button 1 10000 Button 16 Click 2 40000 Button 18 Click 3 100000 Button 20 Click 4 400000 Button 22 Click 5 20000 Button 17 Click 6 80000 Button 19 Click 7 200000 Button 21 Click 8 800000 Button 23 Click

I think I see where these values are created: TM1628::getButtons(void) in TM1628.cpp

Is there something simple I'm missing to get the values I was expecting? Or do i have to do a manual translation to get the expected values? Thx!

zapdogster commented 4 months ago

Not sure this is the best approach, but I just did a brute force translation. Pls let me know if there is a better way:

// ** // Function to translate button hex code returned to expected 0-7 value int fnTranslateButtonCode (uint32_t dwButton) { int i_ButtonTranslated = dwButton >> 16 ;

switch (i_ButtonTranslated) { case 0x01: i_ButtonTranslated = 0 ; break ; case 0x04: i_ButtonTranslated = 1 ; break ; case 0x10: i_ButtonTranslated = 2 ; break ; case 0x40: i_ButtonTranslated = 3 ; break ; case 0x02: i_ButtonTranslated = 4 ; break ; case 0x08: i_ButtonTranslated = 5 ; break ; case 0x20: i_ButtonTranslated = 6 ; break ; case 0x80: i_ButtonTranslated = 7 ; break ; } return i_ButtonTranslated ; }

maxint-rd commented 4 months ago

Hello @zapdogster ,

The getButtons() method of the chip-specific class indeed does the work. In your case of the TM1638 LED&KEY module, it is TM1638.cpp that has the implementation. The number of buttons supported depends on the specific chip. While your module has eight buttons, the TM1638 chip supports 8x3 buttons and simultaneous presses. There is another TM1638 module that has a 4x4 keypad. Other chips have different support for buttons, as you can see in this table. To implement a uniform interface the getButtons() method returns a 32-bit value,, representing the state of a maximum of 32 buttons. The LED&KEY module only uses buttons on the K3 pin, which are returned by getButtons() as the third byte of the 32-bit value, giving you buttons 16-23. (The 4x4 button module also returns other values)

The TM16xxButtons_clicks example uses the TM16xx buttons class to report the pressed button. The callback functions receive buttons numbers in the range 0-31, based on their bit position. The easiest way to change the button number to a 0-7 range in for instance fnClick is to simply subtract 16 from the value:

void fnClick(byte nButton)
{
  nButton=nButton-16;       // change values 16-23 to 0-7
  Serial.print(F("Button "));
  Serial.print(nButton);
  Serial.println(F(" click."));
} // click

Edit: as you noticed the button order may seem less logic. The actual order depends on the wiring on the module. Your method of using a switch statement is a good way, but I would manipulate the button number in the callback function instead of the 32-bit value. My reason is that those callback functions add very useful functionality, such as detecting simultaneous presses, long key presses and double clicks. Therefor if needed I would just make a simple translation function to change the order and call that in the callback functions.

maxint-rd commented 1 week ago

Closed as no further action is expected. Hopefully my last response was helpful. Feel free to reopen if you have further (related) questions.