Manual de bancada · Projeto TORQ

Bancada de validação da ECU — montagem, ligação e roteiro de ensaio

Como montar, ligar, configurar e validar o firmware da ECU TORQ com peças baratas, antes de mandar fabricar a placa. O objetivo não é ver o LED piscar: é antecipar defeito. Cada etapa existe porque pega uma classe específica de erro que, se escapar, aparece depois — com a placa já feita, ou com a moto na rua.

Custo ~R$ 810 na versão mínima Tempo 1 fim de semana até a etapa 4 Fonte bench/BANCADA.md
Leia antes de comprar qualquer coisa

A bobina de ignição da CG 160 entrega 20 a 30 kV no secundário. A seção de segurança não é formalidade burocrática — ela está logo abaixo e precisa ser lida inteira antes de você energizar a bancada pela primeira vez. Se você tem marca-passo ou desfibrilador implantado, não opere o estágio de ignição.

01Segurança — as oito regras

Perigo · pode machucar você

1. Nunca segure o cabo de vela com o sistema energizado, nem com a mão nem com alicate. A energia por centelha é baixa (~30 mJ) e normalmente não mata — mas o choque é violento e involuntário, e o que machuca é a reação: bater o braço na bancada, derrubar a fonte, cair da banqueta.

2. Óculos de proteção ao ligar a bobina pela primeira vez. Eletrolítico invertido e encapsulamento de IGBT já arrancaram olho.

3. Nunca gasolina em bancada aberta. O bico atomiza combustível em névoa, e névoa de gasolina a um metro de uma bobina soltando centelha é uma bomba. Bico seco na etapa 6. Se precisar ver o spray, use fluido de calibração, em local ventilado, com a ignição desenergizada e extintor ABC ao alcance.

Atenção · pode queimar o equipamento

4. Fusível de 5 A na entrada de 12 V, sempre. Um IGBT em curto puxa dezenas de ampères continuamente; sem fusível o que queima é o chicote, e fumaça de PVC em ambiente fechado é problema respiratório de verdade.

5. Dwell limitado — nunca energize a bobina com a saída em nível estático. O primário da CG 160 tem 0,49 Ω. A 14 V com o transistor saturado indefinidamente são ~28 A: o verniz derrete, o primário entra em curto entre espiras e a bobina morre, às vezes explodindo o encapsulamento. O firmware satura em 8 ms e o HAL de bancada satura de novo em 3,5 ms — duas camadas independentes, porque um defeito no core não pode desligar a segunda.

6. Sempre com vela conectada, dentro de caixa metálica aterrada. Bobina disparando com o secundário aberto gera tensão ainda mais alta (a energia não tem por onde escoar) e fura o isolamento da própria bobina. A caixa também contém a interferência: uma centelha aberta reseta o microcontrolador e corrompe a serial, e você vai caçar um defeito de firmware que não existe.

7. Terra único, em estrela, com fio grosso. O retorno da bobina não pode dividir trilho com o terra do microcontrolador: o pico de corrente do dwell gera queda de tensão que o MCU lê como reset. É a causa número um de "a placa reseta quando a ignição dispara".

8. Nunca deixe a bancada energizada sem supervisão. Desligue a fonte antes de mexer em qualquer fio e descarregue os eletrolíticos.

Por que fonte de bancada, e não fonte de PC

Fonte de PC não limita corrente e mascara curto-circuito: o estágio de ignição em falha some com 20 A sem a fonte reclamar. Uma fonte de bancada com limitador ajustado em 2 A é o que transforma um erro de montagem em "a fonte entrou em limitação" em vez de "queimou tudo". É o item que mais economiza dinheiro no conjunto todo.

02Lista de peças e onde comprar

Fornecedores brasileiros, preços em real. Itens marcados estimado não têm link fixo — o preço oscila com o anúncio. Os demais vêm de fornecedor com página própria.

Versão mínima — R$ 802

Chega até a etapa 6 do roteiro: protocolo, roda fônica, ignição com bobina real e injetor seco.

