Hallo an alle!
Ich brauche dringend eure Hilfe und Tipps!!!
Ich möchte gerne eine 3x4 Matrix Tastatur über den Tastatur-Controller
PCF8574 ansteuern.
Nach jedem Tastendruck soll ein Interrupt ausgeführt werden, der dann in der Interrupt Service Routine abgefragt wird und auf dem Seriellen Monitor ausgegeben wird (später auf dem LCD).
Zur Zeit wird die Tastatur nur in der loop schleife abgefagt, was auch wunderbar funktioniert.
Hier der Code:
#include <Wire.h>
#include <i2ckeypad.h>
#define ROWS 4
#define COLS 3
#define PCF8574_ADDR 0x20
i2ckeypad kpd = i2ckeypad(PCF8574_ADDR, ROWS, COLS);
int interrupt0 = 0;
int i = 0;
volatile char taste = '\0';
void setup()
{
Serial.begin(9600);
Wire.begin();
kpd.init();
attachInterrupt(interrupt0, interruptroutine, FALLING);
}
void loop()
{
taste = kpd.get_key();
if(taste != '\0') {
Serial.print(taste);
Serial.print("\n");
Serial.print("interrupt=");
Serial.print(i);
Serial.print("\n");
}
}
void interruptroutine() //InterruptKeyCode
{
i++;
}
Code ende
hier die i2ckeypad.cpp Datei:
#include "i2ckeypad.h"
#include <Wire.h>
// Arduino Versionierung.
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
/*
* PIN MAPPING
*
* Hier können Sie Ihre Wire Zuordnung zwischen Ihrer Tastatur und PCF8574 ändern
* Standard-Mapping für Sparkfun 4x3 Tastatur
*/
#define COL0 2 // P2 PCF8574 ist COL0 gewöhnlich Pin 3 3x4 Tastaturen
#define COL1 0 // P0 of PCF8574, col1 is usually pin 1 of 4x3 keypads
#define COL2 4 // P4 of PCF8574, col2 is usually pin 5 of 4x3 keypads
#define ROW0 1 // P1 of PCF8574, row0 is usually pin 2 of 4x3 keypads
#define ROW1 6 // P6 of PCF8574, row1 is usually pin 7 of 4x3 keypads
#define ROW2 5 // P5 of PCF8574, row2 is usually pin 6 of 4x3 keypads
#define ROW3 3 // P3 of PCF8574, row3 is usually pin 4 of 4x3 keypads
/*
* Taste auf dem Tastenfeld MAPPING
*
*/
const char keymap[4][5] =
{
"789",
"456",
"123",
"0SE"
};
/*
* VAR und Konstanten DEFINITION.
*/
// Standardeinstellung Zeile und Spalte Pinzahlen
int num_rows = 4;
int num_cols = 3;
// PCF8574 i2c Addresse
int pcf8574_i2c_addr;
// Aktuelle Reihe suchen
static int row_select;
// Aktuelle Daten des PCF8574 festgelegt
static int current_data;
//Hex-Byte-Anweisung für jeden Port des PCF8574
const int hex_data[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
// Hex-Daten für jede Zeile der Tastatur vom PCF8574
const int pcf8574_row_data[4] =
{
hex_data[ROW1] | hex_data[ROW2] | hex_data[ROW3] |
hex_data[COL0] | hex_data[COL1] | hex_data[COL2],
hex_data[ROW0] | hex_data[ROW2] | hex_data[ROW3] |
hex_data[COL0] | hex_data[COL1] | hex_data[COL2],
hex_data[ROW0] | hex_data[ROW1] | hex_data[ROW3] |
hex_data[COL0] | hex_data[COL1] | hex_data[COL2],
hex_data[ROW0] | hex_data[ROW1] | hex_data[ROW2] |
hex_data[COL0] | hex_data[COL1] | hex_data[COL2],
};
// Hex-Daten für jeden Spalte der Tastatur vom PCF8574
int col[3] = {hex_data[COL0], hex_data[COL1], hex_data[COL2]};
/*
* CONSTRUCTORS
*/
i2ckeypad::i2ckeypad(int addr)
{
pcf8574_i2c_addr = addr;
}
i2ckeypad::i2ckeypad(int addr, int r, int c)
{
pcf8574_i2c_addr = addr;
num_rows = r;
num_cols = c;
}
/*
* PUBLIC METHODS
*/
void i2ckeypad::init()
{
// Alle PCF8574 Ports auf HIGH setzen
pcf8574_write(pcf8574_i2c_addr, 0x15);
// Beginnen mit der ersten Zeile der Matrix-Tastatur
row_select = 0;
}
char i2ckeypad::get_key()
{
static int temp_key;
int tmp_data;
int r;
int key = '\0';
while( temp_key != keymap[row_select][r])
{
// Suchen Zeile LOW
pcf8574_write(pcf8574_i2c_addr, pcf8574_row_data[row_select]);
for(r=0;r<num_cols;r++) {
// Lesen PCF8574 Port-Daten
tmp_data = pcf8574_byte_read(pcf8574_i2c_addr);
// UM XOR zu erhalten und Aktuelle Daten zu vergleichen und um zu erkennen,
// wenn eine Spalte LOW ist
tmp_data ^= current_data; // current_data = Aktuelle daten
// Taste gedrückt!
if(col[r] == tmp_data) {
temp_key = keymap[row_select][r];
return '\0';
}
}
// Taste wurde gedrückt und dann freigegeben
if((key == '\0') && (temp_key != '\0'))
{
key = temp_key;
temp_key = '\0';
return key;
}
// Alle PCF8574 Ports wieder auf HIGH schalten
pcf8574_write(pcf8574_i2c_addr, 0x15);
// Nexte Zeile
row_select++; // inkrementiere row_select
if(row_select == num_rows) { // Wenn du bei der letzten Zeile angekommen bist,
row_select = 0; // dann beginnne wieder bei der ersten Zeile
}
return key;
}
}
/*
* PRIVATE METHODS
*/
void i2ckeypad::pcf8574_write(int addr, int data)
{
current_data = data;
Wire.beginTransmission(addr); //Beginnt eine Übertragung als Master an die in address angegebene
//Slave-Adresse.
Wire.write(data); //Speichert Daten in einer Warteschleife, die dann an eine Slave-
//Adresse gesendet werden. Wire.write() wird nach wire.beginTransmission
//aufgerufen.
Wire.endTransmission(); //Beendet den Übertragungsblock
}
int i2ckeypad::pcf8574_byte_read(int addr)
{
Wire.requestFrom(addr, 1); //Fordert von einem Gerät Informationen an. Adresse bezeichnet
//dabei die 7-Bit-Geräteadresse, quantity die Anzahl von Bytes,
//die erwartet werden.
return Wire.read(); //Empfängt das nächste Byte, das auf dem Bus für das Gerät vorliegt
//und gibt dieses als »Byte« zurück.
}
Vielen Dank im Voraus
Ich hoffe mir kann jemand helfen