Keypad - část přes i2c část přes piny nodeMCu

Odpovědět
Wasill
Příspěvky: 6
Registrován: 09 zář 2021, 06:24
Reputation: 0

Keypad - část přes i2c část přes piny nodeMCu

Příspěvek od Wasill » 09 zář 2021, 09:03

Zdravím všechny zkušenější, než jsem já :D

Řeším problém, mám NodeMcu (v3 LoLin) a rozšiřující desku PCF8574. Snažím se připojit keypad 5x4 (tedy 9pin). Expander má pouze 8pin, a potřebuji nějak udělat, aby ten 9. pin byl na NodeMcu (D5?). Přes knihovnu keypad.h jsem dokázal 4x4 přímo z nodemcu, přes keypad_i2c.h jsem dokázal 4x4 přes expander. Ale ani jedna knihovna nedovolí kombinaci (něco z desky něco z expanderu). Tedy přes tu i2c knihovnu to nepůjde, ta hledá vše na expanderu. Napadlo mě to udělat přes keypad.h a pojmenovat si piny expanderu(např. exp1,exp2....), a směrovat to na D5, exp1 exp2....

Kód: Vybrat vše

byte rowPins [ROWS] = {D5, exp1, exp2, exp3}; 
ale to se mi prostě nejde :-) nějaké rady jak to zkombinovat? Nebo jak je pojmenovat nebo uložit do variables?

Moc děkuji za jakékoliv popostrčení :-) W

ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

Re: Keypad - část přes i2c část přes piny nodeMCu

Příspěvek od ondraN » 09 zář 2021, 10:20

Jednoduše to udělat nejde. Jedná se o maticový scan a knihovna předpokládá, že je vše na extenderu. Takže buď si ji upravit nebo napsat vlastní, nebo použít jiný extender s knihovnou, která umí 5x4 (nejlepší možnost) :mrgreen:

Uživatelský avatar
kiRRow
Příspěvky: 1152
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Keypad - část přes i2c část přes piny nodeMCu

Příspěvek od kiRRow » 09 zář 2021, 15:40

Napsat něco vlastního není problém. Zapojil bych to tak, že pokud máš 5řádků, tak řádek 1-4 na expandér a pátý na pin MCU a sloupce na expandér. Pak už jen cyklicky zapíšeš vždy na jeden řádek HIGH a přečteš si co je na všech pinech expandéru, každý jiný stisk ti vrátí jinačí byte. Jen u posledního cyklu to musíš ošetřit výjimkou.

Wasill
Příspěvky: 6
Registrován: 09 zář 2021, 06:24
Reputation: 0

Re: Keypad - část přes i2c část přes piny nodeMCu

Příspěvek od Wasill » 09 zář 2021, 21:25

Tada,nenašel jsem smajlika s rozpačitým výrazem, škrábajícího se na hlavě a ještě idealně s komiksovou bublinou se třemi červenými otazníky :D :D
Takhle daleko teda nejsem… pochopil jsem to až po “pak už jen” :? Ten koncept chápu stejně, tak jsem to i zapojil. Jenže jak to číst? Hledal jsem po tutoriálech a všude jsou jen knihovny s hotovým řešením. A i když prohlížím ty knihovny, nechápu, jak těm pinům přistoupit. Všude jen includuj knihovnu, dej adresu i2c a funguj… Slo by prosím prosím trochu přiblížit? :roll:

Uživatelský avatar
gilhad
Příspěvky: 779
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Keypad - část přes i2c část přes piny nodeMCu

Příspěvek od gilhad » 10 zář 2021, 01:20

Vrazil jsem ten chip a "datasheet" do googlu, vypadlo na mě https://www.nxp.com/part/PCF8574T#/ a když se klikne na ten "datasheet" tak je tam popis zapojení, ukázka komunikace a použití a všechno jen přez čisté i2c (tak okolo stránky 13).

Pozor na to, ze ten obvod NENI symetrický - výstup na HIGH je max 0.3mA, zatímco výstup na LOW je 20-25 mA (a taky pokud chceš číst, tak nastavíš zápisem ten pin na VÝSTUP HIGH a pak ho čteš a dostaneš 0/1, zatímco kdybys zapsal výstup na LOW tak přečteš 0, nebo při dostatečně silném vstupním napětí pin odpálíš ). (BTW to taky znamená, že na tom expandéru jsou všechny vstupy nevyhnutelně (hardwarově) INPUT_PULLUP)

