Tutorial 1 button 2 mode – press releases and holding

Status
Not open for further replies.

Trung

New Member
In this project we use an implement 2 mode button (1 button 2 mode).
Connect with microcontroller 16F877A: Button connection RB1, 7-segment LED connected to portd (RD0 ... RD7) and PORTB (RB4 ... RB7).
Description of project: When pressing the release button, each press release tang 7-segment LED unit 1, corresponding to the number of clicks the button. While holding the button, 7-segment LED displays the number is increasing. You watch this video to better understand the post.
Reference code with mikroC Pro for Pic and see more tutorials at dientudieukhien.net:
Code:
/*
 * Project name: 1 Button 2 che do
 * Author: http://dientudieukhien.net
 * Description: Neu nhan button va nha ra thi led 7 doan hien thi so lan nhan button,
 neu nhan giu button - hold button thi led 7 doan se dem len den khi nao nha button.
 * Test configuration:
  MCU:  PIC16F877A
  Oscillator:  HS, 08.0000 MHz
  SW:  mikroC v8.0
*/
unsigned short mask(unsigned short num) {
  switch (num) {
  case 0 : return 0xC0;
  case 1 : return 0xF9;
  case 2 : return 0xA4;
  case 3 : return 0xB0;
  case 4 : return 0x99;
  case 5 : return 0x92;
  case 6 : return 0x82;
  case 7 : return 0xF8;
  case 8 : return 0x80;
  case 9 : return 0x90;
  } //case end
}
unsigned short digit_no, digit10, digit1, digit;
void interrupt() {
  if (digit_no==0) {
  PORTB.F7=0;
  PORTB.F6 = 0;  // Turn off all 7seg displays
  PORTD = digit1;  //  send mask for ones digit to PORTD
  PORTB.F7 = 1;  //  turn on 1st 7 seg., turn off 2nd
  digit_no = 1;
  } else {
  PORTB.F6=0;
  PORTB.F7 = 0;  // Turn off all 7seg displays
  PORTD = digit10;  //  send mask for tens digit to PORTD
  PORTB.F6 = 1;  //  turn on 2nd 7 seg., turn off 1st
  digit_no = 0;
  }
  TMR0 = 0;  //  clear TMRO
  INTCON = 0x20;  //  clear TMR0IF and set TMR0IE
}

void display(unsigned short i){
unsigned short digit;
digit=i%10;
digit1=mask(digit);  //hien thi hang don vi
digit=i/10;
digit10=mask(digit);  // hien thi hang chuc
delay_ms(500);
}

void main() {
unsigned short i,j,dem;
  OPTION_REG  = 0x80;  // Timer0 settings
  TMR0  =  0;
  INTCON  = 0xA0;  // Disable PEIE,INTE,RBIE,T0IE
  trisb=0x03;
  trisd=0x00;
  trisa=0X00;
  portb=0;
  portd=0;
  i=0;
  j=0;
  dem=0;
  display(i);
for(;;){
  if(Button(&portb,1,1,0)){ //Kiem tra button nhan giu hay nhan roi nha ra
  dem=dem+1;
  delay_ms(1);
  }
  if(dem==1){  //Neu nhan roi nha ra
  i=i+1;
  display(i);
  }
  if(dem>1){  //Neu nhan giu - hold button
  display(j);
  j=j+1;
  delay_ms(30);
  if(Button(&portb,1,0,1)){
  i=0;
  j=0;
  delay_ms(1000);
  display(j);
  goto lap;
  }
  }
  lap:  //Kiem tra neu buton nha ra thi resest dem.
  if(Button(&portb,1,0,1)){
  dem=0;
  }
  }
}
 
Here is code for an Arduino that implements two functions with one button. A short press and a long press.
This might interest you as well.

Code:
#define HALT while(true);
#define STATE_NORMAL 0
#define STATE_SHORT 1
#define STATE_LONG 2

const int LED = 13;

// Button input related values
static const byte BUTTON_PIN = 2;
//static const int  STATE_NORMAL = 0; // no button activity
//static const int  STATE_SHORT  = 1; // short button press
//static const int  STATE_LONG  = 2; // long button press
volatile int  resultButton = 0; // global value set by checkButton()

void setup() {
  Serial.begin(9600);
  pinMode(LED,OUTPUT);
  digitalWrite(LED, LOW);
  Serial.println(F("Initializing Button pin"));
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), checkButton, CHANGE);
  Serial.println(F("Button pin initialized"));
}

void loop() {
  int longButton=0;
  int count=0;
 
  while (true) {
  switch (resultButton) {

  case STATE_NORMAL: {
/*  Serial.print(".");
  count++;
  count = count % 10;
  if (count==0) Serial.println(""); */
  break;
  }

  case STATE_SHORT: {
  Serial.println("Short press has been detected");
  digitalWrite(LED,HIGH);
  delay(1000);
  digitalWrite(LED,LOW);
  resultButton=STATE_NORMAL;
  break;
  }

  case STATE_LONG: {
  Serial.println("Button was pressed for long time");
  digitalWrite(LED,HIGH);
  delay(3000);
  digitalWrite(LED,LOW);
  longButton++;
  resultButton=STATE_NORMAL;
  break;
  }
  }
  if (longButton==5) {
  Serial.println("Halting");
  HALT;
  }
  }
}


//*****************************************************************
void checkButton() {
  /*
  * This function implements software debouncing for a two-state button.
  * It responds to a short press and a long press and identifies between
  * the two states. Your sketch can continue processing while the button
  * function is driven by pin changes.
  */

  const unsigned long LONG_DELTA = 1000ul; // hold seconds for a long press
  const unsigned long DEBOUNCE_DELTA = 30ul; // debounce time
  static int lastButtonStatus = HIGH; // HIGH indicates the button is NOT pressed
  int buttonStatus;  // button atate Pressed/LOW; Open/HIGH
  static unsigned long longTime = 0ul, shortTime = 0ul; // future times to determine is button has been poressed a short or long time
  boolean Released = true, Transition = false; // various button states
  boolean timeoutShort = false, timeoutLong = false; // flags for the state of the presses

  buttonStatus = digitalRead(BUTTON_PIN); // read the button state on the pin "BUTTON_PIN"
  timeoutShort = (millis() > shortTime); // calculate the current time states for the button presses
  timeoutLong = (millis() > longTime);

  if (buttonStatus != lastButtonStatus) { // reset the timeouts if the button state changed
  longTime = millis() + LONG_DELTA;
  shortTime = millis() + DEBOUNCE_DELTA;
  }

  Transition = (buttonStatus != lastButtonStatus); // has the button changed state
  Released = (Transition && (buttonStatus == HIGH)); // for input pullup circuit
  lastButtonStatus = buttonStatus; // save the button status

  if ( ! Transition) { //without a transition, there's no change in input
  // if there has not been a transition, don't change the previous result
  resultButton =  STATE_NORMAL | resultButton;
  return;
  }
  if (timeoutLong && Released) { // long timeout has occurred and the button was just released
  resultButton = STATE_LONG | resultButton; // ensure the button result reflects a long press
  } else if (timeoutShort && Released) { // short timeout has occurred (and not long timeout) and button was just released
  resultButton = STATE_SHORT | resultButton; // ensure the button result reflects a short press
  } else { // else there is no change in status, return the normal state
  resultButton = STATE_NORMAL | resultButton; // with no change in status, ensure no change in button status
  }
}
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…