Skocz do zawartości

Kompas HMC5883L złe wartości na MSB


Pomocna odpowiedź

Napisano

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();

   }

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...

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/

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..

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 🙂.

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...