Randomizált billentyűzet

 

2020-07-07

Igazából most egy ravaszabb dologról akarok írni mint a billentyű mátrix szimpla kezelése Arduinóval, de nézegettem az írásaimat, és ez hiányzik, pedig jobban érthető, ha az egyszerűbb dologból indulunk ki. No nézzük. Ha van elég szabad lábunk, elég ha a billentyűzet mátrixunkat egyszerűen rádugjuk az Arduinónkra. Esetünkben a D5..8 lábakat beállítjuk kimenetnek, a D9..12 lábakat pedig bemenetnek, amelyeken bekapcsoljuk a belső felhúzó ellenállást. A lenyomott billentyűket a soros vonalra küldjük, és az Arduino IDE monitorán nézegethetjük. A főhurokba tettem egy 300 msec késleltetést, hogy ne írja rögtön tele a képernyőt. A kbd()-t úgy írtam meg, ne fogja meg az Arduinót, nyugodtan csinálhassa az egyéb dolgait. Amikor a kbd() fut, a négy kimenetet (oszlopot) egymás után '0'-ba kapcsolja, és nézi, hogy valamelyik sorban kap-e '0'-t visssza, mert akkor azt a gombot nyomták le. A kbd() '-'-t ad vissza, ha nincs lenyomott gomb, illetve ha folyamatosan lenyomva tartjuk valamelyik gombot. A programnak van egy hibája, ha az egségsugarú user kipróbálja, hogy egyszerre hány gombot tud lenyomni, akkor két oszlop között két kimenetet rövidre tud zárni. Ezért szerencsésebb megoldás minden lábat bemenetnek konfigurálni, és a csak az éppen soron lévő oszlophoz tartozó lábat átállítani kimenetre, és '0'-ba kapcsolni, majd vissza.


/******************************************************************************
*   Author       -  Kiraly Tibor
*                   http://www.tkiraaly.hu
*   Date         -  2020.07.07.
*   Chip         -  Arduino nano, keyboard matrix
*   Compiler     -  Arduino IDE 1.8.12
*
*   KBD kezelese
*    
*         NANO 
*      ----------+
*                !
*                !        +---------+
*             D5 +--------! S S S S !
*             D6 +--------! S S S S !
*             D7 +--------! S S S S !
*             D8 +--------! S S S S !
*                !        +---------+
*                !          ! ! ! !
*             D9 +----------+ ! ! !
*            D10 +------------+ ! !
*            D11 +--------------+ !
*            D12 +----------------+
*                !
*    
******************************************************************************/

#include "Arduino.h"


#define KBD0    12   
#define KBD1    11   
#define KBD2    10   
#define KBD3    9   
#define KBD4    8   
#define KBD5    7  
#define KBD6    6  
#define KBD7    5  


void setup()
{
   pinMode( KBD0, INPUT_PULLUP);
   pinMode( KBD1, INPUT_PULLUP);
   pinMode( KBD2, INPUT_PULLUP);
   pinMode( KBD3, INPUT_PULLUP);
   pinMode( KBD4, OUTPUT);
   pinMode( KBD5, OUTPUT);
   pinMode( KBD6, OUTPUT);
   pinMode( KBD7, OUTPUT);
   Serial.begin( 9600);
   Serial.println( "Keyboard teszt");
   Serial.println();
}


void loop()
{
   Serial.write( kbd());
   delay( 300);
}


byte kbd()
{
   static byte elozo= '-';
   byte a= '-';
   digitalWrite( KBD4, LOW);
   digitalWrite( KBD5, HIGH);
   digitalWrite( KBD6, HIGH);
   digitalWrite( KBD7, HIGH);
   if( !digitalRead( KBD0)) a= '1';
   if( !digitalRead( KBD1)) a= '4';
   if( !digitalRead( KBD2)) a= '7';
   if( !digitalRead( KBD3)) a= '*';
   digitalWrite( KBD4, HIGH);
   digitalWrite( KBD5, LOW);
   if( !digitalRead( KBD0)) a= '2';
   if( !digitalRead( KBD1)) a= '5';
   if( !digitalRead( KBD2)) a= '8';
   if( !digitalRead( KBD3)) a= '0';
   digitalWrite( KBD5, HIGH);
   digitalWrite( KBD6, LOW);
   if( !digitalRead( KBD0)) a= '3';
   if( !digitalRead( KBD1)) a= '6';
   if( !digitalRead( KBD2)) a= '9';
   if( !digitalRead( KBD3)) a= '#';
   digitalWrite( KBD6, HIGH);
   digitalWrite( KBD7, LOW);
   if( !digitalRead( KBD0)) a= 'A';
   if( !digitalRead( KBD1)) a= 'B';
   if( !digitalRead( KBD2)) a= 'C';
   if( !digitalRead( KBD3)) a= 'D';
   if ( elozo == a) a='-';
   else             elozo= a;
   return a;
}

