"I would prefer not to."
Herman Melville, Bartleby, the Scrivener: A Story of Wall Street (1853)
Um macro pad USB HID discreto, feito com Raspberry Pi Pico e CircuitPython.
bartleby-pad e um firmware CircuitPython para transformar um Raspberry Pi Pico original em um macro pad USB HID de 10 botoes. Cada botao executa uma acao predefinida: escrever texto como teclado USB, acionar um jiggler de mouse de 1 px, operar como modificador de layer ou ficar reservado para uso futuro.
O projeto foi desenhado para ser pequeno, fisico e controlavel: sem wireless, sem interface de configuracao exposta em runtime, sem componentes passivos externos e sem depender de armazenamento plaintext para os payloads finais.
O firmware implementa:
- Emulacao de teclado e mouse USB HID.
- 10 botoes fisicos ligados diretamente a GPIOs do RP2040.
- Stealth Mode:
CIRCUITPYoculto por padrao no boot. - Unlock fisico: segurar o botao
top_left/GP2durante o boot montaCIRCUITPY. - Payloads ofuscados com XOR + Base64 usando o UID de silicio do Pico.
- Payloads V2 com layers e acoes tipadas:
text,mouse_jiggle,layer,noop. - Feedback discreto pelo LED onboard com PWM de baixo duty cycle.
- Debounce 100% por software.
Uso pretendido: automacao pessoal em equipamentos proprios ou ambientes onde voce tem autorizacao. Este projeto nao deve ser usado para contornar politicas, controles ou consentimento de terceiros.
O nome vem de Bartleby, the Scrivener, novela de Herman Melville publicada em 1853.
Bartleby era um copista: alguem cuja funcao era repetir, transcrever e reproduzir texto com precisao mecanica. Mas sua frase mais famosa, "I would prefer not to", virou uma das recusas mais estranhas e persistentes da literatura moderna.
O bartleby-pad inverte essa tensao: ele aceita fazer o trabalho mecanico justamente para que a pessoa nao precise. O dispositivo copia por voce, insere os trechos repetitivos por voce e reduz atrito nas pequenas tarefas textuais que drenam atencao.
A referencia tambem carrega uma ironia operacional:
- Bartleby preferia nao fazer o trabalho repetitivo.
- O usuario prefere nao digitar o trabalho repetitivo.
- O pad executa a parte mecanica, sem entusiasmo, sem interface chamativa, sem drama.
E um pequeno objeto de automacao pessoal com um nome literario porque a ideia central nao e apenas tecnica. E sobre recusar a micro-repeticao que ocupa memoria mental demais.
Referencia literaria: MELVILLE, Herman. Bartleby, the Scrivener: A Story of Wall Street. 1853.
| Referencia | Papel no projeto |
|---|---|
| Bartleby, the Scrivener | Origem do nome e da ideia de recusa ao trabalho mecanico repetitivo. |
| USB HID | Interface padrao para o host enxergar o dispositivo como teclado. |
| CircuitPython | Ambiente simples para firmware iteravel no Raspberry Pi Pico. |
| RP2040 | Microcontrolador alvo: barato, disponivel, suficiente para HID e GPIO polling. |
| OpSec domestica | Baixo perfil visual, menos superficie exposta e comportamento previsivel. |
Algumas strings aparecem dezenas de vezes ao longo do dia: e-mails, telefones, caminhos, comandos, mensagens padrao, URLs internas, snippets e pequenos blocos de texto. Sistemas operacionais e apps oferecem atalhos, snippets e expansores de texto, mas essas solucoes normalmente ficam presas ao ambiente, ao perfil do usuario, a permissoes corporativas ou a sincronizacao em nuvem.
O problema que este projeto resolve e mais fisico:
- Um atalho que funciona em qualquer host que aceite teclado USB.
- Um dispositivo sem instalacao no computador alvo.
- Um conjunto pequeno de acoes que nao depende de conta, daemon, extensao ou app.
- Uma forma de evitar que os payloads fiquem triviais de ler caso o drive
CIRCUITPYseja montado por engano.
O bartleby-pad age como um teclado USB minimalista. Ao pressionar um botao, o firmware procura a macro associada aquela cor e escreve o texto no host usando KeyboardLayoutUS.
Os payloads sao gerados offline por um script host:
macros.local.json -> XOR com UID do Pico -> Base64 -> payloads.json
No Pico, o processo inverso acontece apenas em RAM:
payloads.json -> Base64 decode -> XOR com UID do chip -> JSON em memoria
Se o arquivo for copiado para outro Pico, o UID diferente produz lixo, o parse falha e o dispositivo continua funcionando sem injetar nada.
A protecao de payload deste projeto e ofuscacao, nao criptografia.
Ela foi pensada para impedir leitura casual de payloads.json por uma pessoa sem contexto tecnico. Ela nao protege contra um adversario com acesso fisico ao dispositivo, ferramentas de analise, leitura da flash, SWD ou instrumentacao do hardware.
Nao armazene segredos de alto impacto no bartleby-pad. Para esta versao, trate os payloads como:
- Textos de conveniencia.
- Identificadores de baixo risco.
- Comandos recorrentes que voce revisa antes de executar.
- Boilerplates sem credenciais sensiveis.
| Componente | Especificacao |
|---|---|
| Microcontrolador | Raspberry Pi Pico original, RP2040, sem Wi-Fi |
| Atuadores | 10 botoes tactile SMD normally-open, 4x4x0.8 mm, snap-dome metalico |
| Ligacao | Botao entre GPIO e GND |
| Pull-up | Interno do RP2040 |
| Componentes externos | Nenhum diodo, resistor ou capacitor |
| Feedback | LED onboard GP25 via PWM |
| Botao logico | GPIO provisorio | Funcao inicial |
|---|---|---|
top_left |
GP2 |
Acao + unlock de Stealth Mode no boot |
top_right |
GP3 |
Acao |
upper_left |
GP4 |
Modificador de layer previsto |
upper_right |
GP5 |
Acao |
center_1 |
GP6 |
Acao |
center_2 |
GP7 |
Acao |
center_3 |
GP8 |
Acao |
center_4 |
GP9 |
Acao |
center_5 |
GP10 |
Acao |
center_6 |
GP11 |
Acao |
Layout fisico provisorio, olhando para a face dos botoes com a porta USB-C na parte inferior:
top_left top_right
upper_left upper_right
center_1
center_2
center_3
center_4
center_5
center_6
USB-C
O mapeamento acima e provisorio. Depois da soldagem final, atualize docs/wiring.md e BUTTON_PINS em firmware/code.py.
bartleby-pad/
assets/
README.md # Imagens e material visual publico
firmware/
boot.py # Copiar para a raiz do CIRCUITPY
code.py # Loop principal do dispositivo
tools/
payload_builder.py # Gerador host de payloads ofuscados
examples/
macros.example.json # Exemplo de acoes sem segredos
macros.breadboard-test.json
docs/
setup.md # Setup completo no Pico
wiring.md # Mapeamento fisico e notas de soldagem
hardware-test.md # Roteiro de teste em breadboard
schematics/
README.md # Diagramas e esquemas futuros
tests/
test_payload_builder.py
CONTRIBUTING.md
LICENSE
PRD_bartleby-pad.md
Executa no cold boot e decide se o drive USB sera exposto ao host.
GP2 pressionado no boot -> monta CIRCUITPY
GP2 solto no boot -> oculta CIRCUITPY
O HID permanece habilitado como teclado.
Executa o loop principal:
- Inicializa teclado HID, LED PWM e botoes.
- Carrega
payloads.json. - Deofusca os payloads em RAM com
microcontroller.cpu.uid. - Aguarda todos os botoes serem soltos para evitar disparo acidental apos unlock.
- Escaneia botoes, aplica debounce e executa a acao da layer ativa.
Roda apenas no computador host. Ele recebe:
- UID do Pico.
- Arquivo local de acoes em plaintext.
- Caminho de saida para
payloads.json.
O arquivo payloads.json e o unico payload que deve ser copiado para o Pico.
Consulte docs/setup.md para o passo a passo completo.
Para o primeiro teste fisico, siga docs/hardware-test.md. Ele comeca sem boot.py, mantendo CIRCUITPY visivel ate o botao de unlock estar validado.
Resumo:
- Instale CircuitPython no Raspberry Pi Pico.
- Copie
adafruit_hidparaCIRCUITPY/lib. - Obtenha o UID do Pico no REPL:
import microcontroller
print(bytes(microcontroller.cpu.uid))- Crie um arquivo local de acoes:
Copy-Item examples/macros.example.json macros.local.json- Gere o payload:
python tools/payload_builder.py --uid SEU_UID_HEX --macros macros.local.json --out payloads.json- Copie para a raiz de
CIRCUITPY:
firmware/boot.py -> boot.py
firmware/code.py -> code.py
payloads.json -> payloads.json
- Ejete o drive e reconecte o Pico.
Sem segurar top_left / GP2, o drive CIRCUITPY deve ficar oculto. Segurando top_left / GP2 durante o boot, ele volta a montar para edicao.
Use um objeto JSON com version, layers e as dez chaves logicas. Strings simples ainda sao aceitas como atalho para uma acao text.
{
"version": 2,
"layers": {
"base": {
"top_left": {
"type": "text",
"value": "usuario@example.com"
},
"top_right": {
"type": "mouse_jiggle",
"pixels": 1
},
"upper_left": {
"type": "layer",
"layer": "fn",
"mode": "hold"
},
"upper_right": "+5562999999999"
},
"fn": {
"center_1": {
"type": "text",
"value": "[fn] center_1\n"
}
}
}
}Arquivos locais com acoes reais devem ficar fora do git. O repo ja ignora macros.local.json e payloads.json.
Validar sintaxe e testes do builder:
python -m py_compile tools/payload_builder.py firmware/boot.py firmware/code.py tests/test_payload_builder.py
python -m unittest tests.test_payload_builderGerar um payload de teste sem gravar arquivo:
python tools/payload_builder.py --uid e6601c101f851e26 --macros examples/macros.example.json --out -Gerar payload para teste em breadboard:
python tools/payload_builder.py --uid SEU_UID_HEX --macros examples/macros.breadboard-test.json --out payloads.json- PRD inicial.
- Firmware base para 10 botoes.
- Stealth Mode via
boot.py. - Builder host para
payloads.json. - Documentacao inicial de setup e wiring.
- Roteiro de teste em breadboard.
- CI basico para validacao de host.
- Licenca de software/firmware definida.
- Payload V2 com layers e acoes tipadas.
- Testar em breadboard.
- Atualizar mapeamento real depois da soldagem.
- Testar montagem soldada.
- Opcional: fotos do wiring e montagem.
- Suporte a Pico W ou Pico 2.
- Layouts alem de US-QWERTY.
- Perfis multiplos.
- Interface de configuracao USB serial.
- Criptografia real.
- Atalhos de teclado, delays ou comandos especiais.
- PCB customizado.
- PRD_bartleby-pad.md: documento de produto e decisoes de arquitetura.
- docs/setup.md: instalacao e operacao.
- docs/wiring.md: pinos, topologia e registro pos-soldagem.
- docs/hardware-test.md: roteiro de validacao em breadboard antes da soldagem.
- CONTRIBUTING.md: guia simples para contribuicoes.
- AGENTS.md: memoria persistente para agentes de desenvolvimento.
O projeto ainda esta em fase pessoal e experimental. Se for publicado como open source, contribuicoes devem seguir estes principios:
- Nao adicionar payloads reais, UIDs reais ou segredos ao repo.
- Manter a distincao honesta entre ofuscacao e criptografia.
- Preservar a simplicidade do firmware.
- Priorizar previsibilidade operacional sobre features chamativas.
O software e o firmware deste repositorio sao distribuidos sob AGPL-3.0-or-later. Veja LICENSE.
Nao ha licenca de hardware separada nesta fase, porque o projeto usa apenas Raspberry Pi Pico e botoes discretos, sem PCB, case ou desenho mecanico original. Se schematics/ evoluir para um projeto de hardware autoral, uma licenca de hardware aberta devera ser definida explicitamente.
Este projeto e fornecido para estudo, automacao pessoal e uso autorizado. O autor nao incentiva uso em sistemas de terceiros sem permissao, contorno de controles organizacionais ou armazenamento de credenciais sensiveis no dispositivo.