Manual de bancada · Projeto TORQ
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.
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.
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.
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.
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.
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.
Chega até a etapa 6 do roteiro: protocolo, roda fônica, ignição com bobina real e injetor seco.
| Item | Part number | Fornecedor | Preço |
|---|---|---|---|
| Placa STM32 Black Pill F411 USB-C roda o firmware da ECU — opção econômica |
STM32F411CEU6 | Usinainfo | 72,32 |
| Arduino Nano V3 + cabo gera o sinal da roda fônica — é o coração da bancada |
Nano V3 | Eletrogate | 36,50 |
| Bobina de ignição CG/Titan/Fan 160 primário de 0,49 Ω — é ela que exige limitação de corrente |
Magnetron | RepeçasMotos | 50,89 |
| Bico injetor CG 160 meça a impedância antes de acionar |
Magnetron 90225180 | VarejoPeças | 117,32 |
| IGBT ISL9V3040P3 (TO-220) × 2 driver de ignição em placa perfurada |
ISL9V3040P3 | Mouser (est.) | 90,00 |
| Osciloscópio FNIRSI DSO152 200 kHz — serve para roda fônica e injetor; é pouco para o flyback da bobina |
DSO152 | Mercado Livre | 251,00 |
| Protoboard 830 pontos | — | Eletrogate | 11,90 |
| Módulo relé 2 canais 5 V bomba e ventoinha |
— | Eletrogate | 11,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ínima | R$ 801,83 | ||
Necessária para as etapas 7 e 8, e para medir avanço com precisão.
| Item | Por que vale | Fornecedor | Preço |
|---|---|---|---|
| Nucleo-G474RE | Mesma família do microcontrolador de produção — o firmware roda sem alterar o HAL | Mouser / DigiKey BR | 250,00 |
| Osciloscópio Hantek 6022BE 20 MHz | Recomendado. 20 MHz e 2 canais cobrem tudo da bancada, inclusive o ponto E | KaBuM | 480,00 |
| Fonte de bancada 30 V 5 A | Permite simular bateria fraca (6 V na partida) e sobretensão | Mercado Livre | 550,00 |
| Raspberry Pi Pico | Melhor gerador de roda fônica: o PIO faz o padrão em hardware, sem jitter | MakerHero | 45,00 |
| ESP32 DevKitC | Ponte BLE — é o que o aplicativo enxerga | Curto Circuito | 60,00 |
| Sensor MAP | etapa 7 — sensores reais | Mercado Livre | 130,00 |
| Sonda lambda banda estreita CG 160 | etapa 7 | Mercado Livre | 120,00 |
| PCB protótipo, 5 peças + frete | só depois de validar na protoboard | JLCPCB | 140,00 |
| Total da versão completa | R$ 2.576,83 | ||
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.
| Item | Observaçã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 1N4007 | grampo do injetor — obrigatório |
| Fusível 5 A + porta-fusível | o único item não negociável do conjunto |
| Vela + cachimbo + caixa metálica aterrada | a caixa contém a interferência, não só a centelha |
| Resistores 10k, 4k7, 1k, 470R, 100R, 10R | divisores e acionamento de gate |
| Capacitores 100n cerâmico, 10 µF, 470 µF eletrolítico | o de 470 µF vai junto da bobina — sem ele a fonte afunda no dwell |
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.
+------------------+ 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)
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.
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.
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.
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.
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.
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.
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.
| De | Pino | Para | Pino | Observação |
|---|---|---|---|---|
| Arduino Nano | D9 | STM32 | PA0 | Sinal da roda fônica. 5 V → divisor 10 k / 20 k obrigatório |
| Arduino Nano | GND | STM32 | GND | Terra comum obrigatório |
| STM32 | PA9 (TX) | ESP32 | GPIO16 (RX) | UART 921600 |
| STM32 | PA10 (RX) | ESP32 | GPIO17 (TX) | cruzado |
| STM32 | PB0 | gate do IGBT | via 1 k | ignição 1 · pull-down de 10 k no gate |
| STM32 | PB4 | gate do MOSFET | via 100 R | injetor 1 · pull-down de 10 k no gate |
| STM32 | PA1 | potenciômetro TPS | cursor | pontas em 3,3 V e GND |
| STM32 | PA4 | potenciômetro MAP | cursor | — |
| STM32 | PC0 | potenciômetro ECT | cursor | temperatura do motor |
| STM32 | PB2 | potenciômetro IAT | cursor | temperatura do ar |
| STM32 | PC2 | divisor de VBAT | 39k / 10k | divide por 4,9 — confira com multímetro |
| Fonte 12 V | + | fusível 5 A | — | o fusível vem antes de tudo |
| Fusível | — | bobina (+) e injetor (+) | — | trilho vermelho |
| Coletor do IGBT | — | bobina (−) | — | fio curto e grosso — é o maior emissor de interferência da bancada |
| Bobina secundário | — | vela | — | dentro 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.
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.
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
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.
| Ambiente | Placa | Quando usar |
|---|---|---|
| nucleo_g474re | Nucleo-G474RE | Preferido. Parente próximo do STM32G4 do PowerBox — o que validar aqui migra quase sem mudança |
| blackpill_f411ce | Black Pill F411CE | Alternativa barata. Grava por DFU ou ST-Link |
| esp32dev | ESP32 | ECU 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_moto | Nucleo-G474RE | Só para a etapa 8. Desliga o SAFE_MODE. Existe como ambiente separado justamente para ninguém usar por acidente |
Em bench/hal_arduino/hal_arduino.h:
| Constante | Padrão | O que faz |
|---|---|---|
| SAFE_MODE | 1 | Liga a segunda camada de limites. Só desligue na etapa 8 |
| HAL_SAFE_DWELL_MAX_US | 3500 | Teto de dwell, ~50 % do nominal da CG 160 |
| HAL_SAFE_INJ_MAX_US | 6000 | Teto de pulso do injetor |
| HAL_SAFE_DUTY_MAX_PCT | 35 | Duty médio máximo por saída |
| HAL_TRIGGER_EDGE | RISING | Borda do sensor. Simulado e Hall dão subida; VR condicionado dá descida |
| HAL_OUT_ACTIVE_HIGH | 1 | Mude aqui se usar optoacoplador inversor — nunca no core |
| HAL_DIV_VBAT | — | Ajuste ao divisor que você montou de verdade |
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.
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.
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
Faça na ordem. Não pule. Cada etapa só se justifica porque a anterior passou.
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.
Ligue o ESP32 com a ponte na UART do STM32, TX e RX cruzados, terra comum. Abra o aplicativo.
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.
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.
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.
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.
Troque os potenciômetros pelos sensores de verdade. Desligue um sensor e confirme que o código de falha aparece.
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.
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.
| Ponto | Escala | Esperado | Sintoma ruim |
|---|---|---|---|
| A · saída do simulador | 2 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 IGBT | 5 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 IGBT | 100 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 MOSFET | 50 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 V | 1 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 |
| Sintoma | Causa mais provável |
|---|---|
sync nunca fecha | padrão N-M diferente entre simulador e calibração; borda invertida |
sync cai só em aceleração | tolerância do decodificador apertada demais; jitter do gerador |
trigger_glitches subindo | cabo do sensor perto do cabo de vela; falta blindagem |
| MCU reseta ao disparar a bobina | terra 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 aplicativo | HAL_DIV_VBAT não bate com o divisor montado |
| Bico chia em vez de clicar | MOSFET não é logic-level, ou pulso menor que 1 ms |
| Bobina esquenta | dwell longo; se safe_dwell_clamps está subindo, o core está pedindo mais do que deveria |
safe_duty_trips maior que zero | rotação decodificada absurda (ruído) ou agendamento patológico. Investigue antes de religar. |
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.
| Etapa | Prova objetiva exigida |
|---|---|
| 1 | Um HELLO devolve INFO de 32 bytes; a configuração sobrevive a um reset |
| 2 | O aplicativo conecta e sai de authenticated=0 para 1 |
| 3 | RPM 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 |
| 4 | Osciloscópio no ponto E: avanço medido bate com adv_deg_x10 da telemetria, e o erro não cresce com o RPM |
| 5 | Bobina dispara em 300 a 3000 rpm sem a fonte entrar em limitação; microcontrolador não reseta na centelha |
| 6 | Injetor clica (não chia); largura medida bate com inj_pw_us |
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.
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.