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.

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