• 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
Wyświetlacz TFT 3.5, expander i Klawiatura
#1
Heart 
Witam wszystkich maniaków Arduino. Już na samym wstępie moi drodzy chciałbym powiedzieć wam, w sumie o swoim napotkanym problemie. Otóż buduje własny projekt nawadniania do ogrodu na bazie ekranu tft 3.5 taki jak ten ,,shield" do arduino uno 

   

Przez to że używam tej nakładki niestety brakło mi pinów na to żeby móc swobodnie podpiąć np klawiaturę (nie muszę jej podpinać bo ekran jest dotykowy, ale wiadomo na zewnątrz czasem pada deszcz i zadecydowałem że zostane przy klawiaturze ). Aby podpiąć klawiaturę potrzebowałem użyć expandera.

Wszystko podłączyłem i testowałem. w momencie gdy uzywam tego programu :

Cytat:#include <Wire.h>
#include <Keypad_I2C.h>

#define Keypad_I2CADDR 0x38  // connect pin A0 of 2nd PCF8574 to 5V for address 0x21
// A0 , A1, A2 to ground
const byte ROWS = 4; // four rows
const byte COLS = 3; // four columns

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

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

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



void setup() {
  Wire.begin();
  kpd.begin( makeKeymap(keys) );
  Serial.begin(9600);
}

void loop() {
  char key = kpd.getKey();
  if (key) {
    Serial.println(key);
  }
}

wszystko działa ładnie pięknie i cudownie. Kłopoty zaczynają się w momencie jak próbuję połączyć funkcjonalność klawiatury oraz ekranu w jednym kodzie. Oto on


Cytat:#include <Adafruit_TFTLCD.h>
#include <Adafruit_GFX.h>   
#include <TouchScreen.h>
#include <Keypad_I2C.h>
#include <Wire.h>



#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4

#define Keypad_I2CADDR 0x38

#define TS_MINX 122
#define TS_MINY 111
#define TS_MAXX 942
#define TS_MAXY 890

#define YP A3
#define XM A2
#define YM 9
#define XP 8

#define BLACK  0x0000
#define BLUE    0x001F
#define RED    0xF800
#define GREEN  0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE  0xFFFF
#define ORANGE  0xFCA0
#define PURPLE  0x780F
#define BROWN 0x8200



Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 364);


char aktualnaStrona = '0';

/* 0 - Menu glowne
* 1 - Wilgotnosci
* 2 - Menu Ustawien
* 3 - Ustawienia Czasu
* 4 - Ustawienia Daty
* 5 - Ustawienia Podlewania
* 6 - PN
* 7 - WT
* 8 - SR
* 9 - CZW
* 10 - PT
* 11 - SB
* 12 - ND
*/

const byte ROWS = 4; // four rows
const byte COLS = 3; // four columns

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

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

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

int DT[28] = {15,0,16,0,  15,0,16,0,  15,0,16,0,  15,0,16,0,  15,0,16,0,  15,0,16,0,  15,0,16,0};

void setup () {
  tft.reset();
  uint16_t identifier = tft.readID();
  Wire.begin();
  kpd.begin( makeKeymap(keys) );
  tft.begin(0x9341);
 

 
 
  Menu_glowne();
  aktualnaStrona == '0';

}

void loop ()
{
  if (aktualnaStrona == '0')
  {
  TSPoint p = ts.getPoint();

    if (p.z > ts.pressureThreshhold)
    {
   
  p.x = map(p.x, TS_MAXX, TS_MINX, 0, 320);
  p.y = map(p.y, TS_MAXY, TS_MINY, 0, 480);
     
      if(p.x>240 && p.x<320 && p.y>320 && p.y<400 )
      {
        pinMode(XM, OUTPUT);
        pinMode(YP, OUTPUT);
        Wilgotnosc();
        aktualnaStrona = '1';
      }


      if(p.x>240 && p.x<320 && p.y>400 && p.y<480 )
      {
        pinMode(XM, OUTPUT);
        pinMode(YP, OUTPUT);
        Ustawienia();
        aktualnaStrona = '2';
      }

     
    }
  }


  if (aktualnaStrona == '1')
  {
    TSPoint p = ts.getPoint();

    if (p.z > ts.pressureThreshhold)
    {
   
  p.x = map(p.x, TS_MAXX, TS_MINX, 0, 320);
  p.y = map(p.y, TS_MAXY, TS_MINY, 0, 480);
     
      if(p.x>240 && p.x<320 && p.y>0 && p.y<80 )
      {
        pinMode(XM, OUTPUT);
        pinMode(YP, OUTPUT);
        Menu_glowne();
        aktualnaStrona = '0';
      }
    }
  }


if (aktualnaStrona == '2')
  {
    TSPoint p = ts.getPoint();

    if (p.z > ts.pressureThreshhold)
    {
   
  p.x = map(p.x, TS_MAXX, TS_MINX, 0, 320);
  p.y = map(p.y, TS_MAXY, TS_MINY, 0, 480);
     
      if(p.x>240 && p.x<320 && p.y>0 && p.y<80 )
      {
        pinMode(XM, OUTPUT);
        pinMode(YP, OUTPUT);
        Menu_glowne();
        aktualnaStrona = '0';
      }

      if(p.x>200 && p.x<240 && p.y>30 && p.y<450 )
      {
        pinMode(XM, OUTPUT);
        pinMode(YP, OUTPUT);
        Ustawienia_czasu();
        aktualnaStrona = '3';
      }

      if(p.x>140 && p.x<180 && p.y>30 && p.y<450 )
      {
        pinMode(XM, OUTPUT);
        pinMode(YP, OUTPUT);
        Ustawienia_daty();
        aktualnaStrona = '4';
      }

      if(p.x>80 && p.x<120 && p.y>30 && p.y<450 )
      {
        pinMode(XM, OUTPUT);
        pinMode(YP, OUTPUT);
        Ustawienia_podlewania();
        aktualnaStrona = '5';
      }
    }
  }



  if (aktualnaStrona == '3')
  {
    TSPoint p = ts.getPoint();

    if (p.z > ts.pressureThreshhold)
    {
   
  p.x = map(p.x, TS_MAXX, TS_MINX, 0, 320);
  p.y = map(p.y, TS_MAXY, TS_MINY, 0, 480);
     
      if(p.x>240 && p.x<320 && p.y>0 && p.y<80 )
      {
        pinMode(XM, OUTPUT);
        pinMode(YP, OUTPUT);
        Ustawienia();
        aktualnaStrona = '2';
      }
    }
  }

  if (aktualnaStrona == '4')
  {
    TSPoint p = ts.getPoint();

    if (p.z > ts.pressureThreshhold)
    {
   
  p.x = map(p.x, TS_MAXX, TS_MINX, 0, 320);
  p.y = map(p.y, TS_MAXY, TS_MINY, 0, 480);
     
      if(p.x>240 && p.x<320 && p.y>0 && p.y<80 )
      {
        pinMode(XM, OUTPUT);
        pinMode(YP, OUTPUT);
        Ustawienia();
        aktualnaStrona = '2';
      }
    }
  }

if (aktualnaStrona == '5')
  {
    TSPoint p = ts.getPoint();

    if (p.z > ts.pressureThreshhold)
    {
   
  p.x = map(p.x, TS_MAXX, TS_MINX, 0, 320);
  p.y = map(p.y, TS_MAXY, TS_MINY, 0, 480);
     
      if(p.x>240 && p.x<320 && p.y>0 && p.y<80 )
      {
        pinMode(XM, OUTPUT);
        pinMode(YP, OUTPUT);
        Ustawienia();
        aktualnaStrona = '2';
      }

      if(p.x>220 && p.x<300 && p.y>380 && p.y<460 )
      {
        pinMode(XM, OUTPUT);
        pinMode(YP, OUTPUT);
        Ustaw_podlewanie();
        aktualnaStrona = '6';
      }
    }
  }

  if (aktualnaStrona == '6')
  {
   

Serial.begin(9600);
char key = kpd.getKey();

switch (key) {
  case '1':
  Serial.println("1");
  break;
  case '2':
  Serial.println("2");
  break;
  case '3':
  Serial.println("3");
  break;
  case '4':
  Serial.println("4");
  break;
  case '5':
  Serial.println("5");
  break;
  case '6':
  Serial.println("6");
  break;
  case '7':
  Serial.println("7");
  break;
  case '8':
  Serial.println("8");
  break;
  case '9':
  Ustawienia_podlewania();
  aktualnaStrona = '5';
 
 
  break;
}

}

}




