Pages: [1]   Go Down
Author Topic: Shift register 4021 debounce or something else?  (Read 1712 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Sr. Member
****
Karma: 1
Posts: 259
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi to all, I have 5 4021 registers daisy chained and everything works pretty much as expected except this issue: Sometimes when I press button Arduino thinks I've pressed it twice and since I'm building MIDI controller I can't allow that. The code is pretty much the same as in tutorial.
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8966
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you are connecting to physical buttons you should probably include some debounce logic.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Sr. Member
****
Karma: 1
Posts: 259
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How do I do that for shift registers?
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8966
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Same way as for any other button.  If it has been less than 'n' milliseconds since that button last transitioned from not pressed to pressed, ignore the press.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Sr. Member
****
Karma: 1
Posts: 259
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm lost on this. Here is my code, so I'd appreciate some help with this:

Code:
//#define DEBUG
#include <ShiftRegisterDataCollect.h>

//number of shift registers
#define NUMBER_OF_SHIFT_REGISTERS 5

//shift register pins
#define CLOCK_PIN 7
#define LATCH_PIN 8
#define DATA_PIN 9

//array of first 8 basic 2^n values
int arrayOfBasicValues[8] = { 128, 64, 32, 16, 8, 4, 2, 1 };

//array of sum of basic values
int arrayOfSum[8*NUMBER_OF_SHIFT_REGISTERS] = { 0 };

//array of previous values
boolean arrayOfButtonChange[8*NUMBER_OF_SHIFT_REGISTERS] = { false };

//array of MIDI note values
int arrayOfMIDInotes[8] = { 30, 31, 32, 33, 34, 35, 36, 37 };

//for loop variable
int i = 0;

//Define variables to hold the data for each shift register.
byte switchVar[NUMBER_OF_SHIFT_REGISTERS] = {0};

ShiftRegisterDataCollect shiftData(LATCH_PIN, CLOCK_PIN, DATA_PIN);


void setup() {
  //start serial
  Serial.begin(9600);

}

void loop() {
 
 
  shiftData.latchPin();

  for (i=0; i<NUMBER_OF_SHIFT_REGISTERS; i++)  {
   
  //get values from shift register
  switchVar[i] = shiftData.shiftInFunc();
 
  //break result to set of basic values and then generate MIDI notes
  resultBreak(switchVar[i], i);

  }

}


int resultBreak (int readData, int shiftRegisterNumber) {
 
  int j = 0;
  int n = 0;

  for (j=0; j<8; j++) {
   
 //first part of the loop. get basic values   
 
      if (readData >= arrayOfBasicValues[j]) {
           
            arrayOfSum[j+8*shiftRegisterNumber] = arrayOfBasicValues[j];
           
            readData -= arrayOfBasicValues[j];

      }  else arrayOfSum[j+8*shiftRegisterNumber] = 0;
     
     
      //second part of the loop, send midi values
      if (arrayOfSum[j+8*shiftRegisterNumber] != 0 && arrayOfButtonChange[j+8*shiftRegisterNumber] == false) {
     
              sendMIDI(arrayOfSum[j+8*shiftRegisterNumber], shiftRegisterNumber);
             
              //true indicates that the button is pressed so that the code sends only one MIDI note while button is pressed
              arrayOfButtonChange[j+8*shiftRegisterNumber] = true;
          }
         
       //if the button isn't pressed anymore, set value in arrayOfButtonState to false
      if (arrayOfSum[j+8*shiftRegisterNumber] == 0)  arrayOfButtonChange[j+8*shiftRegisterNumber] = false;   
             
  }
}

void sendMIDI (int value, int shiftRegisterNumber) {
 
   
   int i;
   char note;

   for (i=0; i<8; i++) {
 
    //find the correct value in array of basic values and generate note code
    if (value == arrayOfBasicValues[i])  { note = arrayOfMIDInotes[i] + (8*shiftRegisterNumber); break; }
   
   }
   
    #ifdef DEBUG
    Serial.print("button: ");
    Serial.print (value);
    Serial.print("\n");
    Serial.print("register number: ");
    Serial.print (shiftRegisterNumber + 1);
    Serial.print("\n");

  #else
    Serial.write(0x90);
    Serial.write(note);
    Serial.write(0x45);
   
    #endif
 
}
 
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 34541
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
How do I do that for shift registers?
Make sure you do not read the shift registers any faster than every 20mS. When you get the other stuff in the loop you will find you won't anyway.
Logged

Offline Offline
Sr. Member
****
Karma: 1
Posts: 259
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I eventually solved it using another array.

Code:
//#define DEBUG
#include <ShiftRegisterDataCollect.h>

//number of shift registers
#define NUMBER_OF_SHIFT_REGISTERS 5

//shift register pins
#define CLOCK_PIN 7
#define LATCH_PIN 8
#define DATA_PIN 9

//array of first 8 basic 2^n values
int arrayOfBasicValues[8] = { 128, 64, 32, 16, 8, 4, 2, 1 };

//array of sum of basic values
int arrayOfSum[8*NUMBER_OF_SHIFT_REGISTERS] = { 0 };

//array of previous values
int arrayOfButtonChange[8*NUMBER_OF_SHIFT_REGISTERS] = { 0 };

//array of debouncing time
unsigned long int arrayOfDebounce[8*8*NUMBER_OF_SHIFT_REGISTERS] = { 0 };

//array of MIDI note values
int arrayOfMIDInotes[8] = { 30, 31, 32, 33, 34, 35, 36, 37 };

//for loop variable
int i = 0;

//Define variables to hold the data for each shift register.
byte switchVar[NUMBER_OF_SHIFT_REGISTERS] = {0};

ShiftRegisterDataCollect shiftData(LATCH_PIN, CLOCK_PIN, DATA_PIN);

//minimum time between 2 button presses
unsigned long int debounceDelay = 40;

void setup() {
  //start serial
  Serial.begin(9600);

}

void loop() {
  
  shiftData.latchPin();

  for (i=0; i<NUMBER_OF_SHIFT_REGISTERS; i++)  {
    
  //get values from shift register
  switchVar[i] = shiftData.shiftInFunc();
  
  //break result to set of basic values and then generate MIDI notes
  resultBreak(switchVar[i], i);

  }
}


int resultBreak (int readData, int shiftRegisterNumber) {
  
  int j = 0;
  int n = 0;

  for (j=0; j<8; j++) {
    
 //first part of the loop. get basic values    
 
      if (readData >= arrayOfBasicValues[j]) {
            
            arrayOfSum[j+8*shiftRegisterNumber] = arrayOfBasicValues[j];
            
            readData -= arrayOfBasicValues[j];

      }  else arrayOfSum[j+8*shiftRegisterNumber] = 0;
      
      
      //second part of the loop, send midi values and debounce
      if ((arrayOfSum[j+8*shiftRegisterNumber] - arrayOfButtonChange[j+8*shiftRegisterNumber]) == arrayOfSum[j+8*shiftRegisterNumber]) {
          
                      //debounce
                      arrayOfDebounce[j+8*shiftRegisterNumber] = millis();
                      
                      //set arrayOfButtonChange to 1 since the button has changed state
                      arrayOfButtonChange[j+8*shiftRegisterNumber] = 1;
                      
      }
          //if button state has changed in less than 40ms ignore it, else send MIDI code
          if (((millis() - arrayOfDebounce[j+8*shiftRegisterNumber]) > debounceDelay) && (arrayOfButtonChange[j+8*shiftRegisterNumber] == 1)) {
          
            
            //send MIDI code
            sendMIDI(arrayOfSum[j+8*shiftRegisterNumber], shiftRegisterNumber);
            
            //sets arrayOfButtonChange to 2 since MIDI note has been sent nad makes sure that only one note is sent while button is being pressed
            arrayOfButtonChange[j+8*shiftRegisterNumber] = 2;
      }
          
       //if the button isn't pressed anymore, set value in arrayOfButtonState to zero
      if (arrayOfSum[j+8*shiftRegisterNumber] == 0)  arrayOfButtonChange[j+8*shiftRegisterNumber] = 0;  
              
  }
}

void sendMIDI (int value, int shiftRegisterNumber) {

   int i;
   char note;

   for (i=0; i<8; i++) {
  
    //find the correct value in array of basic values and generate note code
    if (value == arrayOfBasicValues[i])  { note = arrayOfMIDInotes[i] + (8*shiftRegisterNumber); break; }
    
   }
  
    #ifdef DEBUG
    Serial.print("button: ");
    Serial.print (value);
    Serial.print("\n");
    Serial.print("register number: ");
    Serial.print (shiftRegisterNumber + 1);
    Serial.print("\n");

  #else
    Serial.write(0x90);
    Serial.write(note);
    Serial.write(0x45);
    
    #endif
  
}



  
  
« Last Edit: March 15, 2012, 03:28:21 pm by kustom » Logged

Offline Offline
God Member
*****
Karma: 11
Posts: 599
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

..eventually..

Solved?

Greetz Chris
Logged


Pages: [1]   Go Up
Jump to: