(Des) Corretor ortográfico com Arduino

corretor ortográfico com Arduino

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.

Materiais necessários

Para esse artigo é fundamental que o Arduino seja o Leonardo (que você encontra nesse link da Eletrogate) e também é necessário o USB Host Shield (também na Eletrogate, por esse link), que fará a bridge entre o teclado e o computador.

Como funciona o (des) corretor ortográfico com Arduino

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:

  • Teclado para o shield
  • Shield para o Arduino
  • Manipulação dos caracteres
  • repasse para o computador

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!

Sugestões de implementação

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:

  • X para S, quando procedido de consoante
  • X para CH, quando procedido de vogal
  • SS para Ç
  • Z para S, quando a posição de leitura for > 0
  • etc

A biblioteca para o Arduino Leonardo se comportar como um teclado é nativa. Já a do USB Host Shield, você pode se orientar por esse artigo.

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 video mostrando uma frase. Acabei escrevendo ‘sin’ e daí saiu certo o ‘sim’.

Inscreva-se no nosso newsletter, alí em cima à direita e receba novos posts por email.

Siga-nos no Do bit Ao Byte no Facebook.

Prefere twitter? @DobitAoByte.

Inscreva-se no nosso canal Do bit Ao Byte Brasil no YouTube.

Nossos grupos:

Arduino BR – https://www.facebook.com/groups/microcontroladorarduinobr/
Raspberry Pi BR – https://www.facebook.com/groups/raspberrybr/
Orange Pi BR – https://www.facebook.com/groups/OrangePiBR/
Odroid BR – https://www.facebook.com/groups/odroidBR/
Sistemas Embarcados BR – https://www.facebook.com/groups/SistemasEmbarcadosBR/
MIPS BR – https://www.facebook.com/groups/MIPSBR/
Do Bit ao Byte – https://www.facebook.com/groups/dobitaobyte/

Próximo post a caminho!