void Menu_glowne () {
 

  tft.setRotation(1);
  tft.fillScreen(WHITE);  //tlo
 
  tft.drawRoundRect(0,0,80,80,10, BLACK);  //Ustawienia
  tft.fillRoundRect(1,1, 78,78,10,RED);
 
  tft.drawRoundRect(80,0,80,80,10, BLACK); //Wilgotnosc
  tft.fillRoundRect(81,1, 78,78,10,RED);
 
  tft.fillRect(320,0,160,60,BLACK);    //Bloczek na czas
  tft.drawRect(325,5,150,50,WHITE);

  tft.fillRect(0,160,68,160,RED);      //Dni tygodnia po kolei
  tft.fillRect(68,160,68,160,ORANGE);
  tft.fillRect(136,160,68,160,YELLOW);
  tft.fillRect(204,160,68,160,GREEN);
  tft.fillRect(272,160,68,160,CYAN);
  tft.fillRect(336,160,68,160,BLUE);
  tft.fillRect(404,160,76,160,PURPLE);
 

  tft.setTextColor(BLACK);      //Czcionka 1
  tft.setTextSize(1);
  tft.setCursor(10,85);
  tft.print("USTAWIENIA");
  tft.setCursor(90,85);
  tft.print("WILGOTNOSC");

  tft.setTextSize(2);          //Czcionka 2
 
  tft.setTextSize(3);          //Czcionka 3
  tft.setCursor(15,170);
  tft.print("Pn");
  tft.setCursor(83,170);
  tft.print("Wt");
  tft.setCursor(151,170);
  tft.print("Sr");
  tft.setCursor(215,170);
  tft.print("Czw");
  tft.setCursor(287,170);
  tft.print("Pt");
  tft.setCursor(355,170);
  tft.print("Sb");
  tft.setCursor(423,170);
  tft.print("Nd");
  tft.setCursor(150,110);
  tft.print("Menu Glowne");

  tft.setCursor(0,210);      //PN
  tft.print(DT[0]);
  tft.setCursor(35,210);
  tft.print(DT[1]);
  tft.setCursor(0,250);
  tft.print(DT[2]);
  tft.setCursor(35,250);
  tft.print(DT[3]);

  tft.setCursor(68,210);      //WT
  tft.print(DT[4]);
  tft.setCursor(102,210);
  tft.print(DT[5]);
  tft.setCursor(68,250);
  tft.print(DT[6]);
  tft.setCursor(102,250);
  tft.print(DT[7]);

  tft.setCursor(136,210);      //SR
  tft.print(DT[8]);
  tft.setCursor(170,210);
  tft.print(DT[9]);
  tft.setCursor(136,250);
  tft.print(DT[10]);
  tft.setCursor(170,250);
  tft.print(DT[11]);

  tft.setCursor(204,210);      //CZW
  tft.print(DT[12]);
  tft.setCursor(238,210);
  tft.print(DT[13]);
  tft.setCursor(204,250);
  tft.print(DT[14]);
  tft.setCursor(238,250);
  tft.print(DT[15]);

  tft.setCursor(272,210);        //PT
  tft.print(DT[16]);
  tft.setCursor(306,210);
  tft.print(DT[17]);
  tft.setCursor(272,250);
  tft.print(DT[18]);
  tft.setCursor(306,250);
  tft.print(DT[19]);

  tft.setCursor(340,210);      //SB
  tft.print(DT[20]);
  tft.setCursor(374,210);
  tft.print(DT[21]);
  tft.setCursor(340,250);
  tft.print(DT[22]);
  tft.setCursor(374,250);
  tft.print(DT[23]);

  tft.setCursor(408,210);    //ND
  tft.print(DT[24]);
  tft.setCursor(442,210);
  tft.print(DT[25]);
  tft.setCursor(408,250);
  tft.print(DT[26]);
  tft.setCursor(442,250);
  tft.print(DT[27]);
 
  tft.setTextSize(4);      // Czcionka 4
  tft.setTextColor(WHITE);
  tft.setCursor(30,26);
  tft.print("*");
  tft.setCursor(110,26);
  tft.print("C");

}


