Good day,
I'm new to the forum, but enjoy reading and scrolling through other posts to learn more on programming. I'm currently working on a project with a seven segment display counter that increases when a pushbutton is pressed. I've managed to get the counter to add 1 each time you press and release the button. What I'm struggling to do is that when I push and hold the button for longer than 1 second (and keep it pushed) the counter must increase continuously by 1 until the button is released. I've found coding on the forum that do exactly that, but I do not know you to implement and incorporate it in my current code. If someone can help me, I will be eternal gratefull.
Here are my code:
// Assign Shift Register Pins for Data, latch and Clock
int Target_dataPin = 2; //Target Shift Registers
int Target_latchPin = 3;
int Target_clkPin = 4;
// Assign pins for buttons
int Target_ButtonUp = A0;
int Target_ButtonDown = A1;
// Variable for reading the button status
int Target_ButtonUpV = 0;
int Target_ButtonDownV = 0;
// Previous state of each button declaration
int Target_ButtonUpV_LastButtonState = 0;
int Target_ButtonDownV_LastButtonState = 0;
// Initialize what will be displayed / variables
int Target_Display1 = 0, Target_Display2 = 0, Target_Display3 = 0;
// Set counters to zero for displays / set variables for the score
int Target_Count = 0;
void setup()
{
// Declare pins as outputs
pinMode(Target_latchPin, OUTPUT);
pinMode(Target_clkPin, OUTPUT);
pinMode(Target_dataPin, OUTPUT);
// Declare buttons as inputs
pinMode(Target_ButtonUp, INPUT_PULLUP);
pinMode(Target_ButtonDown, INPUT_PULLUP);
}
// End of setup()
void loop()
{
//Read the Button Pins to see if one of them has been pressed
Target_ButtonUpV = digitalRead (Target_ButtonUp);
Target_ButtonDownV = digitalRead (Target_ButtonDown);
//Read the Button Pins to see if one of them has been pressed
if (Target_ButtonUpV != Target_ButtonUpV_LastButtonState) {
// if the state has changed, increment the counter
if (Target_ButtonUpV == HIGH){
if (Target_Count != 999) Target_Count+=1;
}
}
if (Target_ButtonDownV != Target_ButtonDownV_LastButtonState) {
// if the state has changed, decrement the counter
if (Target_ButtonDownV == HIGH){
if (Target_Count != 0) Target_Count-=1;
}
}
// Save the current state as the last state for next time through the loop
Target_ButtonUpV_LastButtonState = Target_ButtonUpV;
Target_ButtonDownV_LastButtonState = Target_ButtonDownV;
delay(50);
UpdateDisplay();
}
// End of loop()
//*******************************
// Shift 8 bits out MSB first
void ShiftBits(byte DataOut)
{
int i = 0;
int pinState;
digitalWrite(Target_dataPin, 0);
digitalWrite(Target_clkPin, 0);
for (i = 7; i >= 0; i--)
{
digitalWrite(Target_clkPin, 0);
if (DataOut & (1 << i))
{
pinState = 1;
}
else
{
pinState = 0;
}
digitalWrite(Target_dataPin, pinState); // Sets the pin to HIGH or LOW depending on pinState
digitalWrite(Target_clkPin, 1); // Register shifts bits on upstroke of clock pin
digitalWrite(Target_dataPin, 0); // Zero the data pin after shift to prevent bleed through
}
digitalWrite(Target_clkPin, 0); // Stop shifting
} // End of ShiftBits()
//*******************************
void UpdateDisplay()
{
int aDecValues[] = { 63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 64 }; //103
unsigned long temp1;
boolean leadingZero;
temp1 = Target_Count;
int hundreds1 = temp1 / 100;
temp1 -= (hundreds1 * 100);
int tens1 = temp1 / 10;
temp1 -= (tens1 * 10);
int units1 = temp1;
if (leadingZero==false) // removing leading zeros
{
if (hundreds1==0 && tens1>0) {
hundreds1 = 64;
}
if (hundreds1==0 && tens1==0 && units1>0) {
hundreds1 = 64;
tens1 = 64;
}
if (hundreds1==0 && tens1==0 && units1==0) {
hundreds1 = 64;
tens1 = 64;
units1 = 64;
}
}
digitalWrite(Target_latchPin, 0);
ShiftBits(aDecValues[hundreds1]);
ShiftBits(aDecValues[tens1]); // Update tens digit
ShiftBits(aDecValues[units1]); // Update units digit
digitalWrite(Target_latchPin, 1);
delay(100); // Adjust this delay to vary the count time
} // End of UpdateDisplay()
That's quite amusing, because most beginners have the opposite problem! Their counters increase while the button is pressed and they want it to increase only once each time the button is pressed. That's because they haven't realised that they need their code to detect when the button changes from not being pressed to being pressed - a "state change" of the button.
So if you remove your code that checks for the button state change, you will get what you want. The only thing you may not have thought of is how fast you want the count to increase while the button is pressed. That's easy to do with delay(), unless there is a problem with using delay() in your sketch, such as needing to multiplex a display.
Dear b707
Thank you for the reply. Wherewith the combined code:
// Assign Shift Register Pins for Data, latch and Clock
int Target_dataPin = 2; //Target Shift Registers
int Target_latchPin = 3;
int Target_clkPin = 4;
// Assign pins for buttons
//int Reset_Button = ;
int Target_ButtonUp = A0;
int Target_ButtonDown = A1;
// Variable for reading the button status
int Target_ButtonUpV = 0;
int Target_ButtonDownV = 0;
// Previous state of each button declaration
int Target_ButtonUpV_LastButtonState = 0;
int Target_ButtonDownV_LastButtonState = 0;
// Initialize what will be displayed / variables
int Target_Display1 = 0, Target_Display2 = 0, Target_Display3 = 0;
// Set counters to zero for displays / set variables for the score
int Target_Count = 0;
// Interval time for long and short press
float value = 0;
unsigned long interval_1 = 30;
unsigned long interval_2 = 1000;
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
void setup()
{
// Declare pins as outputs
pinMode(Target_latchPin, OUTPUT);
pinMode(Target_clkPin, OUTPUT);
pinMode(Target_dataPin, OUTPUT);
// Declare buttons as inputs
pinMode(Target_ButtonUp, INPUT_PULLUP);
pinMode(Target_ButtonDown, INPUT_PULLUP);
}
// End of setup()
void loop() {
// Set currentMillies = millis
unsigned long currentMillis = millis();
if (currentMillis - previousMillis2 >= interval_2) {
//timer2 is done
interval_1 = 30;//this is for timer1
} else {
//timer2 not done
interval_1 = 500;//this is for timer1
}
//Read the Button Pins to see if one of them has been pressed
Target_ButtonUpV = digitalRead (Target_ButtonUp);
Target_ButtonDownV = digitalRead (Target_ButtonDown);
//Read the Button Pins to see if one of them has been pressed
if (Target_ButtonUpV != Target_ButtonUpV_LastButtonState) {
// if the state has changed, increment the counter
if (Target_ButtonUpV == HIGH){
if (Target_Count != 999) Target_Count+=1;
}
}
if (Target_ButtonDownV != Target_ButtonDownV_LastButtonState) {
// if the state has changed, decrement the counter
if (Target_ButtonDownV == HIGH){
if (Target_Count != 0) Target_Count-=1;
}
}
// Save the current state as the last state for next time through the loop
Target_ButtonUpV_LastButtonState = Target_ButtonUpV;
Target_ButtonDownV_LastButtonState = Target_ButtonDownV;
delay(50);
UpdateDisplay();
}
// End of loop()
//*******************************
// Shift 8 bits out MSB first
void ShiftBits(byte DataOut)
{
int i = 0;
int pinState;
digitalWrite(Target_dataPin, 0);
digitalWrite(Target_clkPin, 0);
for (i = 7; i >= 0; i--)
{
digitalWrite(Target_clkPin, 0);
if (DataOut & (1 << i))
{
pinState = 1;
}
else
{
pinState = 0;
}
digitalWrite(Target_dataPin, pinState); // Sets the pin to HIGH or LOW depending on pinState
digitalWrite(Target_clkPin, 1); // Register shifts bits on upstroke of clock pin
digitalWrite(Target_dataPin, 0); // Zero the data pin after shift to prevent bleed through
}
digitalWrite(Target_clkPin, 0); // Stop shifting
} // End of ShiftBits()
//*******************************
void UpdateDisplay()
{
int aDecValues[] = { 63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 64 }; //103
unsigned long temp1;
boolean leadingZero;
temp1 = Target_Count;
int hundreds1 = temp1 / 100;
temp1 -= (hundreds1 * 100);
int tens1 = temp1 / 10;
temp1 -= (tens1 * 10);
int units1 = temp1;
if (leadingZero==false) // removing leading zeros
{
if (hundreds1==0 && tens1>0) {
hundreds1 = 64;
}
if (hundreds1==0 && tens1==0 && units1>0) {
hundreds1 = 64;
tens1 = 64;
}
if (hundreds1==0 && tens1==0 && units1==0) {
hundreds1 = 64;
tens1 = 64;
units1 = 64;
}
}
digitalWrite(Target_latchPin, 0);
ShiftBits(aDecValues[hundreds1]);
ShiftBits(aDecValues[tens1]); // Update tens digit
ShiftBits(aDecValues[units1]); // Update units digit
digitalWrite(Target_latchPin, 1);
delay(100); // Adjust this delay to vary the count time
} // End of UpdateDisplay()
Dear PaulRB
Thank you for the reply. I guess I was lucky to get the counter to work as it is. I did not know about the shiftOut() function and will surely have a look at it for future reference. In the meantime I'm happy with the counter as long as it works. Maybe in a updated version of my project I will try to use shiftOut() instead of shiftBits().
No, it does absolutely nothing. I now see that I have omitted a piece of code from the above pasted code. The code uploaded to the arduino is the correct one. The piece omitted is:
if (Target_ButtonUpV != Target_ButtonUpV_LastButtonState) {
// if the state has changed, increment the counter
if (Target_ButtonUpV == HIGH){
if (currentMillis - previousMillis1 >= interval_1) {
if (Target_Count != 999) Target_Count+=1;
previousMillis1 = currentMillis;
}
} else {//button is low, not pressed
previousMillis2 = currentMillis;
}
Here is the full code:
// Assign Shift Register Pins for Data, latch and Clock
int Target_dataPin = 2; //Target Shift Registers
int Target_latchPin = 3;
int Target_clkPin = 4;
// Assign pins for buttons
//int Reset_Button = ;
int Target_ButtonUp = A0;
int Target_ButtonDown = A1;
// Variable for reading the button status
int Target_ButtonUpV = 0;
int Target_ButtonDownV = 0;
// Previous state of each button declaration
int Target_ButtonUpV_LastButtonState = 0;
int Target_ButtonDownV_LastButtonState = 0;
// Initialize what will be displayed / variables
int Target_Display1 = 0, Target_Display2 = 0, Target_Display3 = 0;
// Set counters to zero for displays / set variables for the score
int Target_Count = 0;
// Interval time for long and short press
float value = 0;
unsigned long interval_1 = 30;
unsigned long interval_2 = 1000;
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
void setup()
{
// Declare pins as outputs
pinMode(Target_latchPin, OUTPUT);
pinMode(Target_clkPin, OUTPUT);
pinMode(Target_dataPin, OUTPUT);
// Declare buttons as inputs
pinMode(Target_ButtonUp, INPUT_PULLUP);
pinMode(Target_ButtonDown, INPUT_PULLUP);
}
// End of setup()
void loop() {
// Set currentMillies = millis
unsigned long currentMillis = millis();
if (currentMillis - previousMillis2 >= interval_2) {
//timer2 is done
interval_1 = 30;//this is for timer1
} else {
//timer2 not done
interval_1 = 500;//this is for timer1
}
//Read the Button Pins to see if one of them has been pressed
Target_ButtonUpV = digitalRead (Target_ButtonUp);
Target_ButtonDownV = digitalRead (Target_ButtonDown);
//Read the Button Pins to see if one of them has been pressed
if (Target_ButtonUpV != Target_ButtonUpV_LastButtonState) {
// if the state has changed, increment the counter
if (Target_ButtonUpV == HIGH){
if (currentMillis - previousMillis1 >= interval_1) {
if (Target_Count != 999) Target_Count+=1;
previousMillis1 = currentMillis;
}
} else {//button is high, not pressed
previousMillis2 = currentMillis;
}
}
if (Target_ButtonDownV != Target_ButtonDownV_LastButtonState) {
// if the state has changed, decrement the counter
if (Target_ButtonDownV == HIGH){
if (Target_Count != 0) Target_Count-=1;
}
}
// Save the current state as the last state for next time through the loop
Target_ButtonUpV_LastButtonState = Target_ButtonUpV;
Target_ButtonDownV_LastButtonState = Target_ButtonDownV;
delay(50);
UpdateDisplay();
}
// End of loop()
//*******************************
// Shift 8 bits out MSB first
void ShiftBits(byte DataOut)
{
int i = 0;
int pinState;
digitalWrite(Target_dataPin, 0);
digitalWrite(Target_clkPin, 0);
for (i = 7; i >= 0; i--)
{
digitalWrite(Target_clkPin, 0);
if (DataOut & (1 << i))
{
pinState = 1;
}
else
{
pinState = 0;
}
digitalWrite(Target_dataPin, pinState); // Sets the pin to HIGH or LOW depending on pinState
digitalWrite(Target_clkPin, 1); // Register shifts bits on upstroke of clock pin
digitalWrite(Target_dataPin, 0); // Zero the data pin after shift to prevent bleed through
}
digitalWrite(Target_clkPin, 0); // Stop shifting
} // End of ShiftBits()
//*******************************
void UpdateDisplay()
{
int aDecValues[] = { 63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 64 }; //103
unsigned long temp1;
boolean leadingZero;
temp1 = Target_Count;
int hundreds1 = temp1 / 100;
temp1 -= (hundreds1 * 100);
int tens1 = temp1 / 10;
temp1 -= (tens1 * 10);
int units1 = temp1;
if (leadingZero==false) // removing leading zeros
{
if (hundreds1==0 && tens1>0) {
hundreds1 = 64;
}
if (hundreds1==0 && tens1==0 && units1>0) {
hundreds1 = 64;
tens1 = 64;
}
if (hundreds1==0 && tens1==0 && units1==0) {
hundreds1 = 64;
tens1 = 64;
units1 = 64;
}
}
digitalWrite(Target_latchPin, 0);
ShiftBits(aDecValues[hundreds1]);
ShiftBits(aDecValues[tens1]); // Update tens digit
ShiftBits(aDecValues[units1]); // Update units digit
digitalWrite(Target_latchPin, 1);
delay(100); // Adjust this delay to vary the count time
} // End of UpdateDisplay()
Sorry, but I don't see any significant difference between the last code and initial one. You said that you have a code example with button hold down. Where is it in the code?
// Assign Shift Register Pins for Data, latch and Clock
int Target_dataPin = 2; //Target Shift Registers
int Target_latchPin = 3;
int Target_clkPin = 4;
// Assign pins for buttons
//int Reset_Button = ;
int Target_ButtonUp = A0;
int Target_ButtonDown = A1;
// Variable for reading the button status
int Target_ButtonUpV = 0;
int Target_ButtonDownV = 0;
// Previous state of each button declaration
int Target_ButtonUpV_LastButtonState = 0;
int Target_ButtonDownV_LastButtonState = 0;
// Initialize what will be displayed / variables
int Target_Display1 = 0, Target_Display2 = 0, Target_Display3 = 0;
// Set counters to zero for displays / set variables for the score
int Target_Count = 0;
**// Interval time for long and short press**
** float value = 0;**
** unsigned long interval_1 = 30;**
** unsigned long interval_2 = 1000;**
** unsigned long previousMillis1 = 0;**
** unsigned long previousMillis2 = 0;**
void setup()
{
// Declare pins as outputs
pinMode(Target_latchPin, OUTPUT);
pinMode(Target_clkPin, OUTPUT);
pinMode(Target_dataPin, OUTPUT);
// Declare buttons as inputs
pinMode(Target_ButtonUp, INPUT_PULLUP);
pinMode(Target_ButtonDown, INPUT_PULLUP);
}
// End of setup()
void loop() {
**// Set currentMillies = millis**
** unsigned long currentMillis = millis();**
** if (currentMillis - previousMillis2 >= interval_2) {**
** //timer2 is done**
** interval_1 = 30;//this is for timer1**
** } else {**
** //timer2 not done**
** interval_1 = 500;//this is for timer1**
** }**
//Read the Button Pins to see if one of them has been pressed
Target_ButtonUpV = digitalRead (Target_ButtonUp);
Target_ButtonDownV = digitalRead (Target_ButtonDown);
//Read the Button Pins to see if one of them has been pressed
if (Target_ButtonUpV != Target_ButtonUpV_LastButtonState) {
// if the state has changed, increment the counter
if (Target_ButtonUpV == HIGH){
**if (currentMillis - previousMillis1 >= interval_1) {**
** if (Target_Count != 999) Target_Count+=1;**
** previousMillis1 = currentMillis;**
** }**
** } else {//button is high, not pressed**
** previousMillis2 = currentMillis;**
** **
** }**
** }**
if (Target_ButtonDownV != Target_ButtonDownV_LastButtonState) {
// if the state has changed, decrement the counter
if (Target_ButtonDownV == HIGH){
if (Target_Count != 0) Target_Count-=1;
}
}
// Save the current state as the last state for next time through the loop
Target_ButtonUpV_LastButtonState = Target_ButtonUpV;
Target_ButtonDownV_LastButtonState = Target_ButtonDownV;
delay(50);
UpdateDisplay();
}
// End of loop()
//*******************************
// Shift 8 bits out MSB first
void ShiftBits(byte DataOut)
{
int i = 0;
int pinState;
digitalWrite(Target_dataPin, 0);
digitalWrite(Target_clkPin, 0);
for (i = 7; i >= 0; i--)
{
digitalWrite(Target_clkPin, 0);
if (DataOut & (1 << i))
{
pinState = 1;
}
else
{
pinState = 0;
}
digitalWrite(Target_dataPin, pinState); // Sets the pin to HIGH or LOW depending on pinState
digitalWrite(Target_clkPin, 1); // Register shifts bits on upstroke of clock pin
digitalWrite(Target_dataPin, 0); // Zero the data pin after shift to prevent bleed through
}
digitalWrite(Target_clkPin, 0); // Stop shifting
} // End of ShiftBits()
//*******************************
void UpdateDisplay()
{
int aDecValues[] = { 63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 64 }; //103
unsigned long temp1;
boolean leadingZero;
temp1 = Target_Count;
int hundreds1 = temp1 / 100;
temp1 -= (hundreds1 * 100);
int tens1 = temp1 / 10;
temp1 -= (tens1 * 10);
int units1 = temp1;
if (leadingZero==false) // removing leading zeros
{
if (hundreds1==0 && tens1>0) {
hundreds1 = 64;
}
if (hundreds1==0 && tens1==0 && units1>0) {
hundreds1 = 64;
tens1 = 64;
}
if (hundreds1==0 && tens1==0 && units1==0) {
hundreds1 = 64;
tens1 = 64;
units1 = 64;
}
}
digitalWrite(Target_latchPin, 0);
ShiftBits(aDecValues[hundreds1]);
ShiftBits(aDecValues[tens1]); // Update tens digit
ShiftBits(aDecValues[units1]); // Update units digit
digitalWrite(Target_latchPin, 1);
delay(100); // Adjust this delay to vary the count time
} // End of UpdateDisplay()