This is a Freescale’s three axis, digital magnetometer MAG3110 is a low-power to adopt & reads an orientation an independent electronic compass that can be provide accurate heading information. It uses 400 kHz fast mode i2C serial interface output and smart embedded function can easily hook it up to your microcontroller.
Block Diagram
The MAG3110 is capable of measuring a magnetic field with an output data rate up to 80 Hz, these output ODR correspond to sample intervals from 12.5 milliseconds to several seconds. MAG3110 chip is available in a dual-flat-no-led package and operates over temperature range of below 40 degree Celsius to + 85 degree Celsius, runs on 1.95 to 3.6 supply voltage – IO voltage 1.62 and useful on electronic compass and location-based services.
Component Required
- Arduino Microcontrollers, Teensy, ESP8266, STM32F10X, NUCLEO_401RE, NUCLEO_F030R8, NUCLEO_F103RB, NUCLEO_F302R8, NUCLEO_F411RE, ATMEGA328 16/12, ATMEGA32u4 16/8/ MHz, ESP8266, ATMEGA250 16 MHz, ATSAM3x8E, ATSAM21D, ATTINY8516/8 MHz (Note: The Diagram below is using NANO. If your using other MCU please refer to the respective pin-outs
- MAG3110 Chip or Module
- Solder Less Bread Board (Prototyping)
- Jumpers Wires / DuPont Wires
Wiring Guide
Sketch Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
#include <Wire.h> // Import wire library #define MAG_ADDR 0x0E //i2C Address 7Bit address void setup() { Wire.begin(); // Start i2c bus this optional for master Serial.begin(9600); config(); // Start MAG3110 on } void loop() { print_values(); delay(5); } void config(void) { Wire.beginTransmission(MAG_ADDR); // Transmit to i2c device 0x0E Wire.write(0x11); // control the register 2 Wire.write(0x80); // set to write 0x80 to enable auto resets Wire.endTransmission(); // set to stop transmitting delay(15); Wire.beginTransmission(MAG_ADDR); // set to transmit i2c device 0x0E Wire.write(0x10); // control register 1 Wire.write(1); // set to write 0x01 to enable active mode Wire.endTransmission(); // set tp stop transmitting } void print_values(void) { serial.print("--------- 14CORE | MAG3110 3-AXIS TEST CODE ----------") serial.println("======================================================") Serial.println("Starting... ") Serial.println("") Serial.print("X = "); Serial.print(read_x()); Serial.println("--------------"); Serial.print(" Y = "); Serial.print(read_y()); Serial.println("----------------"); Serial.print("Z = "); Serial.println(read_z()); } int mag_read_register(int reg) { int reg_val; Wire.beginTransmission(MAG_ADDR); //start transmit to i2c device address 0x0E Wire.write(reg); Wire.endTransmission(); delayMicroseconds(2); //Delay for 1.3 to start and stop Wire.requestFrom(MAG_ADDR, 1); // set to request 1 byte while(Wire.available()) // set the slave may write less than requested { reg_val = Wire.read(); // starting reading the byte } return reg_val; } int mag_read_value(int msb_reg, int lsb_reg) { int val_low, val_high; //set variable to define the MSB and LSB val_high = mag_read_register(msb_reg); delayMicroseconds(2); val_low = mag_read_register(lsb_reg); int out = (val_low|(val_high << 8)); //concatenate the MSB and LSB return out; } int read_x(void) { return mag_read_value(0x01, 0x02); } int read_y(void) { return mag_read_value(0x03, 0x04); } int read_z(void) { return mag_read_value(0x05, 0x06); } |
C Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
/* Includes ------------------------------------------------------------------*/ #include "stm32f10x.h" #include "24C02.h" // i2C Serial 2 Wire Library #include <string.h> #include <stdio.h> #include <math.h> #ifdef __GNUC__ /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf set to 'Yes') calls __io_putchar() */ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif /* __GNUC__ */ /* Private function prototypes -----------------------------------------------*/ void GPIO_Configuration(void); void USART_Configuration(void); uint16_t MAG3110_DataProcess (int MAG3110_XData,int MAG3110_YData); void MAG3110_STD(void); /******************************************************************************* * Function Name : Delay * Description : Delay Time * Input : - nCount: Delay Time * Output : None * Return : None * Attention : None *******************************************************************************/ void Delay (uint32_t nCount) { for(; nCount != 0; nCount--); } int MAG3110_XOFF=0,MAG3110_YOFF=0; int MAG3110_XMax=0,MAG3110_YMax=0,MAG3110_XMin=0,MAG3110_YMin=0; int MAG3110_XData=0,MAG3110_YData=0; int ang; /******************************************************************************* * Function Name : main * Description : Main program * Input : None * Output : None * Return : None * Attention : None *******************************************************************************/ int main(void) { int i; GPIO_Configuration(); USART_Configuration(); I2C_Configuration(); printf("\r\n****************************************************************\r\n"); MAG3110_Init(); i= I2C_Read(I2C1,MAG3110_IIC_ADDRESS,WHO_AM_I_REG,0,1); if (i == MAG3110Q_ID) { printf("ID:MAG3110,OK!\n "); } else { printf("Failed to identify i2C Address\n"); } while(1) { Delay(0xfffff); Delay(0xfffff); Delay(0xfffff); Delay(0xfffff); Delay(0xfffff); Delay(0xfffff); i=I2C_Read(I2C1,MAG3110_IIC_ADDRESS,STATUS_00_REG,0,1); if(i&ZYXDR_MASK) { MAG3110_STD(); printf("The data needs to be calibrated, turning a lap"); printf("\r\n\r\n"); printf("\r\nPoint to the south angle:%d°\r\n",ang); } else { printf("ID Failed!\n"); } } } uint16_t MAG3110_DataProcess (int MAG3110_XData,int MAG3110_YData) { int MAG3110_Ang; MAG3110_XData -= MAG3110_XOFF; MAG3110_YData -= MAG3110_YOFF; if (MAG3110_XData == 0) { if (MAG3110_YData>0) { MAG3110_Ang = 90; } else { MAG3110_Ang = 270; } } else if (MAG3110_YData == 0) { if (MAG3110_XData>0) { MAG3110_Ang = 0; } else { MAG3110_Ang = 180; } } else if ((MAG3110_XData > 0) && (MAG3110_YData > 0)) { MAG3110_Ang = (atan ( ( (float)MAG3110_YData) / ( (float) MAG3110_XData ) ) ) * 180 / 3.14; } else if ((MAG3110_XData < 0) && (MAG3110_YData > 0)) { MAG3110_XData = -MAG3110_XData; MAG3110_Ang = 180 - (atan ( ( (float)MAG3110_YData) / ( (float) MAG3110_XData ) ) ) * 180 / 3.14; } else if ((MAG3110_XData < 0) && (MAG3110_YData < 0)) { MAG3110_XData = -MAG3110_XData; MAG3110_YData = -MAG3110_YData; MAG3110_Ang = (atan ( ( (float)MAG3110_YData) / ( (float) MAG3110_XData ) ) ) * 180 / 3.14 + 180; } else if ((MAG3110_XData > 0) && (MAG3110_YData < 0)) { MAG3110_YData = -MAG3110_YData; MAG3110_Ang = 360 - (atan ( ( (float)MAG3110_YData) / ( (float) MAG3110_XData ) ) ) * 180 / 3.14; } return MAG3110_Ang; } void MAG3110_STD(void) { tword wx, wy, wz; static uint8_t First_Flag=0; wx.mbyte.hi = I2C_Read(I2C1,MAG3110_IIC_ADDRESS,OUT_X_MSB_REG,0,1); wx.mbyte.lo = I2C_Read(I2C1,MAG3110_IIC_ADDRESS,OUT_X_LSB_REG,0,1); wy.mbyte.hi = I2C_Read(I2C1,MAG3110_IIC_ADDRESS,OUT_Y_MSB_REG,0,1); wy.mbyte.lo = I2C_Read(I2C1,MAG3110_IIC_ADDRESS,OUT_Y_LSB_REG,0,1); wz.mbyte.hi = I2C_Read(I2C1,MAG3110_IIC_ADDRESS,OUT_Z_MSB_REG,0,1); wz.mbyte.lo = I2C_Read(I2C1,MAG3110_IIC_ADDRESS,OUT_Z_LSB_REG,0,1); printf("X AXIS:%d ",wx.mbyte.hi*256+wx.mbyte.lo); printf("Y AXIS:%d ",wy.mbyte.hi*256+wy.mbyte.lo); printf("Z AXIS:%d ",wz.mbyte.hi*256+wz.mbyte.lo); MAG3110_XData=wx.mbyte.hi*256+wx.mbyte.lo; MAG3110_YData=wy.mbyte.hi*256+wy.mbyte.lo; if (!First_Flag) { MAG3110_XMax = MAG3110_XData; MAG3110_XMin = MAG3110_XData; MAG3110_YMax = MAG3110_YData; MAG3110_YMin = MAG3110_YData; First_Flag = 1; } if (MAG3110_XData > MAG3110_XMax) { MAG3110_XMax = MAG3110_XData; } else if (MAG3110_XData < MAG3110_XMin) { MAG3110_XMin = MAG3110_XData; } if (MAG3110_YData > MAG3110_YMax) { MAG3110_YMax = MAG3110_YData; } else if (MAG3110_YData < MAG3110_YMin) { MAG3110_YMin = MAG3110_YData; } MAG3110_XOFF = (MAG3110_XMax + MAG3110_XMin) / 2; MAG3110_YOFF = (MAG3110_YMax + MAG3110_YMin) / 2; printf("\r\n MAG3110 X Max:%d ",MAG3110_XMax); printf("MAG3110 X Min:%d\r\n",MAG3110_XMin); printf("MAG3110 X OFF:%d\r\n",MAG3110_XOFF); printf("\r\n MAG3110 Y Max:%d ",MAG3110_YMax); printf("MAG3110 Y Min:%d\r\n ",MAG3110_YMin); printf("AG3110 Y OFF:%d\r\n",MAG3110_YOFF); ang=MAG3110_DataProcess(wx.mbyte.hi*256+wx.mbyte.lo,wy.mbyte.hi*256+wy.mbyte.lo); } void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC , ENABLE); /** * LED1 -> PC9 , LED2 -> PC10 , LED3 -> PC11 , LED4 -> PC12 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { } } #endif /********************************************************************************************************* END FILE *********************************************************************************************************/ |
Downloads
Download MAG3110 Datasheet | PDF