Most nézzük a ravaszságot. Nem szükséges elhinnetek, de van az a szint, amikor mindenfélével megpróbálnak dolgokat kifürkészni. Egy hálózatra nem kötött számítógépről, nem kell ennek PC-nek lennie, lehet ez mondjuk egy digitális zár is, egész érdekes dolgokat tudnak elektromágnesesen (hangolt antennával, nem boltban kapható elektronikával) kigfigyelni. Persze komoly helyeken védekeznek is ez ellen, általában elektromágneses árnyékolással, de lehet zavaró adót is alkalmazni, megvan ennek a részletes szabályozása. Maga a processzor, illetve más belső áramkörök kisugárzásának a megfigyelése, hát az olyan mint EEG, abból sok mindent nem lehet megtudni. A perifériák érdekesek, a billentyűzet és a képernyő. Egy ötlet furakodott a fejembe, a billentyűzet biztonságosabbá tételére. Meg lehet oldani, hogy mindig más sorrendben csengessük végig az oszlopokat, sőt azt is meg lehet csinálni, hogy néha felcseréljük az oszlopokat és a sorokat, ezzel nehezítve a megfigyelést. Erre a megoldásra találtam ki a randomizált kifejezést, és az alábbi programban mutatom be. Az Arduino random() véletlen szám generátorát használom. Az a probléma, hogy valódi véletlen szám generátor nincs. A véletlen szám generálási eljárások valamilyen matematikai formulával képeznek véletlen szerű számsorozatot. Fizikai jelenségeket is fel lehet használni véletlen számok (vagy fehér zaj) generálásához, például tranzisztor emitter-bázis diódájának letörési jelenségét. A matekos megoldásoknál lehet egy kezdőértéket adni a generálási eljárásnak, és onnan indul a generált számsorozat. Én most kezdőértéknek az áramkör bekapcsolásától az első gomb lenyomásáig eltelt idő hosszát használom. A véletlen szám bitjeitől függően összekeverem az oszlopokat, illetve megcserélem a sorokat és az oszlopokat. A dekódoló részt sajnos meg kellett írni az összes sorra és oszlopra is.



/******************************************************************************
*   Author       -  Kiraly Tibor
*                   http://www.tkiraaly.hu
*   Date         -  2020.07.06.
*   Chip         -  Arduino nano, keyboard matrix
*   Compiler     -  Arduino IDE 1.8.12
*
*            NANO 
*        +----------+
*        !          !
*                   !        +---------+
*                D5 +--------! S S S S !
*                D6 +--------! S S S S !
*                D7 +--------! S S S S !
*                D8 +--------! S S S S !
*                   !        +---------+
*                   !          ! ! ! !
*                D9 +----------+ ! ! !
*               D10 +------------+ ! !
*               D11 +--------------+ !
*               D12 +----------------+
*                   !
*
*    Billentyuzet lehallgatas vedelem 
* 
******************************************************************************/

#include "Arduino.h"


#define KBD0    12   
#define KBD1    11   
#define KBD2    10   
#define KBD3    9   
#define KBD4    8   
#define KBD5    7  
#define KBD6    6  
#define KBD7    5  



byte k= '-';
byte kbd_s( void);


void setup()
{
   pinMode( KBD0, INPUT_PULLUP);               // billentyuzet
   pinMode( KBD1, INPUT_PULLUP);
   pinMode( KBD2, INPUT_PULLUP);
   pinMode( KBD3, INPUT_PULLUP);
   pinMode( KBD4, INPUT_PULLUP);
   pinMode( KBD5, INPUT_PULLUP);
   pinMode( KBD6, INPUT_PULLUP);
   pinMode( KBD7, INPUT_PULLUP);
   Serial.begin( 9600);
}


void loop()
{
   k= kbd_s();
   Serial.write( k);
   Serial.println("");
   delay( 200);
} 


