Jag är mer lagd åt det digitala hållet. Om du dessutom har en hel uC att dedikera (minus två "com"-pinnar) så skulle jag rekommendera att koppla det så som det är tänkt. Med andra ord, som rader och kolonner.
Du drar på interna pull-up:erna på ingångarna (som är kopplade till 9,8,7,5), sedan "scannar" du igenom alla kolonnerna (genom att lägga hög signal på alla utgångar [2,4,3,6] utom en där du istället lägger låg nivå. Nu kollar du vilka ingångar som är sänkta och sparar undan detta någonstans.
Sedan byter du till nästa kolonn och återupprepar osv.
Lite kod kan kanske hjälpa:
Anta att raderna är kopplade till de fyra höga pinnarna på en port och kolonnerna är kopplade till de fyra låga.
Lite slöseri på minne. Går ju att optimera men principen är ju samma.
Kod: Markera allt
char keystatus[4][4]; // Knapparnas status, slöseri, men det går snabbt och är enkelt
char coltemp; // Temporär status för nuvarande kolonn
DDRX = 0xF0; // Ställ in ut- och ingångar
PORTX = 0xFF; // Alla pull-ups igång
char outmask = 0x80;
for( char i=0; i<4; i++ ) {
PORTX = ~(outmask); // Låg signal på en av raderna
coltemp = PINX; // Läs in kolonnen
char inmask = 0x01;
for( char j=0; j<4; j++ ) {
if(!(coltemp & inmask) ) { // Maska bort allt utom nuvarande knappen, låg signal => knappen tryckt
keystatus[i][j] = 1;
}
else {
keystatus[i][j] = 0;
}
inmask <<= 1; // Byt till nästa knapp i kolonnen
}
outmask >>= 1; // Byt till nästa rad
}
Har inte testat detta, men det borde fungera. Kanske är någon liten bug, och man får hålla tungan i rätt mun när man kopplar in port-pinnarna så att status för knappen längst upp till vänster (a.k.a knapp 1) verkligen hamnar i keystatus[0][0] osv.
Edit: Fixade ett uppenbart fel i koden... och ett till