Showing posts with label pi. Show all posts
Showing posts with label pi. Show all posts

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

Search This Blog