Skocz do zawartości

Magnetometr QMC5883L + ATmega32


Bonkers

Pomocna odpowiedź

Witam,

Mam problem z przeniesieniem projektu z Arduino na ATmega32. Póki co narazie próbuje obrobić pobieranie danych z czujnika magnetycznego QMC5883L oraz ich wyświetlanie po przez USART. Na podstawie kodu z tej strony https://www.electronicwings.com/avr-atmega/magnetometer-hmc5883l-interfacing-with-atmega16 ,dokumentacji czujnika QMC5883L, a także biblioteki Arduino próbuje przerobić powyższy kod z obsługi  HMC5883L na QMC5883L. Niestety nie udaje mi się zainicjować w programie magnetometru. Poniżej przesyłam link do dokumentacji technicznej oraz kod programu. Proszę o pomoc.

Dokumentacja QMC5883L: http://wiki.epalsite.com/images/7/72/QMC5883L-Datasheet-1.0.pdf

#define F_CPU 16000000UL
#define FOSC 16000000	// Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1

#include <avr/io.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <util/delay.h>
#include <avr/interrupt.h>


#include "USART_irq.h"
#include "i2cmaster.h"

#define QMC5883L_ADDR	0x0D							/* Magnetometer QMC5883L Address */

static FILE mystdout = FDEV_SETUP_STREAM(USART0_Transmit_IO, NULL,_FDEV_SETUP_WRITE);

void Magneto_init()										/* Magneto initialize function */
{
	i2c_start(QMC5883L_ADDR+I2C_WRITE);					/* Start and write SLA+W */									
	i2c_write(0x0B);									/* Defined Set/Reset Period as Default */
	i2c_write(0x01);									/* Configure register  */					
 	i2c_write(0x09);
 	i2c_write(0x1D);									/* Configure register OSR = 512, Full Scale Range = 8G(Gauss), ODR = 200HZ, set continuous measurement mode */
 	i2c_stop();											/* Stop I2C */
}


void Magneto_GetPos(int *x, int *y, int *z)
{

		i2c_start_wait(QMC5883L_ADDR+I2C_WRITE);					/* Start and wait for acknowledgment */
		i2c_write(0x00);											/* Write X register address */										
		
		i2c_rep_start(QMC5883L_ADDR+I2C_READ);						/* Generate repeat start condition with SLA+R */
		/* Read 16 bit x,y,z value (2’s complement form) */
		*x = (((int)i2c_readAck()<<8) | (int)i2c_readAck());
		*y = (((int)i2c_readAck()<<8) | (int)i2c_readAck());
		*z = (((int)i2c_readAck()<<8) | (int)i2c_readNak());
		i2c_stop();
		
}


int main(void)
{
	
	i2c_init();											/* Initialize I2C */
	Magneto_init();	
    USART0_Init(MYUBRR);								// Calculate baud rate
	
	sei();				/* Enable interrupts => enable UART interrupts */
	
	stdout = &mystdout;
	
	int xAxis = 0 , yAxis = 0, zAxis = 0;
	int i = 0;

	
    while (1) 
    {
		Magneto_GetPos(&xAxis, &yAxis, &zAxis);
		printf("x: %d | y: %d | z: %d | t -> %d\n", xAxis, yAxis, zAxis, i);
		

		i++;
		_delay_ms(1000);
    }
}

 

Link do komentarza
Share on other sites

 

9 minut temu, atMegaTona napisał:

A wszystko inne działa? Może to nie z magnetometrem problem jest. Tutaj był podobny wątek: https://forbot.pl/forum/topic/16552-stm32mpu9250ak8963-problem-z-odczytem-danych-z-magnetometru/?tab=comments#comment-133782

 

Tak, USART działa, gdy zakomentuje się linie odpowiadające za inicjalizacje magnetometru. Z tego co widzę to w tym temacie co napisałeś pojawia się problem dopiero po odczycie... a u mnie żaden odczyt nie następuje jak narazie.

Link do komentarza
Share on other sites

A sprawdzałeś sam moduł na innym sofcie? np. od arduino? Może moduł padł albo i2c masz skopane, spróbuj inną biblioteką albo sam napisz, do master jest raptem kilkadzieści  linijek.

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

(edytowany)

Sprawdzałem, wszystko na sofcie Arduino działa poprawnie, sam projekt był pierwotnie uruchomiony na Arduino, a ja chce go teraz przerobić na C pod AVR. Z resztą ta ATmega jest na płytce Arduino. Sam program testowałem na dwóch bibliotekach do I2C, na jednej z nich zrobiłem obsługę wyświetlacza przez I2C więc raczej jest dobra, a druga to z tej strony do magnetometru HMC5883L.

Edytowano przez Bonkers
Link do komentarza
Share on other sites

Nie zostaje nic innego jak metodyczne śledzenie punkt po punkcie wykonywania procedury. Pobaw się debugerem z Atmel Studia. Zwróć uwagę na poprawną kolejność parametrów inicjalizacyjnych.  Nie chce mi się analizować tych bibliotek, dla moich zastosowań nie nadają się do użytku.

Link do komentarza
Share on other sites

Udało mi się to uruchomić. Wszystko działa prawidłowo. Przy starcie I2C trzeba było przesunąć adres urządzenia o jeden bit w lewo a następnie zsumować logicznie z bajtem odpowiadającym za czytanie lub wpisywanie. Wystarczy zamienić poniższe linijki kodu:

I2C_Start(QMC5883L_ADDR+I2C_WRITE);
...
I2C_Start_Wait(QMC5883L_ADDR+I2C_WRITE);
...
I2C_Repeated_Start(QMC5883L_ADDR+I2C_READ);

na

I2C_Start(((QMC5883L_ADDR)<<1) | I2C_WRITE);
...
I2C_Start_Wait(((QMC5883L_ADDR)<<1) | I2C_WRITE);
...
I2C_Repeated_Start(((QMC5883L_ADDR)<<1) | I2C_READ);

 

  • Lubię! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

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