void Wilgotnosc ()
{
  tft.fillScreen(WHITE);
  tft.drawRoundRect(50,90,380,180,5, BLACK);  //Ogrod
  tft.fillRoundRect(51,91,378,178,5,BROWN);
 
  tft.fillRect(50,165,20,30,BLACK);  //Drzwi do folii

  tft.setTextColor(BLACK);
  tft.setTextSize(3);
  tft.setCursor(150,20);
  tft.print("WILGOTNOSC");

  Back();
}

void Ustawienia ()
{
  tft.fillScreen(WHITE);
  Back();
 
  tft.drawRoundRect(30,80,420,40,10, BLACK);  //Ustawienia
  tft.fillRoundRect(31,81,418,38,10, RED);

  tft.drawRoundRect(30,140,420,40,10, BLACK);  //Ustawienia
  tft.fillRoundRect(31,141,418,38,10, RED);

  tft.drawRoundRect(30,200,420,40,10, BLACK);  //Ustawienia
  tft.fillRoundRect(31,201,418,38,10, RED);

  tft.setTextColor(WHITE);
  tft.setTextSize(3);          //Czcionka 3
  tft.setCursor(100,88);
  tft.print("USTAWIENIA CZASU");
  tft.setCursor(100,148);
  tft.print("USTAWIENIA DATY");
  tft.setCursor(55,208);
  tft.print("USTAWIENIA PODLEWANIA");
  tft.setCursor(150,30);
  tft.setTextColor(BLACK);
  tft.print("USTAWIENIA");
}

void Ustawienia_czasu ()
{
  tft.fillScreen(WHITE);
  tft.setCursor(150,30);
  tft.setTextColor(BLACK);
  tft.print("PODAJ CZAS");
  Back();
  Accept();
}

void Ustawienia_daty ()
{
  tft.fillScreen(WHITE);
  tft.setCursor(130,30);
  tft.setTextColor(BLACK);
  tft.print("PODAJ DATE");
  Back();
  Accept();
}

void Ustawienia_podlewania ()
{
  tft.fillScreen(WHITE);
  Back();
  tft.setTextSize(3);
  tft.setTextColor(BLACK);
 
  tft.drawRoundRect(20,20,80,80,10, BLACK);  //Pn
  tft.fillRoundRect(21,21,78,78,10, RED);
  tft.setCursor(45,45);
  tft.print("Pn");

  tft.drawRoundRect(120,20,80,80,10, BLACK);  //Wt
  tft.fillRoundRect(121,21,78,78,10, ORANGE);
  tft.setCursor(145,45);
  tft.print("Wt");

  tft.drawRoundRect(220,20,80,80,10, BLACK);  //Sr
  tft.fillRoundRect(221,21,78,78,10, YELLOW);
  tft.setCursor(245,45);
  tft.print("Sr");

 
  tft.drawRoundRect(320,20,80,80,10, BLACK);  //Czw
  tft.fillRoundRect(321,21,78,78,10, GREEN);
  tft.setCursor(335,45);
  tft.print("Czw");

  tft.drawRoundRect(20,120,80,80,10, BLACK);  //Pt
  tft.fillRoundRect(21,121,78,78,10, CYAN);
  tft.setCursor(45,145);
  tft.print("Pt");

  tft.drawRoundRect(120,120,80,80,10, BLACK);  //Sb
  tft.fillRoundRect(121,121,78,78,10, BLUE);
  tft.setCursor(145,145);
  tft.print("Sb");

  tft.drawRoundRect(220,120,80,80,10, BLACK);  //Nd
  tft.fillRoundRect(221,121,78,78,10, PURPLE);
  tft.setCursor(245,145);
  tft.print("Nd");

  tft.drawRoundRect(320,120,80,80,10, BLACK);  //All
  tft.fillRoundRect(321,121,78,78,10, WHITE); 
  tft.setCursor(335,145);
  tft.print("All");

  tft.drawRoundRect(20,220,210,80,10, BLACK);  //On
  tft.fillRoundRect(21,221,208,78,10, GREEN); 
  tft.setCursor(110,245);
  tft.print("ON");

  tft.drawRoundRect(250,220,210,80,10, BLACK);  //Off
  tft.fillRoundRect(251,221,208,78,10, RED); 
  tft.setCursor(330,245);
  tft.print("OFF");
}

