increment button

Go To Last Post
29 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi everybody

I would like to know how to create an increment once you press a button. It has to be kind of like this:

Every time you press the button, the value should increase by +1 on the display. So if I press the button 5 times that should give the value 5 on the display.

 

I tried to set as follows, but am stuck on increment.

 

void ChoiceOfSMS(void)

{

unsigned char tmp;

tmp = keyscan();


unsigned char a = 1;

while(tmp ='1')                                            // Button 1

{

  a++;

}

lcd_goto(1,1);

data_to_display(a);

}



 

Last Edited: Sat. Oct 22, 2016 - 03:35 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First question: do you know how to detect a "pushed" button? I see no evidence of it in your code. keyscan(), what ever that is, is overkill. How many "buttons" do you have?

 

Second question: what mcu are you using and are you using some sort of pre-made board? If pre-made, which one?

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Sat. Oct 22, 2016 - 01:10 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

THat cannot be your entire program.  THere needs to be some form of AVR_setup to configure input(s), and output(s)  Some includes and a f_CPU define.

 

BUT, lets say thats all done properly.  YOur code will never work properly for several reasons.

 

1) you never clear 'tmp' so after you press your button that first time, 'a' will increment until it overflows then start over repetitively. 

2) no debounce is taking place so your display will appear to 'skip' numbers.  For now the debounce is the least of your concerns.  Post the parts of your program that includes your AVR_SETUP and includes and defines. 

 

JIm

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A further note: that pseudo-code is written a bit like you would when an operating system is available. There is NO operating system, here.

 

Jim (jgm) is absolutely right. You have to figure out how everything is going to be initialized and that includes a bunch of #include statements and probably a bunch of #define statements.

 

Then, get rid of that keyscan idea and work at the level of detecting individual buttons. I assume that you do NOT have a regular keyboard but one or more simple buttons. You need to learn how to detect those buttons. Later that will involve debouncing, but you are a long ways from that point, now.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And please do NOT post such questions on the Studio forum. This is only for Studio related bugs, I'll move the thread to general programming.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Etie,

 

I do not know what your display code looks like, nor do I know what AVR you are using, but to possibly prevent this thread form turning into a mess take look at this:

 

I wrote this, and checked it on a Mega2560 running at 8Mhz, but will work on pretty much any AVR:

/*
 * GccApplication1.c
 *
 * Created: 10/22/2016 12:12:12 AM
 *  Author: jgmDESIGNS-Laptop
 */ 

/*

THIS PROJECT RUNS ON A MEGA2560 MCU.

THE CLOCK FUSE IS SET TO THE INTERNAL 8 MHz OSC

THE CLKDIV8 FUSE is BE DISABLED 

 */ 

#define F_CPU 8000000UL

#include <avr/io.h>
#include <avr/io.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#include <util/delay.h>

void avr_setup(void)
{
	DDRA = 0xFF;	//all outputs
	DDRB = 0x00;	//PORTB input
	PORTB = 0xFF;	//pullups all on
}

int main(void)
{
	avr_setup();

	uint8_t a = 0x00;
	PORTA = a;     //make sure PORTA is clear

	while(1)
	{
		if((PINB & 0x01) == 0)		//check to see if button on PORTB,0 pushed - active low
		{
			_delay_ms(20);		//wait for button to stabilise/lazy debounce

			a++;	//increment a variable by one

			PORTA = a;		//output a to porta

					while((PINB & 0x01) == 0)		//wait here until PORTB,0 button is released
					{

					}//end of while

			_delay_ms(20);		//lazy debounce
		}//end of if

	}//end of while(1)

}//end of main

It simply sits in a loop testing for the button connected to PortB,0 pin.  Once it sees the pin pulled LOW the code waits 20 milliseconds for the button to stabilise(google DEBOUNCE),

then increments the 'a' variable by 1, and sends this to PORTA.  Then the code sits in a WHILE() loop waiting for the button to be released. 

Once it is released the code waits 20 milliseconds for the button to stabilise(google DEBOUNCE), and the loop repeats.

 

In your scenario you would do this:

#define F_CPU 8000000UL      //<-- Change this to your AVRs clock

#include <avr/io.h>
#include <avr/io.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#include <util/delay.h>

