fbpx
ArduinoNovidade

Como utilizar o USB Host Shield com o Arduino Leonardo

O USB Host Shield é uma placa para Arduino que expande suas capacidades, permitindo a conexão e comunicação direta com outros dispositivos, como teclados, mouses, controles de videogame, entre outros. Baseado no chip controlador MAX3421E, o USB Host Shield se comunica via SPI (Serial Peripheral Interface), permitindo que o arduino envie e receba comandos e dados para e de outros dispositivos USB.

Imagem ilustrativa de um módulo Host Shield.
Figura 1 – Módulo USB Host Shield.

A utilização do USB Host Shield oferece várias vantagens, incluindo expansão de funcionalidades, flexibilidade, controle centralizado, facilidade de integração e aplicações em uma ampla variedade de projetos eletrônicos.

A versatilidade do USB Host Shield permite que o Arduino seja usado em uma variedade de aplicações diferentes. Você pode facilmente adaptar o Arduino para atender às necessidades específicas do seu projeto, conectando os dispositivos USB necessários. O Arduino com a USB Host Shield pode atuar como um hub centralizado de controle para dispositivos externos. Isso facilita a integração e o controle de vários componentes em um sistema único.

Devido à sua capacidade de estabelecer comunicação com outros dispositivos USB, o USB Host Shield é especialmente útil em projetos voltados para automação residencial, robótica e sistemas embarcados. Com ele, o Arduino pode controlar e se comunicar com uma variedade de dispositivos para criar sistemas inteligentes e autônomos.

Neste tutorial, o USB Host Shield será utilizado em conjunto com o Arduino Leonardo para demonstrar o seu funcionamento. Especificamente, vamos captar as coordenadas X e Y do movimento de um mouse e realizar a leitura das teclas de um teclado. Os resultados dessa operação serão visualizados no monitor serial do Arduino IDE.

MATERIAIS NECESSÁRIOS

1 x Placa Leonardo R3 compatível com Arduino
1 x Shield USB Host ADK 2.0
1 x Cabo Micro USB

ESQUEMÁTICO DE LIGAÇÃO

O USB Host Shield deve ser encaixado no Arduino Leonardo. Para esse tutorial, utilizamos um mouse e um teclado sem fio. O receptor sem fio do mouse e teclado foi conectado à porta USB do USB Host Shield.

OBSERVAÇÃO: É recomendado utilizar uma alimentação externa (entre 7V e 12V) no USB Host Shield, por meio da porta Vin, pois a saída USB do computador pode não fornecer corrente suficiente para suportar este Shield. Isso pode resultar em falhas de funcionamento ou até mesmo a não operação do dispositivo.

ELABORANDO O CÓDIGO

Após conectar o USB Host Shield ao Arduino Leonardo, vamos à programação. Neste projeto, utilizaremos estes componentes para mostrar como é simples coletar os dados de periféricos utilizando o USB Host Shield com o Arduino Leonardo

Para facilitar a comunicação entre o Arduino e dispositivos USB usando o USB Host Shield, vamos utilizar a biblioteca USB Host Shield library 2.0. Para instalá-la, abra o Gerenciador de Bibliotecas através do caminho: Ferramentas> Gerenciar Bibliotecas… ou por meio do atalho Ctrl+Shift+I. Em seguida, busque por USB Hostshield library 2.0 e clique em instalar, conforme a Figura 2.

Imagem da tela da ide do arduino mostrando a Instalação da biblioteca USB Hostshield library 2.0 através do Gerenciador de Bibliotecas.
Figura 2 – Instalação da biblioteca USB Hostshield library 2.0 através do Gerenciador de Bibliotecas.

Logo após, podemos prosseguir com a programação. Neste projeto, utilizaremos um código exemplo da biblioteca. Para isso, acesse o caminho: Arquivo> Exemplos > USB Host Shield Library 2.0 > HID > USBHIDBootKbdAndMouse, conforme a Figura 3.

imagem do caminho para o exemplo USBHIDBootKbdAndMouse. No Arduino IDE.
Figura 3 – Caminho para o exemplo USBHIDBootKbdAndMouse.

Logo após, o seguinte código será exibido na tela.

#include <hidboot.h>
#include <usbhub.h>

// Satisfy IDE, which only needs to see the include statment in the ino.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>

