Problem:Interfacing keyboard via PS/2 connection with mega8

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

Here's what I am trying to do--

1. To press a key on my keyboard
2. Show that key on Bray's Terminal on my pc
3. Keyboard is connected to Atmega8 ,clock 12MHz

Brief Intro-

Interfacing via a PS/2 connection is really simple atleast hardware wise, connect MCU's Vcc ,Gnd,an External Interrupt Pin and a I/O pin to 4 wires coming out of PS/2 wire.Keyboard has a clock and data from data pin is collected on each falling edge.

(Above is explained lucidly in avr313)

My problem is that I have connected Data and Clock lines to PD4 and PD3 respectively and pulled them up,by writing bit 1 in the respective bit in PORTD.

Now,for every key pressed,a 11 bit code is pressed,and transmission begins with a start bit(logic 0),8 data bits,1 parity bit and a stop bit.

In my case my code is not moving beyond first if condition itself i.e.it's getting stuck at
if(bitcount<1)
{
if(PIND&(1<<4))
{//GETTING STUCK IN THIS IF
}
else
bitcount++;

}......

So evrytime I press a key I expect to see data,but all I get is a test message I plugged in that if-brace which means data pin always remains high and keyboard can't get it to ground EVER.

Any ideas to why this is happening?. Or any other problem one might see in the code.? Also since I have pulled up my DATA and CLOCK,does it mean that a logical 1 sent by keyboard would result in a 0 at MCU input and vice-versa. In my opinion that shouldnt be the case,but just wanted to get that clear.

I am writing my code below-
I am attaching AVR app note,and a code for this project I got from avrfreaks itself. I have modelled my code on that code.


#include
#include "usart.c"
#include
#include "keydata.h"

volatile int bitcount=0;
volatile unsigned char data=0;
int i=0;
int c=0;
volatile unsigned char key;
void init()
{
MCUCR|=(1<<ISC11);
MCUCR&=~(1<<ISC10); //Enabling falling edge external interrupt INT1
GICR|=(1<<INT1);
USART_init(77);
}

void pin_init()
{ DDRD&=~(1<<3);
  DDRD&=~(1<<4); //PD3 connected to clock and input PD4 to data
  PORTD|=(1<<3)|(1<<4);//Enabling pull up
}

void decode()
{

for(i=0;i<79;i++)
 { if(data==keydata[i])
     {
      if(i>9&&i<36)
        key=i+87;
       }
   }
USART_Transmit(key);
}



ISR(INT1_vect)
{
  USART_String("Inside");
  if(bitcount<1)                 //Checking for start bit
   {
     if(PIND&(1<<4))            //Start bit is low so do nothing if high  
      {USART_String("Doing nothing");
	   //Do nothing
        }
     else
     {USART_String(" Finally Here ");
	 bitcount++;
      }  
		}
    
  else                          //Start bit is transmitted.Data bits from 1 to 8.
    { USART_String("Inside 1st outer else");
      if(bitcount<9)
      {USART_String("Inside data bit if");
	   data=data<<1;
       
        if(PIND&(1<<4))
        {data=data|0x01;
         c=1;
		 USART_Transmit('1');
		 }
		 else
		 USART_Transmit('0');
		}
      if(bitcount==12)
       {bitcount=-1;
        decode();
        }
    bitcount++;     
      }
      
  
  }

void main()
{
 pin_init();
 init();
 sei();//Enabling global interrupts

while(1)
 { //Interrupts will do the job
    }  

}

P.S. - USART_Transmit is used to just debug and see where program has reached.

Attachment(s): 

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

Wrong forum, read the guidelines.

[cliff: so moving from Academy to AVR]

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

when i press a key and see bits on terminal..i see only 8 bits...whereas i am expecting 33...including break codes..any explanation for this?

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

abhishekbhardwaj007 wrote:
any explanation for this?

A classic one.

What baud rate UART do you have?
How much time do you think sending strings take?
Is that time greater than keyboard clock speed?
What happens if keyboard clock would like to interrupt, but you are ignoring them and sending debug strings in interrupt?

Maybe you can figure out the rest yourself now?

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

baud rate is 9600 bps..that's a valid point...i"ll try it over the weekend and post it here

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

ok so I tried removing all the USART transmission for debuggings,instead after 33 bytes were received I tried decoding and displaying bit pattern. But all i get is data line staying high that is..11111111,i can't fathom why when i press any key my keyboard isnt pulling clock low and sending appropriate data bit.

My code is-

#include
#include "usart.c"
#include
#include "keydata.h"

volatile int bitcount=0;
unsigned char key;
unsigned char data=0;
void init()
{
MCUCR|=(1<<ISC11);
MCUCR&=~(1<<ISC10); //Enabling falling edge external interrupt INT1
GICR|=(1<<INT1);
USART_init(77);
}

void pin_init()
{ DDRD&=~(1<<3);
  DDRD&=~(1<<4); //PD3 connected to clock and input PD4 to data
  PORTD|=(1<<3)|(1<<4);//Enabling pull up
}

void display()
{
int j;
for(j=0;j<8;j++)
{if(data&(1<<j))
  USART_Transmit('1');
 else
  USART_Transmit('0');
 }
}


