HMC5883 (GY271) and HMC5983 (GY282)
Both HMC5883 and HMC5983 are 3-axis magnetometers which measure the
strength of the magnetic field along three mutually perpendicular axes
with ±0.88 Ga, ±1.3 Ga, ±1.9 Ga, ±2.5 Ga, ±4.0 Ga, ±4.7 Ga, ±5.6 Ga and
±8.1 Ga resolutions. Although there are some slight differences between
them, the same code can be used to read them.
// build with: gcc -o hmc5983 hmc5983.c -lm
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/i2c-dev.h>
#include <math.h>
#define HMC5983_I2C_ADDR 0x1E
void selectDevice(int fd, int addr, char * name)
{
if (ioctl(fd, I2C_SLAVE, addr) < 0) {
fprintf(stderr, "%s not present\n", name);
}
}
void selectRegister(int fd, int reg)
{
char buf[1];
buf[0]=reg;
if (write(fd, buf, 1) != 1) {
fprintf(stderr, "Can't write to HMC5983\n");
}
}
void SelectRegister(int fd, char val)
{
char buf[1];
buf[0]=val;
if (write(fd, buf, 1) != 1) {
fprintf(stderr, "Can't write to HMC5983\n");
}
}
void writeToDevice(int fd, int reg, int val)
{
char buf[2];
buf[0]=reg; buf[1]=val;
if (write(fd, buf, 2) != 2) {
fprintf(stderr, "Can't write to HMC5983\n");
}
}
int main(int argc, char **argv)
{
unsigned int range;
int count, b;
short x, y, z,t;
float xa, ya, za,ta,B;
int fd;
unsigned char buf[16];
FILE *fptr;
if ((fd = open("/dev/i2c-2", O_RDWR)) < 0)
{
// Open port for reading and writing
fprintf(stderr, "Failed to open i2c bus\n");
exit(1);
}
selectDevice(fd, HMC5983_I2C_ADDR, "HMC5983");
writeToDevice(fd, 0x00, 0xf0); // CRA - temp enabled, 8-average, 15 Hz default, normal measurement
writeToDevice(fd, 0x01, 0x00); // CRB - Gain=0
while (1)
{
writeToDevice(fd, 0x02, 0x01); // Mode - single-measurement mode
selectRegister(fd,0x09); // status register
read(fd, buf, 1);
printf("%d\n",buf[0]);
selectRegister(fd,0x03); // first data register
if (read(fd, buf, 6) != 6) { // read 6 data registers
fprintf(stderr, "Unable to read from HMC5983\n");
}
else {
x = buf[0]<<8| buf[1];
z = buf[2]<<8| buf[3];
y = buf[4]<<8| buf[5];
// printf("%d %d %d \n", x, y, z);
xa = x*100.0/1370.0; //in milli tesla
ya = y*100.0/1370.0; //in milli tesla
za = z*100.0/1370.0; //in milli tesla
B = sqrt(xa*xa+ya*ya+za*za);
printf("field : %f %f %f %f nT\n", xa, ya, za,B);
}
selectRegister(fd,0x31); // first data register
if (read(fd, buf, 2) != 2) { // read 6 data registers
fprintf(stderr, "Unable to read from HMC5983\n");
}
else {
t = buf[0]<<8| buf[1];
ta = t/128.0+25.0;
printf("temperature: %f C\n",ta);
}
// fptr = fopen("field.txt", "a");
// printf("%f %f %f %f \n", xa, ya, za,ta);
// fprintf(fptr,"%f %f %f %f \n", xa, ya, za,ta);
// fclose(fptr);
sleep(1);
}
return 0;
}
// build with: gcc -o hmc5983 hmc5983.c -lm
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/i2c-dev.h>
#include <math.h>
#define HMC5983_I2C_ADDR 0x1E
void selectDevice(int fd, int addr, char * name)
{
if (ioctl(fd, I2C_SLAVE, addr) < 0) {
fprintf(stderr, "%s not present\n", name);
}
}
void selectRegister(int fd, int reg)
{
char buf[1];
buf[0]=reg;
if (write(fd, buf, 1) != 1) {
fprintf(stderr, "Can't write to HMC5983\n");
}
}
void SelectRegister(int fd, char val)
{
char buf[1];
buf[0]=val;
if (write(fd, buf, 1) != 1) {
fprintf(stderr, "Can't write to HMC5983\n");
}
}
void writeToDevice(int fd, int reg, int val)
{
char buf[2];
buf[0]=reg; buf[1]=val;
if (write(fd, buf, 2) != 2) {
fprintf(stderr, "Can't write to HMC5983\n");
}
}
int main(int argc, char **argv)
{
unsigned int range;
int count, b;
short x, y, z,t;
float xa, ya, za,ta,B;
int fd;
unsigned char buf[16];
FILE *fptr;
if ((fd = open("/dev/i2c-2", O_RDWR)) < 0)
{
// Open port for reading and writing
fprintf(stderr, "Failed to open i2c bus\n");
exit(1);
}
selectDevice(fd, HMC5983_I2C_ADDR, "HMC5983");
writeToDevice(fd, 0x00, 0xf0); // CRA - temp enabled, 8-average, 15 Hz default, normal measurement
writeToDevice(fd, 0x01, 0x00); // CRB - Gain=0
while (1)
{
writeToDevice(fd, 0x02, 0x01); // Mode - single-measurement mode
selectRegister(fd,0x09); // status register
read(fd, buf, 1);
printf("%d\n",buf[0]);
selectRegister(fd,0x03); // first data register
if (read(fd, buf, 6) != 6) { // read 6 data registers
fprintf(stderr, "Unable to read from HMC5983\n");
}
else {
x = buf[0]<<8| buf[1];
z = buf[2]<<8| buf[3];
y = buf[4]<<8| buf[5];
// printf("%d %d %d \n", x, y, z);
xa = x*100.0/1370.0; //in milli tesla
ya = y*100.0/1370.0; //in milli tesla
za = z*100.0/1370.0; //in milli tesla
B = sqrt(xa*xa+ya*ya+za*za);
printf("field : %f %f %f %f nT\n", xa, ya, za,B);
}
selectRegister(fd,0x31); // first data register
if (read(fd, buf, 2) != 2) { // read 6 data registers
fprintf(stderr, "Unable to read from HMC5983\n");
}
else {
t = buf[0]<<8| buf[1];
ta = t/128.0+25.0;
printf("temperature: %f C\n",ta);
}
// fptr = fopen("field.txt", "a");
// printf("%f %f %f %f \n", xa, ya, za,ta);
// fprintf(fptr,"%f %f %f %f \n", xa, ya, za,ta);
// fclose(fptr);
sleep(1);
}
return 0;
}
No comments:
Post a Comment