sercankurt
Joined: 28 Aug 2021 Posts: 12
|
QMC5883L compass sensor library |
Posted: Sun Aug 29, 2021 2:20 pm |
|
|
Hi all!
This library works with QMC5883L GY-271 compass sensor. (its just a note: its written DB 5883 7008 on the chip)
Once it was HMC5883L library but I changed values according to QMC5883L datasheet and works for me well.
important note: you need identify your device's i2c address by scanning i2c bus scanner program via your microcontroller, Not arduino.
Code: |
// QMC5883 Library
#define W_DATA 0x1A //'Used to perform a Write operation
#define R_DATA 0x1B //'Used to perform a Read operation
#define CON_A 0xA0
#define CON_B 0x0B //'Send continuous Measurement mode.
#define MOD_R 0x09 //'Read/Write Register, Selects the operating mode.
#define X_MSB 0x01 //'Read Register, Output of X MSB 8-bit value.
#define X_LSB 0x00 //'Read Register, Output of X LSB 8-bit value.
#define Z_MSB 0X05 //'Read Register, Output of Z MSB 8-bit value.
#define Z_LSB 0X04 //'Read Register, Output of Z LSB 8-bit value.
#define Y_MSB 0X03 //'Read Register, Output of Y MSB 8-bit value.
#define Y_LSB 0X02 //'Read Register, Output of Y LSB 8-bit value.
void hmc5883_write(int add, int data)
{
i2c_start();
i2c_write(W_DATA);
i2c_write(add);
i2c_write(data);
i2c_stop();
}
int16 hmc5883_read(int add){
int retval;
i2c_start();
i2c_write(W_DATA);
i2c_write(add);
i2c_start();
i2c_write(R_DATA);
retval=i2c_read(0);
i2c_stop();
return retval;
}
void hmc5883_init(){
hmc5883_write(CON_B, 0x01);
delay_ms(100);
hmc5883_write(MOD_R, 0b10011001);
delay_ms(100);
hmc5883_write(CON_A, 0b10000001);
delay_ms(100);
} |
Here is an example:
Code: |
#include <16F887.h>
#fuses HS, NOWDT, NOPROTECT, NOMCLR
#use delay(clock=20M)
#use I2C(MASTER, sda=PIN_C4, scl=PIN_C3, fast=100000, force_hw) //You can change, according your board ports
#use RS232(BAUD = 9600, XMIT = PIN_C6, RCV = PIN_C7, STOP = 1, STREAM = Bluetooth) // optional, you can erase
#include "i2c_flex_lcd.c" // optional. You can use your own lcd library
#include "HMC5883.c"
#include "math.h"
int8 M_data[6]; //6 units 8 bit Measured datas
int16 Xm=0,Ym=0,Zm=0; //16 bit X,Y,Z variables
void main()
{
delay_ms(10);
lcd_init(0x7e,16,2);
hmc5883_init();
lcd_clear();
while(TRUE)
{
M_data[0]=hmc5883_read(0x00); //Read X (LSB)
M_data[1]=hmc5883_read(0x01); //Read X (MSB)
M_data[2]=hmc5883_read(0x02); //Read Y (LSB)
M_data[3]=hmc5883_read(0x03); //Read Y (MSB)
M_data[4]=hmc5883_read(0x04); //Read Z (LSB)
M_data[5]=hmc5883_read(0x05); //Read Z (MSB)
Xm=make16(M_data[1],M_data[0]);
Ym=make16(M_data[3],M_data[2]);
Zm=make16(M_data[5],M_data[4]);
float Heading = atan2((signed int16)Ym-360,(signed int16)Xm-310) * 180 / pi + 180;
//****-360 and -310, you can delete them or change it. I added them by trial-and-error in order to set my azimuth accuracy. Up to you ///
lcd_gotoxy(1,1);
printf(lcd_putc,"X=%ld ",Xm);
lcd_gotoxy(9,1);
printf(lcd_putc,"Y=%ld ",Ym);
lcd_gotoxy(1,2);
printf(lcd_putc,"Z=%ld ",Zm);
lcd_gotoxy(9,2);
printf(lcd_putc,"h=%f ",Heading);
fprintf(bluetooth,"\n h=%f ",Heading); // optional, you can erase
delay_ms(250);
}
} |
|
|