void decode()
{key=0;
int i;
for(i=0;i<79;i++)
 { if(data==keydata[i])
     {
      if(i>9&&i<36)
        key=i+87;
       }
   }
USART_Transmit(key);


}



ISR(INT1_vect)
{
bitcount++;

  if(bitcount>1&&bitcount<10)
   {data=data<<1;
    if(PIND&&(1<<4))
    data=data|0x01;
     }
   
  if(bitcount==33)
   {bitcount=0;
    display();
    decode();
    }

}        

 


void main()
{
 pin_init();
 init();
 sei();//Enabling global interrupts

while(1)
 { //Interrupts will do the job
    }  

}

and Rx on terminal is--

11111111<0>11111111<0>11111111<0>11111111<0>11111111<0>11111111<0>11111111<0>11111111<0>11111111<0>11111111<0>11111111<0>11111111<0>

still no success :-(

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

You lack discipline when writing code. I started to read your code and stopped reading after a few lines. You would have to pay me to work through that code in detail.

Some obvious things:

- You don't like meaningful comments

- You haven't provided all the code, as the header files indicate

- You don't pay attention to the difference between bitwise and logical operations

- You modify a non volatile variable in an interrupt

- You think placing opening and closing brackets somewhere is good enough as long as it silences the compiler. I would not be surprised if you managed to mix up some of your nested if() statements

- You like magic numbers, so no one can easily understand what you mean

- You indent randomly

I am not surprised it doesn't work. It is not even obvious what "working" would mean.

Stealing Proteus doesn't make you an engineer.

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

Thanks for the criticism.
It will help me in the future.

I am posting the code again with better indentation and comments (tried my best to make it lucid)

#include
#include "usart.c"
#include
#include "keydata.h"

volatile int bitcount=0;
unsigned char key;
volatile unsigned char data=0;
 
 void init()          			//This function is used to enable falling edge interrupt at PD3 
 {                    			//and set up UART with baud rate 9600bps
	MCUCR|=(1<<ISC11);
	MCUCR&=~(1<<ISC10); 		//Enabling falling edge external interrupt INT1
	GICR|=(1<<INT1);
	USART_init(77);     		//Baud rate 9600 bps.Initialise function definition can be seen in usart.c
  }

 void pin_init()                         //Function used for pin initializations
 { 	DDRD&=~(1<<3);                  //PD3 connected to clock line on keyboard
  	DDRD&=~(1<<4); 			//PD4 connected to data  line on keyboard
  	PORTD|=(1<<3)|(1<<4);		//Enabling pull up on both pins
  }

  void display()                          //Function used to debug.Shows the bits
 {                                       //stored in 'data' after key has been pressed
	int j;                          //and released. 
	for(j=0;j<8;j++)
		{if(data&(1<<j))         //As 1 is left shifted and bitwise ANDED with data
  		 USART_Transmit('1');    //Each bit of data is tested,and only if it's 1 a '1' is sent to terminal.
 		 else                    
  	         USART_Transmit('0');
 		  }
  }

   void decode()                           //Function for decoding character stored in data.
 {	
        key=0;                          //keydata is an array which forms are lookuptable.
	int i;
	for(i=0;i<79;i++)
 		{ if(data==keydata[i])  //data being sequentially tested
     			{
      			 if(i>9&&i<36)  //Condition for checking if 'a' to 'z' has been pressed
        		  key=i+87;
       			   }
   		  }
	USART_Transmit(key);

  }



  ISR(INT1_vect)                          //Falling edge Interrupt vector attached to clock pin
 {
        bitcount++;                     //Incrementing counter.

  	if(bitcount>1&&bitcount<10)     //Bits 2 to 10 are data bits.
   	{data=data<<1;                  //Left shifting data and if PIND.4 is high placing a 1 at LSB.
    	if(PIND&&(1<<4))
    	data=data|0x01;
     	  }
   
  	if(bitcount==33)                //33 count means key has been pressed and released.
   	{bitcount=0;                    //Wrapping up counter for next time a key is pressed.
    	 display();                     //Calling display routine for showing individual bits in data.
    	 decode();                      //Calling decode pattern for figuring what key has been pressed.
    	  }

  }        
 
 


  void main()
 {
  	pin_init();
 	init();
 	sei();//Enabling global interrupts

	while(1)
 		{ //Interrupts will do the job
    			}  

 }

I am using an Atmega8 with a clock of 12Mhz.

Definition of Working for this project?

This project involves pressing a key on the Keyboard and observing what's pressed on the Bray's terminal interface on my laptop. Unfortunately right now my display routine is showing any key pressed as 11111111,which means that PD4 connected to data line of keyboard which had been pulled up isn't undergoing any change.This scenario is against expected outcome,which involved a unique 8-bit code for each key pressed on the keyboard.

I am using a USB keyboard connected to a USB-PS/2 converter.Then connected to a PS/2 cable and then to MCU on breadboard.

PD4--Data line of keyboard
PD3--Clock line of keyboard
Vcc--Vcc line of keyboard
GND--Gnd line of keyboard

Please find attached below two header files used.

Attachment(s): 

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

its working now...problem was in

if (PIND&&(1<<4))

i had in my hurry pressed an extra AND there.

after correcting to

if(PIND&(1<<4))

it works