



Neste tutorial, exploraremos uma aplicação para a placa Raspberry Pi Pico: utilizar a RP Pico para simular um teclado USB para interação com um computador. Para isso, será utilizada a biblioteca Keyboard.h, que permite ao RP Pico enviar pressionamentos de tecla para um computador conectado através da porta USB nativa de seu computador. Também será demonstrado como a placa RP Pico pode detectar e interagir com as funções Num Lock, Caps Lock e Scroll Lock de um computador hospedeiro. Por fim, será demonstrado como criar um Gerenciador de Autenticação com a placa RP Pico. Ao integrar três push buttons à placa Raspberry Pi Pico, será possibilitado a execução de ações específicas no sistema operacional Windows 11 (SO do Computador). Ao pressionar o botão LOGIN, a senha armazenada na memória FLASH da RP Pico será enviada para permitir o acesso à sessão do Windows. Para evitar equívocos causados pelo Caps Lock, será implementada uma função que formata corretamente a senha, independentemente do estado do Caps Lock. Outras funcionalidades incluirão o botão LOGOUT, que enviará um comando para realizar o logout no Windows, e o botão BLOQUEAR, que permitirá bloquear o sistema, exigindo que o usuário faça login novamente para acessar a sessão atual do Windows.
Neste post será necessário os seguintes materiais:
Para utilizar a placa Raspberry Pi Pico deve-se instalar o núcleo Arduino Pico na IDE Arduino. Para isso, siga os passos abaixo:



Para que a placa Raspberry Pi Pico possa enviar comandos para o computador, é necessário utilizar a biblioteca Keyboard.h. Esta biblioteca permite enviar pressionamentos de tecla para um computador conectado através da porta USB do RP Pico.
Para programar a placa RP Pico, será utilizado o núcleo Arduino Pico desenvolvido por Earle F. Philhower, III (earlephilhower). Este núcleo possui dois stacks USB. As stacks USB são implementações de protocolos e drivers USB que possibilita a comunicação entre dispositivos Arduino e outros dispositivos por meio da interface USB (Universal Serial Bus: Porta Serial Universal). As duas stacks USB existentes no núcleo do Arduino Pico são: Arduino e Adafruit TinyUSB. A stack Arduino (Pico SDK) é a versão mais simples e a stack Adafruit TinyUSB é a mais completa.
A escolha entre essas duas pilhas USB pode ser feita através do menu da Arduino IDE. Para isso,na Arduino IDE, navegue no menu Ferramentas ➜ USB Stack. Então, selecione a opção pico-SDK (stack Arduino) ou a opção Adafruit TinyUSB.
Neste post, estaremos utilizando a Stack Arduino (Pico SDK), pois a mesma fornece as funcionalidades necessárias.
Para a utilização da biblioteca Keyboard.h não é necessário nenhuma instalação de biblioteca, apenas é necessário ter o núcleo Arduino-Pico (de earlephilhower) instalado em sua IDE Arduino. Para instruções de como instalar este núcleo, confira o tópico anterior Configurando IDE Arduino para a RP Pico.
*Caracteres ASCII azuis são chamados de caracteres de controle, códigos de controle ou caracteres não imprimíveis; Caracteres ASCII vermelhos são caracteres visíveis/imprimíveis que incluem letras maiúsculas, letras minúsculas, números e pontuação básica; Códigos Hexadecimais devem ser precedidos de '0x'; Códigos Binários devem ser precedidos de '0b'.
void begin(const uint8_t *layout = KeyboardLayout_en_US): Inicia a emulação de um teclado conectado a um computador. Esta função inicia o teclado com o layout fornecido. O layout padrão é o teclado em inglês dos Estados Unidos (en_US).
layout: representa o layout do teclado. O layout padrão é KeyboardLayout_en_US. a biblioteca oferece suporte aos seguintes layouts de teclado nacionais:
#include <Keyboard.h> // Inclui a biblioteca para o uso da emulação de teclado
void setup() {
Keyboard.begin(); // Inicia a comunicação com o teclado
}
void loop() {
if (BOOTSEL) { // Verifica se o botão BOOTSEL foi pressionado
Keyboard.print("ESP32!"); // Envia uma série de pressionamentos de caracteres
while (BOOTSEL) {} // Aguarda o usuário soltar o botão BOOTSEL
}
delay(10); // Atraso de 10 milissegundos
}
void end(void): Encerra a emulação do teclado, desligando a comunicação com o computador ao qual o teclado está conectado.
#include <Keyboard.h> // Inclui a biblioteca para o uso da emulação de teclado
void setup() {}
void loop() {
if (BOOTSEL) { // Verifica se o botão BOOTSEL foi pressionado
Keyboard.begin(); // Inicia a comunicação com o teclado
Keyboard.print("Teste!"); // Envia uma série de pressionamentos de caracteres
Keyboard.end(); // Finaliza a comunicação com o teclado
while (BOOTSEL) {} // Aguarda o usuário soltar o botão BOOTSEL
}
delay(10); // Atraso de 10 milissegundos
}
size_t write(uint8_t k): Envia um pressionamento de tecla para um computador conectado. Isso é semelhante a pressionar e soltar uma tecla do teclado. Somente caracteres ASCII presentes no teclado são suportados, além de modificadores de teclado adicionais e teclas especiais (como CTRL, SHIFT, ALT, entre outras).
k: O byte a ser escrito, representando a tecla a ser pressionada e solta. Este byte pode ser um inteiro, um caractere, um hexadecimal ou um binário. Confira a tabela de Caracteres ASCII e a tabela de Modificadores de teclado e teclas especiais.#include <Keyboard.h> // Inclui a biblioteca para o uso da emulação de teclado
void setup() {
Keyboard.begin(); // Inicia a comunicação com o teclado
}
void loop() {
if (BOOTSEL) { // Verifica se o botão BOOTSEL foi pressionado
Keyboard.write(65); // pressiona e solta a tecla com código ASCII decimal 65 - letra A
Keyboard.write(0x42); // pressiona e solta a tecla com código ASCII hexadecimal 42 - letra B
Keyboard.write(0b1000011); // pressiona e solta a tecla com código ASCII binário 1000011 - letra C
Keyboard.write('D'); // pressiona e solta a tecla de caractere ASCII 'D'
while (BOOTSEL) {} // Aguarda o usuário soltar o botão BOOTSEL
}
delay(10); // Atraso de 10 milissegundos
}
size_t write(const uint8_t *buffer, size_t size): Envia uma série de pressionamentos de teclas para um computador conectado. Isso é semelhante a pressionar e soltar sequencialmente várias teclas do teclado. Somente caracteres ASCII presentes no teclado são suportados, além de modificadores de teclado adicionais e teclas especiais (como CTRL, SHIFT, ALT, entre outras).
buffer: Um ponteiro para o array de bytes (buffer) contendo as teclas a serem pressionadas, com cada byte representando a tecla a ser pressionada e solta. Este byte pode ser um inteiro, um caractere, um hexadecimal ou um binário. Confira a tabela de Caracteres ASCII e a tabela de Modificadores de teclado e teclas especiais;size: O tamanho do buffer, indicando a quantidade de teclas a serem pressionadas.size nesta função.#include <Keyboard.h> // Inclui a biblioteca para o uso da emulação de teclado
void setup() {
Keyboard.begin(); // Inicia a comunicação com o teclado
}
void loop() {
if (BOOTSEL) { // Verifica se o botão BOOTSEL foi pressionado
uint8_t keyBuffer[] = { 'c', 'a', 'l', 'c', 'u', 'l', 'a', 'd', 'o', 'r', 'a' , '\n'}; // Define um buffer com as teclas a serem pressionadas
size_t tamanhoBuffer = sizeof(keyBuffer)/sizeof(uint8_t); // Calcula o tamanho do buffer em bytes
Keyboard.write(keyBuffer,tamanhoBuffer); // pressiona e solta cada tecla do buffer keyBuffer formando a palavra 'calculadora' com uma quebra de linha
while (BOOTSEL) {} // Aguarda o usuário soltar o botão BOOTSEL
}
delay(10); // Atraso de 10 milissegundos
}
size_t press(uint8_t k): Simula a pressionamento (como se uma tecla fosse pressionada e mantida pressionada no teclado) de uma tecla no Computador conectado. Está função é útil ao usar teclas modificadoras (como SHIFT, CTRL, ALT, F1, F2, WIN, TAB, entre outros).
k: O byte que representa a tecla a ser pressionada. Confira a tabela de Caracteres ASCII e a tabela de Modificadores de teclado e teclas especiais.#include <Keyboard.h> // Inclui a biblioteca para o uso da emulação de teclado
void setup() {
Keyboard.begin(); // Inicia a comunicação com o teclado
}
void loop() {
if (BOOTSEL) { // Verifica se o botão BOOTSEL foi pressionado
//Série de pressionamentos para abrir o Gerenciador de Tarefas do Windows (Ctrl + Shift + Esc)
Keyboard.press(KEY_LEFT_CTRL); // pressiona e mantém pressionada a tecla com chave KEY_LEFT_CTRL (tecla Ctrl esquerda)
Keyboard.press(KEY_LEFT_SHIFT); // pressiona e mantém pressionada a tecla com chave KEY_LEFT_SHIFT (tecla Shift esquerda)
Keyboard.press(KEY_ESC); // pressiona e mantém pressionada a tecla com chave KEY_ESC (tecla Esc)
delay(100); // atraso de 100 milissegundos
Keyboard.releaseAll(); // solta todas as teclas pressionadas
while (BOOTSEL) {} // Aguarda o usuário soltar o botão BOOTSEL
}
delay(10); // Atraso de 10 milissegundos
}
size_t release(uint8_t k): Simula a liberação da tecla especificada que estava mantida pressionada no Computador conectado.
k: O byte que representa a tecla a ser solta. Confira a tabela de Caracteres ASCII e a tabela de Modificadores de teclado e teclas especiais.#include <Keyboard.h> // Inclui a biblioteca para o uso da emulação de teclado
void setup() {
Keyboard.begin(); // Inicia a comunicação com o teclado
}
void loop() {
if (BOOTSEL) { // Verifica se o botão BOOTSEL foi pressionado
//Série de pressionamentos para colar a última coisa que estiver na área de trânsferência
Keyboard.press(KEY_LEFT_CTRL); // pressiona e mantém pressionada a tecla com chave KEY_LEFT_CTRL (tecla Ctrl esquerda)
Keyboard.press('v'); // pressiona e mantém pressionada a tecla com caractere ASCII 'v' (tecla v minúsculo)
delay(100); // atraso de 100 milissegundos
Keyboard.release(KEY_LEFT_CTRL); // solta a tecla pressionada especificada
Keyboard.release('v'); // solta a tecla pressionada especificada
while (BOOTSEL) {} // Aguarda o usuário soltar o botão BOOTSEL
}
delay(10); // Atraso de 10 milissegundos
}
void releaseAll(void): Simula a liberação de todas as teclas que foram previamente pressionadas no teclado do Computador conectado.
#include <Keyboard.h> // Inclui a biblioteca para o uso da emulação de teclado
void setup() {
Keyboard.begin(); // Inicia a comunicação com o teclado
}
void loop() {
if (BOOTSEL) { // Verifica se o botão BOOTSEL foi pressionado
//Série de pressionamentos para abrir o histórico da área de transferência
Keyboard.press(KEY_LEFT_GUI); // pressiona e mantém pressionada a tecla com chave KEY_LEFT_GUI (tecla Windows esquerda)
Keyboard.press('v'); // pressiona e mantém pressionada a tecla com caractere ASCII 'v' (tecla v minúsculo)
delay(100); // atraso de 100 milissegundos
Keyboard.releaseAll(); // solta todas as teclas pressionadas
while (BOOTSEL) {} // Aguarda o usuário soltar o botão BOOTSEL
}
delay(10); // Atraso de 10 milissegundos
}
size_t consumerPress(uint16_t k): Simula o pressionamento de uma tecla de controle multimídia, como play, pause, volume up, volume down, entre outras, no Computador conectado.
k: O byte que representa a tecla a ser solta. Confira a tabela de Modificadores de teclado e teclas especiais.#include <Keyboard.h> // Inclui a biblioteca para o uso da emulação de teclado
void setup() {
Keyboard.begin(); // Inicia a comunicação com o teclado
}
void loop() {
if (BOOTSEL) { // Verifica se o botão BOOTSEL foi pressionado
//Série de pressionamentos para deixar o sistema de áudio do Windows Mudo ou 'desmutado'
Keyboard.consumerPress(KEY_MUTE); // pressiona e mantém pressionada a tecla com chave KEY_MUTE (tecla mudo)
delay(100); // atraso de 100 milissegundos
Keyboard.consumerRelease(); // solta todas as teclas pressionadas de controle de mídia
while (BOOTSEL) {} // Aguarda o usuário soltar o botão BOOTSEL
}
delay(10); // Atraso de 10 milissegundos
}
size_t consumerRelease(): Simula a liberação das teclas de controle multimídia no Computador conectado.
#include <Keyboard.h> // Inclui a biblioteca para o uso da emulação de teclado
void setup() {
Keyboard.begin(); // Inicia a comunicação com o teclado
}
void loop() {
if (BOOTSEL) { // Verifica se o botão BOOTSEL foi pressionado
//Série de pressionamentos para pausar/dar play na mídia atual que está tocando no Windows
Keyboard.consumerPress(KEY_PLAY_PAUSE); // pressiona e mantém pressionada a tecla com chave KEY_PLAY_PAUSE (tecla play / pause)
delay(100); // atraso de 100 milissegundos
Keyboard.consumerRelease(); // solta todas as teclas de controle de mídia pressionadas
while (BOOTSEL) {} // Aguarda o usuário soltar o botão BOOTSEL
}
delay(10); // Atraso de 10 milissegundos
}
size_t Print::print(const char str[]): Envia um ou mais pressionamentos de tecla para um computador conectado.
str: Um char, int ou uma string representando as teclas a serem enviadas.#include <Keyboard.h> // Inclui a biblioteca para o uso da emulação de teclado
void setup() {
Keyboard.begin(); // Inicia a comunicação com o teclado
}
void loop() {
if (BOOTSEL) { // Verifica se o botão BOOTSEL foi pressionado
Keyboard.print("abc"); // Envia uma série de pressionamentos de caracteres
while (BOOTSEL) {} // Aguarda o usuário soltar o botão BOOTSEL
}
delay(10); // Atraso de 10 milissegundos
}
size_t Print::println(const char c[]): Envia um ou mais pressionamentos de tecla para um computador conectado, seguido por um pressionamento na tecla Enter.
c: Um char, int ou uma string representando as teclas a serem enviadas.#include <Keyboard.h> // Inclui a biblioteca para o uso da emulação de teclado
void setup() {
Keyboard.begin(); // Inicia a comunicação com o teclado
}
void loop() {
if (BOOTSEL) { // Verifica se o botão BOOTSEL foi pressionado
Keyboard.println("xyz"); // Envia uma série de pressionamentos de caracteres
while (BOOTSEL) {} // Aguarda o usuário soltar o botão BOOTSEL
}
delay(10); // Atraso de 10 milissegundos
}
Para a placa Raspberry Pi Pico detectar quando o computador estiver com as funções Num Lock, Caps Lock e Scroll Lock ativas é utilizada uma função callback na programação da placa. Esta função é a onLed. Veja abaixo a sintaxe dela:
void onLED(LedCallbackFcn fcn, void *cbData = nullptr):
Ela possui os seguintes parãmetros:
fcn: parâmetro do tipo LedCallbackFcn que aceita uma função de callback cuja assinatura é definida como typedef void(*LedCallbackFcn)(bool numlock, bool capslock, bool scrolllock, bool compose, bool kana, void *cbData);. Os parâmetros desta assinatura da callback são:
numlock: parâmetro booleano que indica se a função Num Lock está ativa ou não (ao estar ativada trava as funções no teclado numérico do computador).capslock: parâmetro booleano que indica se a função Caps Lock está ativa ou não (ao estar ativada deixa as letras em maiúsculas).scrolllock: parâmetro booleano que indica se a função Scroll Lock está ativa ou não (ao estar ativada bloqueia a rolagem da página).compose: parâmetro booleano que indica o estado da função Compose ou não (ao estar ativada permite a criação de caracteres especiais, veja mais sobre em Compose key - Wikipedia).kana: parâmetro booleano que indica o estado da função Kana ou não (ao estar ativada permite a inserção de caracteres em sistemas de escrita japonesa, veja mais sobre em Japanese input method - Wikipedia).cbData: parãmetro que permite que dados adicionais possam ser passados para a função de callback.cbData : parãmetro OPCIONAL que permite que dados adicionais possam ser passados para a função de callback.#include <Keyboard.h> // Inclui a biblioteca para o uso da emulação de teclado
bool nl, cl, sl; // variáveis globais que armazenam o status atual de Num Lock, Caps Lock e Scroll Lock
void ledCallBack(bool numlock, bool capslock, bool scrolllock, bool compose, bool kana, void *cbData) {
nl = numlock; // Atualiza o status de Num Lock na variável global
cl = capslock; // Atualiza o status de Caps Lock na variável global
sl = scrolllock; // Atualiza o status de Scroll Lock na variável global
}
void setup() {
Serial.begin(115200); // configura o monitor serial em 115200 de baudrate
Keyboard.onLED(ledCallBack); // Associa a função de callback para monitorar os estados das teclas
Keyboard.begin(); // Inicia a comunicação com o teclado
}
void loop() {
Serial.println("--------------------------------------------\n");
Serial.println("Num Lock \t Caps Lock \t Scroll Lock");
Serial.print(" ");
Serial.print(nl); // Exibe o status atual de Num Lock
Serial.print("\t\t ");
Serial.print(cl); // Exibe o status atual de Caps Lock
Serial.print("\t\t ");
Serial.println(sl); // Exibe o status atual de Scroll Lock
Serial.println("--------------------------------------------\n");
delay(100);
}
Ao sketch ser executado na placa RP Pico e ao ser apertada as teclas Num Lock, Caps Lock ou Scroll Lock do computador, o monitor serial exibe:
Quando uma String é passada como parâmetro para a função print da biblioteca Keyboard.h e o computador de destino estiver com a função Caps Lock ativada, a String pode ser recebida incorretamente. Veja o exemplo:
#include <Keyboard.h> // Inclui a biblioteca para o uso da emulação de teclado
void setup() {
Keyboard.begin(); // Inicia a comunicação com o teclado
}
void loop() {
if (BOOTSEL) {// Verifica se o botão BOOTSEL foi pressionado
Keyboard.println("ABCdef"); // Envia uma série de pressionamentos de caracteres
while (BOOTSEL);// Aguarda o usuário soltar o botão BOOTSEL
}
delay(10); // atraso de 10 milissegundos no loop principal
}
Neste código anterior, ao pressionar o botão BOOTSEL seria enviado para o computador:
ABCdefabcDEFformatarString:
// Função para formatar a string, levando em consideração o estado do Caps Lock .
// Lógica de funcionamento:
// - se a função Caps Lock do computador estiver acionada:
// -> os caracteres da string que forem maiúsculos serão transformados em minúsculos,
// e os caracteres da string que forem minúsculos serão transformados em maiúsculos;
//
// - se a função Caps Lock do computador NÃO estiver acionada:
// -> os caracteres da string que forem maiúsculos permanecerão maiúsculos,
// e os caracteres da string que forem minúsculos permanecerão minúsculos.
//
String formatarString(String string, bool capsLockAtivo) {
if (capsLockAtivo) { // Verifica se o Caps Lock está ativado
for (int i = 0; i < string.length(); i++) { // Percorre cada caractere da string
if (isAlpha(string[i])) { // Verifica se o caractere é uma letra
if (isUpperCase(string[i])) { // Verifica se o caractere é maiúsculo
string[i] = toLowerCase(string[i]); // Converte para minúsculo
} else { // se não, caso o caractere seja minúsculo, ...
string[i] = toUpperCase(string[i]); // Converte para maiúsculo
}
}
}
}
return string; // Retorna a string formatada
}
Para utilizar esta função no sketch, basta informar nos parâmetros a string a ser formatada e o status da função Caps Lock no computador. Veja o Exemplo:
#include <Keyboard.h> // Inclui a biblioteca para o uso da emulação de teclado
bool cl; // variável global que armazena o status atual de Caps Lock
void ledCallBack(bool numlock, bool capslock, bool scrolllock, bool compose, bool kana, void *cbData) {
cl = capslock; // Atualiza o status de Caps Lock na variável global
}
void setup() {
Keyboard.onLED(ledCallBack); // Associa a função de callback para monitorar os estados das teclas
Keyboard.begin(); // Inicia a comunicação com o teclado
}
void loop() {
if (BOOTSEL) {// Verifica se o botão BOOTSEL foi pressionado
Keyboard.println(formatarString("ABCdef", cl)); // Envia uma série de pressionamentos de caracteres, com a string sendo formatada adequadamente
while (BOOTSEL);// Aguarda o usuário soltar o botão BOOTSEL
}
delay(10); // atraso de 10 milissegundos no loop principal
}
// Função para formatar a string, levando em consideração o estado do Caps Lock .
// Lógica de funcionamento:
// - se a função Caps Lock do computador estiver acionada:
// -> os caracteres da string que forem maiúsculos serão transformados em minúsculos,
// e os caracteres da string que forem minúsculos serão transformados em maiúsculos;
//
// - se a função Caps Lock do computador NÃO estiver acionada:
// -> os caracteres da string que forem maiúsculos permanecerão maiúsculos,
// e os caracteres da string que forem minúsculos permanecerão minúsculos.
//
String formatarString(String string, bool capsLockAtivo) {
if (capsLockAtivo) { // Verifica se o Caps Lock está ativado
for (int i = 0; i < string.length(); i++) { // Percorre cada caractere da string
if (isAlpha(string[i])) { // Verifica se o caractere é uma letra
if (isUpperCase(string[i])) { // Verifica se o caractere é maiúsculo
string[i] = toLowerCase(string[i]); // Converte para minúsculo
} else { // se não, caso o caractere seja minúsculo, ...
string[i] = toUpperCase(string[i]); // Converte para maiúsculo
}
}
}
}
return string; // Retorna a string formatada
}
Agora, neste código, ao pressionar o botão BOOTSEL seria enviado para o computador:
ABCdefABCdefAgora será mostrado como criar um Gerenciador de Autenticação com a placa Raspberry Pi Pico. Ao se clicar em um dos três pushbuttons conectados à placa RP Pico, será enviado ao computador com Sistema Operacional Windows 11 uma determinada ação:
Clique aqui para fazer o download do sketch completo. Antes de prosseguir, modifique o valor das seguintes variáveis no sketch:
SENHA_WINDOWS pela sua senha de autenticação no Windows 11;/******************************************************************************
Simule um Teclado com Raspberry Pi Pico
+
Gerenciador de Autenticação com RP Pico
Criado em 05 de Fevereiro de 2024
por Michel Galvão (https://micsg.com.br)
Sketch Principal
Eletrogate | Arduino, Robótica, IoT, Apostilas e Kits
https://www.eletrogate.com/
******************************************************************************/
#include <Keyboard.h> // Inclui a biblioteca para o uso da emulação de teclado
#include "credencial.h" // Inclui o arquivo credencial.h que armazena a senha do Computador Windows
#define pinLogin 17 // Define o pino do botão para acionar a função login
#define pinLogout 16// Define o pino do botão para acionar a função logout
#define pinBloquear 15// Define o pino do botão para acionar a função bloqueio
bool cl; // variável global que armazena o status atual de Caps Lock
void ledCallBack(bool numlock, bool capslock, bool scrolllock, bool compose, bool kana, void *cbData) {
cl = capslock; // Atualiza o status de Caps Lock na variável global
}
void setup() {
Serial.begin(115200); // configura o monitor serial em 115200 de baudrate
Keyboard.onLED(ledCallBack); // Associa a função de callback para monitorar os estados das teclas
Keyboard.begin(); // Inicia a comunicação com o teclado
pinMode(pinLogin, INPUT_PULLUP);// Configura o pino do botão login como entrada com resistor de pull-up interno
pinMode(pinLogout, INPUT_PULLUP);// Configura o pino do botão logout como entrada com resistor de pull-up interno
pinMode(pinBloquear, INPUT_PULLUP);// Configura o pino do botão bloqueio como entrada com resistor de pull-up interno
}
void loop() {
if (!digitalRead(pinLogin)) { // se a leitura do botão login for igual à 0 (LOW), ...
// Estrutura de controle para esperar o usuário soltar o botão Login
do { // Início do bloco 'do'
delay(100); // Aguarda por 100 milissegundos
}
while (!digitalRead(pinLogin));// Continua repetindo o loop enquanto o botão de login estiver em nível lógico baixo (pressionado)
Serial.println("Login acionado"); // Informa pelo Monitor Serial que a Função Login será executada
Keyboard.write(KEY_RETURN); // pressiona e solta a tecla ENTER
delay(500); // pausa o programa por 350 milissegundos
Keyboard.print(formatarString(senhaWindows, cl)); // Envia uma série de pressionamentos dos caracteres da variável contendo a senha de login do Windows 11, com a senha sendo formatada adequadamente
delay(150); // pausa o programa por 150 milissegundos
Keyboard.write(KEY_RETURN); // pressiona e solta a tecla ENTER
}
if (!digitalRead(pinLogout)) { // se a leitura do botão logout for igual à 0 (LOW), ...
// Estrutura de controle para esperar o usuário soltar o botão Logout
do { // Início do bloco 'do'
delay(100); // Aguarda por 100 milissegundos
}
while (!digitalRead(pinLogout)); // Continua repetindo o loop enquanto o botão de login estiver em nível lógico baixo (pressionado)
Serial.println("Logout acionado"); // Informa pelo Monitor Serial que a Função Logout será executada
Keyboard.press(KEY_LEFT_CTRL); // pressiona e mantém pressionada a tecla com chave KEY_LEFT_CTRL (tecla Ctrl esquerda)
Keyboard.press(KEY_LEFT_ALT); // pressiona e mantém pressionada a tecla com chave KEY_LEFT_ALT (tecla Alt)
Keyboard.press(KEY_DELETE); // pressiona e mantém pressionada a tecla com chave KEY_DELETE (tecla Delete)
Keyboard.releaseAll(); // solta todas as teclas pressionadas
delay(500); // pausa o programa por 350 milissegundos
Keyboard.write(KEY_LEFT_ALT); // pressiona e solta a tecla ALT
delay(150); // pausa o programa por 100 milissegundos
Keyboard.write('s'); // pressiona e solta a tecla de caractere ASCII 's' (para fazer logout no Windows 11)
}
if (!digitalRead(pinBloquear)) { // se a leitura do botão bloquear for igual à 0 (LOW), ...
// Estrutura de controle para esperar o usuário soltar o botão Bloquear
do { // Início do bloco 'do'
delay(100); // Aguarda por 100 milissegundos
}
while (!digitalRead(pinBloquear)); // Continua repetindo o loop enquanto o botão de bloqueio estiver em nível lógico baixo (pressionado)
Serial.println("Bloqueio acionado"); // Informa pelo Monitor Serial que a Função Bloquear será executada
Keyboard.press(KEY_LEFT_CTRL); // pressiona e mantém pressionada a tecla com chave KEY_LEFT_CTRL (tecla Ctrl esquerda)
Keyboard.press(KEY_LEFT_ALT); // pressiona e mantém pressionada a tecla com chave KEY_LEFT_ALT (tecla Alt)
Keyboard.press(KEY_DELETE); // pressiona e mantém pressionada a tecla com chave KEY_DELETE (tecla Delete)
Keyboard.releaseAll(); // solta todas as teclas pressionadas
delay(500); // pausa o programa por 350 milissegundos
Keyboard.write(KEY_LEFT_ALT); // pressiona e solta a tecla ALT
delay(150); // pausa o programa por 100 milissegundos
Keyboard.write('b'); // pressiona e solta a tecla de caractere ASCII 'b' (para bloquear o Windows 11)
}
delay(10); // atraso de 10 milissegundos no loop principal
}
// Função para formatar a string, levando em consideração o estado do Caps Lock .
// Lógica de funcionamento:
// - se a função Caps Lock do computador estiver acionada:
// -> os caracteres da string que forem maiúsculos serão transformados em minúsculos,
// e os caracteres da string que forem minúsculos serão transformados em maiúsculos;
//
// - se a função Caps Lock do computador NÃO estiver acionada:
// -> os caracteres da string que forem maiúsculos permanecerão maiúsculos,
// e os caracteres da string que forem minúsculos permanecerão minúsculos.
//
String formatarString(String string, bool capsLockAtivo) {
if (capsLockAtivo) { // Verifica se o Caps Lock está ativado
for (int i = 0; i < string.length(); i++) { // Percorre cada caractere da string
if (isAlpha(string[i])) { // Verifica se o caractere é uma letra
if (isUpperCase(string[i])) { // Verifica se o caractere é maiúsculo
string[i] = toLowerCase(string[i]); // Converte para minúsculo
} else { // se não, caso o caractere seja minúsculo, ...
string[i] = toUpperCase(string[i]); // Converte para maiúsculo
}
}
}
}
return string; // Retorna a string formatada
}
/******************************************************************************
Simule um Teclado com Raspberry Pi Pico
+
Gerenciador de Autenticação com RP Pico
Criado em 05 de Fevereiro de 2024
por Michel Galvão (https://micsg.com.br)
Credencial
Eletrogate | Arduino, Robótica, IoT, Apostilas e Kits
https://www.eletrogate.com/
******************************************************************************/
const char *senhaWindows = "SENHA_WINDOWS"; // variável que armazena a senha de autenticação do Windows
Keyboard.h para emular um teclado.credencial.h para obter a senha do Windows.pinLogin, pinLogout, e pinBloquear são definidos como os pinos dos botões para acionar as funções de login, logout e bloqueio, respectivamente.credencial.h:
senhaWindows.Veja no vídeo abaixo o funcionamento do projeto:
Em um passo além do projeto original, pode-se utilizar um Módulo Leitor Biométrico (Impressão Digital) - DY50 ou um Kit Módulo RFID Mfrc522 13.56 Mhz para aprimorar ainda mais a autenticação no Windows e permitir ao usuário que, facilmente, possa se autenticar utilizando sua digital, um cartão RFID ou um chaveiro RFID. Curtiu o post? Avalie e deixe um comentário! Siga-nos também no Instagram e nos marque quando fizer algum projeto nosso: @eletrogate. Até a próxima!
|
Aprenda a utilizar a placa Raspberry Pi Pico para emular um teclado USB em um Computador, além disso, veja também como criar um Gerenciador de Autenticação de Computador Windows 11 com RP Pico.
Encontre tudo na Loja Eletrogate com frete grátis para compras acima de R$ 200