void avr_setup(void)
{
	DDRA = 0xFF;	//all outputs
	DDRB = 0x00;	//PORTB input
	PORTB = 0xFF;	//pullups all on
}

int main(void)
{
	avr_setup();

	uint8_t a = 0x00;

	while(1)
	{
		if((PINB & 0x01) == 0)		//check to see if button on PORTB,0 pushed - active low
		{
			_delay_ms(20);		//wait for button to stabilise/lazy debounce

			a++;	//increment a variable by one

			lcd_goto(1,1);

			data_to_display(a);

					while((PINB & 0x01) == 0)		//wait here until PORTB,0 button is released
					{

					}//end of while

			_delay_ms(20);		//lazy debounce
		}//end of if

	}//end of while(1)

}//end of main

Untested.

 

Hope this helps.

 

Jim

 

EDIT: spelling

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

Last Edited: Sat. Oct 22, 2016 - 04:44 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello everyone,
I'm sorry for inaccurate information on the code. And so the purpose of the exercise to do.
In fact I use ARV STK500, ATmelStudio 7 ATmega16 and a 3x4 keypad.
I have on hand a keypad code is active, but I have pragrammer each button.
That is why I have started the '1' key. For the "1" button should have to display each message record and its index. And stokage capacity is limited á 10 messages. However after appuer 10 times, the Lcd is playing "A" instead of 10 á the position lcd_goto (1.1) and the message lcd_goto á the position (2,0).

For example: when I support once the "1" button, the LCD displays 1 á the position (1,1) and the message á the position (2,0).

 

the routine ChoiceSMS  is only for the button "1".
The position to display the message is already fixed. 

 

 

Thank you so much for your response.
My English is so poor.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Make sure you disable the JTAG interface as it resides on PORTC.

Instead of using 'if' statements for key presses, you might want to implement a switch instead.

Jim

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jgmdesign wrote:
Make sure you disable the JTAG interface as it resides on PORTC.

Wouldn't it be far better to use the JTAG - so that you can actually see what's going on inside the chip ?!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Agreed, but his code has the keypad attached to PORTC, that's why I mentioned disabling JTAG. Of course the OP can always change the code to use another port, unless this is a PCBoard.

Jim

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Hi,

JTAG is long off

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I still try as below but no raction button "1".

 

unsigned char ChoiceSMS(void)

    uint8_t tmp = 0x01;

 

        while(keyscan()== '1')        //check to see if button "1" is pressed
        {   
            _delay_ms(20);        //wait for button to stabilise/lazy debounce
            
            tmp++;    //increment tmp variable by one
             if (tmp =0x0A)
             {
                 tmp = 0;
             }
             LCD_goto(1,1);
             switch(tmp)
             {
                 case 1:
                 if (tmp =1)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("first message");
                 }
                 break;
                 case 2:
                 if (tmp =2)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("2nd message");
                 }
                 break;    
                 case 3:
                 if (tmp =3)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("3 message");
                 }
                 break;
                 case 4:
                 if (tmp =4)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("4 message");
                 }
                 break;
                 case 5:
                 if (tmp =5)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("4 message");
                 }
                 break;
                 case 6:
                 if (tmp =6)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("5 message");
                 }
                 break;
                 case 7:
                 if (tmp =7)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("6 message");
                 }
                 break;
                 case 8:
                 if (tmp =8)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("7 message");
                 }
                 break;
                 case 9:
                 if (tmp =9)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("8 message");
                 }
                 break;
                 case 10:
                 if (tmp ='A')
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("9 message");
                 }
                 break;                 
                 
                 default: return;            

             }
            _delay_ms(20);        //lazy debounce
        }//end while
     
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Etie wrote:
switch(tmp) {

case 1:

if (tmp =1)

...

1)  As you are already in "case 1:", you >>know<< that the value of tmp is 1 -- otherwise the code would not be executed.

2)  (tmp = 1) is incorrect -- if you want to make the comparison, then it is (tmp == 1) for comparison, and not the assignment operator.

3) 

Etie wrote:
if (tmp ='A')
Assuming you meant to use the comparison operator == and you know tmp is 10, how do you expect a comparison against 'A' 0x41 to work?

4)  ...and before the switch(), you limit the value of tmp to no more than 9

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd still like to see keyscan.

 

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bobgardner wrote:

I'd still like to see keyscan.

 