byte kbd_s( void)                      // lehallgatas vedett bill. kezeles, + perg.ment
{
   static byte elozo= '-';             // elozo lenyomott billentyu
   static byte elso_gomb= 1;           // elso gombnyomas
   byte a= '-';                        // visszadott ertek, ha nem volt semmi lenyomva
   byte i= 4;                          // szanlalo 4 sor / oszlop
   byte p[]= { 0, 1, 2, 3, 4};         // 0..3 oszlop (sor), 4 - buffer
   byte r= (byte) random( 32);         // 5 bites veletlen szam
   if( r & B00000001)                  // keveres
   {
      p[ 4]= p[ 0];
      p[ 0]= p[ 1];
      p[ 1]= p[ 4];
   }
   if( r & B00000010)
   {
      p[ 4]= p[ 2];
      p[ 2]= p[ 3];
      p[ 3]= p[ 4];
   }
   if( r & B00000100)
   {
      p[ 4]= p[ 1];
      p[ 1]= p[ 3];
      p[ 3]= p[ 4];
   }
   if( r & B00001000)
   {
      p[ 4]= p[ 0];
      p[ 0]= p[ 2];
      p[ 2]= p[ 4];
   }
   if( r & B00010000)                  // valtas sorra
   {
      p[ 0]+= 4;
      p[ 1]+= 4;
      p[ 2]+= 4;
      p[ 3]+= 4;
   }
   while( i--)
   {
      switch ( p[ i])
//      switch ( 7)                    // teszteleshez
      {
         case 0:
            pinMode( KBD0, OUTPUT);
            digitalWrite( KBD0, LOW);         
            if( !digitalRead( KBD4)) a= '1';
            if( !digitalRead( KBD5)) a= '2';
            if( !digitalRead( KBD6)) a= '3';
            if( !digitalRead( KBD7)) a= 'A';
            pinMode( KBD0, INPUT_PULLUP);
            break;
         case 1:
            pinMode( KBD1, OUTPUT);
            digitalWrite( KBD1, LOW);         
            if( !digitalRead( KBD4)) a= '4';
            if( !digitalRead( KBD5)) a= '5';
            if( !digitalRead( KBD6)) a= '6';
            if( !digitalRead( KBD7)) a= 'B';
            pinMode( KBD1, INPUT_PULLUP);
            break;
         case 2:
            pinMode( KBD2, OUTPUT);
            digitalWrite( KBD2, LOW);         
            if( !digitalRead( KBD4)) a= '7';
            if( !digitalRead( KBD5)) a= '8';
            if( !digitalRead( KBD6)) a= '9';
            if( !digitalRead( KBD7)) a= 'C';
            pinMode( KBD2, INPUT_PULLUP);
            break;
         case 3:
            pinMode( KBD3, OUTPUT);
            digitalWrite( KBD3, LOW);         
            if( !digitalRead( KBD4)) a= '*';
            if( !digitalRead( KBD5)) a= '0';
            if( !digitalRead( KBD6)) a= '#';
            if( !digitalRead( KBD7)) a= 'D';
            pinMode( KBD3, INPUT_PULLUP);
         case 4:
            pinMode( KBD4, OUTPUT);
            digitalWrite( KBD4, LOW);         
            if( !digitalRead( KBD0)) a= '1';
            if( !digitalRead( KBD1)) a= '4';
            if( !digitalRead( KBD2)) a= '7';
            if( !digitalRead( KBD3)) a= '*';
            pinMode( KBD4, INPUT_PULLUP);
            break;
         case 5:
            pinMode( KBD5, OUTPUT);
            digitalWrite( KBD5, LOW);         
            if( !digitalRead( KBD0)) a= '2';
            if( !digitalRead( KBD1)) a= '5';
            if( !digitalRead( KBD2)) a= '8';
            if( !digitalRead( KBD3)) a= '0';
            pinMode( KBD5, INPUT_PULLUP);
            break;
         case 6:
            pinMode( KBD6, OUTPUT);
            digitalWrite( KBD6, LOW);         
            if( !digitalRead( KBD0)) a= '3';
            if( !digitalRead( KBD1)) a= '6';
            if( !digitalRead( KBD2)) a= '9';
            if( !digitalRead( KBD3)) a= '#';
            pinMode( KBD6, INPUT_PULLUP);
            break;
         case 7:
            pinMode( KBD7, OUTPUT);
            digitalWrite( KBD7, LOW);         
            if( !digitalRead( KBD0)) a= 'A';
            if( !digitalRead( KBD1)) a= 'B';
            if( !digitalRead( KBD2)) a= 'C';
            if( !digitalRead( KBD3)) a= 'D';
            pinMode( KBD7, INPUT_PULLUP);
      }
      if( a != '-')                    // ha volt lenyomott gomb
      {
         if( elso_gomb)                // az elso gombnyomasnal
         {
            elso_gomb= 0;
            randomSeed( millis());
         }
         break;
      }   
   }
   if ( elozo == a) a='-';
   else             elozo= a;
   return a;
}

Itt a vége, fuss el véle.