![](/media/cache/profiles/Timo_01_DSC_4754_533x533.jpg.50x50_q85.jpg)
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.
Diff: main.cpp
- Revision:
- 0:2666acd6dfb3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Dec 06 20:46:15 2021 +0000 @@ -0,0 +1,172 @@ +/* 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); + } +} \ No newline at end of file