• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Zabawa z klawiaturą na przerwaniu
#1
Witam wszystkich forumowiczów.

Od kilku dni zmagam się z dość irytującym wyzwaniem. Tworzę na arduino mały projekcik, który zawiera w sobie kilka elementów (najczęściej używanych modułów) a dokładniej lcd, klawiaturę oraz moduł rf433. Na razie jestem na etapie obsługi klawiatury 4x4. Zamarzyło mi się stworzenie programu, który pozwoliłby na korzystanie z klawiatury jak w starych dobrych telefonach tzn przypisanie pod klawisze kilku znaków np przycisk 2 - znaki A,B,C,2.
Klawiatura jak i wyświetlacz są obsługiwane przez i2c. Mój problem polega na tym, iż w momencie gdy nacisnę przycisk np 2 odczekam (aż zostanie zakończona funkcja obsługi przerwania - co spowoduje przesunięcie kursora) i nacisnę inny przycisk np 3, to program się zawiesza. Gdy nacisnę ten sam przycisk, to wszystko jest ok. Tak samo, gdy zmienna czas nie zdąży zostać zwiększona do 3 w przerwaniu i nacisnę inny przycisk, to program również zadziała. Moim zdaniem sam kod wygląda ok ale może popełniłem jakiś błąd logiczny...

Kod:
#include <TimerOne.h>
#include <Keypad_I2C.h>
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>

LiquidCrystal_I2C lcd(0x3F, 8, 2);
SoftwareSerial mySerial(2, 3); //RX, TX

//const int Led3 = 11;
//byte f_led3 = 0; //flaga diody Led3

const byte ROWS = 4;
const byte COLS = 4;

const char P1[] = {' ', '/', '.', '-', '1'};
const char P2[] = {'A', 'B', 'C', '2'};
const char P3[] = {'D', 'E', 'F', '3'};
const char P4[] = {'G', 'H', 'I', '4'};
const char P5[] = {'J', 'K', 'L', '5'};
const char P6[] = {'M', 'N', 'O', '6'};
const char P7[] = {'P', 'Q', 'R', 'S', '7'};
const char P8[] = {'T', 'U', 'V', '8'};
const char P9[] = {'W', 'X', 'Y', 'Z', '9'};
const char P0[] = {' ', '/', '.', '-'};

char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};

byte rowPins[ROWS] = {0,1,2,3};
byte colPins[COLS] = {4,5,6,7};

int i2caddress = 0x20;

Keypad_I2C kpd = Keypad_I2C( makeKeymap(keys), rowPins, colPins, ROWS, COLS, i2caddress );

void setup()
{
 lcd.begin();                          //Inicjalizacja lcd
 kpd.begin();                          //Inicjalizacja klawiatury
 mySerial.begin(2400);          


 // Turn on the backlight and print a message.
 lcd.backlight();
 lcd.print("TEXT:");

 //Ustawienie przerwania
 Timer1.initialize(300000);
 Timer1.attachInterrupt(stan_klawisza);
}

volatile int aktywne_przerwanie = 0;          //Zmienna, która włącza bądź wyłącza wykonywanie zawartości funkcji obsługi przerwania
char key;
volatile int czas = 0;                        //Zmienna, która jeżeli osiągnie określoną liczbę, przesunie kursor w prawą stronę
volatile int pozycja = 0;
int maxlicznik = 0;
volatile int licznik = 0;
char aktualny_klawisz = 'G';
char poprzedni_klawisz = 'H';
int pierwsze_przejscie_petli = 1;

char tekst[8];
int del = 0;

void loop()
{
 key = kpd.getKey();

 if(key)
 {
   aktualny_klawisz = key;
   aktywne_przerwanie = 1;
   czas = 0;
   
   if(key == '1' || key == '7' || key == '9') maxlicznik = 5; else maxlicznik = 4;     //maxlicznik jest równy 5 dla przycisków, które mają 'pod sobą' 5 znaków zaś przyjmuje wartość 4 dla przycisków, które mają pod sobą 4 znaki

   if(pierwsze_przejscie_petli == 1)         //na samym początku przyjmujemy jakoby przecisk został wciśnięty po raz drugi (zmienne poprzedni_klawisz i aktualny klawisz muszą być sobie równe)
   {
     poprzedni_klawisz = aktualny_klawisz;
     pierwsze_przejscie_petli = 0;
   }

   /*if(key == '*')                    //przycisk '*' służy do usuwania ostatniego znaku i cofnięcia kursora
   {
     aktywne_przerwanie = 0;
     czas = 0;
     if(pozycja > 0) pozycja--;
     tekst[pozycja] = ' ';
     del = 1;
     lcd.setCursor(0,1);
     lcd.printstr(tekst);
   }*/
   if(aktualny_klawisz != poprzedni_klawisz)
   {
     licznik = 0;
     if(pozycja < 7) pozycja++;
     
     if(key == '1') tekst[pozycja] = P1[licznik];
     else if(key == '2') tekst[pozycja] = P2[licznik];
     else if(key == '3') tekst[pozycja] = P3[licznik];
     else if(key == '4') tekst[pozycja] = P4[licznik];
     else if(key == '5') tekst[pozycja] = P5[licznik];
     else if(key == '6') tekst[pozycja] = P6[licznik];
     else if(key == '7') tekst[pozycja] = P7[licznik];
     else if(key == '8') tekst[pozycja] = P8[licznik];
     else if(key == '9') tekst[pozycja] = P9[licznik];
     lcd.setCursor(0,1);
     lcd.printstr(tekst);
     del = 0;
   }
   else if(aktualny_klawisz == poprzedni_klawisz)
   {
     if(licznik == maxlicznik) licznik = 0;
     if(key == '1') tekst[pozycja] = P1[licznik];
     else if(key == '2') tekst[pozycja] = P2[licznik];
     else if(key == '3') tekst[pozycja] = P3[licznik];
     else if(key == '4') tekst[pozycja] = P4[licznik];
     else if(key == '5') tekst[pozycja] = P5[licznik];
     else if(key == '6') tekst[pozycja] = P6[licznik];
     else if(key == '7') tekst[pozycja] = P7[licznik];
     else if(key == '8') tekst[pozycja] = P8[licznik];
     else if(key == '9') tekst[pozycja] = P9[licznik];
     licznik++;
     lcd.setCursor(0,1);
     lcd.printstr(tekst);
   }
   poprzedni_klawisz = aktualny_klawisz;
 }
}
 
//OBSŁUGA PRZERWANIA
void stan_klawisza()
{
 if(aktywne_przerwanie == 1)
 {
   czas++;
   if(czas >= 3)
   {
     if(pozycja < 7) pozycja++;
     licznik = 0;
     czas = 0;
     aktywne_przerwanie = 0;
   }
 }
};
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości