Sparkfun 7 Segment Serial Display - Push button Counter

Hi,

I have been trying to make a simple Pushbutton counter that adds up every time the button is pressed.

I am using the SparkFun 7 Segment serial display and a simple push button. https://www.sparkfun.com/products/11442

I did not find anything similar in the example library, just tried to follow a tutorial online but it uses different hardware.

http://missionduke.com/wordpress/2011/0 … s-counter/

The tutorial kinda works but the numbers appear randomly on the screen, meaning it does not count 0001,0002,0003,0004,0005… It counts 0100, 0002, 0300, 0004, 0500, …

So it is a little bit confused.

If anyone can recommend a good example or an idea how to make it simply work. Its appreciated a lot!!!

Are you debouncing the button input? The link to the code on that site returns a 404.

Hi,

I found out that I have to debounce the button. The code I have now works with counting up the numbers but I still need to debounce the button.

I am trying to do that now.

/*
 Stepper Motor Control - one revolution

 This program drives a unipolar or bipolar stepper motor.
 The motor is attached to digital pins 8 - 11 of the Arduino.

 The motor should revolve one revolution in one direction, then
 one revolution in the other direction.


 Created 11 Mar. 2007
 Modified 30 Nov. 2009
 by Tom Igoe

 */
#include <SoftwareSerial.h>  //for software serial communication
#include <Stepper.h>


#define txPin 5  //change to your serial port on Arduino board
#define rxPin 6  //not used but is required


SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);
int buttonPressCount;

const int  buttonPin = 3;    //the pin that the pushbutton is attached to

int buttonPushCounter = 0;   //counter for the number of button presses
int buttonState = 0;         //current state of the button
int lastButtonState = 0;     //previous state of the button


const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

void setup() {
  // set the speed at 60 rpm:
  myStepper.setSpeed(225);
  pinMode(buttonPin, INPUT);  //initialize the button pin as a input
  // initialize the serial port:
  Serial.begin(9600);

   pinMode(txPin, OUTPUT);
 //the following resets the board, changes the brightness to 100%, and sets the board to '0000':
 mySerial.begin(9600);
 mySerial.print(0x7A); //special character
 mySerial.print(0x00); //set brightness to full
 mySerial.print(0x76); //reset board
 mySerial.print(0); //send '0' character
 mySerial.print(0); //send '0' character
 mySerial.print(0); //send '0' character
 mySerial.print(0); //send '0' character
}

void loop() {
  // step one revolution  in one direction:
  Serial.println("clockwise");
  myStepper.step(stepsPerRevolution);


buttonState = digitalRead(buttonPin);  //read the pushbutton input pin

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // went from off to on:
      buttonPushCounter++;
      
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter, DEC);
      updateDisplay(buttonPushCounter);  //function to update the display 'requires button press count'
      
      
    } 

  }
 
  lastButtonState = buttonState;  // save the current state as the last state, for next time through the loop
 
}


void updateDisplay(int buttonPushCounter){
String intString = String(buttonPushCounter);  //changes integer to a string
char displayChars[4];  //create array to hold the four numbers
int stringLength = intString.length();  //get length of the string
//the following will determine if the button press count variable has 1, 2, 3, or 4 numbers in it
//and will fill the empty spaces with '0'. so if the button press count variable is '29' it will end up being '0029':
if(stringLength == 4){
  displayChars[0] = intString.charAt(0);
  displayChars[1] = intString.charAt(1);
  displayChars[2] = intString.charAt(2);
  displayChars[3] = intString.charAt(3);
}else if(stringLength == 3){
  displayChars[0] = 0;
  displayChars[1] = intString.charAt(0);
  displayChars[2] = intString.charAt(1);
  displayChars[3] = intString.charAt(2);
}else if(stringLength == 2){
  displayChars[0] = 0;
  displayChars[1] = 0;
  displayChars[2] = intString.charAt(0);
  displayChars[3] = intString.charAt(1);
}else if(stringLength == 1){
  displayChars[0] = 0;
  displayChars[1] = 0;
  displayChars[2] = 0;
  displayChars[3] = intString.charAt(0);
}
// mySerial.print(0x76); //Reset board
 //mySerial.print(0x76); //Reset board
 //mySerial.print(0x76); //Reset board
 //mySerial.print(0x76); //Reset board
 mySerial.print(displayChars[0]); //Send '0' character
 mySerial.print(displayChars[1]); //Send '0' character
 mySerial.print(displayChars[2]); //Send '0' character
 mySerial.print(displayChars[3]); //Send '0' character

delay(100); //this will make it so you don't get double counts. you could also use this to avoid someone pressing the button repeatedly 'for fun!'
  
}

Hi,

To make it clear for anyone that wants to help me:

I have this code running above. It is basically a 4 digit display that counts up when a button is pressed and a stepper is moving a mechanism.

The last hours I have been trying to debounce the button, because everytime the button is pushed the stepper motor shortly stops.

I tried using the arduino library bounce2 (https://github.com/thomasfredericks/Bounce2).

This debounce tutorial (https://www.arduino.cc/en/Tutorial/Debounce).

And also tried hardware debouncing…

I had no luck. Nothing worked for me. I think I am implementing it wrong.

Any suggestions how to simply make it debounce?

:?

Maybe you could tell us how you tried to implement them…

Hi, Ok I have been reading and trying some other things and managed now to have a debounced button that counts the display up 1 every time its pushed. This works perfectly. My next step is now to have a Stepper motor running at the same. I have been trying to make it work with attachinterrupt. But no luck. Does anyone know a way how to have the stepper running continuously while the button can count up numbers?

Thanks!

Counter Code (This works!)

#include <SoftwareSerial.h>

// These are the Arduino pins required to create a software seiral
//  instance. We'll actually only use the TX pin.
const int softwareTx = 8;
const int softwareRx = 7;

const int buttonPin = 2;
int buttonState;
int lastButtonState = LOW;

long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers



SoftwareSerial s7s(softwareRx, softwareTx);

unsigned int counter = 0;  // This variable will count up to 65k
char tempString[10];  // Will be used with sprintf to create strings

void setup(){
  
  pinMode(buttonPin, INPUT);
  // Must begin s7s software serial at the correct baud rate.
  //  The default of the s7s is 9600.
  s7s.begin(9600);
clearDisplay(); 
   
}

void loop(){
 
  // Magical sprintf creates a string for us to send to the s7s.
  //  The %4d option creates a 4-digit integer.
  sprintf(tempString, "%4d", counter);

  // This will output the tempString to the S7S
  s7s.print(tempString);
  setDecimals(0b00001000);  // Sets digit 3 decimal on


int reading = digitalRead(buttonPin);

// If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        counter++;
      }
    }

}
 lastButtonState = reading;
}


// Send the clear display command (0x76)
//  This will clear the display and reset the cursor
void clearDisplay()
{
  s7s.write(0x76);  // Clear display command
}


// Turn on any, none, or all of the decimals.
//  The six lowest bits in the decimals parameter sets a decimal 
//  (or colon, or apostrophe) on or off. A 1 indicates on, 0 off.
//  [MSB] (X)(X)(Apos)(Colon)(Digit 4)(Digit 3)(Digit2)(Digit1)
void setDecimals(byte decimals)
{
  s7s.write(0x77);
  s7s.write(decimals);
}

Attachinterrupt Code (This code does not work. On the first button push it counts up 1 and then doesn’t react anymore.)

#include <SoftwareSerial.h>

// These are the Arduino pins required to create a software seiral
//  instance. We'll actually only use the TX pin.
const int softwareTx = 8;
const int softwareRx = 7;



const int buttonPin = 0;
int buttonState;
int lastButtonState = LOW;

long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers




SoftwareSerial s7s(softwareRx, softwareTx);

unsigned int counter = 0;  // This variable will count up to 65k
char tempString[10];  // Will be used with sprintf to create strings

void setup(){
  pinMode(buttonPin, INPUT);
  attachInterrupt(buttonPin, count, RISING);
 
  s7s.begin(9600);
clearDisplay(); 
   
}

void loop(){
 
  // Magical sprintf creates a string for us to send to the s7s.
  //  The %4d option creates a 4-digit integer.
  sprintf(tempString, "%4d", counter);

  // This will output the tempString to the S7S
  s7s.print(tempString);
  setDecimals(0b00001000);  // Sets digit 3 decimal on



}

// Send the clear display command (0x76)
//  This will clear the display and reset the cursor
void clearDisplay()
{
  s7s.write(0x76);  // Clear display command
}


// Turn on any, none, or all of the decimals.
//  The six lowest bits in the decimals parameter sets a decimal 
//  (or colon, or apostrophe) on or off. A 1 indicates on, 0 off.
//  [MSB] (X)(X)(Apos)(Colon)(Digit 4)(Digit 3)(Digit2)(Digit1)
void setDecimals(byte decimals)
{
  s7s.write(0x77);
  s7s.write(decimals);
}


 void count() {
 

int reading = digitalRead(buttonPin);

// If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        counter++;
      }
    }

}
 lastButtonState = reading;
 
 }

ajurtan:
Attachinterrupt Code (This code does not work. On the first button push it counts up 1 and then doesn’t react anymore.)

As noted at [https://www.arduino.cc/en/Reference/AttachInterrupt](https://www.arduino.cc/en/Reference/AttachInterrupt):

Typically global variables are used to pass data between an ISR and the main program. To make sure variables shared between an ISR and the main program are updated correctly, declare them as volatile.