Skip to content

Repository files navigation

bartleby-pad hero



"I would prefer not to."


Herman Melville, Bartleby, the Scrivener: A Story of Wall Street (1853)



bartleby-pad

Um macro pad USB HID discreto, feito com Raspberry Pi Pico e CircuitPython.


Status Platform CircuitPython HID CI Licenca: AGPL v3+

Visao Geral

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: CIRCUITPY oculto por padrao no boot.
  • Unlock fisico: segurar o botao top_left / GP2 durante o boot monta CIRCUITPY.
  • 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.

Origem do Nome

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.

Referencias Conceituais

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.

O Problema

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 CIRCUITPY seja montado por engano.

A Solucao

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.

Aviso de Seguranca

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.

Hardware

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

Mapeamento Provisorio

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.

Arquitetura

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

boot.py

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.

code.py

Executa o loop principal:

  1. Inicializa teclado HID, LED PWM e botoes.
  2. Carrega payloads.json.
  3. Deofusca os payloads em RAM com microcontroller.cpu.uid.
  4. Aguarda todos os botoes serem soltos para evitar disparo acidental apos unlock.
  5. Escaneia botoes, aplica debounce e executa a acao da layer ativa.

payload_builder.py

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.

Instalacao e Uso

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:

  1. Instale CircuitPython no Raspberry Pi Pico.
  2. Copie adafruit_hid para CIRCUITPY/lib.
  3. Obtenha o UID do Pico no REPL:
import microcontroller
print(bytes(microcontroller.cpu.uid))
  1. Crie um arquivo local de acoes:
Copy-Item examples/macros.example.json macros.local.json
  1. Gere o payload:
python tools/payload_builder.py --uid SEU_UID_HEX --macros macros.local.json --out payloads.json
  1. Copie para a raiz de CIRCUITPY:
firmware/boot.py -> boot.py
firmware/code.py -> code.py
payloads.json    -> payloads.json
  1. 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.

Formato das Acoes

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.

Desenvolvimento

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_builder

Gerar 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

Roadmap

  • 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.

Fora de Escopo da V1

  • 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.

Documentacao

Contribuindo

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.

Licenca

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.

Disclaimer

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.

About

"i wold prefer not" -bartleby, the scrivener

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages