Following on from our recent blog post on using the 8-digit 7-segment display on TM1638 modules with Arduino, here we will look at taking advantage of the eight push buttons on a TM1638 module (labelled S1 to S8 in the photograph below). Click here to buy TM1638 modules for under £2 delivered.
The tm1638 library for Arduino has a function getButtons():
byte buttons=module.getButtons();
…which returns an 8-bit byte value which tells you which of the eight buttons are currently being pressed.
Press the left most button S1, buttons returns 1, press S2 and get 2, press S3 and get 4, press S4 and get 8, S5=16, S6=32, S7=64, and S8 returns 128. Pressing multiple buttons at the same time results in buttons having a value equal to the sum of the values for the individual buttons being pressed – e.g. press S1 and S2 simultaneously and the value of buttons will be 1+2=3.
If only one button is being pressed at a time, then you can easily test for it – e.g. if buttons is equal to 64, we know that button S7 is being pressed; but if S7 is pressed simultaneously with another button, the returned value of buttons will not be equal to 64, and without doing some messy calculations, we cannot know which other button(s) have been pressed.
Here is the code required to display the 0-255 value of buttons on the LED display of the TM1638 corresponding to the button(s) currently being pressed.
buttons=module.getButtons(); module.setDisplayToDecNumber(buttons,0,false);
We know that the value of buttons is always a number between 0 to 255 – an 8-bit byte. Knowing that 1 = 00000001, 2 = 00000010, 4 = 00000100, 8 = 00001000 etc in binary, we can simply examine the bits of the byte, and where we find 1s, we know that the button corresponding to that bit is being pressed.
If S1 and S3 are pressed simultaneously for example, module.getButtons() will return the value 4+1 = 5 which is 00000101 in binary. The bit furthest to the right (the least significant bit) corresponds to S1, the second from the right to S2, the third from the right to S3, and so on. 0 indicates not pressed, and 1 indicates pressed.
With Arduino we have the handy function getBit(x, n) where x is the byte to be examined, and n is the position of the bit within that byte to be checked – 1 for the least significant bit to the right, and increasing as we move left to the more significant bits.
(Note that as the 8 LEDs on the TM1638 are controlled using an 8-bit byte also, if you get the value of the byte buttons=module.getButtons(), you can illuminate the corresponding LEDs with module.setLEDs(buttons). For example, module.setLEDs(1) will illuminate the first (left most) LED, module.setLEDs(128) will illuminate the last (right most) LED. With this code, whichever button(s) are pressed, the corresponding LEDs will all light up simultaneously.)
Below is an example Arduino sketch we have written to show how the TM1638 buttons can be tested individually to see if they are currently being pressed. The function we have written isButtonBeingPressed(buttonNumber) is used to test if a particular button (from 1 to 8) is currently being pressed. Knowing that button is being pressed can be used for user inputs to control your projects.
/* * REUK.co.uk - February 2016 * Useful function to test if one of the eight user input buttons * on a TM1638 module is currently being pressed. */ // The byte buttons is the value returned by the TM1638 to indicate // which buttons are currently being pressed. byte buttons; #include <TM1638.h> // define a module on data pin 8, clock pin 9 and strobe pin 7 TM1638 module(8, 9, 7); void setup(){} void loop(){ // The buttons S1 to S8 have the following values: // S1 = 1, S2 = 2, S3 = 4, S4 = 8, S5 = 16, S6 = 32, S7 = 64, S8 = 128 // If multiple buttons are pressed simultaneously, add their values together. // DEMONSTRATION - Loop through the 8 buttons, testing each to see if it is // currently being pressed. If a button is being pressed, show its number (1-8) // on the LED display...Leave it displayed until a different button is pressed. for(int buttonToTest = 1; buttonToTest < 9; buttonToTest++){ // Let the TM1638 process the button inputs buttons = module.getButtons(); if(isButtonBeingPressed(buttonToTest)){ // This button (buttonToTest) has been found to be pressed, so display it's number S1-S8 module.setDisplayToDecNumber(buttonToTest, 0, false); } } } // This function will return true if a particular button n is currently being pressed. boolean isButtonBeingPressed(int n){ // Button 1 status shown by bit0 of the byte buttons returned by module.getButtons() // Button 2 status shown by bit1 or the byte buttons ... // Button 3 status shown by bit2...etc // n - the number of the button to be tested) should be an integer from 1 to 8 if(n < 1 or n > 8) return false; // Read in the value of getButtons from the TM1638 module. buttons = module.getButtons(); // Which bit must we test for this button? int bitToLookAt = n - 1; // Read the value of the bit - either a 1 for button pressed, or 0 for not pressed. byte theValueOfTheBit = bitRead(buttons, bitToLookAt); // If the button is pressed, return true, otherwise return false. if(theValueOfTheBit == 1) return true; else return false; }