Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Printing ASCII values with combination of 2buttons

Status
Not open for further replies.

dsk2858

Member level 2
Joined
Aug 17, 2011
Messages
47
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
Chennai,India
Activity points
1,683
Printing ASCII values with combination of 2-KEYS

I actually tried to implement a 2key combination to print a ASCII value according to the below logic.
I am using AVR STUDIO-4 IDE.

k1 k2 o/p
0 0 no operation
0 1 A
1 0 B
1 1 C
i used switch & case statements to implement it the code is as follows.
Code:
#include<avr/io.h>
#include<util/delay.h>
void delay_ms(unsigned int d)
{
_delay_ms(d);
}
void usart_init (void)//initializing UART for serial communication
{ 
UCSRB = (1<<TXEN);
UCSRC = (1<< UCSZ1)|(1<<UCSZ0)|(1<<URSEL);
UBRRL = 0x33;
}
void usart_send (unsigned char ch)//sending data to PC
{
while (!(UCSRA & (1<<UDRE)));
UDR = ch;
}
int main (voide)
{
unsigned char z;
unsigned int a;
DDRB=0x00;//input port
while(1)
{
z=PINB;
z&=0b00000011
switch(z)
{
case(0):
{
break;
}
case(1):
{
a='A';
usart_init();
usart_send(a);
break;
}
case(2):
{
a='B';
usart_init();
usart_send(a);
break;
}
case(3):
{
a='C;
usart_init();
usart_send(a);
break;
}
}
}
}
}
return 0;
}

The problem i am facing is as follows.
when i am pressing K2 then it is switching to case(1)and printing A
when i am pressing K1 then it is switching to case (2)and printing B
but the main problem lies here when both the keys K1 and K2 are pressed at a time then only it is switching to case(3) and printing C.
how to over come this problem , as there are only two keys i can press them at a time but if there are combination of 3 or 4 keys how to procede.
which c statements to be used .
 

Re: Printing ASCII values with combination of 2-KEYS

but the main problem lies here when both the keys K1 and K2 are pressed at a time then only it is switching to case(3) and printing C.
how to over come this problem , as there are only two keys i can press them at a time but if there are combination of 3 or 4 keys how to procede.
which c statements to be used .

Do you mean that it is hard to press the two buttons simultaneously?

You can add a small delay when you detect a button press and after that check to see if a second button has been pressed, if not then show A or B, this will give you a small time frame in order to press the second button too.
 
To be frank i am completely new to the world of embedded programming in other words DUMMY.
I bought a book THE AVR MICROCONTROLLER AND EMBEDDED SYSTEM USING ASSEMBLY AND C by MUHAMMAD ALI MAZIDI

I have a task given by my professor to implement PC key board with a combination of Eight keys and to transmit it wireless to PC to display on HYPER TERMINAL.

That's the reason i started from the beginning .
actually i am getting confused how to implement it.Which conditional statements to be used whether DO-WHILE or IF-ELSE-IF.
How much time delay should be taken when simultaneously pressing the keys.

It would be helpful if you can explain me with an example.
 

What are the combinations that you expect to get from the buttons?
8 buttons can give up to 255 combinations , so how many of them do you intend to use?

If you have sequential input values that represent sequential characters then you can convert them directly.
In the ASCII table 'A' is decimal 65, 'B' is 66 etc, if you have a value of 1 that should give 'A' , 2 for 'B' etc all you have to do is add to the input value the decimal number 64 so that 1 becomes 65 , 2 becomes 66 etc.

You can set a='A' or a=65 , the result is exactly the same.

The delay I mention is just to provide a small tolerance to the user when pressing the keys simultaneously, usually one of the buttons will make contact first so I think that you should delay a few ms and check if any other button has been pressed too and then proceed to send the uart value.

What I propose is something like

Code:
while (PINB==0); // stay here until something is pressed
_delay_ms(10) // I'm not sure how much delay you need
z |= PINB; // read the input , all the buttons should be down after applied  delay