Takže nebudeš zapisovat na jeden řádek HIGH, ale LOW (a všechny ostatní piny - jak výstupní tak vstupní - zapíšeš HIGH) a pak to přečteš, a kde se ti na "vstupech" objeví LOW, tam to bylo stisknuto.

No a pak si rozebereš, co ta odpověď vlastně znamená.

Osobně mi přijde jednodušší použít MCU pin na čtení (INPUT_PULLUP) a zapisovat vyhradně na ten expandér, ale asi to není kritické.

---

Takže komunikace přez i2c - pošlu adresu, zapíšu samé jedničky (až na jednu nulu - kterou to scanuju), přečtu výsledek (projdu vstupy, kde je 0, tam to je spojené - a na základě toho vychytám stisknutá tlačítka - podle zapojení - buď v jedné řadě, nebo v jednom sloupci).
Posunu si kde budu scanovat teď, a zase to celé znova, jen ta scanovací nula bude na dalším místě.

Uživatelský avatar
kiRRow
Příspěvky: 1152
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Keypad - část přes i2c část přes piny nodeMCu

Příspěvek od kiRRow » 10 zář 2021, 15:30

Tohle je pro 4x4 - řádky jsou na expandéru 0 - 3 ... sloupce 4 - 7

Kód: Vybrat vše

char checkKeyPad() {
  byte readData; // co mi chodí z expandéru
  char returnByte = false;  // co chci aby mi funkce vracela za znak

  for(int line = 0; line <= 3; line++) { // prolistuji si 4 řádky ( ty jich pak budeš mít 5 )
  keyPad.write(line, LOW); // na požadovaný pin zapíšu LOW
  readData = keyPad.read8(); // přečtu kompletně celž expandér
  //Serial.println(readData); -- tady si můžeš vypsat co z toho leze
  
  if((readData & 0xF0) != 0xF0){ // je třeba vymaskovat první 4 bity, abych nečetl i to, kde já posílám LOW - když z žádného sloupce neleze nic LOW, tak se ta podmínka nespustí --> není nic zmáčklého
    //Serial.print("Ctu : "); -- tady si můžeš vypsat co z toho leze
    //Serial.println(readData); -- tady si můžeš vypsat co z toho leze
    switch(readData){ // tady už musíš sám rozhodnout co chceš vrátit
      case 119://1 // já třeba při stisku jedničky chci vrátit 49 což znamený v ASCII číslo 1
        returnByte = 49;
        keyPadNowInt = 1; // ale zároveň jsem kvůli něčemu potřeboval i tu jedničku -- tyhle budeš muset zakomentovat, já to tam tímhle valil rovnou do globální proměnné
      break;
      case 123://2
        returnByte = 50;
        keyPadNowInt = 2;
      break;
      case 125://3
        returnByte = 51;
        keyPadNowInt = 3;
      break;
      case 126://A
        returnByte = 65;
        //keyPadNowInt = 10;
      break;
      case 183://4
        returnByte = 52;
        keyPadNowInt = 4;
      break;
      case 187://5
        returnByte = 53;
        keyPadNowInt = 5;
      break;
      case 189://6
        returnByte = 54;
        keyPadNowInt = 6;
      break;
      case 190://B
        returnByte = 66;
        //keyPadNowInt = 11;
      break;
      case 215://7
        returnByte = 55;
        keyPadNowInt = 7;
      break;
      case 219://8
        returnByte = 56;
        keyPadNowInt = 8;
      break;
      case 221://9
        returnByte = 57;
        keyPadNowInt = 9;
      break;
      case 222://C
        returnByte = 67;
        //keyPadNowInt = 12;
      break;
      case 231://E
        returnByte = 69;
        //keyPadNowInt = 14;
      break;
      case 235://0
        returnByte = 48;
        keyPadNowInt = 0;
      break;
      case 237://F
        returnByte = 70;
        //keyPadNowInt = 15;
      break;
      case 238://D
        returnByte = 68;
        //keyPadNowInt = 13;
      break;
    }
  }
  keyPad.write(line, HIGH); // tady je zase potřeba ten pin hodit zpátky na HIGH
  }
  if(returnByte == keyPadLast){ // pokud naskenovaná klávesa je stejná jako ta poslední
    returnByte = false; // buď ji furt ještě někdo drží, nebo není nic stisknuto - tak chci vrátit false
    keyPadNowInt = false;
  } else {
    keyPadLast = returnByte; // ulož si nově stisknutou klávesu
  }

  return returnByte; // vrať výsledek
}
Tak ... a teď to musíš rozšířit o jeden cyklus navíc, kdy při 5tém oběhu nesmíš zapsat HIGH na 4tý pin expandéru, ale na pin MCU ... a taky dostaneš stejné výsledky, ale díky tomu že víš že jsi v posledním cyklu, tak umíš rozeznat co jsi stisknul

