Wednesday, December 11, 2019

HMC5883 (GY271) and HMC5983 (GY282)

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;
    }

No comments:

Search This Blog