Câmbio, óleo, flex e I/O configurável: o checklist que define uma ECU standalone, atacado inteiro antes da placa existir

ECU standalone se compara por checklist — quantas entradas, quantas saídas, protege óleo?, corta pra trocar de marcha?, roda E85? Nos últimos dois dias atacamos esse checklist inteiro: proteção de óleo condicional a RPM, quickshifter por corte de ignição, flex fuel por lambda e o modelo de I/O configurável que não desliga fail-safety. Tudo testado em CI, hardware ainda em trânsito.

Quem compra ECU standalone compara tabela de especificação. Quantas entradas configuráveis, quantas saídas, controla câmbio?, protege por pressão de óleo?, roda flex? É assim que uma FuelTech, uma Haltech e uma Link são postas lado a lado — e foi por isso que fixamos paridade com esse checklist como north star do produto (verticalizada em V-twin, que é onde essas ECUs tratam a gente como cidadão de segunda classe).

Nos últimos dois dias, atacamos o checklist inteiro. A placa ainda está em trânsito.

Proteção de óleo: o piso é uma função de RPM

Pressão de óleo escala com a rotação da bomba: ~110 kPa em marcha lenta quente é saudável num Twin Cam; os mesmos 110 kPa a 5500 RPM significam biela passando fome. Um limite escalar não expressa isso — então o piso é uma tabela RPM→kPa mínimo, igual às ECUs de referência fazem.

Dois detalhes de engenharia que importam mais que a feature:

O corte usa o mesmo caminho do overboost. Quando a pressão fura o piso (com debounce, latch e histerese de recuperação), o monitor promove o estado pro mesmo Cutoff que a proteção de sobrepressão de turbo já usava. Zero mecanismo de corte novo pra dar manutenção — e o DTC sai no padrão de sempre (P0521 a P0524).

Sender morto conta como pressão BAIXA. A política de fallback é assume-LOW: quem liga essa proteção tem um motor que vale mais que uma parada incômoda, então um sensor defeituoso não pode silenciosamente desarmar a única rede que protege o virabrequim. Repara que é a direção oposta do corte de mistura pobre — que se recusa a agir com a sonda morta. Fail-safe não é uma regra única; é decidir, proteção por proteção, qual direção de falha machuca menos.

Câmbio: estimar a marcha e cortar ignição — pelo caminho já provado

O Twin Cam piloto não tem sensor de marcha. O GearEstimator infere a marcha engatada pela redução que dá pra observar: RPM do motor dividido pela rotação da roda (via velocidade), casado contra janelas de relação por marcha. E aqui um detalhe que me agrada: janelas sobrepostas são erro de validação do tune, não um desempate em runtime. Se duas marchas podem reclamar a mesma leitura, o arquivo nem carrega.

O quickshifter corta ignição — nunca combustível — pelo tempo configurado por marcha: a carga continua fluindo, o torque colapsa, o engate entra sem embreagem. O corte é aplicado pela mesma flag de inibição que o gate de sincronização do decoder já usava dentro do scheduler. De novo o mesmo princípio: superfície nova, mecanismo provado. E os gates falham todos pra direção OFF: switch preso gera exatamente um corte, sem marcha estimada não corta, e a largura é clampada em 200 ms mesmo que um tune editado na mão tente passar mais.

Flex: o limite de mistura pobre agora segue o combustível

Esse era um footgun documentado no código esperando a vez: o corte de proteção por mistura pobre disparava em AFR 15.5 — calibrado pra gasolina. Em E85, 15.5 é λ ≈ 1.6: o motor derrete bem antes de o “protetor” acordar.

Agora o limite é lambda constante: o trip point é derivado do estequiométrico do combustível ativo. Em gasolina, o resultado é bit-idêntico ao limite legado (tem teste comparando os bits do float); em E85 vira ~10.2, em metanol ~6.8. A mesma margem física, qualquer combustível no tanque.

I/O configurável sem desligar a fail-safety

A peça maior do arco. O modelo, fixado em ADR: a placa publica capacidade, o tune publica binding. Cada placa exporta a lista de canais físicos que tem; o basemap liga canal→papel. E os papéis são um enum fechado — pressão de óleo, conteúdo de etanol, switch de embreagem, pedido de shift, velocidade, e assim por diante (10 papéis de entrada hoje). O core consome papéis, nunca canal cru.

Por que não copiar o modelo clássico de “entrada 7, saída 12” numerada? Porque papel fechado permite o que canal numerado não permite: o fallback de falha é parte do binding, como enum de segurança — assume-baixo, assume-alto ou assume-valor. Sensor fora dos rails de plausibilidade, calibração malformada, canal morto: tudo colapsa pra suposição segura declarada no tune. Um tune errado degrada; não desarma fail-safety. E o schema (v2) pina isso: um consumidor antigo rejeita um arquivo com io_channels em vez de ignorar silenciosamente uma política de fallback que é safety-relevante.

As saídas seguem a mesma doutrina: 7 funções, cada uma uma state machine pequena e testável em host. A ventoinha falha ligada quando a temperatura não é confiável (resfriar à toa é inofensivo; não resfriar não é). A saída de nitro só espelha o flag do controlador progressivo — o handshake de segurança continua inviolável, não existe segunda lógica de armamento pra divergir. O air shifter dispara exatamente um pulso por corte, switch preso não re-dispara. E saída nenhuma realimenta o loop: são torneiras de leitura do estado que o loop já computou.

A ECU também começou a falar CAN de verdade

O firmware ganhou a task de broadcast CAN: as cadências (100/50/10/1 Hz

  • frame de boot + DTCs em round-robin) vêm da spec do protocolo, não de constantes soltas. E o caso feio foi tratado primeiro: numa bancada sem transceiver — ou num chicote em curto na moto — o periférico nunca completa transmissão. A política é timeout por mailbox, aborta, backoff exponencial, reinicializa o periférico — e nada nesse caminho bloqueia o executor: o watchdog segue alimentado e o loop de controle nem fica sabendo que o barramento morreu.

Tuner, biblioteca cloud — e um bug real de perda de dados

O Tuner ganhou as abas de Transmission, Oil Pressure e Flex no editor, e uma biblioteca de basemaps ligada na cloud — a API pública já serve os tunes curados, com download gated e update por hash. E no caminho apareceu um bug que justifica o arco sozinho: o round-trip de abrir-e-salvar um tune descartava silenciosamente as seções que o parser não conhecia. Perda de dados de calibração, quieta. Corrigido com testes de regressão dos dois lados (Rust e TypeScript).

O que continua sendo bancada

Honestidade de sempre: o lado físico de tudo isso é fio e silício que ainda não chegou. O PWM/GPIO real das saídas fica pro bring-up. A Nucleo não tem transceiver CAN — e o emulador não modela o periférico bxCAN de forma confiável, então a prova de TX é analisador lógico na bancada. As curvas reais de sender de óleo vêm do manômetro da minha TC124. O quickshifter v1 é switch digital (front-end de strain-gauge é hardware que a placa atual não tem). Nada disso é segredo: está documentado no código, função por função.

Por que isso importa

O ecu-firmware passou de mil testes nesse arco (1072, ~674 só no core). Mas o número que eu mais vigio é outro: golden traces byte-idênticos em todas as ondas. Tune sem as seções novas = firmware que se comporta bit a bit como antes, por construção. É assim que se adiciona um checklist inteiro de features numa ECU sem tocar no caminho crítico de quem já confia nela.

Checklist de spec vende ECU. O que segura cliente é o que não está na tabela: cada checkbox desses chegou com o modo de falha decidido, escrito e testado antes de encostar num motor.

Lista de espera

Quer saber em primeira mão.

Pistonix está em desenvolvimento ativo. Inscreva-se pra receber atualizações de produto, basemaps prévios, convites pra rodar nos eventos do Milwaukee Garage Drag Racing e prioridade na lista de compra do Pistonix Forge.

  • Atualizações mensais de roadmap e firmware
  • Convite para sessões de tuning na pré-venda
  • Prioridade para o lote inicial do Pistonix Forge
  • Acesso antecipado a basemaps por motor

Ao se inscrever você concorda em receber emails do Pistonix. Não compartilhamos seu email. Você pode descadastrar a qualquer momento. (LGPD)