Check Post#7, his source code is there

 

JIm

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 formally i apologize for this serious error of comparison. I have already corrected.
I'd made the mistake of the kopie I posted before.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

here's the code I wanted poster.
I am sorry for the inconvenience that I have cuase.
I am only a beginner in programming.

 

/*
Routine the button "1" to choice the message between 1 to A. 
*/
unsigned char ChoiceSMS(void)
{ 
        
        uint8_t tmp = 0x01;          // Index Message (to be increment)

        while(keyscan()== '1')         //check to see if button "1" activ is
        {   
            _delay_ms(20);             //wait for button to stabilise/lazy debounce
            
            tmp++;    //increment tmp variable by one
             if (tmp ==0x0A)
             {
                 tmp = 0;
             }
             
             switch(tmp)
             {
                 case 1:
                 if (tmp == 0x01)
                 {
                     LCD_Print("1st message");
                     LCD_goto(1,1);
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                 }
                 break;
                 case 2:
                 if (tmp == 0x02)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("2nd message");
                 }
                 break;    
                 case 3:
                 if (tmp ==0x03)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("3rd message");
                 }
                 break;
                 case 4:
                 if (tmp ==0x04)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("4th message");
                 }
                 break;
                 case 5:
                 if (tmp ==0x05)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("5th message");
                 }
                 break;
                 case 6:
                 if (tmp ==0x06)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("6th message");
                 }
                 break;
                 case 7:
                 if (tmp ==0x07)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("7th message");
                 }
                 break;
                 case 8:
                 if (tmp ==0x08)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("8th message");
                 }
                 break;
                 case 9:
                 if (tmp ==0x09)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("9th message");
                 }
                 break;
                 case 10:
                 if (tmp ==0x0A)
                 {
                     data_to_dis(tmp);
                     LCD_goto(2,0);
                     LCD_Print("10th message");
                 }
                 break;                 
                 default: return;            
             }
            _delay_ms(20);        //lazy debounce
        }

     
}

Please use CODE <> tags button in toolbar - JGM

Last Edited: Sat. Oct 22, 2016 - 05:51 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi everyone

The code works now, but there is still a problem.
After 10 times press on the button. the next support is the 11th to return at 1 but it is still remains af 10.

However the 12th press on the come to 1.
can you tell me what's wrong?

 

/*
Routine the button "1" to choice the message between 1 to A. 
*/
unsigned char ChoiceSMS(void)
{ 
        
        uint8_t tmp = 0x00;          // Index Message (to be increment)
    do
    {
        while(keyscan()== '1')         //check to see if button "1" activ is
        {   
            
            _delay_ms(50);             //wait for button to stabilise/lazy debounce
            tmp++;                     //increment tmp variable by one
            _delay_ms(50);             //wait for button to stabilise/lazy debounce
            
             if (tmp ==0x10)
             {
                 tmp = 0;
             }
         
             switch(tmp)
             {
                 case 1:
                 if (tmp == 0x01)
                 {  
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);                     
                     LCD_goto(2,0);
                     LCD_Print("1st message");
                 }
                 break;
                 case 2:
                 if (tmp == 0x02)
                 {   
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);
                     LCD_goto(2,0);
                     LCD_Print("2nd message");
                 }
                 break;    
                 case 3:
                 if (tmp ==0x03)
                 {    
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);                     
                     LCD_goto(2,0);
                     LCD_Print("3rd message");
                 }
                 break;
                 case 4:
                 if (tmp ==0x04)
                 {    
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);
                     LCD_goto(2,0);
                     LCD_Print("4th message");
                 }
                 break;
                 case 5:
                 if (tmp ==0x05)
                 {    
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);
                     LCD_goto(2,0);
                     LCD_Print("5th message");
                 }
                 break;
                 case 6:
                 if (tmp ==0x06)
                 {    
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);                     
                     LCD_goto(2,0);
                     LCD_Print("6th message");
                 }
                 break;
                 case 7:
                 if (tmp ==0x07)
                 {    
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);
                     LCD_goto(2,0);
                     LCD_Print("7th message");
                 }
                 break;
                 case 8:
                 if (tmp ==0x08)
                 {    
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);
                     LCD_goto(2,0);
                     LCD_Print("8th message");
                 }
                 break;
                 case 9:
                 if (tmp ==0x09)
                 {    
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);                     
                     LCD_goto(2,0);
                     LCD_Print("9th message");
                 }
                 break;
                 case 10:
                 if (tmp ==0x0A)
                 {    
                      LCD_goto(1,1);
                      data_to_dis(0x41);
                     LCD_goto(2,0);
                     LCD_Print("10th message");
                 }
                 break;                 
                 default: return;    // In the case of an incorrect value        
             }
            _delay_ms(50);        //lazy debounce
            
        }
        
    }while(1);
    return 0;
}

 

Last Edited: Sat. Oct 22, 2016 - 09:13 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You ignored the point Lee made? Each case: then tests if tmp==N but you already know it is equal because you wouldn't be in case N: otherwise. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
 case 1:
                 if (tmp == 0x01)
                 {  
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);                     
                     LCD_goto(2,0);
                     LCD_Print("1st message");
                 }
                 break;
                 case 2:
                 if (tmp == 0x02)
                 {   
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);
                     LCD_goto(2,0);
                     LCD_Print("2nd message");
                 }
                 break;    

 

Instead:

                 case 1:
                 {  
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);                     
                     LCD_goto(2,0);
                     LCD_Print("1st message");
                 }
                 break;
                 
                 case 2:
                 {   
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);
                     LCD_goto(2,0);
                     LCD_Print("2nd message");
                 }
                 break;    

Untested.

 

THere is no need for the IF statement as the CASE does this for you.

 

Jim

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There are 2 main mistakes in your code (ok 3 if the "if" in the case count, either if or case ).

1: 

             if (tmp ==0x10) 

I guess you mean 10 and not 16! (10 hex).

2:

 

                 tmp = 0;

But you have no case for the value 0 !

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1: 

             if (tmp ==0x10) 

I guess you mean 10 and not 16! (10 hex).

2:

 

                 tmp = 0;

But you have no case for the value 0 !

 

1 - agreed.  Although symptoms for current code would be to reset at 16th press not 12th.

 

2 - there is a default case to handle this

 

David  

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But OP don't want to get there!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello 

Having changed the id 0x10 á 0x0A.
 

if (tmp ==0x0A)

             {
                 tmp = 0;
             }

 

case 10 is not dispayed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No because the switch never see the value 10 because you have just changed it to 0!!!

 

You need to find out what you really want, and please remove all those "if"'s in the switch, (if you don't understand why, then study some C ) 

Last Edited: Sun. Oct 23, 2016 - 11:16 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Etie,

CASE is essentially the same thing as IF when you use a SWITCH.

You are doing the same job twice the way you have things.

Jim

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you change it to 0x0B you will see all 10 cases. 

 

David

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As you don't seem to be getting the point:

             switch(tmp)
             {
                 case 1:
                 if (tmp == 0x01)
                 {  
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);                     
                     LCD_goto(2,0);
                     LCD_Print("1st message");
                 }
                 break;
                 case 2:
                 if (tmp == 0x02)
                 {   
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);
                     LCD_goto(2,0);
                     LCD_Print("2nd message");
                 }
                 break;    
                 case 3:
                 if (tmp ==0x03)
                 {    
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);                     
                     LCD_goto(2,0);
                     LCD_Print("3rd message");
                 }
                 break;
        etc.

The bits in bold are completely pointless and should be removed:

             switch(tmp)
             {
                 case 1:
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);                     
                     LCD_goto(2,0);
                     LCD_Print("1st message");
                    break;
                 case 2:
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);
                     LCD_goto(2,0);
                     LCD_Print("2nd message");
                    break;    
                 case 3:
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);                     
                     LCD_goto(2,0);
                     LCD_Print("3rd message");
                    break;
        etc.

The point is that a switch()/case: construct is almost exactly the same as if you had used:

            if (tmp == 1) {
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);                     
                     LCD_goto(2,0);
                     LCD_Print("1st message");
            } else
            if (tmp == 2) {
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);
                     LCD_goto(2,0);
                     LCD_Print("2nd message");
            } else
            if (tmp == 3) {
                     LCD_goto(1,1);
                     data_to_dis(tmp + 0x30);                     
                     LCD_goto(2,0);
                     LCD_Print("3rd message");
            }
        etc.

So you don't need both the switch/case stuff AND the "if (tmp==) ..." sutff too.