Hallo miteinander. Ich bin gerade frisch ins Arduino eingestiegen. Hab vom programmieren sehr wenig Erfahrung und schon ein Problem.
Ich hab hier ein Beispielcode und würde den gerne umändern auf eine 4x4 Matrix Keypad.
Schau im Moment aber wie Schweinchen ins Uhrwerk. Über etwas HIlfe würde ich mich sehr feuen,danke.
/* keyPadHiduino Example Code
by: Jim Lindblom
date: January 5, 2012
license: MIT license. If you find this code useful, please
feel free to use this code however you'd like, commercially
or otherwise. Just keep this license on there whatever you do.
This code implements a 12-key USB keypad. You can type 0-9,
* is the + sign and the # key is enter. I'm using SparkFun's
12-button keypad, your pinouts may vary. Multi-touch is
not supported.
SparkFun Keypad Pinout:
Rows and columns are connected as such:
-------------
| 1 | 2 | 3 | - 3
| 4 | 5 | 6 | - 7
| 7 | 8 | 9 | - 6
| * | 0 | # | - 1
-------------
| | |
2 4 5
*/
// Pins 1-7 of the keypad connected to the Arduino respectively:
int keypadPins[7] = {2, 3, 4, 5, 10, 16, 14};
int keypadStatus; // Used to monitor which buttons are pressed.
int timeout; // timeout variable used in loop
void setup()
{
for (int i=0; i<7; i++)
{
pinMode(keypadPins[i], INPUT); // Set all keypad pins as inputs
digitalWrite(keypadPins[i], HIGH); // pull all keypad pins high
}
}
void loop()
{
keypadStatus = getKeypadStatus(); // read which buttons are pressed
if (keypadStatus != 0) // If a button is pressed go into here
{
sendKeyPress(keypadStatus); // send the button over USB
timeout = 2000; // top of the repeat delay
while ((getKeypadStatus() == keypadStatus) && (--timeout)) // Decrement timeout and check if key is being held down
delayMicroseconds(1);
while (getKeypadStatus() == keypadStatus) // while the same button is held down
{
sendKeyPress(keypadStatus); // continue to send the button over USB
delay(50); // 50ms repeat rate
}
}
}
/* sendKeyPress(int key): This function sends a single key over USB
It requires an int, of which the 12 LSbs are used. Each bit in
key represents a single button on the keypad.
This function will only send a key press if a single button
is being pressed */
void sendKeyPress(int key)
{
switch(key)
{
case 1: // 0x001
Keyboard.write('1'); // Sends a keyboard '1'
break;
case 2: // 0x002
Keyboard.write('2');
break;
case 4: // 0x004
Keyboard.write('3');
break;
case 8: // 0x008
Keyboard.write('4');
break;
case 16: // 0x010
Keyboard.write('5');
break;
case 32: // 0x020
Keyboard.write('6');
break;
case 64: // 0x040
Keyboard.write('7');
break;
case 128: // 0x080
Keyboard.write('8');
break;
case 256: // 0x100
Keyboard.write('9');
break;
case 512: // 0x200
Keyboard.write('+');
break;
case 1024: // 0x400
Keyboard.write('0'); // Sends a keyboard '0'
break;
case 2048: // 0x800
Keyboard.write('\n'); // Sends the 'ENTER' key
break;
}
}
/* getKeypadStatus(): This function returns an int that represents
the status of the 12-button keypad. Only the 12 LSb's of the return
value hold any significange. Each bit represents the status of a single
key on the button pad. '1' is bit 0, '2' is bit 1, '3' is bit 2, ...,
'#' is bit 11.
This function doesn't work for multitouch.
*/
int getKeypadStatus()
{
int rowPins[4] = {keypadPins[2], keypadPins[6], keypadPins[5], keypadPins[0]}; // row pins are 2, 7, 6, and 1 of the keypad
int columnPins[3] = {keypadPins[1], keypadPins[3], keypadPins[4]}; // column pins are pins 2, 4, and 5 of the keypad
int keypadStatus = 0; // this will be what's returned
/* initialize all pins, inputs w/ pull-ups */
for (int i=0; i<7; i++)
{
pinMode(keypadPins[i], INPUT);
digitalWrite(keypadPins[i], HIGH);
}
for (int row=0; row<4; row++)
{ // initial for loop to check all 4 rows
pinMode(rowPins[row], OUTPUT); // set the row pin as an output
digitalWrite(rowPins[row], LOW); // pull the row pins low
for (int col=0; col<3; col++)
{ // embedded for loop to check all 3 columns of each row
if (!digitalRead(columnPins[col]))
{
keypadStatus |= 1 << ((row+1)*3 + (col+1) - 4); // set the status bit of the keypad return value
}
}
pinMode(rowPins[row], INPUT); // reset the row pin as an input
digitalWrite(rowPins[row], HIGH); // pull the row pin high
}
return keypadStatus;
}
Wollte ich auch gerade schreiben, kam mir auch so vor. Hatte aber noch Wartezeit.
Was mir überhaupt nicht klar ist:
case 1: // 0x001
Keyboard.write('1'); // Sends a keyboard '1'
break;
case 2: // 0x002
Keyboard.write('2');
[code]
das ist das case 1, 2, 4, 8, 16 etc. und 0x001, 0x002, 0x004, 0x008, und jetzt 0x010, 0x020 etc.
Ein Hinweis nach was ich schauen muss.
Glaube ich eher nicht. Das ist eher hilfreich bei einem Arduino Mini oder Pro Mini.
Der Pro Micro ist so etwas wie der Leonardo, oder der Micro, hat also einen ATmega32u4 drauf und der kümmert sich auch selbst um die USB-Verbindung und kann sich auch als USB-Keyboard oder Maus "ausgeben".
Ein USB-Serial-Adapter hilft da nicht allzu viel - obwohl so etwas natürlich in keinem Microkontroller-Bastellabor fehlen sollte - im vorliegenden konkreten Fall aber wenig sinnvoll.
Hallo,
eine kurze Anmerkung: Bitte darauf achten, dass beim Drücken mehrerer Tasten gleichzeitig, auch Spalten und Zeilen zusätzlich miteinander verbunden werden. Deshalb ist es zwingend erforderlich, die Ansteuersignale über "Open Collectoren" zu realisieren.
Gruß Manfred
Hallo, nochmals zur Tastatur Matrix:
in der Anlage ist der Fall dargestellt, dass die Tasten 4 und 5 gleichzeitig gedrückt werden. Um die Tastatur abfragen zu können, müssen die Ausgänge des ATmega ja zwangsläufig auf unterschiedlichen Logikpegel liegen. Wenn man den E-Technikverstand nicht gänzlich dem Softwareverstand opfert, sieht man, dass die zwei Ausgangsstufen miteinander kurzgeschlossen sind. Also "OpenCollectoren" zwingend erforderlich. Sonst würde nur helfen, die inaktiven Ausgänge als Eingänge zu schalten und dann erst den für die Sequenz notwendigen Pin von Eingang aus Ausgang umzuschalten..
Gruß Manfred
Danke für die Antworten. Ich bin jetzt ein Stück weiter, d.h. es funktioniert soweit gut, bis auf die case Anweisung lässt sich nicht erweitern.
#include <Keypad.h>
#include <Keyboard.h>
/* keyPadHiduino Example Code
by: Jim Lindblom
date: January 5, 2012
license: MIT license - feel free to use this code in any way
you see fit. If you go on to use it in another project, please
keep this
This code turns your ProMicro, with an ATmega32U4, into an
HID USB Keypad. Buttons 0-9 enter their respective number,
The * button enters a '+' and the # button enters a 'Enter'.
Keypad Pinout:
Rows and columns are connected as such on the keypad:
-------------
| 1 | 2 | 3 | - 3
| 4 | 5 | 6 | - 7
| 7 | 8 | 9 | - 6
| * | 0 | # | - 1
-------------
| | |
2 4 5
This is how they're connected to the ProMicro:
Keypad Pin ------ Pro Micro Pin
1 ------------------ 2
2 ------------------ 3
3 ------------------ 4
4 ------------------ 5
5 ------------------ 6
6 ------------------ 7
7 ------------------ 8
8 ------------------ 9
*/
// Pins 1-8 of the keypad connected to the Arduino respectively:
int keypadPins[8] = {2, 3, 4, 5, 6, 7, 8, 9};
int keypadStatus; // Used to monitor which buttons are pressed.
int timeout; // timeout variable used in loop
void setup()
{
for (int i=0; i<9; i++)
{
pinMode(keypadPins[i], INPUT); // Set all keypad pins as inputs
digitalWrite(keypadPins[i], HIGH); // pull all keypad pins high
}
}
void loop()
{
keypadStatus = getKeypadStatus(); // read which buttons are pressed
if (keypadStatus != 0) // If a button is pressed go into here
{
sendKeyPress(keypadStatus); // send the button over USB
timeout = 2000; // top of the repeat delay
while ((getKeypadStatus() == keypadStatus) && (--timeout)) // Decrement timeout and check if key is being held down
delayMicroseconds(1);
while (getKeypadStatus() == keypadStatus) // while the same button is held down
{
sendKeyPress(keypadStatus); // continue to send the button over USB
delay(50); // 50ms repeat rate
}
}
}
/* sendKeyPress(int key): This function sends a single key over USB
It requires an int, of which the 12 LSbs are used. Each bit in
key represents a single button on the keypad.
This function will only send a key press if a single button
is being pressed */
void sendKeyPress(int key)
{
switch(key)
{
case 1: // 0x001
Keyboard.write('1'); // Sends a keyboard '1'
break;
case 2: // 0x002
Keyboard.write('2');
break;
case 4: // 0x004
Keyboard.write('3');
break;
case 8: // 0x008
Keyboard.write('4');
break;
case 16: // 0x010
Keyboard.write('5');
break;
case 32: // 0x020
Keyboard.write('6');
break;
case 64: // 0x040
Keyboard.write('7');
break;
case 128: // 0x080
Keyboard.write('8');
break;
case 256: // 0x100
Keyboard.write('9');
break;
case 512: // 0x200
Keyboard.write('U');
break;
case 1024: // 0x400
Keyboard.write('0'); // Sends a keyboard '0'
break;
case 2048: // 0x800
Keyboard.write('\n'); // Sends the 'ENTER' key
break;
case 4096: // 0x800
Keyboard.write('t'); // Sends the 't' key
break;
case 8192: // 0x800
Keyboard.write('B'); // Ab hier keine Funktion
break;
}
}
/* getKeypadStatus(): This function returns an int that represents
the status of the 12-button keypad. Only the 12 LSb's of the return
value hold any significange. Each bit represents the status of a single
key on the button pad. '1' is bit 0, '2' is bit 1, '3' is bit 2, ...,
'#' is bit 11.
This function doesn't work for multitouch.
*/
int getKeypadStatus()
{
int rowPins[4] = {2,3,4,5}; // row pins are 1, 2, 3, and 4 of the keypad
int columnPins[4] = {6,7,8,9}; // column pins are pins 5, 6, 7, and 8 of the keypad
int keypadStatus = 0; // this will be what's returned
/* initialize all pins, inputs w/ pull-ups */
for (int i=0; i<9; i++)
{
pinMode(keypadPins[i], INPUT);
digitalWrite(keypadPins[i], HIGH);
}
for (int row=0; row<4; row++)
{ // initial for loop to check all 4 rows
pinMode(rowPins[row], OUTPUT); // set the row pin as an output
digitalWrite(rowPins[row], LOW); // pull the row pins low
for (int col=0; col<4; col++)
{ // embedded for loop to check all 3 columns of each row
if (!digitalRead(columnPins[col]))
{
keypadStatus |= 1 << ((row+1)*3 + (col+1) - 4); // set the status bit of the keypad return value
}
}
pinMode(rowPins[row], INPUT); // reset the row pin as an input
digitalWrite(rowPins[row], HIGH); // pull the row pin high
}
return keypadStatus;
}
case 2048: // 0x800
case 4096: // 0x800
case 8192: // 0x800
richtiger wäre wohl
case 1024: // 0x400
case 2048: // 0x800
case 4096: // 0x1000 // 2^12
case 8192: // 0x2000 // 2^13
da sieht man, dass du auf das 13. und 14. Bit testest.
Da hast Du ja recht, nur wie kann ich weitere bits nutzen? Wo sind die 12bits denn deklariert.
Wie gesagt, ich bin ziemlich neu in der programmierung und schon froh, dass es soweit funktioniert.
Evt. kannst Du mir das ändern oder einen link zum nachlesen geben.