Skocz do zawartości
qro9qs

Klawiatura Numeryczna USB z Arduino Host

Pomocna odpowiedź

Posiadam aktualnie układ pracujący z klawiaturą membranową 4x4. Działa poprawnie 

Naszła mnie chęć wymiany jej na klawiaturę numeryczną USB. 
Czy da się to zrealizować w arduino po tych 4 przewodach? Ktoś ma to już za sobą bądź jest mi w stanie pomóc?

Udostępnij ten post


Link to post
Share on other sites

To zależy jakie Arduino masz. Na przykład Arduino Zero chodzi na SAMD21, które potrafi obsługiwać USB Host, i dla którego są przykłady obsługi klawiatury USB. Z UNO się nie da.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Świetnie, dziękuję. Myślę, że to pomoże. 
Czy wiesz może, czy piny cyfrowe 2-13 są w dalszym ciągu do użytku (na górze płytki są wyprowadzenia) czy są już one wykorzystywane przez ten układ?

Udostępnij ten post


Link to post
Share on other sites

W zakładce "documentation" masz podlinkowany schemat — sprawdź sobie które piny są podłączone.

Udostępnij ten post


Link to post
Share on other sites

Jeżeli nie potrzebujesz mocno urządzeń peryferyjnych atmegi, czyli real-time, liczników, SPI, może I2C, to polecam przejście na jakieś raspberry pi. Nawet wersję 1, która kosztuje teraz pewnie mniej niż schield USB do Arduino.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites
(edytowany)
#include <hidboot.h>
#include <usbhub.h>

#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>

class KbdRptParser : public KeyboardReportParser
{
    void PrintKey(uint8_t mod, uint8_t key);

  protected:
    void OnControlKeysChanged(uint8_t before, uint8_t after);
    void OnKeyDown	(uint8_t mod, uint8_t key);
    void OnKeyUp	(uint8_t mod, uint8_t key);
    void OnKeyPressed(uint8_t key);
};

void KbdRptParser::PrintKey(uint8_t m, uint8_t key)
{
  MODIFIERKEYS mod;
  *((uint8_t*)&mod) = m;
  Serial.print((mod.bmLeftCtrl   == 1) ? "C" : " ");
  Serial.print((mod.bmLeftShift  == 1) ? "S" : " ");
  Serial.print((mod.bmLeftAlt    == 1) ? "A" : " ");
  Serial.print((mod.bmLeftGUI    == 1) ? "G" : " ");

  Serial.print(" >");
  PrintHex<uint8_t>(key, 0x80);
  Serial.print("< ");

  Serial.print((mod.bmRightCtrl   == 1) ? "C" : " ");
  Serial.print((mod.bmRightShift  == 1) ? "S" : " ");
  Serial.print((mod.bmRightAlt    == 1) ? "A" : " ");
  Serial.println((mod.bmRightGUI    == 1) ? "G" : " ");
};

void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)
{
  Serial.print("DN ");
  PrintKey(mod, key);
  uint8_t c = OemToAscii(mod, key);

  if (c)
    OnKeyPressed(c);
}

void KbdRptParser::OnControlKeysChanged(uint8_t before, uint8_t after) {

  MODIFIERKEYS beforeMod;
  *((uint8_t*)&beforeMod) = before;

  MODIFIERKEYS afterMod;
  *((uint8_t*)&afterMod) = after;


}

void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)
{
  Serial.print("UP ");
  PrintKey(mod, key);
}

void KbdRptParser::OnKeyPressed(uint8_t key)
{
  Serial.print("ASCII: ");
  Serial.println((char)key);
};

USB     Usb;

HIDBoot<USB_HID_PROTOCOL_KEYBOARD>    HidKeyboard(&Usb);

KbdRptParser Prs;

void setup()
{
  Serial.begin( 115200 );
#if !defined(__MIPSEL__)
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif

  if (Usb.Init() == -1)
    Serial.println("OSC did not start.");
  HidKeyboard.SetReportParser(0, &Prs);

    pinMode(2, OUTPUT);            
}

void loop()
{
  Usb.Task();


  
  digitalWrite(2, LOW);
  
  switch(???????????){
      case '?????????': digitalWrite(2, HIGH); break;
      
  }
}


Załadowałem taki kod, odczytuje poprzez host USB z klawiatury numerycznej. Przykładowo na zdjęciu odczytane kolejno klawisze ,,Num Lock", ,,7", ,,4", ,,1", ,,0". 

Chcę odwołać się do tego za pomocą switcha, aby klikając np. przycisk ,,Num Lock" na PIN 2 podawany był stan wysoki. W jaki sposób odnieść się do tego? Co zawrzeć zamiast znaków zapytania w ostatnich liniach kodu?

83264488_482928929069119_1863013812068679680_n.jpg

Edytowano przez qro9qs

Udostępnij ten post


Link to post
Share on other sites

