One click leading to displaying multiple time on the real term

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

I have interfaced a matrix keypad with the xmega a3bu and have configured it with usb cdc protocol, but when i see the key pressed data in the real term, if click a button once its displaying multiple times(as shown in the image). Any suggestions on what i should do to prevent it?

Attachment(s): 

This topic has a solution.

Nitin Shenoy

Last Edited: Tue. Feb 5, 2019 - 05:12 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Looks like a missing semi-colon on line 47 ;-)

 

Seriously, how do you expect anyone to suggest a fix without showing the code?

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

oops,my bad.

#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <asf.h>


void row_col1(void);
void row_col2(void);
void row_col3(void);
void row_col4(void);
void row1_col(void);
void row2_col(void);
void row3_col(void);
void row4_col(void);
void row1_col1(void);
void row2_col2(void);
void row3_col3(void);
void row4_col4(void);
void col1(void);
void col2(void);
void col3(void);
void col4(void);
void blink(void);

unsigned int blinkduration = 0;
/**
 * \brief main function
 */
int main (void)
{
	PORTC.DIRCLR = 0x0F;
	PORTC.DIRSET = 0xF0;
	PORTR.DIRSET = 0x03;
	PORTR_OUTSET = 0x03;
	PORTD_DIRSET = 0x20;
	PORTD_OUTCLR = 0x20;
	
	
	
	
	
	
#if SAMD21 || SAMR21
	/* Initialize basic board support features.
	 * - Initialize system clock sources according to device-specific
	 *   configuration parameters supplied in a conf_clocks.h file.
	 * - Set up GPIO and board-specific features using additional configuration
	 *   parameters, if any, specified in a conf_board.h file.
	 */
	system_init();
#else
	/* Initialize basic board support features.
	 * - Initialize system clock sources according to device-specific
	 *   configuration parameters supplied in a conf_clock.h file.
	 * - Set up GPIO and board-specific features using additional configuration
	 *   parameters, if any, specified in a conf_board.h file.
	 */
	sysclk_init();
	board_init();
#endif

	// Initialize interrupt vector table support.
	irq_initialize_vectors();

	// Enable interrupts
	cpu_irq_enable();

	/* Call a local utility routine to initialize C-Library Standard I/O over
	 * a USB CDC protocol. Tunable parameters in a conf_usb.h file must be
	 * supplied to configure the USB device correctly.
	 */
	stdio_usb_init();

	// Get and echo characters forever.

	

	while (true) {

		row_col1();
		_delay_ms(10);
		row_col2();
		_delay_ms(10);
		row_col3();
		_delay_ms(10);
		row_col4();
		_delay_ms(10);
		row1_col();
		_delay_ms(10);
		row2_col();
		_delay_ms(10);
		row3_col();
		_delay_ms(10);
		row4_col();
		_delay_ms(10);
		row1_col1();
		_delay_ms(10);
		row2_col2();
		_delay_ms(10);
		row3_col3();
		_delay_ms(10);
		row4_col4();
		_delay_ms(10);
		col1();
		_delay_ms(10);
		col2();
		_delay_ms(10);
		col3();
		_delay_ms(10);
		col4();
		_delay_ms(10);
		
		}
}

void row_col1()
{
	
	PORTC.OUTSET = 0x20;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0xD0;
	
	if(((PORTC.IN & 0x01)==0b00000001)&&((PORTC.IN & 0x2F)==0b00100000)) //1
	{
		printf("1");
	}
	
}

void row_col2()
{
	
	PORTC.OUTSET = 0x40;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0xB0;
	
	if(((PORTC.IN & 0x01))&&((PORTC.IN & 0x4F)==0b01000000)) //2
	{
		
		printf("2");
		
		
	}
}

void row_col3()
{
	
	PORTC.OUTSET = 0x80;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0x70;
	
	if(((PORTC.IN & 0x01))&&((PORTC.IN & 0x8F)==0b10000000)) //3
	{
		
		printf("3");
		

		

	}
}

void row_col4()
{
	PORTC.OUTSET = 0x10;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0xE0;
	
	if(((PORTC.IN & 0x01))&&((PORTC.IN & 0x1F)==0b00010000)) //4
	{
		printf("4");
		
	}
	
	
}
///////////////////////////////////////////////////////////////////////////////////////
void row1_col()
{
	
	PORTC.OUTSET = 0x20;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0xD0;
	
	if(((PORTC.IN & 0x02))&&((PORTC.IN & 0x2F)==0b00100000)) //5
	{
		
		printf("5");
		

	}
	
	
}

void row2_col()
{
	
	PORTC.OUTSET = 0x40;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0xB0;
	
	if(((PORTC.IN & 0x02))&&((PORTC.IN & 0x4F)==0b01000000)) //6
	{
		printf("6");
		
	}
}

void row3_col()
{
	
	PORTC.OUTSET = 0x80;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0x70;
	
	if(((PORTC.IN & 0x02))&&((PORTC.IN & 0x8F)==0b10000000)) //7
	{
		
		printf("7");


	}
}