void Back ()        //Bloczek powrot
{         
  tft.drawRect(420,0,60,60,BLACK);   
  tft.fillRect(421,1,58,58,RED);
  tft.setTextColor(BLACK);     
  tft.setTextSize(1);
  tft.setCursor(430,65);
  tft.print("POWROT");
  tft.setTextColor(WHITE);
  tft.setTextSize(4);
  tft.setCursor(443,17);
  tft.print("B");
}

void Accept ()
{
  tft.drawRect(420,260,60,60,BLACK);   
  tft.fillRect(421,261,58,58,RED);
  tft.setTextColor(BLACK); 
  tft.setTextSize(1);
  tft.setCursor(427,250);
  tft.print("AKCEPTUJ");
  tft.setTextColor(WHITE);
  tft.setTextSize(4);
  tft.setCursor(440,274);
  tft.print("A");
}

void Ustaw_podlewanie ()
{
  tft.fillScreen(WHITE);
  tft.setCursor(20,30);
  tft.setTextColor(BLACK);
  tft.setTextSize(3);
  tft.print("PODAJ CZAS PODLEWANIA");
  Back();
  Accept();
  tft.setTextSize(3);
  tft.setTextColor(BLACK);
  tft.setCursor(10,150);
  tft.print("15:15 - 15:30");
  tft.setCursor(240,150);
  tft.print("16:15 - 16:30");
}

Problem pojawia się konkretnie w miejscu menu if == 6. W poprzednim ifie == 5 po przyciśnięciu przycisku na ekranie uruchamia się funkcja Ustaw_podlewanie(); rysująca moje menu a po wejściu w ifa==6 w miejscu char key = kpd.getKey(); program świruje, ekran robi się biały , a na porcie szeregowym podczas klikania w klawiature pojawiają się odwrócone znaki zapytania i za którymś kliknięciem wyswietli się np 5 lub inna cyferka którą klikam. Proszę bardzo o jakieś rady i wskazówki. Jedyne co mi do głowy przychodzi to, że może ekran też komunikuje się poprzez IC2 i nie mogą działać w tym samym czasie?

Poniżej załączam schemat
   
 
Odpowiedź
#2
Serial.begin() powoduje zajęcie określonej pamięci i jej brak to pierwsze co przyszło mi do głowy. Nie widzę powodu, by inicjować go w menu, zrób to na początku raz. A jak ewentualnie potrzebujesz go na chwilę to jest też opcja by go wyłączyć, a jak to co napisałeś tworzy obiekt zajmujący pamięć, potem znowu i znowu? Tego nie sprawdzałem, bo nigdy mi do głowy nie wpadło, by to robić gdzieś poza setup, ale kiedyś zmieniałem prędkość i użyłem Serial.end() i dopiero potem nowy begin (no OK, ten jeden raz mi wpadło).
 
Odpowiedź
#3
(28-05-2020, 15:09)kaczakat napisał(a): Serial.begin() powoduje zajęcie określonej pamięci i jej brak to pierwsze co przyszło mi do głowy. Nie widzę powodu, by inicjować go w menu, zrób to na początku raz. A jak ewentualnie potrzebujesz go na chwilę to jest też opcja by go wyłączyć, a jak to co napisałeś tworzy obiekt zajmujący pamięć, potem znowu i znowu? Tego nie sprawdzałem, bo nigdy mi do głowy nie wpadło, by to robić gdzieś poza setup, ale kiedyś zmieniałem prędkość i użyłem Serial.end() i dopiero potem nowy begin (no OK, ten jeden raz mi wpadło).

Dziękuje za odpowiedź. Mam nieco opóźnioną reakcję, ale obowiązki w ostatnim czasie mnie trochę przytłoczyły. Masz rację niepotrzebnie inicjowałem go w loopie. Teraz kod działa poprawnie i klawiatura dobrze wyświetla wciskane przyciski w porcie szeregowym. 

Niestety ekran nadal robi się biały a wszystkie narysowane do tej pory elementy menu znikają tak jakby klawiatura i ekran wzajemnie się blokowały.

Tak jakby getKey blokowało możliwość wyświeltania na ekranie.
 
