STM32 - ESC: Problema com meu BEMF

Nov 06 2020

Estou fazendo um ESC para meu motor BLDC. Eu usei um STM32 (para gerar meu PWM), 3 drivers mosfet IR2101 (https://www.infineon.com/dgdl/ir2101.pdf?fileId=5546d462533600a4015355c7a755166c) e 6 mosfets para controlar as diferentes fases do motor.

Meu esquema:

Eu gero minha fase com um PWM no lado alto e um GPO no lado baixo.

Lado ALTO do meu PWM (fases A, B e C)

FASE A (indo abaixo de 0V!)

O sinal parece correto, mas quando eu conecto meu motor podemos ver que o BEMF está invertido em comparação com um bom BEMF.

FASE ABC

BEMF ABC

Tento alterar a frequência do PWM, alterar o ciclo de trabalho ou o atraso entre cada fase, mas nada muda (e às vezes é pior ...). Você tem uma ideia do porquê?

Meu STM funciona a 8MHz. Frequência PWM: 900 Hz com ciclo de trabalho de 5%. Durante este teste, meu motor consome 12 V / 0,8 A.

EDITAR

Não sei por que meu BEMF está invertido em comparação com um bom.

Abaixo você pode ver minha fase C (amarelo), o aterramento virtual do meu motor (azul claro), a operação matemática Fase C - aterramento virtual (azul escuro) e a saída do meu LM339 (rosa).

Eu vi vários assuntos sobre esse problema no Stack Exchange, mas a cada vez a resposta não é clara. ( insira a descrição do link aqui ).

Eu acho que meu PWM e BEMF não estão 'em fase' .. Eu preciso de algumas explicações.

Respostas

3 slightlynybbled Nov 10 2020 at 09:10

Bem-vindo ao StackExchange! Muito bem, primeiro post.

Você está correto, sua tensão de força está fora de fase com o seu motor.

Parece-me que você está amostrando no local incorreto durante seu ciclo de PWM. Certifique-se de que sua amostra ADC ocorra no centro do ciclo PWM quando o ciclo PWM estiver alto. Pode haver um ciclo de trabalho mínimo necessário para obter uma amostra adequada, mas pode não ser o caso, pois 900 Hz é uma frequência muito baixa.

É difícil supor a partir de suas capturas de tela de escopo, mas parece que a fase é negativa indo para o lado inferior de seu PWM e positiva para cima de seu PWM ... então seu código provavelmente está fazendo exatamente o que você estão dizendo para fazer, mas no lugar errado do ciclo.

Eu gosto de verificar meu tempo de interrupção (aproximadamente) configurando um pino para ligar quando a interrupção ADC começa e desligar quando a interrupção ADC termina. Normalmente consigo obter boas informações com isso.

Se você verificar / corrigir o tempo de amostra do ADC e o problema persistir, poste uma captura de tela de uma fase conforme ela está aumentando, eixo Y em escala real.

Fique com isso! Os problemas são resolvidos abaixando a cabeça e trabalhando nisso. Mas lembre-se de ir embora e dormir um pouco. Os problemas parecem muito diferentes pela manhã!


editado para adicionar

Com base em seus comentários, estou percebendo que pode haver alguns mal-entendidos básicos (posso estar errado).

Calculando a tensão neutra

Em primeiro lugar, você não precisa medir uma tensão neutra. Este é um módulo ADC desperdiçado. Você pode calcular a sua tensão de neutro: neutral = (phaseA + phaseB + phaseC) / 3;. Recomendo que você converta isso em uma notação de ponto fixo para velocidade, mas a matemática está correta. Agora, esse é um ADC a menos de que você precisa!

Seu neutro parece muito correto. Se você fizer mentalmente as contas que acabei de descrever, verá que a tensão do neutro é de fato a média (ou quase) das tensões de fase.

Configurar registros para fazer o trabalho

Em seguida, se você configurar seus registros TIM1 e ADC12 alinhados ao centro e disparados no pico do modo de contador, nenhum cálculo será necessário para amostrar corretamente.

Quando comutar

Em seu comentário, você escreveu

se a fase flutuante - o terreno virtual = 0. Se for verdade, então eu teoricamente sei quanto tempo devo esperar antes de comutar a próxima fase para alto

Isso é verdade apenas na metade das vezes e eu só quero expressar isso com clareza. Observe que a fase BEMF está alternando entre subir em uma fase e descer em outra.

if(phaseIsRising){
    if(phaseVoltage > neutral)
        commutate();
}else{
    if(phaseVoltage < neutral)
        commutate();
}

Se você implementar corretamente o código acima, poderá operar o motor, mas 30 graus avançado. Acredite em mim, ficará muito melhor do que nas suas capturas de tela.

Trabalho Adicional

Se você chegar até aqui, deixarei para você determinar como deslocar o evento de comutação em 30 graus.