void row4_col()
{
	PORTC.OUTSET = 0x10;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0xE0;
	
	if(((PORTC.IN & 0x02))&&((PORTC.IN & 0x1F)==0b00010000)) //8
	{
		printf("8");
		
	}
	
	
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
void row1_col1()
{
	
	PORTC.OUTSET = 0x20;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0xD0;
	
	if(((PORTC.IN & 0x04))&&((PORTC.IN & 0x2F)==0b00100000)) //9
	{
		
		printf("9");
		
	}
	
}

void row2_col2()
{
	
	PORTC.OUTSET = 0x40;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0xB0;
	
	if(((PORTC.IN & 0x04))&&((PORTC.IN & 0x4F)==0b01000000)) //10
	{
		printf("10");
		
		
		
	}
}

void row3_col3()
{
	
	PORTC.OUTSET = 0x80;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0x70;
	
	if(((PORTC.IN & 0x04))&&((PORTC.IN & 0x8F)==0b10000000)) //11
	{
		
		printf("11");
		

		

	}
}

void row4_col4()
{
	PORTC.OUTSET = 0x10;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0xE0;
	
	if(((PORTC.IN & 0x04))&&((PORTC.IN & 0x1F)==0b00010000)) //12
	{
		printf("12");
		
	}
	
	
}

//////////////////////////////////////////////////////////////////////////////////
void col1()
{
	
	PORTC.OUTSET = 0x20;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0xD0;
	
	if(((PORTC.IN & 0x08))&&((PORTC.IN & 0x2F)==0b00100000)) //13
	{
		
		printf("13");
		
	}
	
}

void col2()
{
	
	PORTC.OUTSET = 0x40;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0xB0;
	
	if(((PORTC.IN & 0x08))&&((PORTC.IN & 0x4F)==0b01000000)) //14
	{
		
		printf("14");
		
	}
}

void col3()
{
	
	PORTC.OUTSET = 0x80;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0x70;
	
	if(((PORTC.IN & 0x08))&&((PORTC.IN & 0x8F)==0b10000000)) //15
	{
		
		printf("15");
		

	}
}

void col4()
{
	PORTC.OUTSET = 0x10;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0xE0;
	
	if(((PORTC.IN & 0x08))&&((PORTC.IN & 0x1F)==0b00010000)) //16
	{
		printf("16");
		
	}
	
	
}

 

Nitin Shenoy

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

I don't see anything in there to debounce your keypad.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

Does a delay before every printf function help to prevent debounce?

Nitin Shenoy

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

nitinjs wrote:

Does a delay before every printf function help to prevent debounce?

 

No.

 

To debounce a signal you need to read it, wait, read it again, and then, if both reads returned the same value, process that value as being debounced. You need the signal to be stable in one state, or the other, for a period of time.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

Can you tell me how to implement it in xmega a3bu?

Nitin Shenoy

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

In xmega a3bu, it is exactly same way as mega 328P or a tiny 2313. 

 

Here is the like to the  definitive description of switch bounce and how to manage it in software, not specific to any particular MCU:

 

http://www.ganssle.com/debouncin...

 

Jim

 

 

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

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

I don't think Ganssle mentions the method I use which is 'vertical counters'...

 

https://www.compuphase.com/elect...

 

...which is very code efficient. I run the code inside a timer ISR running at 5-10ms.

 

I like it because as written it does a full 8-bit port in one go but can also be easily scaled to 16, 24, or even 32 bits wide.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

Last Edited: Tue. Jan 29, 2019 - 08:58 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:
the method I use which is 'vertical counters'...
For AVR note that "Danni" and "theusch" have posted implementations of both vertical and horizontal counters for AVR (I can never remember which way round though!). Their code is for traditioanl Tiny/Mega but as it's just IO it should be very easy to port to Xmega. (or, for that matter, any micro type with GPIO).

 

Cliff

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

can you suggest me a sample code. I'm not understanding on how to proceed?

Nitin Shenoy

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

nitinjs wrote:

can you suggest me a sample code. I'm not understanding on how to proceed?

Have you read the Ganssle articles? Have you searched for 'denounce vertical counters'?

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

I denounce vertical counters!

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

Kartman wrote:
I denounce vertical counters!

 

Ah, caught out by my phone's autocorrect.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

Last Edited: Fri. Feb 1, 2019 - 07:24 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
void row_col1()
{
	
	PORTC.OUTSET = 0x20;
	PORTC.OUTCLR = 0x0F;
	PORTC_OUTCLR = 0xD0;
	
	
	if(((PORTC.IN & 0x01)==0b00000001)&&((PORTC.IN & 0x2F)==0b00100000)) //1
	{
			timeout_start_singleshot(0,10);
	}

		// Check for debounce timeout expire
		if (timeout_test_and_clear_expired(10)) {
			// Toggle LED0 if button is pressed down
		if (((PORTC.IN & 0x01)==0b00000001)&&((PORTC.IN & 0x2F)==0b00100000)) {


			PORTR_OUTCLR = PIN0_bm;
			_delay_ms(100);
			PORTR_OUTSET = PIN0_bm;
				
		}	
	

Here I've used a timeout function for my debounce code, I'm ticking 10 times and checking again if the button is pressed, but it does not seem to work.

Nitin Shenoy

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

You really are making something simple into a complex mess. You’re supposed to sample the input ten times!

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

Shouldn't it be done using ticking like above.I'm checking the button after 10 ticks again.

Nitin Shenoy

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

Thank you!

 

Nitin Shenoy