Manual
do
Maker
.
com
Muitas pessoas usam o Arduino para trabalho, outros tantos para aprendizado, mais um monte para diversão. Eu gosto de usar pra diversão. O Arduino, vendo-o como um brinquedo, atende a todas as idades. Nesse artigo vou mostrar como é simples fazer um (des)corretor ortográfico com Arduino. O mais legal é que não implementei todas as possibilidades, apenas alguns exemplos.
Para esse artigo é fundamental que o Arduino seja o Leonardo (que você encontra nesse link da Eletrogate) e também é necessário o USB Shield (também na Eletrogate, por esse link), que fará a bridge entre o teclado e o computador.
O USB Host Shield serve para diversas coisas, como controles de PS4, XBOX, interface com smartphones etc. Nesse artigo utilizo a funcionalidade de dispositivo de entrada - no caso, o teclado. Quando algo é digitado no teclado, é feita a leitura, então o valor é convertido para o equivalente ao char da tabela ASCII. Nesse momento já podemos interagir com os valores.
Para enviar ao computador, o Arduino Leonardo tem a habilidade de funcionar como um teclado, então usamos esse recurso para repassar o que manipulamos da recepção do teclado. Resumindo:
Nem me preocupei em escrever "from scratch", modifiquei o sketch do USB Host Shield e adicionei a funcionalidade de teclado ao Arduino Leonardo, bem simples. Criei algumas funções para manipular os caracteres de entrada antes de repassar ao computador, então, se uma pessoa começar a digitar e não souber dessa "sacanagem", vai ficar doida tentando corrigir o texto!
Coloquei apenas a mudança de G para J, de M para N, de N para M e C para C. Outras implementações que seriam interessantes:
A biblioteca para o Arduino Leonardo se comportar como um teclado é nativa. Já a do USB Host Shield.
O código que utilizei pro exemplo mais abaixo ficou assim:
#include <hidboot.h>
#include <usbhub.h>
#include "Keyboard.h"
// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>
unsigned char words[20] = {0};
byte i = 0;
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 change_mn(unsigned char checkS)
{
if (i == 0) return; if (checkS == 'm')
{
i = i-1; words[i] = 'n';
}
}
void change_nm(unsigned char checkS)
{
if (i == 0) return;
if (checkS == 'n')
{
i = i-1;
words[i] = 'm';
}
}
void change_gj(unsigned char checkS)
{
if (checkS == 'g')
{
i = i > 0 ? i-1 : 0; words[i] = 'j';
}
}
void change_cs(unsigned char checkS)
{
if (checkS == 'c' && i == 0)
{
words[i] = 's';
}
}
void clearWord(unsigned char key_pressed)
{
if (key_pressed == ' ' || i >18)
{
Serial.println("");
Serial.print("word: ");
//Serial.println(words);
for (byte a = 0; a < 20;a++)
{
words[a] = 0;
}
i = 0;
} else {
i += 1;
//Serial.println(words);
}
}
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.print((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.print("LeftCtrl changed");
}
if (beforeMod.bmLeftShift != afterMod.bmLeftShift)
{
Serial.print("LeftShift changed");
}
if (beforeMod.bmLeftAlt != afterMod.bmLeftAlt)
{
Serial.print("LeftAlt changed");
}
if (beforeMod.bmLeftGUI != afterMod.bmLeftGUI)
{
Serial.print("LeftGUI changed");
}
if (beforeMod.bmRightCtrl != afterMod.bmRightCtrl)
{
Serial.print("RightCtrl changed");
}
if (beforeMod.bmRightShift != afterMod.bmRightShift)
{
Serial.print("RightShift changed");
}
if (beforeMod.bmRightAlt != afterMod.bmRightAlt)
{
Serial.print("RightAlt changed");
}
if (beforeMod.bmRightGUI != afterMod.bmRightGUI)
{
Serial.print("RightGUI changed");
}
}
void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)
{
//Serial.print("UP ");
//PrintKey(mod, key);
}
void KbdRptParser::OnKeyPressed(uint8_t key)
{
char pressed = (unsigned char) key;
words[i] = pressed;
change_mn(pressed);
change_nm(pressed);
change_cs(pressed);
change_gj(pressed);
Keyboard.write(words[i]);
clearWord(pressed);
Serial.print(pressed);
Serial.print(i);
};
USB Usb;
//USBHub Hub(&Usb);
HIDBoot<USB_HID_PROTOCOL_KEYBOARD> HidKeyboard(&Usb);
KbdRptParser Prs;
void setup()
{
Serial.begin(115200);
Keyboard.begin();
#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("Starting...");
if (Usb.Init() == -1)
Serial.print("OSC did not start.");
delay(200);
HidKeyboard.SetReportParser(0, &Prs);
}
void loop()
{
Usb.Task();
}
O vídeo mostrando uma frase. Acabei escrevendo 'sin' e daí saiu certo o 'sim'.
Inscreva-se no nosso canal Manual do Maker no YouTube.
Próximo post a caminho!
Revisão: Ricardo Amaral de Andrade
Autor do blog "Do bit Ao Byte / Manual do Maker".
Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.