Connect with us

LCD with pushbutton

Discussion in 'Microcontrollers, Programming and IoT' started by lady_krizzie, Aug 15, 2012.

  1. lady_krizzie

    lady_krizzie

    30
    0
    Aug 2, 2012
    I made code, that when you push the button it will count. But when you press it for a long time, it still increments and still counts.How can I make it such that if I press it even too long, it only counts once? Thank you very much in advance.

    Code:
    [#define F_CPU 8000000UL
    
    #include <avr/io.h>
    #include <util/delay.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include "lcd.h"
    
    
    int main (void)
    {
        
        hw_lcd_init();
        DDRB &= ~(1 << PINB0); 
        PORTB |= (1 << PINB0); 
        //int PRESSED = 0;
        int COUNT = 0;
        char buffer [16];
        lcd_clrscr();
        while(1) {
            sprintf(buffer,"%d",COUNT);        
            lcd_puts_wrap(buffer);
            
            if ((PINB & (1<<PINB0))){
                //BUTTON IS NOT PUSH        
        
            }else{
                //BUTTON IS PUSHED
                COUNT=COUNT+1;
            }
            _delay_ms(100);
        }        
        return 0;
    }
    
     
    Last edited by a moderator: Aug 15, 2012
  2. Harald Kapp

    Harald Kapp Moderator Moderator

    9,129
    1,842
    Nov 17, 2011
    You don't tell us which MC you use. From your code it should be an Atmel AVR. I do not have the LCD.h, but anyway: you introduce a state variable (button_state) to keep track of whether the button has already been pressed or not. This varaible is set when a first change from not-pressed to pressed occurs. Also in that case the counter is incremented by 1.
    If during the next pass of the loop the button is still pressed, this will be detected since the state variable is already set. Therefore the count will not be incremented.
    When in one pass of the loop it is detected that the button is not pressed, the state variable is reset. See my code example.

    Note that you have made no provisions for debouncing the pushbutton. So you may occasionally see the count increment by more than one. If you're lucki the rest of the loop takes so long that debouncing is not necessary.
    [edit]: I didn't see the 100ms delay loop immediately. This will suffice to suppress any bouncing. Sorry

    Code:
    #define F_CPU 8000000UL
    
    #include <avr/io.h>
    #include <util/delay.h>
    #include <stdlib.h>
    #include <stdio.h>
    /* #include "lcd.h" */
    
    
    int main (void)
    {
    int button_state;
    button_state = 0;	/* set button state to not pressed */ 
    
    hw_lcd_init();
    DDRB &= ~(1 << PINB0); 
    PORTB |= (1 << PINB0); 
    //int PRESSED = 0;
    int COUNT = 0;
    char buffer [16];
    lcd_clrscr();
    while(1) {
    sprintf(buffer,"%d",COUNT); 
    lcd_puts_wrap(buffer);
    
    if ((PINB & (1<<PINB0))){
    //BUTTON IS NOT PUSH 
       button_state = 0;   /* set button state to not pressed */ 
    }else{
    	if (button_state == 0) { /* button not yet pressed */
    //BUTTON IS PUSHED
    		button_state = 1;   /* set button state to pressed */
    		COUNT=COUNT+1;
    	}
    }
    _delay_ms(100);
    } 
    return 0;
    }
     
  3. CocaCola

    CocaCola

    3,635
    4
    Apr 7, 2012
    You can also insert a conditional WHILE LOOP after the COUNT=COUNT+1 put the program in a "WHILE Pressed" loop waiting until the button is released before it continues...
     
  4. Harald Kapp

    Harald Kapp Moderator Moderator

    9,129
    1,842
    Nov 17, 2011
    The advantage of CocaCola's approach is that you do not need a state variable. Useful if you run out of memory.
    The disadvantage is that you can't do anything else useful during the waiting time (unless you put it into the WHILE loop, too).

    In my approach both aspects are reversed.

    It's up to you to decide which approach suits your application more. From the code fragment you've shown us it wouldn't make a difference.
     
  5. foTONICS

    foTONICS

    332
    9
    Sep 30, 2011
    I agree with both these guys, although Harolds approach would be beneficial if you ever wanted to add options to your program later on
     
  6. CocaCola

    CocaCola

    3,635
    4
    Apr 7, 2012
    As Harald said it's all about what you need or want the program to do in the end... I use flags all the time just like he suggested when it's beneficial to the overall program and I will use conditional 'pauses' when it works for that program... There are plenty of times when a program doesn't need to be doing anything when the button it pressed (and many times when I prefer it just wait) and there are plenty of other times when it needs to do things, it just depends on the program...
     
  7. lady_krizzie

    lady_krizzie

    30
    0
    Aug 2, 2012
    Thank you sirs', I learned much. I also did the flag similar Harald yesterday but it didn't work. But when I saw his code, I fully understand how to use flag, and it worked. I will also try to do CocaCola's approach...
     
  8. lady_krizzie

    lady_krizzie

    30
    0
    Aug 2, 2012
    In connection with this code, i connect a pulse generator that when I turn it on, it will count and also will display the same count in the LCD. And the pushbutton was programmed that when it is pressed it should reset the display on the LCD.

    Code:
    int buffer [16];
    int main void
    sprintf(buffer, "Count:%d", count); 
    lcd_puts(buffer);
    ...in the main routine,
    a) the pulse generator was set to on, the lcd display start to count
    COUNT = COUNT + 1;
    b) When the button is pushed,
    COUNT = 0;

    ...I am expecting that the output will be like this:
    COUNT:0

    But it shows like this:

    COUNT:236 //if LCD display counts
    COUNT:036 //it will reset only one digit

    What am I lacking?
     
    Last edited by a moderator: Aug 16, 2012
  9. lady_krizzie

    lady_krizzie

    30
    0
    Aug 2, 2012
    I put memset and initialize that the buffer like this:
    buffer [0]= '\0'
    ...but it doesn't clear the display back to zero.
     
  10. dahhal

    dahhal

    58
    0
    Jul 17, 2012
    the buffer should be a char array and not int
     
  11. lady_krizzie

    lady_krizzie

    30
    0
    Aug 2, 2012
    yes, I used char but it doesn't work. Here is my code:

    Code:
     int main (void)
    {
    	int button_flag;
    	button_flag = 0;
    	
    	int button_flag2;
    	button_flag2 = 0;
    
    	hw_lcd_init();
    	DDRB &= ~(1 << PINB1); //counter
    	PORTB |= (1 << PINB1);
    	DDRB &= ~(1 << PINB0); //pushbutton
    	PORTB |= (1 << PINB0);
    	
    	
    	int COUNT=0;
    	char buffer [16]= {0};
    	buffer [0] = '\0';
    	
    
    	lcd_clrscr();
    	
    	while(1) {
    		
    		sprintf(buffer,"%d",COUNT);
    		lcd_puts_wrap(buffer);
    		
    		if ((PINB & (1<<PINB0))){
    			button_flag2 = 0;   // set button to not pushed
    		}else{
    			if (button_flag2 == 0) { 
    			//button IS PUSHED
    			button_flag2 = 1;   //set button to pushed
    			COUNT =0;
    			memset(&buffer[0],0,strlen(buffer));
    		}
    	}
    	
    		if ((PINB & (1<<PINB1))){
    			//COUNTER IS NOT PUSH
    			button_flag = 0;   // set counter to not pushed
    		}else{
    			if (button_flag == 0) { 
    			button_flag = 1;   //set counter to pushed
    			COUNT = COUNT+1 ;
    		}
    	}
    		}
    		
    		return 0;
    	}
     
  12. dahhal

    dahhal

    58
    0
    Jul 17, 2012
    you might want to try to bring back the 100 ms delay you had before.

    The delay would have helped to debounce the circuit,

    Have you got the code for lcd_puts_wrap()? I would guess you don't need all that memset jazz. A routine like that should print every character until a null chararcter '\0' or carriage return '\r' depending on the established protocol.
     
  13. lady_krizzie

    lady_krizzie

    30
    0
    Aug 2, 2012
    delay just slows down the display in the LCD and would not much the count in the counter or pulse generator. lcd_puts_wrap came from a customize library of Fluery. And was made by my boss.
     
  14. dahhal

    dahhal

    58
    0
    Jul 17, 2012
    seems your logic is more complex then the first time you posted it.

    The logic is confusing, as the varible names are not great. It would be best to use variable names that make sense to the application. Are you counting all the times that the pulsegenerator goes from a low to high transition, and when the pushButton does a low to high transition. If so the names should reflect it.

    is the issue that you have some sort of overflow in what you want printed on the LCD? In your situation I would try to find some usage of the r lcd_puts_wrap() function. In my last post I wasn't saying it was bad code, I was just trying to understand the input that the sub routine expects. If you don't have access to the code, try to find spec, or working examples from other projects that use the code.
     
  15. lady_krizzie

    lady_krizzie

    30
    0
    Aug 2, 2012
    Machine problem was solved. I just put lcd_clrscr
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-