//then check the value
 
As you had suggested i had written the program.
But when i am simulating that in ISIS with different time delays i found a problem.
First time when i pressed a button (01) then it is printing '2'. after that i pressed (10) then insted of printing '3' it is printing '4'.
then what ever the in put is it is printing '4' only .
then i found that the register 'Z' which is storing PINB pressed value was not returning to zero .
i also included return value at last of the program, but "Z' is not turning to zero.
Code:
#include<avr/io.h>
#include<util/delay.h>
#define F_CPU 8000000UL
void delay_ms(unsigned int d)
{
_delay_ms(d);
}
void usart_init (void)
{ 
UCSRB = (1<<TXEN);
UCSRC = (1<< UCSZ1)|(1<<UCSZ0)|(1<<URSEL);
UBRRL = 0x33;
}
void usart_send (unsigned char ch)
{
while (!(UCSRA & (1<<UDRE)));
UDR = ch;
}
int main (void)
{
unsigned int z,f,a;
DDRB=0x00;
while(1)
{
[COLOR="#FF0000"]while(PINB==0x00);
_delay_ms(100);
z|=PINB;[/COLOR]
switch(z)
{
case(0):
{
a='1';
usart_init();
usart_send(a);
break;
}
case(1):
{
a='2';
usart_init();
usart_send(a);
break;
}
case(2):
{
a='3';
usart_init();
usart_send(a);
break;
}
case(3):
{
a='4';
usart_init();
usart_send(a);
break;
}
}
}
return 0;
}

Please suggest me the solution for that.
 

Yes that was my mistake sorry, I had originally written

Code:
z=PINB;
_delay_ms(100);
z|=PINB;

but then I have removed the first assignment and I forgot to remove the OR operator from the assignment after the delay.

Use z=PINB;

---------- Post added at 13:29 ---------- Previous post was at 13:23 ----------

You should get the habit of using formatting in your code, see how much better it looks

Code:
#include<avr/io.h>
#include<util/delay.h>
#define F_CPU 8000000UL
void delay_ms(unsigned int d)
{
    _delay_ms(d);
}
void usart_init (void)
{
    UCSRB = (1<<TXEN);
    UCSRC = (1<< UCSZ1)|(1<<UCSZ0)|(1<<URSEL);
    UBRRL = 0x33;
}
void usart_send (unsigned char ch)
{
    while (!(UCSRA & (1<<UDRE)));
    UDR = ch;
}
int main (void)
{
    unsigned int z,f,a;
    DDRB=0x00;
    while(1)
    {
        while(PINB==0x00);
        _delay_ms(100);
        z=PINB;
        switch(z)
        {
        case(0):
        {
            a='1';
            usart_init();
            usart_send(a);
            break;
        }
        case(1):
        {
            a='2';
            usart_init();
            usart_send(a);
            break;
        }
        case(2):
        {
            a='3';
            usart_init();
            usart_send(a);
            break;
        }
        case(3):
        {
            a='4';
            usart_init();
            usart_send(a);
            break;
        }
        }
    }
    return 0;
}

As an additional note I see no reason to add return 0; at the end of main.
First of all the execution will never exit the super loop so it will never reach that line but if for any reason it did you would be in trouble, you should never let the execution get out of the main.

---------- Post added at 13:39 ---------- Previous post was at 13:29 ----------

Another addition in the code may be a condition to check if all the buttons are off before restarting the loop because the code as it is now will resend the same character over and over again, I don't know if this is the desired behaviour.

I also think that there is a chance to leave the buttons in such a moment that one of them will be off and the other on exactly when the input is sampled , in that case you will get a wrong result and that is why I think you should add a condition to check if all the buttons are off before checking for the next pressed button.
 
