The sensor is the PmodCMPS2 compass sensor with the 3D magnetometer chip MMC34160PJ Data sheet https://download.mikroe.com/documents/datasheets/MMC3416xPJ_Rev_C_2013_10_30.pdf The values for Helsinki in December 2021 ( Model used WMM-2020 https://www.ngdc.noaa.gov/geomag/calculators/magcalc.shtml#igrfwmm ) North component = 146 milli Gaus East component = 25 milli Gaus Vertical component = 502 milli Gaus Total field = 524 milli Gaus Connect: L432KC -- PmodCMPS2 PA_9 -- SCL PA_10 -- SDA GND -- GND 3V3 -- VCC Set the jumpers SDA and SCL on the PmodCMPS2.
main.cpp
- Committer:
- timo_k2
- Date:
- 2021-12-06
- Revision:
- 0:2666acd6dfb3
File content as of revision 0:2666acd6dfb3:
/* mbed Microcontroller Library * Copyright (c) 2019 ARM Limited * SPDX-License-Identifier: Apache-2.0 * * The sensor is the PmodCMPS2 compass sensor with * the 3D magnetometer chip MMC34160PJ * Data sheet * https://download.mikroe.com/documents/datasheets/MMC3416xPJ_Rev_C_2013_10_30.pdf * * On the earth surface the world magnetic field points towards the north and * in level with the horizon at the equador. Further north the field starts * pointing downwards. In southern Europe it points downwards with inclination * 60 degrees. In Scandinavia it points downwards with inclination 75 degrees. * At the north pole it points straight down with inclination 90 degrees. * * The declination is the difference between geaographic and magnetic north pole. * The declination depends where and when you are observing the field. * * The values for Helsinki in December 2021 ( Model used WMM-2020 * https://www.ngdc.noaa.gov/geomag/calculators/magcalc.shtml#igrfwmm ) * Declination 9 degr 45 min * Inclination 73 degr 35 min * North component 14572 nT = 146 milli Gaus * East component 2505 nT = 25 milli Gaus * Vertical component 50222 nT = 502 milli Gaus * Total field 52353 nT = 524 milli Gaus * * Connect: * L432KC -- PmodCMPS2 * PA_9 -- SCL * PA_10 -- SDA * GND -- GND * 3V3 -- VCC * Set the jumpers SDA and SCL on the PmodCMPS2. * * version 06.12.2021 * Timo Karppinen Apache-2.0 **********************************************************************/ #include "mbed.h" I2C i2c(PA_10, PA_9); // Pins D1 and D0 on the L432KC const int CMPS2_address = 0x30; // 7 bit I2C address 0110000b for MMC34160PJ const int addr8bit = 0x30 << 1; // address plus the 0 for write the 1 for read int main() { char cmd[2]; // Typically command register address , command // Initialize compass ThisThread::sleep_for(2000ms); //command internal control register 0 for set operation cmd[0] = 0x07; // Control register0 cmd[1] = 0x80; // control register0 bit7 = true, "refill cap" i2c.write(addr8bit, cmd, 2); ThisThread::sleep_for(50ms); cmd[0] = 0x07; // Control register0 cmd[1] = 0x20; // control register0 bit5 = true, SET i2c.write(addr8bit, cmd, 2); ThisThread::sleep_for(50ms); //command internal control register 1 to 16 bit resolution, 8ms measurement time cmd[0] = 0x08; // Control register1 cmd[1] = 0x00; // bit0 = false bit1 = false, 16 bits 8ms i2c.write(addr8bit, cmd, 2); ThisThread::sleep_for(500ms); while (1) { //Get heading int xyzA[3]; for(int i = 0; i < 3; i++){ xyzA[i] = 0; } int xyzB[3]; for(int i = 0; i < 3; i++){ xyzB[i] = 0; } int xyz[3]; for(int i = 0; i < 3; i++){ xyz[i] = 0; } //command internal control register 0 for set operation cmd[0] = 0x07; // Control register0 cmd[1] = 0x80; // control register0 bit7 = true, "refill cap" i2c.write(addr8bit, cmd, 2); ThisThread::sleep_for(100ms); cmd[0] = 0x07; // Control register0 cmd[1] = 0x20; // control register0 bit5 = true, SET i2c.write(addr8bit, cmd, 2); ThisThread::sleep_for(50ms); //command internal control register 0 bit 0 (measure) cmd[0] = 0x07; // Control register0 cmd[1] = 0x01; // bit0 = 1, Take measurement i2c.write(addr8bit, cmd, 2); ThisThread::sleep_for(50ms); // Wait for measurement data ready ThisThread::sleep_for(500ms); //Reading six bytes char temp[6]; cmd[0] = 0x00; i2c.write(addr8bit, cmd, 1); i2c.read(addr8bit, temp, 6); // converting to 16 bit integers xyzA[0] = (int)((temp[1]<<8) | temp[0]); xyzA[1] = (int)((temp[3]<<8) | temp[2]); xyzA[2] = (int)((temp[5]<<8) | temp[4]); printf("Bytes read from CMPS X %d %d Y %d %d Z %d %d\n", temp[0 ],temp[1], temp[2], temp[3], temp[4], temp[5]); //printf(" Magnetic field X %d mG Y %d mG Z %d mG\n", xyz[0], xyz[1], xyz[2]); //command internal control register 0 for set operation cmd[0] = 0x07; // Control register0 cmd[1] = 0x80; // control register0 bit7 = true, "refill cap" i2c.write(addr8bit, cmd, 2); ThisThread::sleep_for(100ms); cmd[0] = 0x07; // Control register0 cmd[1] = 0x40; // control register0 bit6 = true, RESET i2c.write(addr8bit, cmd, 2); ThisThread::sleep_for(50ms); //command internal control register 0 bit 0 (measure) cmd[0] = 0x07; // Control register0 cmd[1] = 0x01; // bit0 = 1, Take measurement i2c.write(addr8bit, cmd, 2); ThisThread::sleep_for(50ms); // Wait for measurement data ready ThisThread::sleep_for(500ms); //Reading six bytes //char temp[6]; cmd[0] = 0x00; i2c.write(addr8bit, cmd, 1); i2c.read(addr8bit, temp, 6); // converting to 16 bit integers xyzB[0] = (int)((temp[1]<<8) | temp[0]); xyzB[1] = (int)((temp[3]<<8) | temp[2]); xyzB[2] = (int)((temp[5]<<8) | temp[4]); printf("Bytes read from CMPS X %d %d Y %d %d Z %d %d\n", temp[0 ],temp[1], temp[2], temp[3], temp[4], temp[5]); // Eliminate offset from X Y Z. The field was measured with both coil orientations. for(int i = 0; i < 3; i++){ xyz[i] = xyzA[i] - xyzB[i]; // xyz[i] = ( xyz [i] *100)/yourfactor; // Scale factor. 100/(yourfactor) } printf(" Magnetic field X %d mG Y %d mG Z %d mG\n", xyz[0], xyz[1], xyz[2]); // Get the correct scale factor by pointing each sensor axis x, y, z towards // 73 degrees down and to the north to get the highest values. // Devide your highest value by 524. You should get something between 3 and 4 // Multiply your value by 100 and replace "yourfactor" with the result. ThisThread::sleep_for(1000ms); } }