Dúvida sobre o magnetômetro HMC5883L

É possível ler os dados de um magnetômetro de grau em grau? Exemplo: Se estiver lendo 90° e gira-lo rapidamente para 180°, ler: 91°, 92°, 93°, 94°, sequenciando até chegar em 180°?

Se a resposta for positiva, como farei isso?

Agradeço.

Ludicon,

Uma bússola é um tipo simples de magnetômetro em que mede a direcção de um campo magnético ambiente, por tanto módulo em questão funciona como uma bússola.

Você já instalou a biblioteca para lidar com este magnetômetro? Se não me falhe a memória, este modelo tem uma biblioteca bem simples, acho que é essa: https://github.com/sleemanj/HMC5883L_Simple ela põe exemplos no editor do arduino, incluindo um para usá-lo como compass. Se tiver um código pronto, posso dar uma olhada para ajudar.

Sksdutra,

Já tenho a biblioteca e o sensor funciona perfeitamente, porém como as leituras são sempre para o local onde ele está sendo apontado, se girado rapidamente ele não sequência de um em um grau até onde você parou de girar. Para ele sequenciar os graus unitariamente, teria que girá-lo muitíssimo devagar e essa não é a opção que eu preciso. Gostaria que a leitura do sensor fosse como de um encoder que você pode incrementar/decrementar de um em um. Para entender melhor sobre a minha dúvida, observer o vídeo https://www.youtube.com/watch?v=f4IeZDXWQH4 e veja o que ocorre quando o sensor é movimentado (despreze as casas decimais).

Desde de já agradeço sua atenção.

OK, acho que entendi o que você quer fazer, quer dar ao sensor um comportamento semelhante ao de um rotary encoder.

Infelizmente eu não tenho esse sensor e não tenho como testar, mas eu acredito que seja possível.

O que acontece é que:

  1. Aparentemente, essa biblioteca usa float para mostrar os dados e creio que você precise de um inteiro (algo opcional);
  2. Há um delay na leitura de tal forma que ele já mostra o grau onde o sensor aponta e, pelo que entendi, o que você quer é que mostre todos os graus anteriores como se estivesse girando uma chave (rotary encoder).

Minha solução, se não houver algo pronto na API da lib, seria algo do tipo: Subtrair o dado atual do dado anterior e o resultado seria mostrar o dado anterior N vezes + 1, vou exemplificar levando em conta números inteiros:

Leitura anterior: 50
Leitura atual: 100
Resultado da leitura atual menos leitura anterior: 100 - 50 = 50

Mostrar a leitura anterior 50 vezes (+1)
50 + 1
51 + 1

99 + 1 (100)

Creio que com esse algoritmo você conseguiria o comportamento requerido.

Sksdutra, mais uma vez agradeço seu retorno e você entendeu perfeitamente, porém infelizmente não dá para usar sua sugestão porque “Leitura anterior” receberia os dados do sensor e enquanto estiver girando iria dar os saltos que você viu no vídeo.

Meu projeto é para rastreamento de satélite onde uso o sensor HMC5883L fixado em um pan tilt com motores de corrente alternada e baixa velocidade. Coordenadas de azimute e elevação do satélite são enviadas para porta serial do Arduino através de um software.

O sistema compara a diferença entre os dados do sensor e os recebidos pela porta serial, que se atendida condições acionam os relés para girar os motores para esquerda ou direita e acima ou abaixo, acompanhando assim o percurso do satélite.

Na comparação entre os dados, os relés não estavam desligando nas condições que foram definidas. Vou chamar isso de instabilidade do sensor. Fica numa espécie de loop tentando corrigir a condição definida. Para solucionar esse problema, embora não goste de usar a função delay, essa foi a única que resolveu a situação e tudo passou a funcionar como pretendido, porém com essa opção apareceu um novo problema.

Quando a diferença entre os dados comparados é grande, o relé fica ligando e desligando devido ao delay(100) e, até a condição do if ser atendida, demora bastante.

Segue a parte do código referente a comparação entre o sensor e os dados recebido pela serial. Observação: utilizo relé invertido.

“a” são os dados recebidos pela serial
“heading” são os dados recebidos do sensor

if((abs(a - heading)>=2)){ 
if(a < heading){
        digitalWrite(m_right, LOW);
        delay(100); }
else{
    digitalWrite(m_right, HIGH);}
    
  if(a > heading){
          digitalWrite(m_left, LOW);
         delay(100);
        digitalWrite(m_left, HIGH);}

Gostaria de uma ideia para resolver esse problema.

Sobre a questão do encoder, achei esse projeto no YouTube que parece que ele consegue o comportamento que você pretende, ele usa funções matemáticas para calcular o giro.

Essa segunda questão, me parece que o problema é demorar para que a condição seja atendida, se isso independe do controle do desenvolvedor, pois são dados coletados, não creio que hajam muitas opções a não ser aguardar.

Infelizmente não tenho como usar encoder devido ao espaço no pan tilt, mas com certeza funcionaria. Uma alternativa que estou pensando é usar um módulo pwm para controlar/diminuir a velocidade dos moteres de acordo com a diferença na comparação entre os dados coletados.

Agradeço bastante por sua atenção, grande abç.