Skidlz

Debounced Button Module

May 17th, 2021 (edited)
546
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //Debounced button module------------------------
  2. //8 buttons are read through a 74*165 shift register
  3. //8 LEDs are driven by a 74*541 buffer
  4. //can invert or toggle any of 8 outputs
  5. //pressing both invert & toggle lets you set hiZ
  6.  
  7. //pins------------------------------------------
  8. const int shft = 8;     //shift/!load
  9. const int clk = 9;      //clock
  10. const int shftOut = 10; //output !qh
  11.  
  12. const int invBtn = 11;  //invert button
  13. const int tglBtn = 12;  //toggle button
  14.  
  15. typedef struct BUTTON {
  16.   int outPin;     //output pin to control
  17.   int lastState;  // the previous reading from the input pin
  18.   int state;
  19.   unsigned long tStamp; //last toggled time stamp
  20.   int outState;   //status of output pin
  21.   bool toggle;    //output toggles with each press
  22.   bool invert;    //invert output
  23.   bool hiZ;
  24. } BUTTON;
  25.  
  26. const int but_cnt = 8;
  27. BUTTON buttons[but_cnt]; // array of button structs
  28.  
  29. const long debounceDelay = 50;    // the debounce time
  30.  
  31. void setup() {
  32.   //shift reg for buttons 0-7
  33.   pinMode(shft, OUTPUT);
  34.   pinMode(clk, OUTPUT);
  35.   pinMode(shftOut, INPUT);
  36.   digitalWrite(shft, HIGH);
  37.  
  38.   pinMode(invBtn, INPUT_PULLUP);
  39.   pinMode(tglBtn, INPUT_PULLUP);
  40.  
  41.   //--------outPin, lastState, state, tStamp, outState, toggle, invert
  42.   buttons[0] = (BUTTON){7, LOW, LOW, 0, LOW, false, false, false}; //init button array
  43.   buttons[1] = (BUTTON){6, LOW, LOW, 0, LOW, false, false, false};
  44.   buttons[2] = (BUTTON){5, LOW, LOW, 0, LOW, false, false, false};
  45.   buttons[3] = (BUTTON){4, LOW, LOW, 0, LOW, false, false, false};
  46.   buttons[4] = (BUTTON){3, LOW, LOW, 0, LOW, false, false, false};
  47.   buttons[5] = (BUTTON){2, LOW, LOW, 0, LOW, false, false, false};
  48.   buttons[6] = (BUTTON){1, LOW, LOW, 0, LOW, false, false, false};
  49.   buttons[7] = (BUTTON){0, LOW, LOW, 0, LOW, false, false, false};
  50.  
  51.   for (int i = 0; i < but_cnt; i++){ //setup pins
  52.     pinMode(buttons[i].outPin, OUTPUT); //out 0
  53.     digitalWrite(buttons[i].outPin, buttons[i].outState);
  54.   }
  55. }
  56.  
  57. void loop() {
  58.   //check toggle & invert buttons-----------------
  59.   int togglePressed = !digitalRead(tglBtn);
  60.   int invertPressed = !digitalRead(invBtn);
  61.  
  62.   //latch button shift register--------------------
  63.   digitalWrite(shft, LOW);
  64.   delay(1);
  65.   digitalWrite(shft, HIGH); //shift
  66.   delay(1);
  67.  
  68.   //loop buttons-----------------------------------
  69.   for (int i = 0; i < but_cnt; i++){
  70.     int reading = digitalRead(shftOut); //read button
  71.  
  72.     digitalWrite(clk, LOW); //clock next bit out of shift reg
  73.     delay(1);
  74.     digitalWrite(clk, HIGH);
  75.    
  76.     //reset debounce timer if state changed
  77.     if (reading != buttons[i].lastState) buttons[i].tStamp = millis();
  78.  
  79.     if ((millis() - buttons[i].tStamp) > debounceDelay) { //waited longer than delay
  80.       if (reading != buttons[i].state) { //button has changed
  81.         buttons[i].state = reading;
  82.         if (togglePressed || invertPressed){ //one or both modifier buttons pressed
  83.           if (reading){ //toggle settings
  84.             if (!(togglePressed && invertPressed)){ // one or the other
  85.               buttons[i].toggle = buttons[i].toggle ^ togglePressed;
  86.               buttons[i].invert = buttons[i].invert ^ invertPressed;
  87.             } else { //both = hiZ toggle
  88.               buttons[i].hiZ = !buttons[i].hiZ;
  89.               pinMode(buttons[i].outPin, buttons[i].hiZ ? INPUT:OUTPUT); //toggle hiZ output
  90.             }
  91.           }
  92.         } else { //no modifier buttons pressed
  93.           if (buttons[i].toggle){
  94.             if (reading) buttons[i].outState = !buttons[i].outState;
  95.           } else {
  96.             buttons[i].outState = reading;
  97.           }
  98.         }
  99.       }
  100.     }
  101.    
  102.     int output = buttons[i].outState ^ buttons[i].invert;
  103.     digitalWrite(buttons[i].outPin, output); //write output
  104.     buttons[i].lastState = reading;
  105.   }  
  106. }
Add Comment
Please, Sign In to add comment