Rubik's Resolverescaneie, resolva, anime, integre

Guia de arquitetura do firmware

Como estruturar o firmware ESP32 deste projeto

Esta página explica, de forma visual e prática, como organizar o código embarcado para executar o plano mecânico vindo do sistema web.

Leitura rápida para quem vai implementar

Se você entrou agora no projeto, estes três pontos resumem o papel do firmware e evitam confundir responsabilidade de backend com controle físico.

O ESP32 não resolve o cubo

Ele recebe um plano mecânico pronto e apenas executa a parte física com segurança.

O contrato já está definido

jobId, actions e status started/finished/error já estão preparados no Next.js.

A ordem de implementação importa

Comece por comunicação, machine state e homing antes de controlar todas as ações físicas.

1. Visão geral da função do ESP32

O ESP32 faz

  • Recebe o `mechanicalPlan` já pronto.
  • Executa ações físicas com precisão.
  • Publica status (`queued`, `started`, `finished`, `error`).
  • Aplica segurança (homing, timeout, parada segura).

O ESP32 não faz

  • Não faz scanner de câmera.
  • Não resolve o cubo logicamente.
  • Não recalcula sequência de solução.
  • Não deve acoplar regras de UI.

2. Papel do ESP32 na arquitetura geral

Website / BackendMechanicalPlanESP32Motores + Sensores

Website / Frontend

Responsável por: Scanner guiado, revisão manual, visualização e animação.

Não deve fazer: Não controla hardware diretamente.

Backend / Solver / Planner

Responsável por: Valida CubeState, gera logicalMoves e mechanicalPlan.

Não deve fazer: Não pilota motores em tempo real.

Firmware ESP32

Responsável por: Executa mechanicalPlan com segurança e precisão mecânica.

Não deve fazer: Não resolve cubo, não faz scanner, não recalcula solução.

3. Estrutura recomendada do firmware

A separação por módulos evita acoplamento entre comunicação, execução, controle físico e segurança.

comm

Recebe comandos, parseia payload e publica status.

Isola protocolo de comunicação do controle físico.

plan_executor

Executa a lista de ações em ordem e controla índice atual.

Mantém execução determinística e auditável por job.

motor_controller

Abstrai direção, velocidade, aceleração e precisão de motores.

Evita espalhar detalhes de driver por todo firmware.

clamp_controller

Abre/fecha garras com sequência segura.

Garante fixação estável do cubo antes de girar eixos.

homing_controller

Leva eixos à referência conhecida no boot e quando necessário.

Sem homing, o estado mecânico fica ambíguo.

safety_controller

Timeout, falha de sensor, inconsistência e parada segura.

Protege máquina, usuário e cubo contra erro de execução.

machine_state

Estado global da máquina e transições permitidas.

Facilita debug, telemetria e integração com o backend.

config

Pinos, limites, perfis de velocidade e parâmetros físicos.

Centraliza calibração sem alterar regras de negócio.

4. Fluxo interno do firmware

1

Boot do ESP32

2

Load de config + init de drivers

3

Homing inicial

4

Estado ready

5

Recebe mechanicalPlan

6

Valida estrutura + entra em queued

7

Publica started

8

Executa ação por ação

9

Publica finished ou error

5. Estados da máquina

Estado explícito aumenta previsibilidade operacional, facilita debug e define transições seguras.

idle

Firmware ligado, sem plano carregado.

homing

Ajustando referência mecânica inicial.

ready

Pronto para receber e validar plano.

queued

Plano aceito, aguardando início de execução.

started

Execução iniciada; frontend pode disparar animação.

executing

Ações sendo executadas em sequência.

finished

Plano finalizado com sucesso.

error

Falha detectada; exige tratamento e recuperação.

6. Contrato de integração

Plano recebido pelo ESP32

{
  "jobId": "cube-001",
  "actions": [
    { "type": "home", "target": "all" },
    { "type": "clamp", "name": "A", "state": "close" },
    { "type": "rotate_cube", "axis": "x", "degrees": 90 },
    { "type": "turn_face", "actuator": "right", "degrees": 90 },
    { "type": "wait", "durationMs": 120 }
  ]
}

Status devolvido pelo ESP32

{
  "jobId": "cube-001",
  "status": "started",
  "updatedAt": "2026-04-08T18:00:00.000Z"
}

O frontend já está preparado para iniciar animação ao receber started. Também espera finished e error.

7. Módulos principais do firmware

1. comm

Recebe comandos, parseia payload e publica status.

Isola protocolo de comunicação do controle físico.

2. plan_executor

Executa a lista de ações em ordem e controla índice atual.

Mantém execução determinística e auditável por job.

3. motor_controller

Abstrai direção, velocidade, aceleração e precisão de motores.

Evita espalhar detalhes de driver por todo firmware.

4. clamp_controller

Abre/fecha garras com sequência segura.

Garante fixação estável do cubo antes de girar eixos.

5. homing_controller

Leva eixos à referência conhecida no boot e quando necessário.

Sem homing, o estado mecânico fica ambíguo.

6. safety_controller

Timeout, falha de sensor, inconsistência e parada segura.

Protege máquina, usuário e cubo contra erro de execução.

7. machine_state

Estado global da máquina e transições permitidas.

Facilita debug, telemetria e integração com o backend.

8. config

Pinos, limites, perfis de velocidade e parâmetros físicos.

Centraliza calibração sem alterar regras de negócio.

8. Organização sugerida de código

Árvore de diretórios

firmware/
  src/
    main.cpp
    comm/
      comm_manager.cpp
    executor/
      plan_executor.cpp
    motors/
      motor_controller.cpp
    clamps/
      clamp_controller.cpp
    homing/
      homing_controller.cpp
    safety/
      safety_controller.cpp
    state/
      machine_state.cpp
    config/
      machine_config.h

Regra prática

  • `main.cpp` orquestra boot e loop principal.
  • Cada pasta expõe API clara e pequena.
  • Estado global centralizado em `machine_state`.
  • Parâmetros físicos isolados em `config`.

9. Ações mecânicas que o firmware deve entender

Tipos de ação

  • `home`
  • `clamp`
  • `rotate_cube`
  • `turn_face`
  • `wait`

Modelagem sugerida (firmware)

enum class ActionType {
  Home,
  Clamp,
  RotateCube,
  TurnFace,
  Wait
};

struct MechanicalAction {
  ActionType type;
  // campos específicos por tipo
};

logicalMoves (backend)

Representação lógica de solução do cubo.

["R", "U", "R'", "U'", "F2"]

mechanicalPlan (firmware)

Ações físicas executáveis por atuadores.

turn_face / clamp / home / wait

10. Segurança e confiabilidade

Homing obrigatório antes de execução.
Timeout por ação e timeout global por job.
Validação de plano antes de entrar em `queued`.
Botão de emergência / parada segura.
Fallback para estado `error` com diagnóstico.
Logs e status para depuração remota.

11. O que o firmware não deve fazer

Não resolver o cubo.
Não interpretar scanner/câmera.
Não recalcular movimentos lógicos.
Não depender da UI a cada passo mecânico.
Não misturar lógica de cubo com controle físico.

12. Resumo prático para implementar

  1. Comunicação básica (receber plano + enviar status).
  2. Machine state e transições permitidas.
  3. Homing inicial confiável.
  4. Controle de 1 motor com perfil de movimento.
  5. Execução de ações simples (`home`, `wait`, `clamp`).
  6. Integração de ações completas (`turn_face`, `rotate_cube`) e safety.

13. Integração final com o projeto web

O que precisa bater entre os dois lados

  • Mesmos tipos de ação (`home`, `clamp`, `turn_face`, etc.).
  • Mesmo contrato de status (`queued`, `started`, `finished`, `error`).
  • `jobId` preservado em todo o ciclo.
  • Semântica de erro consistente para troubleshooting.

Comparações essenciais

  • Backend decide a lógica; firmware executa física.
  • Estado lógico do cubo ≠ posição física de atuadores.
  • Website orienta fluxo; ESP32 garante segurança operacional.
  • Frontend anima por `logicalMoves`; máquina executa `mechanicalPlan`.