ItemPart numberFornecedorPreço
Placa STM32 Black Pill F411 USB-C
roda o firmware da ECU — opção econômica
STM32F411CEU6Usinainfo72,32
Arduino Nano V3 + cabo
gera o sinal da roda fônica — é o coração da bancada
Nano V3Eletrogate36,50
Bobina de ignição CG/Titan/Fan 160
primário de 0,49 Ω — é ela que exige limitação de corrente
MagnetronRepeçasMotos50,89
Bico injetor CG 160
meça a impedância antes de acionar
Magnetron 90225180VarejoPeças117,32
IGBT ISL9V3040P3 (TO-220) × 2
driver de ignição em placa perfurada
ISL9V3040P3Mouser (est.)90,00
Osciloscópio FNIRSI DSO152
200 kHz — serve para roda fônica e injetor; é pouco para o flyback da bobina
DSO152Mercado Livre251,00
Protoboard 830 pontosEletrogate11,90
Módulo relé 2 canais 5 V
bomba e ventoinha
Eletrogate11,90
Jumpers, LEDs, resistores, potenciômetros
os potenciômetros simulam TPS e os NTC
Eletrogate (est.)60,00
Multímetro(est.)45,00
Fonte 12 V 5 A(est.)55,00
Total da versão mínimaR$ 801,83

Versão completa — acrescenta R$ 1.775

Necessária para as etapas 7 e 8, e para medir avanço com precisão.

ItemPor que valeFornecedorPreço
Nucleo-G474RE Mesma família do microcontrolador de produção — o firmware roda sem alterar o HAL Mouser / DigiKey BR250,00
Osciloscópio Hantek 6022BE 20 MHz Recomendado. 20 MHz e 2 canais cobrem tudo da bancada, inclusive o ponto E KaBuM480,00
Fonte de bancada 30 V 5 A Permite simular bateria fraca (6 V na partida) e sobretensão Mercado Livre550,00
Raspberry Pi Pico Melhor gerador de roda fônica: o PIO faz o padrão em hardware, sem jitter MakerHero45,00
ESP32 DevKitCPonte BLE — é o que o aplicativo enxerga Curto Circuito60,00
Sensor MAPetapa 7 — sensores reaisMercado Livre130,00
Sonda lambda banda estreita CG 160etapa 7Mercado Livre120,00
PCB protótipo, 5 peças + fretesó depois de validar na protoboardJLCPCB140,00
Total da versão completaR$ 2.576,83

Consumíveis — comprar junto, valores pequenos

Não estão nos totais acima porque são de loja de bairro ou já entram no kit de jumpers. Fornecedor típico: Baú da Eletrônica, Eletrogate, ou qualquer loja de componentes.

ItemObservação crítica
MOSFET IRLZ44N Não use IRF540. Precisa ser logic level — é o "L" do nome. Com 3,3 V no gate o IRF540 nunca satura, esquenta e morre. É o erro de bancada mais comum de todos
TVS 400 V + diodo 1N4007grampo do injetor — obrigatório
Fusível 5 A + porta-fusívelo único item não negociável do conjunto
Vela + cachimbo + caixa metálica aterradaa caixa contém a interferência, não só a centelha
Resistores 10k, 4k7, 1k, 470R, 100R, 10Rdivisores e acionamento de gate
Capacitores 100n cerâmico, 10 µF, 470 µF eletrolíticoo de 470 µF vai junto da bobina — sem ele a fonte afunda no dwell
Alternativa mais segura e mais barata

Em vez de montar o driver de gate discreto, use um módulo de ignição automotivo pronto — o "TCI" de moto, ou o módulo Bosch de 4 pinos. Ele já traz driver de gate, grampo de tensão e limitação de corrente internos. Você liga o pino do microcontrolador (via resistor de 1 k e, idealmente, um optoacoplador 6N137) direto na entrada de sinal. Foi exatamente para isso que ele foi projetado.

03Como as peças se conectam

   +------------------+   roda     +-------------------+   UART    +--------------+
   | Arduino Nano     |  fonica    | STM32 (Nucleo)    |  921600   | ESP32        |
   | sketch_crank_sim |----------->| sketch_ecu        |<--------->| ble_bridge   |
   +------------------+  (dente)   |  core real +      |           +--------------+
          ^  pot 10k               |  hal_arduino      |                 | BLE
          |                        +-------------------+                 v
       [ RPM ]                       |     |      |                 app Flutter
                                     |     |      +--> ADC: pots simulando sensores
                                     |     +---------> MOSFET --> injetor
                                     +---------------> IGBT   --> bobina --> vela
                                                                  (caixa aterrada)
              USB do STM32 --------------------------------------> PC (protocolo/console)

04Ordem de montagem

Monte nesta ordem e energize só no fim de cada bloco. Montar tudo e ligar de uma vez transforma um defeito isolado em três simultâneos.

1Terra em estrela, antes de qualquer componente

Escolha um ponto da protoboard como terra único e leve todos os retornos até ele com fio grosso e curto. Este é o passo que mais gente pula e o que mais gera defeito fantasma depois.

2Alimentação com fusível

Fonte 12 V → fusível de 5 A → trilho vermelho da protoboard. Ajuste o limitador de corrente da fonte em 2 A antes de ligar qualquer coisa. Coloque o eletrolítico de 470 µF no trilho, o mais perto possível de onde a bobina vai ficar.

3Placas e comunicação

Fixe as três placas. Ligue a UART entre STM32 e ESP32 com TX de um no RX do outro, e terra comum obrigatório. Sem terra comum o sinal flutua e a decodificação enlouquece.

4Sinal de rotação, com divisor

O Arduino Nano trabalha em 5 V e o STM32 em 3,3 V, e o pino de trigger não é tolerante a 5 V. Monte o divisor 10 k / 20 k entre eles. "Funcionou na minha placa" não é projeto.

Alternativa: use um Raspberry Pi Pico no lugar do Nano — já é 3,3 V e ainda gera o padrão de dentes por hardware (PIO), sem jitter.

5Sensores simulados

Potenciômetros de 10 k alimentados em 3,3 V, cursor indo ao pino do conversor A/D através de um resistor de 1 k, com capacitor de 100 n para o terra. Esse RC dá 160 µs de filtro — corta ruído sem atrasar a malha de 1 kHz.

6Saídas de potência — só depois que as etapas 1 a 3 de validação passarem

Primeiro LEDs com resistor de 470 Ω nas saídas de ignição e injeção. Bobina e bico entram apenas nas etapas 5 e 6 do roteiro de validação.

Detalhes que não são opcionais

05Tabela de ligação

DePinoParaPinoObservação
Arduino NanoD9STM32PA0 Sinal da roda fônica. 5 V → divisor 10 k / 20 k obrigatório
Arduino NanoGNDSTM32GND Terra comum obrigatório
STM32PA9 (TX)ESP32GPIO16 (RX)UART 921600
STM32PA10 (RX)ESP32GPIO17 (TX)cruzado
STM32PB0gate do IGBTvia 1 kignição 1 · pull-down de 10 k no gate
STM32PB4gate do MOSFETvia 100 Rinjetor 1 · pull-down de 10 k no gate
STM32PA1potenciômetro TPScursorpontas em 3,3 V e GND
STM32PA4potenciômetro MAPcursor
STM32PC0potenciômetro ECTcursortemperatura do motor
STM32PB2potenciômetro IATcursortemperatura do ar
STM32PC2divisor de VBAT39k / 10kdivide por 4,9 — confira com multímetro
Fonte 12 V+fusível 5 Ao fusível vem antes de tudo
Fusívelbobina (+) e injetor (+)trilho vermelho
Coletor do IGBTbobina (−)fio curto e grosso — é o maior emissor de interferência da bancada
Bobina secundárioveladentro de caixa metálica aterrada

Pinagem do ESP32 quando ele roda a ECU sozinho: ignição em 26/27, injeção em 25/33, trigger em 35 (só entrada), TPS em 36, MAP em 39, IAT em 34, ECT em 15, VBAT em 12.

06Software — instalar, compilar e gravar

Instalação

Instale o PlatformIO, que resolve toolchain e bibliotecas sozinho. Pela linha de comando:

pip install platformio

Ou instale a extensão PlatformIO IDE no VS Code, que traz tudo junto.

Gravar as três placas

cd bench/sketch_ecu
pio run -e nucleo_g474re -t upload
pio device monitor -b 921600
cd bench/sketch_crank_sim
pio run -e nano -t upload

cd bench/sketch_ble_bridge
pio run -t upload
Por que a bancada prova alguma coisa

O platformio.ini do sketch_ecu aponta src_dir para a raiz do repositório e seleciona os arquivos a dedo. A bancada compila o mesmo código que vai para a placa de produção — nenhum arquivo do firmware é duplicado. No dia em que a bancada e o produto divergirem, a bancada para de provar qualquer coisa.

Ambientes disponíveis

AmbientePlacaQuando usar
nucleo_g474reNucleo-G474REPreferido. Parente próximo do STM32G4 do PowerBox — o que validar aqui migra quase sem mudança
blackpill_f411ceBlack Pill F411CEAlternativa barata. Grava por DFU ou ST-Link
esp32devESP32ECU e ponte BLE no mesmo chip. Cômodo para a etapa 2. Nunca use para medir qualidade de avanço — o alarme de timer do ESP32 é relativo, não absoluto, e a pilha BLE disputa CPU com o agendamento de ignição
nucleo_g474re_motoNucleo-G474RESó para a etapa 8. Desliga o SAFE_MODE. Existe como ambiente separado justamente para ninguém usar por acidente

Constantes que você precisa conferir

Em bench/hal_arduino/hal_arduino.h:

ConstantePadrãoO que faz
SAFE_MODE1Liga a segunda camada de limites. Só desligue na etapa 8
HAL_SAFE_DWELL_MAX_US3500Teto de dwell, ~50 % do nominal da CG 160
HAL_SAFE_INJ_MAX_US6000Teto de pulso do injetor
HAL_SAFE_DUTY_MAX_PCT35Duty médio máximo por saída
HAL_TRIGGER_EDGERISINGBorda do sensor. Simulado e Hall dão subida; VR condicionado dá descida
HAL_OUT_ACTIVE_HIGH1Mude aqui se usar optoacoplador inversor — nunca no core
HAL_DIV_VBATAjuste ao divisor que você montou de verdade
Atenção · o erro que faz você caçar defeito no lugar errado

O core assume conversor A/D de 12 bits referenciado a 5,000 V; o microcontrolador da bancada lê em 3,3 V. Quem reconcilia é o HAL, usando as constantes HAL_DIV_*. Se elas não baterem com o divisor que você montou, o aplicativo mostra 8 V de bateria com a fonte em 14 V — e você vai procurar o defeito no lugar errado.

Confira com multímetro na primeira ligação. Se o app mostra 13,0 V e o multímetro mostra 14,0 V, multiplique HAL_DIV_VBAT por 14,0/13,0.

Atenção · o defeito traiçoeiro

HAL_TRIGGER_EDGE precisa casar com cal.trigger_edge. Se as duas discordarem, o avanço sai com meio dente de erro constante — e isso é traiçoeiro porque a moto funciona, só que fraca. Você só descobre medindo.

Comandos do simulador de roda fônica

r <rpm>              rotação fixa
ramp <rpm> <ms>      rampa — o transiente é o teste de verdade
sweep <a> <b> <ms>   varredura contínua
p <N> <M>            padrão N dentes com M faltando (CG 160 = p 12 1)
pot on|off           usa o potenciômetro para controlar o RPM
inv                  inverte a polaridade do sinal
noise <n>            injeta n pulsos espúrios
miss <n>             suprime n dentes
stat                 estatísticas
help                 lista os comandos

07Roteiro de validação — oito etapas

Faça na ordem. Não pule. Cada etapa só se justifica porque a anterior passou.

1Protocolo por USB, sem nada ligado

Só o STM32 na protoboard, alimentado pelo USB. Sem bobina, sem bico, sem simulador. Com BENCH_CONSOLE 1, confira que a ECU dá boot, que aparecem os códigos de falha de sensor fora de faixa (é o esperado — não há sensor nenhum) e que rpm=0 sync=0. Depois ponha BENCH_CONSOLE 0, recompile e mande um HELLO binário: deve voltar um INFO de 32 bytes.

Valida
toolchain, HAL de tempo, parser do protocolo, CRC-16, gravação que sobrevive a reset
Pega
clock errado, endianness, struct com padding, baud incorreto, EEPROM emulada não gravando
2Aplicativo conecta por BLE

Ligue o ESP32 com a ponte na UART do STM32, TX e RX cruzados, terra comum. Abra o aplicativo.

Valida
mapa GATT, MTU, CCCD, autenticação HMAC, reconexão
Pega
travamento em "atualizando descriptor", MTU não negociado, frame maior que o MTU sem fragmentação, segredo de fábrica divergente entre app e firmware
3Roda fônica decodificada

Ligue o simulador. Ainda sem bobina e sem bico.

r 1000
p 12 1
ramp 6000 800
noise 1
miss 1

Compare o RPM gerado com o que a ECU decodifica. Tolerância de 1 %. Na rampa o erro pode subir transitoriamente, mas o sync não pode cair. O pulso espúrio tem de aparecer em trigger_glitches, não em sync_losses.

Pega
O defeito mais caro de todos: decodificador que perde a referência em transiente. Numa moto isso é "morre ao acelerar", e leva semanas para diagnosticar sem bancada
4LED no lugar da bobina

LED com resistor de 470 Ω nas saídas de ignição e injeção. Ainda sem potência. Em 300–600 rpm o LED pisca visivelmente. É aqui que entra o osciloscópio pela primeira vez — e onde se mede avanço e dwell sem risco nenhum.

Pega
saída invertida (LED aceso que apaga na centelha), dwell no lugar do pulso, canal trocado entre cilindros, evento perdido em alta rotação
5Bobina real, com vela, em caixa aterrada

Releia a seção de segurança. Fonte limitada em 2 A, vela montada e aterrada, óculos. Comece em 300 rpm e suba devagar, de olho na corrente da fonte: em 12-1 a 3000 rpm com dwell de 3,5 ms, a média fica em torno de 1 A. Se a fonte entrar em limitação, desligue — é dwell longo demais ou IGBT conduzindo parcialmente.

Pega
MCU resetando na centelha (terra ruim), serial corrompendo (blindagem), IGBT esquentando (driver fraco), bobina esquentando (dwell)
6Injetor seco

Bico sem líquido nenhum. Em rotação baixa, cada abertura é um clique nítido. Meça o pulso e compare com inj_pw_us da telemetria. Varie o TPS pelo potenciômetro e veja a largura acompanhar a tabela de VE.

Pega
MOSFET não saturando — o bico "chia" em vez de clicar, e a causa é quase sempre IRF540 no lugar do IRLZ44N; grampo ausente; pulso abaixo de 1 ms, que não abre o bico
7Sensores reais

Troque os potenciômetros pelos sensores de verdade. Desligue um sensor e confirme que o código de falha aparece.

Pega
curva NTC invertida, TPS fora de calibração, sensor VR que não sincroniza na partida por limiar fixo, ruído de MAP sem janela de amostragem
8Moto real

Só depois de 1 a 7 passarem. Compile o ambiente nucleo_g474re_moto. Antes de dar partida, com a chave ligada e o motor parado, confirme por telemetria que bateria, temperaturas e TPS estão plausíveis. Tenha o botão de corte de emergência no seu alcance, não no da moto.

Pega
o que a bancada não simula — vibração, temperatura, ruído do alternador, queda de tensão na partida

08Medição com osciloscópio

Perigo

Nunca encoste a ponta no cabo de vela ou no secundário da bobina. Para isso existe ponta de alta tensão 1000:1 ou pinça indutiva. Ponta sempre em 10× quando houver potência, e o fio de terra da ponta o mais curto possível — rabicho comprido é antena e mostra oscilação que não existe.

PontoEscalaEsperadoSintoma ruim
A · saída do simulador2 V/div
1 ms/div
quadrada 0–3,3 V, duty 50 %, vão de 2 períodos por volta, subida < 1 µs acima de 3,6 V = falta divisor; bordas em rampa = capacitância de cabo; degraus = ruído
B · gate do IGBT5 V/div
1 ms/div
0 → 12 V em < 1 µs, platô limpo. A largura do platô é o dwell; com SAFE_MODE nunca acima de 3,5 ms platô de Miller longo = driver fraco, IGBT dissipando na região linear
C · coletor do IGBT100 V/div
ponta 10×
repouso 12 V; no dwell cai a < 2 V; no corte, pico de 300–400 V grampado acima de 400 V = grampo ausente; saturação acima de 3 V = gate mal acionado
D · dreno do MOSFET50 V/div
1 ms/div
repouso 12 V; no pulso cai a < 0,5 V; fechamento grampado em ~50 V. Em marcha lenta, 2–3 ms nível baixo acima de 1 V = MOSFET não saturou; sem pico = grampo em curto
E · avanço × dente
a medida que importa
1 ms/div
a 3000 rpm
CH1 no trigger, CH2 no gate. Dispare na falha da roda.
graus = Δt_us × rpm × 6 / 1.000.000
divergência constante = offset mal configurado; divergência que cresce com o RPM = latência de ISR ou erro de previsão do agendador — é o defeito que a bancada existe para pegar
F · trilho de 12 V1 V/div
acoplamento AC
afundamento menor que 0,5 V no início do dwell mais de 1 V = falta o eletrolítico de 470 µF ou o fio é fino demais

09Diagnóstico rápido

SintomaCausa mais provável
sync nunca fechapadrão N-M diferente entre simulador e calibração; borda invertida
sync cai só em aceleraçãotolerância do decodificador apertada demais; jitter do gerador
trigger_glitches subindocabo do sensor perto do cabo de vela; falta blindagem
MCU reseta ao disparar a bobinaterra não é estrela; falta o eletrolítico de 470 µF
App trava em "atualizando descriptor"callback de CCCD fazendo I/O; notificação antes da subscrição
Bateria errada no aplicativoHAL_DIV_VBAT não bate com o divisor montado
Bico chia em vez de clicarMOSFET não é logic-level, ou pulso menor que 1 ms
Bobina esquentadwell longo; se safe_dwell_clamps está subindo, o core está pedindo mais do que deveria
safe_duty_trips maior que zerorotação decodificada absurda (ruído) ou agendamento patológico. Investigue antes de religar.

10Contratar a montagem — escopo e aceitação

Se você vai passar isto para uma empresa ou profissional montar, o que segue é o que precisa estar no combinado. O ponto mais importante não é a lista de peças: é o critério de aceitação, porque é ele que define quando o serviço está pago.

O que você entrega ao contratado

O que ele entrega a você

Critério de aceitação — o serviço está pronto quando

EtapaProva objetiva exigida
1Um HELLO devolve INFO de 32 bytes; a configuração sobrevive a um reset
2O aplicativo conecta e sai de authenticated=0 para 1
3RPM decodificado bate com o gerado dentro de 1 %; em rampa de 800 ms o sync não cai; pulso espúrio aparece em trigger_glitches, não em sync_losses
4Osciloscópio no ponto E: avanço medido bate com adv_deg_x10 da telemetria, e o erro não cresce com o RPM
5Bobina dispara em 300 a 3000 rpm sem a fonte entrar em limitação; microcontrolador não reseta na centelha
6Injetor clica (não chia); largura medida bate com inj_pw_us
Atenção · o item que separa serviço bom de serviço caro

Exija a medição do ponto E — avanço contra dente de referência. Divergência que cresce com a rotação denuncia erro no agendador, e é justamente o defeito que só a bancada pega. Sem essa medida, você pagou por uma bancada bonita que não provou nada.

Fora do escopo — deixe explícito no combinado

As etapas 7 e 8 (sensores reais e moto) não devem entrar no contrato de montagem. A etapa 8 envolve moto sua, risco físico e o firmware sem SAFE_MODE. Também não está no escopo medir a roda fônica da CG 160 — isso é levantamento de engenharia, com objetivo diferente, e merece contrato separado.