Odpowiedź
#4
Niestety jakoś bardzo z tym kodem Ci nie pomogę, pewnie nikt, bo jest bardzo rozbudowany i przy takim stopniu skomplikowania tego nie ogarnę.
Jeśli jednak pytasz o dodatkowe informacje to na pewno warto zamieścić kod aktualny. Zapoznaj się z funkcją getkey czy aby nie jest blokująca, bo są takie że jak ją wywołasz to musi być jakaś reakcja, może po jej wywołaniu powinien być wciśnięty przycisk.
Wg mnie to nie powinno tak wyglądać, podobnie jak z serialem. Nie powinno się wchodzić do jakiegoś pola menu i tam trzymać programu. Część programu odpowiedzialna za menu powinna pamiętać gdzie jest, jaki jest aktualny wybór. W pętli głównej niezależnie od tego co jest na ekranie powinny dalej być obsługiwane wszystkie elementy układu, zliczanie czasu, odczyt wejść, sprawdzanie czy został naciśnięty przycisk, pomiar temperatury, itp. A tylko ta funkcja, która obsługuje menu powinna sobie sprawdzać czy jeśli był wciśnięty przycisk, to jaki, w jakim miejscu menu jest i jaką akcję w związku z tym powinna zostać wykonana. Czyli do każdego punktu menu powinna być przypisana funkcja, która zostanie wywołana z tym przyciskiem jako argumentem i przynajmniej zmieni pozycję menu lub wartość zmiennej w tym elemencie menu.
Trzeba też w miarę dokładnie widzieć ile czasu zajmuje narysowanie jednego ekranu, tak by nie obciążało to zbytnio całości programu. Tu, przy podlewaniu akcje są bardzo powolne i jakby to było powiedzmy 20ms to rysowałbym go raz na 200ms, chyba że nic się nie zmieniło na ekranie. Ale 20ms to bardziej tego 2x16 tekstowy.
To co Ty wybierasz w menu, a czy to jest rysowane to też powinno być luźniej powiązane. Menu ma żyć w pamięci RAM, a że jest wyświetlane na serial, na LCD 2x16 czy na TFT to już wybór tylko w funkcji wyświetlania.
 
Odpowiedź
#5
A mnie trochę dziwi że wykorzystuje I2c w "Keypad_I2C.h" jak piny zajęte przez LCD "#define LCD_RESET A4" i tu podejrzewam będzie błąd..
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#6
(08-06-2020, 01:11)kaczakat napisał(a): Niestety jakoś bardzo z tym kodem Ci nie pomogę, pewnie nikt, bo jest bardzo rozbudowany i przy takim stopniu skomplikowania tego nie ogarnę.
Jeśli jednak pytasz o dodatkowe informacje to na pewno warto zamieścić kod aktualny. Zapoznaj się z funkcją getkey czy aby nie jest blokująca, bo są takie że jak ją wywołasz to musi być jakaś reakcja, może po jej wywołaniu powinien być wciśnięty przycisk.
Wg mnie to nie powinno tak wyglądać, podobnie jak z serialem. Nie powinno się wchodzić do jakiegoś pola menu i tam trzymać programu. Część programu odpowiedzialna za menu powinna pamiętać gdzie jest, jaki jest aktualny wybór. W pętli głównej niezależnie od tego co jest na ekranie powinny dalej być obsługiwane wszystkie elementy układu, zliczanie czasu, odczyt wejść, sprawdzanie czy został naciśnięty przycisk, pomiar temperatury, itp. A tylko ta funkcja, która obsługuje menu powinna sobie sprawdzać czy jeśli był wciśnięty przycisk, to jaki, w jakim miejscu menu jest i jaką akcję w związku z tym powinna zostać wykonana. Czyli do każdego punktu menu powinna być przypisana funkcja, która zostanie wywołana z tym przyciskiem jako argumentem i przynajmniej zmieni pozycję menu lub wartość zmiennej w tym elemencie menu.
Trzeba też w miarę dokładnie widzieć ile czasu zajmuje narysowanie jednego ekranu, tak by nie obciążało to zbytnio całości programu. Tu, przy podlewaniu akcje są bardzo powolne i jakby to było powiedzmy 20ms to rysowałbym go raz na 200ms, chyba że nic się nie zmieniło na ekranie. Ale 20ms to bardziej tego 2x16 tekstowy.
To co Ty wybierasz w menu, a czy to jest rysowane to też powinno być luźniej powiązane. Menu ma żyć w pamięci RAM, a że jest wyświetlane na serial, na LCD 2x16 czy na TFT to już wybór tylko w funkcji wyświetlania.