@qro9qs możesz np. umieścić tego switcha w funkcji OnKeyUp i wtedy wykorzystujesz zmienną 'key', a w poszczególnych case'ach wpisujesz to co masz na podglądzie w monitorze portu szeregowego 🙂

Udostępnij ten post


Link to post
Share on other sites

W ten sposób nie działa, chyba, że coś zapisałem źle?

void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)
{
  pinMode(2, OUTPUT); 
  Serial.print("UP ");
  PrintKey(mod, key);
  switch(key){
    case '53': digitalWrite(2, HIGH); break;
    
  }
}

 

Udostępnij ten post


Link to post
Share on other sites

@qro9qs wpisz 53 jako liczbę, czyli bez apostrofów 🙂

Udostępnij ten post


Link to post
Share on other sites

Również nie działa, poza tym kolejny przycisk to 5F a tutaj wyskakuje błąd jeśli niema apostrofów. 

Udostępnij ten post


Link to post
Share on other sites

Aha... to tak będziemy teraz strzelać. Proponuję 0x53 i 0x5f - wygrałem misia?

Udostępnij ten post


Link to post
Share on other sites

Niestety żaden z proponowanych pomysłów nie pracuje. 
Zapytam raz jeszcze....gdzie powinienem umieścić w głownym kodzie switcha oraz w jaki sposób zadeklarować go? Switch po keyu i case z liczbami jak np. '53' lub '5F' nie działa. 

 

Switch:
 

pinMode(2, OUTPUT);
pinMode(3, OUTPUT);

switch(????){
  case 'klawisz oznaczony jako 53': digitalWrite(2, HIGH), digitalWrite(3, LOW);break; 
  case 'klawisz oznaczony jako 5F': digitalWrite(2, LOW), digitalWrite(3, HIGH);break;
}



Główny kod:

#include <hidboot.h>
#include <usbhub.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>

class KbdRptParser : public KeyboardReportParser
{
    void PrintKey(uint8_t mod, uint8_t key);

  protected:
    void OnControlKeysChanged(uint8_t before, uint8_t after);
    void OnKeyDown	(uint8_t mod, uint8_t key);
    void OnKeyUp	(uint8_t mod, uint8_t key);
    void OnKeyPressed(uint8_t key);
};

void KbdRptParser::PrintKey(uint8_t m, uint8_t key)
{
  MODIFIERKEYS mod;
  *((uint8_t*)&mod) = m;
  Serial.print((mod.bmLeftCtrl   == 1) ? "C" : " ");
  Serial.print((mod.bmLeftShift  == 1) ? "S" : " ");
  Serial.print((mod.bmLeftAlt    == 1) ? "A" : " ");
  Serial.print((mod.bmLeftGUI    == 1) ? "G" : " ");

  Serial.print(" >");
  PrintHex<uint8_t>(key, 0x80);
  Serial.print("< ");

  Serial.print((mod.bmRightCtrl   == 1) ? "C" : " ");
  Serial.print((mod.bmRightShift  == 1) ? "S" : " ");
  Serial.print((mod.bmRightAlt    == 1) ? "A" : " ");
  Serial.println((mod.bmRightGUI    == 1) ? "G" : " ");
};

void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)
{
  Serial.print("DN ");
  PrintKey(mod, key);
  uint8_t c = OemToAscii(mod, key);

  if (c)
    OnKeyPressed(c);
}

void KbdRptParser::OnControlKeysChanged(uint8_t before, uint8_t after) {

  MODIFIERKEYS beforeMod;
  *((uint8_t*)&beforeMod) = before;

  MODIFIERKEYS afterMod;
  *((uint8_t*)&afterMod) = after;
}

void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)
{
  Serial.print("UP ");
  PrintKey(mod, key);
}

void KbdRptParser::OnKeyPressed(uint8_t key)
{
};

USB     Usb;
HIDBoot<USB_HID_PROTOCOL_KEYBOARD>    HidKeyboard(&Usb);
KbdRptParser Prs;

void setup()
{
  Serial.begin( 115200 );
#if !defined(__MIPSEL__)
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif

  if (Usb.Init() == -1)
    Serial.println("OSC did not start.");
  HidKeyboard.SetReportParser(0, &Prs);
}

void loop(){
   Usb.Task();
  }

 

Udostępnij ten post


Link to post
Share on other sites
7 godzin temu, qro9qs napisał:

Zapytam raz jeszcze....gdzie powinienem umieścić w głownym kodzie switcha oraz w jaki sposób zadeklarować go? Switch po keyu i case z liczbami jak np. '53' lub '5F' nie działa. 

@qro9qs czy testowałeś zapis zgodny z sugestią @ethanak tzn. z przedrostkiem 0x (bo to są liczby zapisane w systemie szesnastkowym)?

Udostępnij ten post


Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.


×
×
  • Utwórz nowe...