class MouseRptParser : public MouseReportParser
{
  protected:
    void OnMouseMove(MOUSEINFO *mi);
    void OnLeftButtonUp(MOUSEINFO *mi);
    void OnLeftButtonDown(MOUSEINFO *mi);
    void OnRightButtonUp(MOUSEINFO *mi);
    void OnRightButtonDown(MOUSEINFO *mi);
    void OnMiddleButtonUp(MOUSEINFO *mi);
    void OnMiddleButtonDown(MOUSEINFO *mi);
};
void MouseRptParser::OnMouseMove(MOUSEINFO *mi)
{
  Serial.print("dx=");
  Serial.print(mi->dX, DEC);
  Serial.print(" dy=");
  Serial.println(mi->dY, DEC);
};
void MouseRptParser::OnLeftButtonUp	(MOUSEINFO *mi)
{
  Serial.println("L Butt Up");
};
void MouseRptParser::OnLeftButtonDown	(MOUSEINFO *mi)
{
  Serial.println("L Butt Dn");
};
void MouseRptParser::OnRightButtonUp	(MOUSEINFO *mi)
{
  Serial.println("R Butt Up");
};
void MouseRptParser::OnRightButtonDown	(MOUSEINFO *mi)
{
  Serial.println("R Butt Dn");
};
void MouseRptParser::OnMiddleButtonUp	(MOUSEINFO *mi)
{
  Serial.println("M Butt Up");
};
void MouseRptParser::OnMiddleButtonDown	(MOUSEINFO *mi)
{
  Serial.println("M Butt Dn");
};

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;

  if (beforeMod.bmLeftCtrl != afterMod.bmLeftCtrl) {
    Serial.println("LeftCtrl changed");
  }
  if (beforeMod.bmLeftShift != afterMod.bmLeftShift) {
    Serial.println("LeftShift changed");
  }
  if (beforeMod.bmLeftAlt != afterMod.bmLeftAlt) {
    Serial.println("LeftAlt changed");
  }
  if (beforeMod.bmLeftGUI != afterMod.bmLeftGUI) {
    Serial.println("LeftGUI changed");
  }

  if (beforeMod.bmRightCtrl != afterMod.bmRightCtrl) {
    Serial.println("RightCtrl changed");
  }
  if (beforeMod.bmRightShift != afterMod.bmRightShift) {
    Serial.println("RightShift changed");
  }
  if (beforeMod.bmRightAlt != afterMod.bmRightAlt) {
    Serial.println("RightAlt changed");
  }
  if (beforeMod.bmRightGUI != afterMod.bmRightGUI) {
    Serial.println("RightGUI changed");
  }

}

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;
USBHub     Hub(&Usb);

HIDBoot < USB_HID_PROTOCOL_KEYBOARD | USB_HID_PROTOCOL_MOUSE > HidComposite(&Usb);
HIDBoot<USB_HID_PROTOCOL_KEYBOARD>    HidKeyboard(&Usb);
HIDBoot<USB_HID_PROTOCOL_MOUSE>    HidMouse(&Usb);

KbdRptParser KbdPrs;
MouseRptParser MousePrs;

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
  Serial.println("Start");

  if (Usb.Init() == -1)
    Serial.println("OSC did not start.");

  delay( 200 );

  HidComposite.SetReportParser(0, &KbdPrs);
  HidComposite.SetReportParser(1, &MousePrs);
  HidKeyboard.SetReportParser(0, &KbdPrs);
  HidMouse.SetReportParser(0, &MousePrs);
}

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

Realize a transferência do código para a placa e, em seguida, abra o monitor serial do Arduino IDE para visualizar os dados recebidos. Em nosso projeto, quando o mouse for movimentado, serão exibidas as coordenadas em X e Y. De modo semelhante, quando uma tecla do teclado for pressionada, a tecla será indicada na tela.

Primeiramente, movimentando o mouse é possível observar que o serial monitor exibe as coordenadas em X e Y de acordo com o movimento, conforme a Figura 4.

Tela mostrando o monitor serial do Arduino IDE exibindo as coordenadas X e Y do mouse.
Figura 4 – Monitor serial do Arduino IDE exibindo as coordenadas X e Y do mouse.

Do mesmo modo, quando uma tecla do teclado for pressionada, o monitor serial exibirá a tecla e o código referente a tecla pressionada.

Tela com o monitor serial do Arduino IDE exibindo a leitura das teclas do teclado.
Figura 5 – Monitor serial do Arduino IDE exibindo a leitura das teclas do teclado.

Se você conseguiu obter os mesmos resultados no teste, significa que o USB Host Shield e o Arduino Leonardo estão funcionando corretamente. Parabéns, agora é só criar seu código e desfrutar com criatividade.

Espero ter ajudado,
Obrigado a todos e, em caso de dúvidas, deixe seu comentário abaixo!

Dúvidas? Deixe seu comentário
Estagiário no setor de desenvolvimento na Casa da Robótica

Graduando em Engenharia da Computação pela Faculdade Independente do Nordeste. Estagiário do setor de desenvolvimento da Casa da Robótica.

Bacharel em Engenharia Elétrica com ênfase em Eletrônica, mestra em Engenharia Industrial e especialista em Docência com ênfase em Educação Inclusiva. Atua no setor de Desenvolvimento de Produtos na Casa da Robótica. Editora chefe e articulista no Blog da Robótica. Fanática por livros, Star Wars e projetos Maker.

Deixe uma pergunta

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.