Dziękuję bardzo za zaangażowanie

Co do kodu to rozumiem, w wolnej chwili wyrzucę z niego wszystko co jest zbędne. Opisze go tak, żeby był zrozumiały przy zachowaniu niezbędnego minimum. Doczytam nieco więcej o getkey, ale powiedz mi proszę w jaki sposób zmienić prędkość odświeżania?

Co do mojego serial () to jest on chwilowo i służy tylko i wyłącznie jako debugger bo nie wiem czy istnieje jakiś leszy sposób na sprawdzanie programu w arduino IDE. 

Co do menu to właściwie co masz na myśli? Tak naprawdę to dodałem tam tylko i wyłącznie ify, bo taki najprostszy pomysł przyszedł mi do głowy, żeby pogrupować to co ma się wyświetlać w zależności co kliknie użytkownik.

W pętli głównej niezależnie od tego co jest na ekranie powinny dalej być obsługiwane wszystkie elementy układu, zliczanie czasu, odczyt wejść,

To rozumiem, poza menu dodam funkcję obsługi czasu bo mam też do zamontowania układ RTC

A tylko ta funkcja, która obsługuje menu powinna sobie sprawdzać czy jeśli był wciśnięty przycisk, to jaki, w jakim miejscu menu jest i jaką akcję w związku z tym powinna zostać wykonana.


Szczerze powiedziawszy to myślałem, że właśnie w ten sposób postępuje, mamy ify i w zależności co sobie kliknę na ekranie to wywołuje akcję typu wchodze w menu ustawień i moge wybrać np ustawienie czasu.

Za jakieś głupie pytania z góry przepraszam, ale jest to mój większy projekt i chcę dowiedzieć się jak najwięcej.
 
Odpowiedź
#7
(08-06-2020, 05:54)Jarewa0606 napisał(a): A mnie trochę dziwi że wykorzystuje I2c w "Keypad_I2C.h" jak piny zajęte przez LCD "#define LCD_RESET A4" i tu podejrzewam będzie błąd..

Jarewa, właśnie nasuwa mi się pytanie, bo starsze arduino UNO ma piny scl sda na A4 i A5, z tych pinów korzysta ekran TFT LCD, ale ja mam arduino UNO nieco nowsze i ma już osobne wyprowadzenie SCL i SDA na własne piny, widać to na moim załączonym schemacie w 1 poście. Sprawdzę to i zobaczę czy da sie to jakoś połączyć, ale myślałem ,że na a4 i a5 już nie ma scl sda skoro jest osobne wyprowadzenie. Coraz bardziej przekonuję się, że chyba będę musiał stworzyć własny układ zamiast bazować na ardunio. 

Załączam ponownie schemat.
   
 
Odpowiedź
#8
Każde ardunio Atmega384p SDA , SCL to A4,A5 inaczej być nie morze taka jest budowa wewnętrzna mikro kontrolera..... Po prostu w twojej płytce piny są zdublowane a jest to samo masz podwójne A4,A5....
Masz konflikt sprzętowy, I I2C resetuje ci dane SPI... Jedyne wyjście to przerobić LCD zmienić fyzycznie ten pin na inny nie używany i odpowiednio w programie przypisać zwolnić A4 w LCD.
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#9
(10-06-2020, 19:57)Jarewa0606 napisał(a): Każde ardunio Atmega384p SDA , SCL  to A4,A5 inaczej być nie morze taka jest budowa wewnętrzna mikro kontrolera..... Po prostu w twojej płytce piny są zdublowane a jest to samo masz podwójne A4,A5....
Masz konflikt sprzętowy,  I I2C resetuje ci dane SPI...  Jedyne wyjście to przerobić LCD zmienić fyzycznie ten pin na inny nie używany i odpowiednio w programie przypisać zwolnić A4 w LCD.


A co w przypadku gdy arduino również będzie korzystać z komunikacji I2C, w sumie to tez średnio to wygląda bo mi sie piny skończyły i musiałem użyć expandera. Czy jest ewentualnie możliwość podpięcia tej klawiatury przez expander żeby działała tak jakby była podłączona normalnie? Chociaż expander też komunikuje się przez i2c  Confused
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości