Ir ao conteúdo
  • Cadastre-se

HMC5883L (Bússola) PIC CCS C


Posts recomendados

Este é um código para HMC5883L (Magnetômetro / Bússola) com o CCS C, como ele (HMC5883L) dá para medir a intensidade e direção do campo magnético terrestre e assim determinar o norte magnético. Com o norte magnético, sabendo a declinação magnética no local, é possível determinar o norte geográfico.
 
O código foi testado (não muito) com o PIC18F4550.
 
Código para teste:

#include <18F4550.h>#device ADC=10#FUSES NOFCMEN                  // Fail-safe clock monitor disabled#FUSES NOIESO                   // Internal External Switch Over mode disabled#FUSES NOPUT                    // Disable Power Up Timer#FUSES BROWNOUT                 // Reset when brownout detected#FUSES BORV27                   // Brownout reset at 2.7V#FUSES NOVREGEN                 // USB voltage regulator disabled#FUSES NOPBADEN                 // PORTB pins are configured as digital I/O on RESET#FUSES NOLPT1OSC                // Timer1 configured for higher power operation#FUSES MCLR                     // Master Clear pin enabled#FUSES STVREN                   // Stack full/underflow will cause reset#FUSES NOLVP                    // No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O#FUSES NOXINST                  // Extended set extension and Indexed Addressing mode disabled (Legacy mode)#FUSES NOPROTECT                // Code not protected from reading#FUSES NOCPB                    // No Boot Block code protection#FUSES NOCPD                    // No EE protection#FUSES NOWRT                    // Program memory not write protected#FUSES NOWRTC                   // Configuration registers not write protected#FUSES NOWRTB                   // Boot block not write protected#FUSES NOWRTD                   // Data EEPROM not write protected#FUSES NOEBTR                   // Memory not protected from table reads#FUSES NOEBTRB                  // Boot block not protected from table reads#FUSES NOICPRT#use delay(internal=8MHz)#use rs232(baud=115200, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8, stream=PORT1)/*-----------------------------------------------------------------------------*/#use i2c(Master, Fast, sda=PIN_B0, scl=PIN_B1, force_hw)// Fast = 400 000KHz | Se for I2C por software force_sw#include <HCM5883L.c>/*-----------------------------------------------------------------------------*/#byte OSCCON = 0xFD3#byte MCU_TRISD = 0xF95#byte MCU_LATD = 0xF8C#bit SCS1 = OSCCON.1#bit SCS0 = OSCCON.0#bit MCU_TRISD1 = MCU_TRISD.1#bit LED = MCU_LATD.1int resultado_self_teste, status;signed int16 eixo_x, eixo_y, eixo_z; float x_micro_tesla, y_micro_tesla, z_micro_tesla, intensidade_total, inclinacao, azimute;void main() {    SCS1 = 1;                                          MCU_TRISD1 = 0;                               // PD1 como saída  LED = 1;                                      // Inicia com  LED desligado.    status = self_test_HCM5883L(resultado_self_teste);  if(status == 1)    printf("\fSelf test nao realizado sensor nao detectado.\n\n\r");      else if(status == 2)      printf("\fSelf test nao realizado atualizacao dos data out registers demorou mais que o normal.\n\n\r");              else { // status == 0          printf("\fSelf Test.\n\r>Teste positivo:\n\r");                    if(!bit_test(resultado_self_teste, 0))// bit 0 = resultado do teste positivo             printf("Eixo X passou - ");         // para o eixo X. Se for 0 = passou.            else                                // 1 significa não passou.              printf("Eixo X nao passou - ");                   if(!bit_test(resultado_self_teste, 1))// bit 1 = resultado do teste positivo              printf("Eixo Y passou - ");         // para o eixo Y. Se for 0 = passou.               else                                // 1 significa não passou.              printf("Eixo Y nao passou - ");                  if(!bit_test(resultado_self_teste, 2))// bit 2 = resultado do teste positivo             printf("Eixo Z passou.");           // para o eixo Z. Se for 0 = passou.            else                                // 1 significa não passou.              printf("Eixo Z nao passou.");                    printf("\n\n\r>Teste negativo:\n\r");                    if(!bit_test(resultado_self_teste, 3))// bit 2 = resultado do teste negativo             printf("Eixo X passou - ");         // para o eixo X. Se for 0 = passou.            else                                // 1 significa não passou.              printf("Eixo X nao passou - ");                  if(!bit_test(resultado_self_teste, 4))// E assim por diante.             printf("Eixo Y passou - ");            else                printf("Eixo Y nao passou - ");                  if(!bit_test(resultado_self_teste, 5))             printf("Eixo Z passou.\n\n\r");            else                printf("Eixo Z nao passou.\n\n\r");           }           // Ajusta o ganho do sensor de acordo com a intensidade do campo no local.  status = ajustar_ganho_HCM5883L();  // A biblioteca usa três variáveis globais que guardam o conteúdo  // dos registradores Configuration Register A, Configuration Register B e  // Mode Register. As variáveis são: _configuration_rega_shadow,  // _configuration_regb_shadow e _mode_register_shadow.      if(status == 0)    printf("Ganho ajustado para %u", _configuration_regb_shadow>>5);         else if(status == 1)      printf("Ganho nao ajustado, sensor nao detectado.");            else if(status == 2)        printf("Ganho nao ajustado, atualizacao dos data out registers demorou mais que o normal.");                else //status == 3          printf("Ganho nao ajustado, instensidade do campo fora do range do instrumento.");  // Configura o sensor para fazer a média de 8 medições, fazer uma medição   // a cada 133mS (7.5Hz) e operação contínua (assim que termina uma conversão  // ele inicia outra).  status = configurar_HCM5883L(_samples_averaged_8 | _data_rate_7_5HZ | _continuous_meass_mode);  if(status == 0)    printf("\n\n\rConfiguracao realizada 8 amostras - 7.5Hz - Op. continua.");    else // status == 1      printf("\n\n\rConfiguracao nao realizada, sensor nao detectado.");      delay_ms(10000);    // Usado quando o sensor é configurado para _single_meass_mode em vez   // de _continuous_meass_mode  /*status = iniciar_conversao_HCM5883L();  if(status == 1)    printf("\n\nzrSensor nao detectado.");*/         while(true) {    LED=!LED;        // Lendo a medição de cada eixo    /*status = ler_HCML5883L(eixo_x, eixo_y, eixo_z);    if(status == 0)      printf("\fX: Ld% - Y: Ld% - Z: Ld%.");      else // status == 1        printf("\fsensor nao detectado.");*/        // É possível desprezar a variável status (para as outras funções também):    ler_HCML5883L(eixo_x, eixo_y, eixo_z);    printf("\fHX: %Ld | HY: %Ld | HZ: %Ld", eixo_x, eixo_y, eixo_z);      // Convertendo os valores medidos para micro Tesla    valores_brutos_para_microtesla(eixo_x, eixo_y, eixo_z, x_micro_tesla, y_micro_tesla, z_micro_tesla);    printf("\n\rX: %.1fuT | Y: %.1fuT | Z: %.1fuT", x_micro_tesla, y_micro_tesla, z_micro_tesla);        // Calculando a intensidade do campo     intensidade_total = calcular_intensidade_total(x_micro_tesla, y_micro_tesla, z_micro_tesla);    printf("\n\rIntensidade do campo: %.1fuT", intensidade_total);           // Calculando a inclinação magnética    inclinacao = calcular_inclinacao(eixo_x, eixo_y, eixo_z);    printf("\n\rInclinacao: %.1f graus", inclinacao);         // Calculando o azimute, para uma declinação magnética de -22.3°     // http://www.magnetic-declination.com/    // X e Y devêm estar na posição horizontal.    // O eixo X é a referencia.    azimute = calcular_azimute(eixo_x, eixo_y, -22.3);    printf("\n\rAzimute: %.1f graus | ", azimute);      if ((azimute >= 22.5) && (azimute < 67.5)) printf("NORDESTE");    else if ((azimute >= 67.5) && (azimute < 112.5)) printf("LESTE");    else if ((azimute >= 112.5) && (azimute < 157.5)) printf("SUDESTE");    else if ((azimute >= 157.5) && (azimute < 202.5)) printf("SUL");    else if ((azimute >= 202.5) && (azimute < 247.5)) printf("SUDOESTE");    else if ((azimute >= 247.5) && (azimute < 292.5)) printf("OESTE");    else if ((azimute >= 292.5) && (azimute < 337.5)) printf("NOROESTE");    else printf("NORTE");        delay_ms(250);  // para 7.5Hz o sensor faz uma medição a cada 134mS                    // mas se a medição anterior não foi lida ele não atualiza                    // os registradores com os novos valores.  }  }

 

Palavras de configuração para a função "configurar_HCM5883L":

_samples_averaged_1    // Uma única amostra     _samples_averaged_2    // Média de 2 amostras  _samples_averaged_4    // Média de 4 amostras  _samples_averaged_8    // Média de 8 amostras  _data_rate_0_75HZ      // 0.75Hz       _data_rate_1_5HZ       // 1.5Hz_data_rate_3HZ         // 3Hz   _data_rate_7_5HZ       // 7.5Hz  _data_rate_15HZ        // 15Hz  _data_rate_30HZ        // 30Hz  _data_rate_75HZ        // 75Hz  _continuous_meass_mode // Termina uma medição e inicia outra  _single_meass_mode     // Termina uma medição e vai para o modo inativo_idle_mode             // Modo inativo

 

KObqzUu.jpg

 

 

Teste:

 

Download do código:

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...