A compilation of some hardware sensors and their shared programming interfaces.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MAG3110.h Source File

MAG3110.h

00001 /* MAG3110.h
00002  * Tested with mbed board: FRDM-KL46Z
00003  * Author: Mark Gottscho
00004  * mgottscho@ucla.edu
00005  */
00006 
00007 #ifndef MAG3110_H
00008 #define MAG3110_H
00009 
00010 #include "mbed.h"
00011 #include "I2CSensor.h"
00012 #include "PeriodicSensor.h"
00013 
00014 
00015 /**
00016  * This class allows for easy control of an MAG3110 magnetometer IC.
00017  */
00018 class MAG3110 : public I2CSensor, public PeriodicSensor {
00019     public:
00020         /**
00021          * Enumeration of allowed ADC sampling data rates.
00022          * The device does sample averages such that
00023          * the output data rate ODR = ADC_RATE / OVERSMPL_RATIO in all cases except for when ADC_RATE is 80 Hz (min). In this case,
00024          * there are multiple ODR for the same ADC_RATE, OVERSMPL_RATIO combination.
00025          * Note that there are non-unique combinations for the same ODR.
00026          */
00027         typedef enum {
00028             AHZ1280, //1280 Hz
00029             AHZ640,  //640 Hz
00030             AHZ320,  //320 Hz
00031             AHZ160,  //160 Hz
00032             AHZ80    //80 Hz
00033         } adc_smpl_rate_t;
00034         
00035         /**
00036          * Enumeration of allowed oversampling ratios.
00037          * The device does sample averages such that
00038          * the output data rate ODR = ADC_RATE / OVERSMPL_RATIO in all cases except for when ADC_RATE is 80 Hz (min). In this case,
00039          * there are multiple ODR for the same ADC_RATE, OVERSMPL_RATIO combination.
00040          * Note that there are non-unique combinations for the same ODR.
00041          */
00042         typedef enum {
00043             O16, //16:1
00044             O32, //32:1
00045             O64, //64:1
00046             O128 //128:1
00047         } oversmpl_ratio_t;
00048         
00049         /**
00050          * Enumeration of possible output data rates.
00051          * The device does sample averages such that
00052          * the output data rate ODR = ADC_RATE / OVERSMPL_RATIO in all cases except for when ADC_RATE is 80 Hz (min). In this case,
00053          * there are multiple ODR for the same ADC_RATE, OVERSMPL_RATIO combination.
00054          * Note that there are non-unique combinations for the same ODR.
00055          */
00056         typedef enum {
00057             HZ80,   //80 Hz
00058             HZ40,   //40 Hz
00059             HZ20,   //20 Hz
00060             HZ10,   //10 Hz
00061             HZ5,    //5 Hz
00062             HZ2_5,  //2.5 Hz
00063             HZ1_25, //1.25 Hz
00064             HZ0_63, //0.63 Hz
00065             HZ0_31, //0.31 Hz
00066             HZ0_16, //0.16 Hz
00067             HZ0_08  //0.08 Hz
00068         } smpl_rate_t;
00069     
00070         /**
00071          * @param sda the pin identifier for SDA I2C signal
00072          * @param scl the pin identifier for SCL I2C signal
00073          * @param i2c_addr the 8-bit I2C address for this device. Note that LSB is a don't care.
00074          */
00075         MAG3110 (PinName sda, PinName scl, int i2c_addr);
00076         
00077         /**
00078          *
00079          */
00080         ~MAG3110();
00081         
00082         /**
00083          * Self-initialization to some nice preset. You must ensure the device is first deactivated using setActive().
00084          */
00085         void selfInit();
00086         
00087         //I2C-specific methods
00088         
00089         /**
00090          * Implements the pure virtual method of the parent I2CSensor class.
00091          * @returns the 8-bit device identifier.
00092          */
00093         uint8_t whoAmI();
00094         
00095         //Device-specific methods
00096         
00097         /**
00098          * @returns true if the device is active
00099          */
00100         bool isActive ();
00101         
00102         /**
00103          * @param activate if true, enables the device, else disables it
00104          */
00105         void setActive (bool activate);
00106         
00107         /**
00108          * @returns the 8-bit system mode status
00109          */
00110         uint8_t getSystemMode ();
00111         
00112         /**
00113          * @param rate optional pointer, if provided, will be set to the output sampling rate
00114          * @param ratio optional pointer, if provided, will be set to the oversampling ratio
00115          * @param adc_rate optional pointer, if provided, will be set to the ADC rate
00116          */
00117         void getOutputSamplingParameters (smpl_rate_t *rate, oversmpl_ratio_t *ratio, adc_smpl_rate_t *adc_rate);
00118         
00119         /**
00120          * @param rate the enumerated value corresponding to the output data sample rate to use
00121          * @param ratio the number of ADC samples per output sample (averaged)
00122          * @param adc_rate optional pointer, set to the resulting adc_rate used for the combination of rate and ratio
00123          * @returns true if the operation succeeded and the first two parameters were correct
00124          */
00125         bool setOutputSamplingParameters (smpl_rate_t rate, oversmpl_ratio_t ratio, adc_smpl_rate_t *adc_rate);
00126         
00127         /**
00128          * @returns the value in the data register
00129          */
00130         uint8_t getDataRegisterStatus ();
00131         
00132         
00133         //Device-specific data sampling methods
00134         /**
00135          * @param sampleNow if true, queries the device for the sample and returns it. if false, gets the last queried value.
00136          * The latter is preferred if this object is set up to sample using interrupts.
00137          * @returns a 16-bit value representing the latest data sample for the X dimension, centered at 0.
00138          */
00139         int16_t getX (bool sampleNow);
00140         
00141         /**
00142          * @param sampleNow if true, queries the device for the sample and returns it. if false, gets the last queried value.
00143          * The latter is preferred if this object is set up to sample using interrupts.
00144          * @returns a 16-bit value representing the latest data sample for the Y dimension, centered at 0.
00145          */
00146         int16_t getY (bool sampleNow);
00147         
00148         /**
00149          * @param sampleNow if true, queries the device for the sample and returns it. if false, gets the last queried value.
00150          * The latter is preferred if this object is set up to sample using interrupts.
00151          * @returns a 16-bit value representing the latest data sample for the Z dimension, centered at 0.
00152          */
00153         int16_t getZ (bool sampleNow);
00154         
00155         /**
00156          * @param sampleNow if true, queries the device for the sample and returns it. if false, gets the last queried value.
00157          * The latter is preferred if this object is set up to sample using interrupts.
00158          * Returns the latest X data reading as a float in uT
00159          */
00160         float getFloatX (bool sampleNow);
00161         
00162         /**
00163          * @param sampleNow if true, queries the device for the sample and returns it. if false, gets the last queried value.
00164          * The latter is preferred if this object is set up to sample using interrupts.
00165          * Returns the latest Y data reading as a float in uT
00166          */
00167         float getFloatY (bool sampleNow);
00168         
00169         /**
00170          * @param sampleNow if true, queries the device for the sample and returns it. if false, gets the last queried value.
00171          * The latter is preferred if this object is set up to sample using interrupts.
00172          * Returns the latest Z data reading as a float in uT
00173          */
00174         float getFloatZ (bool sampleNow);
00175 
00176         /**
00177          * Get the die temperature. Note that the actual sensor range is only -40C to 125C, so not all outputs are valid.
00178          * @returns 8-bit die temperature data
00179          */
00180         int8_t getDieTemp();   
00181         
00182         /**
00183          * @returns the die temperature in deg Celsius. Note that the actual sensor range is only -40C to 125C, so not all possible outputs may be valid.
00184          */
00185         float getFloatDieTemp ();
00186      
00187     private:
00188         /**
00189          * Interrupt service routine for fetching magnetometer data from the device.
00190          */
00191         virtual void __sample_data_ISR();
00192     
00193         ///////////////// CONSTANTS /////////////////////
00194         
00195         //Device register addresses
00196         static const uint8_t DR_STATUS =        0x00;
00197         static const uint8_t OUT_X_MSB =        0x01;
00198         static const uint8_t OUT_X_LSB =        0x02;
00199         static const uint8_t OUT_Y_MSB =        0x03;
00200         static const uint8_t OUT_Y_LSB =        0x04;
00201         static const uint8_t OUT_Z_MSB =        0x05;
00202         static const uint8_t OUT_Z_LSB =        0x06;
00203         static const uint8_t WHO_AM_I =         0x07;
00204         static const uint8_t SYSMOD =           0x08;
00205         static const uint8_t OFF_X_MSB =        0x09;
00206         static const uint8_t OFF_X_LSB =        0x0A;
00207         static const uint8_t OFF_Y_MSB =        0x0B;
00208         static const uint8_t OFF_Y_LSB =        0x0C;
00209         static const uint8_t OFF_Z_MSB =        0x0D;
00210         static const uint8_t OFF_Z_LSB =        0x0E;
00211         static const uint8_t DIE_TEMP =         0x0F;
00212         static const uint8_t CTRL_REG1 =        0x10;
00213         static const uint8_t CTRL_REG2 =        0x11; 
00214         
00215         //Register masks
00216         static const uint8_t DR_STATUS_ZYXOW_MASK =                 0x80; //b1000 0000
00217         static const uint8_t DR_STATUS_ZOW_MASK =                   0x40; //b0100 0000
00218         static const uint8_t DR_STATUS_YOW_MASK =                   0x20; //b0010 0000
00219         static const uint8_t DR_STATUS_XOW_MASK =                   0x10; //b0001 0000
00220         static const uint8_t DR_STATUS_ZYXDR_MASK =                 0x08; //b0000 1000
00221         static const uint8_t DR_STATUS_ZDR_MASK =                   0x04; //b0000 0100
00222         static const uint8_t DR_STATUS_YDR_MASK =                   0x02; //b0000 0010
00223         static const uint8_t DR_STATUS_XDR_MASK =                   0x01; //b0000 0001
00224         static const uint8_t SYSMOD_MASK =                          0x03; //b0000 0011
00225         static const uint8_t OFF_X_LSB_MASK =                       0xFE; //b1111 1110
00226         static const uint8_t OFF_Y_LSB_MASK =                       0xFE; //b1111 1110
00227         static const uint8_t OFF_Z_LSB_MASK =                       0xFE; //b1111 1110
00228         static const uint8_t CTRL_REG1_DR_MASK =                    0xB0; //b1110 0000
00229         static const uint8_t CTRL_REG1_OS_MASK =                    0x18; //b0001 1000
00230         static const uint8_t CTRL_REG1_FR_MASK =                    0x04; //b0000 0100
00231         static const uint8_t CTRL_REG1_TM_MASK =                    0x02; //b0000 0010
00232         static const uint8_t CTRL_REG1_AC_MASK =                    0x01; //b0000 0001
00233         static const uint8_t CTRL_REG2_AUTO_MRST_EN_MASK =          0x80; //b1000 0000
00234         static const uint8_t CTRL_REG2_RAW_MASK =                   0x20; //b0010 0000
00235         static const uint8_t CTRL_REG2_MAG_RST_MASK =               0x10; //b0001 0000
00236         
00237         //Mapping of data values
00238         static const float TEMP_DIV = 1; //deg Celsius/level. Note that 8-bit range is -128C to 127C, but the sensor can only do -40C to 125C.
00239         static const float DATA_CONVERSION = 0.10; //uT/level
00240         
00241         //////////////// VARIABLES /////////////////////
00242         //MAG3110 state ("cached" from the values actually on the device)
00243         volatile int16_t __x;
00244         volatile int16_t __y;
00245         volatile int16_t __z;
00246         
00247         bool __active;
00248         adc_smpl_rate_t __adc_rate;
00249         oversmpl_ratio_t __ratio;
00250         smpl_rate_t __rate;
00251 };
00252 
00253 #endif