Skocz do zawartości

Kompas HMC5883L złe wartości na MSB


Mateusz

Pomocna odpowiedź

Witam.

Mam mały problem z kompasem (HMC5883L).

Używam atmegi 8 z 8MHz wewn. rezonatorem RC.

Chciałbym odebrać dane po I2C. Używam 2 sensorów na płytce kompasu i akcelerometru (akcelerometr działa bez zarzutów). Problem jest tylko z HMC5883L kiedy próbuję odczytać wartość z osi X czyli dwa bajty (X_LSB, X_MSB) X_LSB odbierany jest dobrze ale przy odbiorze X_MSB odbieram tylko 0,1 albo 255.

Kod: (tylko rzeczy związane z I2C i odbieraniem danych)

main.c:

   #define F_CPU 8000000UL
   #include <avr/io.h>
   #include <util/delay.h> 
   #include <stdio.h>
   #include <stdlib.h>
   #include <avr/interrupt.h>
   #include <compat/twi.h>
   #include "TWI_lib.h"
   #include "UART_ATM8.h"

   int main(void)
   {
       int x_msb, x_lsb;
       char buf[20];

       USART_Init();
       TWI_Init();
       HMC5883L_init();
       _delay_ms(100);

       while(1)
       {

           x_msb = read_czujnik_hmc(0x03);
           x_lsb = read_czujnik_hmc(0x04);
           HMC5883L_init();  // Odświeżanie danych w rejestrach kompasu

           int16_t x = x_lsb | (x_msb << 8);  // łączenia danych

           sprintf(buf,"%d\n",x_msb);
           USART_send_string(buf);  // Wysyłanie odebranych dancyh

           _delay_ms(10);

       }
   }

TWI_lib.c:

   #include "TWI_lib.h"
   #include <util/delay.h> 

   #define SetBit(x,y)    x |= (1<<y)
   #define ClrBit(x,y) x &= ~(1<<y)
   #define NegBit(x,y) x ^= (1<<y)
   int error=0;


   void TWI_Init()
   {
     TWSR =0b00000000;    // Preskaler = 1  ->> TWPS1=0 TWPS0=0

     TWBR=32;

   }

   void TWI()
   {
       TWCR=(1<<TWINT) | (1<<TWSTO) | (1<<TWEN); //Sending stop sequence
       while((TWCR&(1<<TWSTO)));    //Oczekiwanie na ustawienie bitu stop
   }

   void TWI_write(char dane)
   {
       TWDR=dane;
       TWCR=(1<<TWINT) | (1<<TWEN);
       while(!(TWCR & (1<<TWINT)));
   }

   unsigned char TWI_read(unsigned char ack)
   {
       TWCR=(1<<TWINT) | (ack<<TWEA) | (1<<TWEN);
       while(!(TWCR & (1<<TWINT)));
       return TWDR;
   }

   unsigned char read_czujnik_hmc(unsigned char adres)
   {
       char ITGWriteAddress = 0x3C;
       char ITGReadAddress = 0x3D;
       unsigned char odczyt;
       TWI();
       return odczyt;
   }

   void HMC5883L_init()
   {
       char ITGWriteAddress = 0x3C;
       char ITGReadAddress = 0x3D;
       TWI();

       _delay_ms(10);

       TWI();

   }
Link do komentarza
Share on other sites

Nie podajesz jak inicjalizujesz czujnik (jaki zakres).

Z tego co widzę wyniki są jak najbardziej ok, tylko Ty je źle interpretujesz.

Tak jak kolega podaje 0xFFcostam to wartość ujemna...

Link do komentarza
Share on other sites

No tak ale tam są ja dostaje na MSB tylko 3 wartości. Działa to tak że w jakimś tam położeniu czujnika mam wartość około 300 (po przeliczeniu) i potem nie ważne w którą stronę bym kręcił wartości idą w dół aż do ujemnych.

Inicjalizacja czujnika:

void HMC5883L_init()
{
char ITGWriteAddress = 0x3C;
   char ITGReadAddress = 0x3D;
TWI();

_delay_ms(10);

TWI();

}

Udało mi się po zrobieniu tego tak jak na tej stronie:

http://torrentula.to.funpic.de/tag/hmc5883l/

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

No dobrze, a czym różni się rozwiązanie "na tej stronie" od Twojego? Że składa dwa rejestry 8-bitowe w jednego int'a ze znakiem? Czy może lepszą inicjalizacją trybu pracy? Może opisz co robiłeś źle i co tamto rozwiązanie poprawiło bo inaczej pozostanie niemiłe wrażenie, że faktycznie tylko Ci się "udało" i wciąż nie bardzo rozumiesz jak to działa..

Link do komentarza
Share on other sites

Bo też do końca nie wiem 🙂.

Są dwie opcje:

1) Ja nie odbierałem wszystkich danych tzn x,z,y tylko pojedyncze dane z osi a okazało się, że HMC5883L działa w taki sposób, że jak wyślemy zapytanie o rejestr 0x03 to wysyła wszystkie osie jedna po drugiej.

2) Gotowa biblioteka do obsługi TWI jest po prostu bardziej niezawodna od mojej 🙂.

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.