Uživatelský avatar
kiRRow
Příspěvky: 1152
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Keypad - část přes i2c část přes piny nodeMCu

Příspěvek od kiRRow » 10 zář 2021, 19:48

nějak bych tak ještě měl zmínit, že tohle je vyrvanej kus kódu jen pro ilustraci... potřebuje to knihovnu <PCF8574.h> a zavést třídu PCF8574 keyPad(KEYPAD_ADDR); // adresa toho expandéru kde máš klávesnici .... jsem tam toho měl víc

Wasill
Příspěvky: 6
Registrován: 09 zář 2021, 06:24
Reputation: 0

Re: Keypad - část přes i2c část přes piny nodeMCu

Příspěvek od Wasill » 12 zář 2021, 12:41

Vau, super, díky všem, hlavně díky za vzor! Vyzkouším snad hned zítra večer, snad bude čas a sednu nad tím. Ještě jednou díky a dám vědět výsledek :-)

Wasill
Příspěvky: 6
Registrován: 09 zář 2021, 06:24
Reputation: 0

Re: Keypad - část přes i2c část přes piny nodeMCu

Příspěvek od Wasill » 14 zář 2021, 00:57

Ahoj, takže pokrok :-) Z kódu po odkomentování Serial.println(readData) čtu returnByte. Pro začátek si vystačím s 4x4, až zprovozním, půjdu testovat dál :-) Dál jsem se zatím nedostal. Zjistil jsem, že <PCF8574.h> není jen jedna :-) Dohromady jsem zkusil 3. U první crashovala u keyPad.write, že třída nemá tohoto membera. U druhého zase keyPad.read8(). Až ta 3. vyšla (pro budoucí pokolení https://github.com/RobTillaart/PCF8574). Teď mi zbývá do loop() zpracovat ten return z checkKeyPad(), aby vypisoval smysluplně. Je jedna ráno, víc už nevymyslím, až bude funkční, přidám komplet info. Nicméně už nyní moc děkuji za příklad :-)

Uživatelský avatar
kiRRow
Příspěvky: 1152
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Keypad - část přes i2c část přes piny nodeMCu

Příspěvek od kiRRow » 14 zář 2021, 15:33

Zakomentuj první Serial.println, odkomentuj tyhle

Kód: Vybrat vše

  if((readData & 0xF0) != 0xF0){ // je třeba vymaskovat první 4 bity, abych nečetl i to, kde já posílám LOW - když z žádného sloupce neleze nic LOW, tak se ta podmínka nespustí --> není nic zmáčklého
    //Serial.print("Ctu : "); -- tady si můžeš vypsat co z toho leze
    //Serial.println(readData); -- tady si můžeš vypsat co z toho leze
to maskování způsobí, že ti to bude vypisovat jen při stiskuté klávese

Kód: Vybrat vše

  if(returnByte == keyPadLast){ // pokud naskenovaná klávesa je stejná jako ta poslední
    returnByte = false; // buď ji furt ještě někdo drží, nebo není nic stisknuto - tak chci vrátit false
    keyPadNowInt = false;
  } else {
    keyPadLast = returnByte; // ulož si nově stisknutou klávesu
  }
tohle pak dělá, že ti funkce vráti stisklou klávesu jen 1x i když jí budeš držet delší dobu
Všechny proměnné, které ti to napsalo, že neexistují by měly být globální - je to jen opravdu pro ilustraci, nečekal jsem že to budeš chtít používat

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 9 hostů