debounce with seven segment and shift register not lighting correct segments.

Writing a code to count button presses on a seven segment counter it needs to wait 200ms before it can count as a press which I have written a function for as well as a function to display the code on the segment. however rather than displaying any numbers or letters it lights up random segments ignores the debounce completely. any advice you can give me to correct this would be appreciated.

const int latchPin = 7; 
const int dataPin  = 4;  
const int clockPin = 8; 
int button = 13;  
int currentState = 1;
int previousState = 0;
int counter = 0;
unsigned long lastDebounceTime = 0; 
unsigned long debounceDelay = 200;   
int buttonState;
int lastButtonState = LOW;
bool b;

int number_array[16] =  // 0-9 A-F
  {
    B11111100,//0
    B01100000,//1
    B11011010,//2
    B11110010,//3
    B01100110,//4
    B10110110,//5
    B10111110,//6
    B11100000,//7
    B11111110,//8
    B11100110,//9
    B11101110,//A
    B00111110,//B
    B10011100,//C
    B01111010,//D
    B10011110,//E
    B10001110,//F
  };
  
void setup() {
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    pinMode(button, INPUT);
    debounce(button);
    writeToRegister (counter);

}

void loop() {
  debounce(button);
  if(counter<16){
    if(b) {counter++;}writeToShiftRegister(counter);}
    else if (counter == 16) {counter = 0;}
  }

  void writeToRegister (byte data){
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST,data);
    digitalWrite(latchPin, HIGH);}


  bool debounce(int pin){
  boolean state;
  boolean previousState;
  unsigned char count;
  if (b != digitalRead(pin)) {
    for(count = 0; count<20 && b != digitalRead(pin); count++);
    b=((count>=20 && b!=digitalRead(pin))?!b:b);
      if(!b) {(millis()-lastDebounceTime > debounceDelay);{
    lastDebounceTime = millis();
  }}}}

Did you write your own debounce routine?
There are tutorials for that.

ieee488:
Did you write your own debounce routine?
There are tutorials for that.

yes I followed several to get this one. though non of them seem to work when I put them inside a function.

The following should do the trick if a button press causes the input to go high. If a press causes the input to go low, then you will have to edit pines 70 and 75.

Note: The debouncing function I wrote was quick, untested, and blocking (~8ms of delay). You can change it to become non-blocking if you want.

const byte latchPin = 7;
const byte dataPin  = 4;
const byte clockPin = 8;
byte button = 13;
byte counter = 0;
byte previousState = 0;

int number_array[16] =  // 0-9 A-F
{
  B11111100,//0
  B01100000,//1
  B11011010,//2
  B11110010,//3
  B01100110,//4
  B10110110,//5
  B10111110,//6
  B11100000,//7
  B11111110,//8
  B11100110,//9
  B11101110,//A
  B00111110,//B
  B10011100,//C
  B01111010,//D
  B10011110,//E
  B10001110,//F
};

void setup()
{
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(button, INPUT);
  debounce(button);
  writeToRegister (counter);
}

void loop()
{
  debounce(button, previousState);
  
  if (counter < 16)
  {
    if (!pressed)
    {
      counter++;
    } writeToShiftRegister(counter);
  }
  else if (counter == 16)
  {
    counter = 0;
  }
}

void writeToRegister (byte data)
{
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, data);
  digitalWrite(latchPin, HIGH);
}


void debounce(int pin, byte &previousState)
{
  byte currentState = 0;
  byte pressed = 0;

  currentState = digitalRead(pin);
  
  if(currentState && !previousState)
  {
    while(pressed != 0xFF)
    {
      delay(1);
      pressed = (pressed << 1) | digitalRead(pin);
    }
  }

  previousState = currentState;
}

Power_Broker:
The following should do the trick if a button press causes the input to go high. If a press causes the input to go low, then you will have to edit pines 70 and 75.

Note: The debouncing function I wrote was quick, untested, and blocking (~8ms of delay). You can change it to become non-blocking if you want.

const byte latchPin = 7;

const byte dataPin  = 4;
const byte clockPin = 8;
byte button = 13;
byte counter = 0;
byte previousState = 0;

int number_array[16] =  // 0-9 A-F
{
  B11111100,//0
  B01100000,//1
  B11011010,//2
  B11110010,//3
  B01100110,//4
  B10110110,//5
  B10111110,//6
  B11100000,//7
  B11111110,//8
  B11100110,//9
  B11101110,//A
  B00111110,//B
  B10011100,//C
  B01111010,//D
  B10011110,//E
  B10001110,//F
};

void setup()
{
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(button, INPUT);
  debounce(button);
  writeToRegister (counter);
}

void loop()
{
  debounce(button, previousState);
 
  if (counter < 16)
  {
    if (!pressed)
    {
      counter++;
    } writeToShiftRegister(counter);
  }
  else if (counter == 16)
  {
    counter = 0;
  }
}

void writeToRegister (byte data)
{
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, data);
  digitalWrite(latchPin, HIGH);
}

void debounce(int pin, byte &previousState)
{
  byte currentState = 0;
  byte pressed = 0;

currentState = digitalRead(pin);
 
  if(currentState && !previousState)
  {
    while(pressed != 0xFF)
    {
      delay(1);
      pressed = (pressed << 1) | digitalRead(pin);
    }
  }

previousState = currentState;
}

i’ve tried modifying it like above however, it keeps segments d-g lit but doesnt change

dancingapples:
i’ve tried modifying it like above however, it keeps segments d-g lit but doesnt change

But does your button cause the Arduino input to go high or low during a button press? Also, can you just test if the button was debounced and ignore the segment LEDs for now? Let’s fix one thing at a time.

The reason you’re seeing seemingly random segments is because you are sending the wrong thing to the shift register.

Look, you have an array with the bit patterns for the 7-segment in them. But when you call shiftout, instead of sending the bit pattern that corresponds to the number you want to display, you just send the number itself. So the display lights up the segments in the bit pattern that number represents.

Instead of shifting out data, try shifting out number_array[data].

Delta_G:
The reason you’re seeing seemingly random segments is because you are sending the wrong thing to the shift register.

Look, you have an array with the bit patterns for the 7-segment in them. But when you call shiftout, instead of sending the bit pattern that corresponds to the number you want to display, you just send the number itself. So the display lights up the segments in the bit pattern that number represents.

Instead of shifting out data, try shifting out number_array[data].

Ive just tried switching to the array and though it gives returns actual numbers and letters now there completely random.

const byte latchPin = 7;  // Pin connected to Pin 12 of 74HC595 (Latch)
const byte dataPin  = 4;  // Pin connected to Pin 14 of 74HC595 (Data)
const byte clockPin = 8;  // Pin connected to Pin 11 of 74HC595 (Clock)
byte button = 13;  
byte currentState = 1;
byte previousState = 0;
int counter = 0;
unsigned long lastDebounceTime = 0; 
unsigned long debounceDelay = 200;   
int buttonState;
int lastButtonState = LOW;
bool b;

int number_array[16] =  // 0-9 A-F
  {
    B11111100,//0
    B01100000,//1
    B11011010,//2
    B11110010,//3
    B01100110,//4
    B10110110,//5
    B10111110,//6
    B11100000,//7
    B11111110,//8
    B11100110,//9
    B11101110,//A
    B00111110,//B
    B10011100,//C
    B01111010,//D
    B10011110,//E
    B10001110,//F
  };
  
void setup() {
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    pinMode(button, INPUT);
    debounce(button, previousState);
    writeToRegister(counter);
}

void loop() {
  while(digitalRead(button) ==LOW){
    debounce(button, previousState);
  }
  if(counter<16){
    if(!b) {counter++;}writeToRegister(counter);}
    else if (counter == 16) {counter = 0;}
  }

  void writeToRegister (byte data){
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST,number_array[data]);
    digitalWrite(latchPin, HIGH);}


  void debounce(int pin, byte &previousState){
  byte currentState = 0;
  byte b = 0;

  currentState = digitalRead(pin);
  if(currentState && !previousState){
    while(b != 0xFF){
      delay(1);
      b=(b<<1) | digitalRead(pin);
    }
  }
  previousState = currentState;
  }

this is what I’ve got so far.

It sounds like you didn't even have working sketch of being able to write the correct number ignoring for the moment use of the switch.

while(digitalRead(button) ==LOW){
    debounce(button, previousState);
  }

What’s the use of having that weird debounce routine if you’re just going to use digitalRead anyway to handle the loop?

Why do you have a global boolean named b and a local byte named b in the debounce function? Having two variables in the same scope with the same name is a recipe for trouble. Single letter variable names suck anyways.

I don’t get the point of your debounce routine. As far as I can tell, none of what it does affects any other part of the program in any way. It’s like it’s just there doing its own thing and not telling anybody about it. The only non-local variable it has anything to do with is previousState and that isn’t used anywhere else in the code.

When you get to here:

if(counter<16){
    if(!b) {counter++;}writeToRegister(counter);}
    else if (counter == 16) {counter = 0;}
  }

What’s the value of b? Where did it get that value? What’s the point of b?