26-10-2017, 00:10
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...
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;
}
}
};