Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

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.

Latest threads

New Articles From Microcontroller Tips

Back
Top