i added the code in the above program and tried it with different delays. this time i downloaded it on to my trainer with ATMEGA32 MCU. still same problem which i had mentioned before is getting executing.
when i am pressing
k1 k2 o/p
0 0 1
0 1 2---this is getting printed
1 0 3---this is also getting printed

1 1 4---- it is not getting printed,only when both the buttons are pressed at a time only it is getting printer ,that is pressing two buttons simultaneously is not getting practical.


the delay was 20ms When i am pressing k1 button first an trying to press k2 button by that time it is printing '2', then i increased the delay from 20ms to 500ms with different ranges , but still i am facing the same problem.

Please help me to solve this problem.
thanking you in advance.
 

Is your code the same as post #6?

1 1 4---- it is not getting printed,only when both the buttons are pressed at a time only it is getting printer ,that is pressing two buttons simultaneously is not getting practical.
I'm not sure what the current problem , you get 4 if you press the buttons simultaneously but you want something different?
 
I don't understand the problem.
You said
when i am pressing
k1 k2 o/p
0 0 1
0 1 2---this is getting printed
1 0 3---this is also getting printed

1 1 4---- it is not getting printed,only when both the buttons are pressed at a time only it is getting printer ,that is pressing two buttons simultaneously is not getting practical.

so you never get 1?
and you get 4 when you press both buttons simultaneously, isn't that what you wanted?

You said that the button inputs are 0 0 when there is no button pressed , have you used pull down resistors to be sure of that or you have left them floating?
My recommendation would be to enable the internal pullups and invert the logic, 1 when no button is pressed and 0 when a button is pressed (the buttons should connect the input to gnd in this case)
 
sorry, it was my misunderstanding the meaning of SIMULTANEOUSLY.
you get 4 when you press both buttons simultaneously, isn't that what you wanted?
when pressing both the buttons simultaneously it is printing 4.
But my requirement is not that.

As i had considered only TWO buttons it is possible to press the tow buttons at a time , but when i am considering EIGHT BUTTONS it is not possible to press all the eight buttons at a time

1 1 1 1 1 1 1 1-A

Because i need to design a hand GLOVE where this eight buttons would be placed, and is not possible to press two buttons at a time. glove.jpg

Up to my knowledge there would be a few milliseconds delay to press the combination of this numbers and until i stop the button pressing the port to which i had connected the switches should be monitored for the next button press with in a few milliseconds delay after the delay has been processed and there was no key press detected the detected combinations ASCII value should be printed.

this is what is not happening with the above code.

please forgive me if i did any mistakes till now.
 

You can use a loop with a duration depending on the time you need and inside the loop scan the input and OR any new value that you read.

I mean something like

Code:
z=PINB;  // this is to clear the previous value, you can also use z=0 so that the value gets filled in the following loop
for (i=0;i<10000;i++) // you can change the duration of the scan from this
{
	z |=PINB;
}

This doesn't check the button order, I suppose you don't care about that.
 
sorry for this , BUT i could not under stand, what is the purpose of for loop here
 

The loop is providing a fixed period for which it scans the input and each detected button press is added in the store variable z
Suppose that you press button 1 , z becomes 0b00000001.
Then you press button 2 , this gives an input of 0b00000010 and z is already 0b00000001 , if you OR these two z = 0b00000001 | 0b00000010 you get 0b00000011

It will be much easier to calculate the delay if you modify the code to something like

Code:
z=PINB;  // this is to clear the previous value, you can also use z=0 so that the value gets filled in the following loop
for (i=0;i<10;i++) // you can change the duration of the scan from this
{
   _delay_ms(1);	
   z |=PINB;
}
 
Thank you for brief explanation . soon i would implement and return back .
 

Hi alexan_e,
It took long time to implement it, i as out of station,

The good news is that i gout the out put as you directed me to achieve it.

here i up loaded the video of it

Thanking you very much.

I also posted a new thread with a title Accessing MS-word through hyperterminal
HTML:
https://www.edaboard.com/threads/242099/#post1035744

could you please help regarding this too.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top