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.

OBSERVAÇÃO 2: Outro detalhe de suma importância está relacionado ao tipo de mouse que você vai conectar no USB Host shield, pois existem tecnologias diferentes e a depender do modelo de mouse pode ser que o código que você gravou no Arduino Leonardo não seja compatível com o modelo do seu mouse. Em resumo, se você comprou um programa de alguém que disse funcionar para todos os mouses, cuidado! Pois já realizamos testes e o mesmo código funcionou para um modelo de mouse e para outro não, justamente devido ao modelo de mouse que exige uma programação diferente.

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 (com velocidade – BAUD RATE setada para 115200) 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. Vale ressaltar que essa programação NÃO faz com que você consiga ver a movimentação do ponteiro do mouse do seu PC com o mouse plugado no USB Host Shield, ou seja, você vai movimentar o mouse sem ver o ponteiro, mas saberá as coordenadas X e Y dele através do monitor serial.

Primeiramente, movimentando o mouse é possível observar que o serial monitor exibe as coordenadas em X e Y de acordo com o movimento, mas não é possível ver a movimentação do ponteiro visualmente, só é possível ver as coordenadas 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.

Meu mouse não funcionou com o código acima e agora?

Como mencionado na OBSERVAÇÃO 2, isso pode acontecer porque seu mouse possui uma tecnologia diferente do que foi programado no código acima, então vamos disponibilizar um segundo código para teste (apenas do mouse), mas vale ressaltar que também não é certeza de que o código abaixo irá funcionar, mas vamos testar. Vou disponibilizar o link para baixar o código, porque ele possui algumas dependências e no arquivo para download já vai tudo junto.

Clique Aqui para baixar o código

Ao baixar o arquivo do link acima você verá um arquivo .rar, você deverá ter o programa winrar instalado para descompactar e aí você clica com botão direito sob o arquivo .rar e vá na opção extrair para “hidmousereport\”. Ao descompactar você entra na pasta hidmousereport e abra o arquivo chamado hidmousereport.ino. Ao abrir o código você verá o código principal e as outras duas dependências, totalizando 3 abas conforme ilustrado na Figura 6.

Figura 6 – Exibição do segundo código de testes abrindo em conjunto com as dependências

Faça o upload desse código para o Arduino Leonardo (já deixe o mouse conectado ao USB Host Shield), abra o Monitor Serial do arduino e movimente o mouse para ver se as coordenadas X e Y serão exibidas. Se o primeiro ou segundo código deste tutorial funcionou então significa que tanto o arduino Leonardo quanto o USB Host Shield estão funcionando certinho. Caso você use um código de outras pessoas e não esteja funcionando, mas com o nosso código funcionou então significa que o problema está no código que a pessoa fez não ser compatível com o seu mouse.

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.

Bacharel em Engenharia de Computação. Um dos criadores do Blog da Robótica. Faz parte da equipe Casa da Robótica desde 2017. Apaixonado por tecnologias e pelas “loucuras” que é possível criar usando microcontroladores e impressoras 3D. Ex-BBB, mas isso é uma longa história... que poderá ser contada posteriormente.

Deixe uma pergunta

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