2019-2020 LIS2DW12 Accelerometer Project

Dependencies:   X_NUCLEO_IKS01A3

Revision:
8:fa346d946e7e
Parent:
7:4a3b6202963e
Child:
9:7cda26534126
--- a/main.cpp	Thu Sep 05 15:43:50 2019 +0000
+++ b/main.cpp	Tue Sep 17 08:48:13 2019 +0000
@@ -37,24 +37,69 @@
 */
 
 /*
-    LELEC2811 Magnetometer LIS2MDL Project
+    LELEC2811 Multisensor IKS01A3 Project
     M. Lefebvre - 2019
 */
 
 /* Includes */
 #include <stdlib.h>
+#include <time.h>
 #include "mbed.h"
 #include "XNucleoIKS01A3.h"
 #include "stm32l073xx.h"
 #include "stm32l0xx_hal_flash.h"
 
 /* Defines */
+#define FS                      25.0    // Sampling frequency (Hz)
+
+// LIS2MDL Magnetometer
 #define LIS2MDL_ODR             50.0    // Output data rate (10, 20, 50 or 100 Hz)
 #define LIS2MDL_LP              0       // Power mode (0 for high-resolution mode, 1 for low-power mode)
 #define LIS2MDL_LPF             0       // Bandwidth (0 for ODR/2, 1 for ODR/4)
 #define LIS2MDL_COMP_TEMP_EN    1       // Temperature compensation (0 disabled, 1 enabled)
 #define LIS2MDL_OFF_CANC        1       // Offset cancellation (0 for no offset cancellation, 1 for offset cancellation, 2 for set pulse only at power-on)
-#define FS                      12.5    // Sampling frequency (Hz)      
+#define LIS2MDL_DATA_SIZE       12      // Number of bytes for LIS2MDL magnetometer data
+
+// LPS22HH Pressure sensor
+#define P0                      1013.26 // Sea level pressure (hPa)
+#define LPS22HH_ODR             50.0    // Output data rate (one-shot, 1, 10, 25, 50, 75, 100, 200 Hz)
+#define LPS22HH_LOW_NOISE_EN    1       // Low-noise (0 disabled, 1 enabled)
+#define LPS22HH_LPF_CFG         3       // Device bandwidth (0 for ODR/2, 2 for ODR/9, 3 for ODR/20)
+
+// LIS2DW12 Accelerometer
+#define LIS2DW12_ODR            4       // Output data rate (0 power down, 1 HP 12.5Hz/LP 1.6Hz, 2 for 12.5Hz, 3 for 25Hz, 4 for 50Hz, 5 for 100Hz, 6 for 200Hz, 7 for HP 400Hz/LP 200Hz, 8 for HP 800Hz/LP 200Hz, 9 for HP 1600Hz/LP 200Hz)
+#define LIS2DW12_FS             4       // Full-scale +-(2, 4, 8 or 16 g)
+#define LIS2DW12_BW_FILT        2       // Filter bandwidth (0 for ODR/2, 1 for ODR/4, 2 for ODR/10, 3 for ODR/20)
+#define LIS2DW12_LP_MODE        0       // Low-power modes 1 to 4 (1 gives the max. rms noise, 4 gives the min. rms noise)
+#define LIS2DW12_MODE           1       // Mode (0 for low-power, 1 for high-performance, 2 for single data conversion)
+#define LIS2DW12_LOW_NOISE      1       // Low-noise (0 disable, 1 enabled)
+#define LIS2DW12_POWER_MODE     LIS2DW12_LP_MODE + (LIS2DW12_MODE << 2) + (LIS2DW12_LOW_NOISE << 4)
+
+// HTS221 Relative humidity and temperature sensor
+#define HTS221_ODR              1       // Output data rate (one-shot, 1Hz, 7Hz, 12.5Hz)
+#define HTS221_HEATER           0       // Heater configuration (0 disabled, 1 enabled)
+#define HTS221_AVGH             32      // Humidity averaging (4 to 512)
+#define HTS221_AVGT             16      // Temperature averaging (2 to 256)
+
+// LSM6DSO Accelerometer + gyroscope
+#define LSM6DSO_ODR_XL          12.5    // Accelerometer output data rate (12.5, 26, 52, 104, 208, 416, 833, 1.66k, 3.33k, 6.66kHz)
+#define LSM6DSO_FS_XL           4       // Accelerometer full scale (2, 4, 8, 16g)
+#define LSM6DSO_XL_HM_MODE      1       // Accelerometer high-performance mode (0 enabled, 1 disabled)
+#define LSM6DSO_XL_ULP_EN       0       // Accelerometer ultra-low-power configuration (0 disabled, 1 enabled)
+#define LSM6DSO_ODR_G           16      // Gyroscope output data rate (12.5, 26, 52, 104, 208, 416, 833, 1.66k, 3.33k, 6.66kHz)
+#define LSM6DSO_FS_G            1000    // Gyroscope full scale (250, 500, 1000, 2000dps)
+
+/* Functions definition */
+bool acquisition_task(bool verbose);
+void read_task();
+void print_flash_info();
+bool erase_flash(bool verbose);
+bool write_flash(uint32_t Flash_addr, uint32_t* Flash_wdata, int32_t n_words, bool verbose);
+void read_flash(uint32_t Flash_addr, uint32_t* Flash_rdata, uint32_t n_bytes);
+void button1_enabled_cb(void);
+void button1_onpressed_cb(void);
+static char *print_double(char *str, double v);
+float pressure_to_altitude(double pressure);
 
 /* Serial link */
 Serial pc(SERIAL_TX, SERIAL_RX);
@@ -76,6 +121,307 @@
 static LIS2DW12Sensor *accelerometer = mems_expansion_board->accelerometer;
 static STTS751Sensor *temp = mems_expansion_board->t_sensor;
 
+/* Main */
+int main()
+{
+    uint8_t id;
+    float read_reg, read_reg_1;
+    uint8_t read_reg_int, read_reg_int_1, read_reg_int_2;
+    
+    bool save_data = false;
+    uint32_t Flash_addr = FLASH_BANK2_BASE;
+
+    /* Serial link configuration */
+    pc.baud(115200);
+    
+    /* Button configuration */
+    button1.fall(callback(button1_onpressed_cb)); // Attach ISR to handle button press event
+    
+    /* Reset message */
+    printf("\n\r**************************************************\n\r");
+    printf("LELEC2811 IKS01A3 Multisensor Program\n\r");
+    printf("**************************************************\n\r");
+    
+    /* LIS2MDL magnetometer sensor configuration */
+    magnetometer->enable();
+    printf("/***** LIS2MDL magnetometer configuration *****/\r\n");
+    
+    magnetometer->read_id(&id);
+    printf("LIS2MDL magnetometer = 0x%X\r\n", id);
+    
+    magnetometer->set_m_odr(LIS2MDL_ODR);
+    magnetometer->get_m_odr(&read_reg);
+    printf("LIS2MDL ODR = %1.1f [Hz]\r\n", read_reg);
+    
+    magnetometer->set_m_lp(LIS2MDL_LP);
+    magnetometer->get_m_lp(&read_reg_int);
+    printf("LIS2MDL LP = %1d\r\n", read_reg_int);
+    
+    magnetometer->set_m_lpf(LIS2MDL_LPF);
+    magnetometer->get_m_lpf(&read_reg_int);
+    printf("LIS2MDL LPF = %1d\r\n", read_reg_int);
+    
+    magnetometer->set_m_comp_temp_en(LIS2MDL_COMP_TEMP_EN);
+    magnetometer->get_m_comp_temp_en(&read_reg_int);
+    printf("LIS2MDL COMP_TEMP_EN = %1d\r\n", read_reg_int);
+    
+    magnetometer->set_m_off_canc(LIS2MDL_OFF_CANC);
+    magnetometer->get_m_off_canc(&read_reg_int);
+    printf("LIS2MDL OFF_CANC = %1d\r\n", read_reg_int);
+    
+    /* LPS22HH pressure sensor configuration */
+    press_temp->enable();
+    printf("/***** LPS22HH pressure sensor configuration *****/\r\n");
+    
+    press_temp->read_id(&id);
+    printf("LPS22HH pressure = 0x%X\r\n", id);
+    
+    press_temp->set_odr(LPS22HH_ODR, LPS22HH_LOW_NOISE_EN);
+    press_temp->get_odr(&read_reg, &read_reg_int);
+    printf("LPS22HH ODR = %1.1f [Hz]\r\n", read_reg);
+    printf("LPS22HH LOW_NOISE_EN = %1d\r\n", read_reg_int);
+    
+    press_temp->set_lpfp_cfg(LPS22HH_LPF_CFG);
+    press_temp->get_lpfp_cfg(&read_reg_int);
+    printf("LPS22HH LPF_CFG = %1d\r\n", read_reg_int);
+    
+    /* LIS2DW12 accelerometer sensor configuration */
+    accelerometer->enable_x();
+    printf("/***** LIS2DW12 accelerometer sensor configuration *****/\r\n");
+    
+    accelerometer->read_id(&id);
+    printf("LIS2DW12 accelerometer = 0x%X\r\n", id);
+    
+    accelerometer->set_x_odr(LIS2DW12_ODR);
+    accelerometer->get_x_odr(&read_reg);
+    printf("LIS2DW12 ODR = %1.3f [Hz]\r\n", read_reg);
+    
+    accelerometer->set_x_fs(LIS2DW12_FS);
+    accelerometer->get_x_fs(&read_reg);
+    printf("LIS2DW12 FS = %1.3f [g]\r\n", read_reg);
+    
+    accelerometer->set_x_bw_filt(LIS2DW12_BW_FILT);
+    accelerometer->get_x_bw_filt(&read_reg_int);
+    printf("LIS2DW12 BW_FILT = %1d\r\n", read_reg_int);
+    
+    accelerometer->set_x_power_mode(LIS2DW12_POWER_MODE);
+    accelerometer->get_x_power_mode(&read_reg_int, &read_reg_int_1, &read_reg_int_2);
+    printf("LIS2DW12 LP_MODE = %1d\r\n", read_reg_int);
+    printf("LIS2DW12 MODE = %1d\r\n", read_reg_int_1);
+    printf("LIS2DW12 LOW_NOISE = %1d\r\n", read_reg_int_2);
+    
+    /* HTS221 relative humidity and temperature sensor configuration */
+    hum_temp->enable();    
+    printf("/***** HTS221 humidity sensor configuration *****/\r\n");
+    
+    hum_temp->read_id(&id);
+    printf("HTS221 humidity & temperature = 0x%X\r\n", id);
+    
+    hum_temp->set_odr(HTS221_ODR);
+    hum_temp->get_odr(&read_reg);
+    printf("HTS221 ODR = %1.3f [Hz]\r\n", read_reg);
+    
+    hum_temp->set_heater(HTS221_HEATER);
+    hum_temp->get_heater(&read_reg_int);
+    printf("HTS221 HEATER = %1d\r\n", read_reg_int);
+    
+    hum_temp->set_avg(HTS221_AVGH, HTS221_AVGT);
+    hum_temp->get_avg(&read_reg, &read_reg_1);
+    printf("HTS221 AVGH = %1.0f\r\n", read_reg);
+    printf("HTS221 AVGT = %1.0f\r\n", read_reg_1);
+    
+    /* STTS751 Temperature sensor configuration */
+    temp->enable();
+    printf("/***** STTS751 temperature sensor configuration *****/\r\n");
+    
+    temp->read_id(&id);
+    printf("STTS751 temperature = 0x%X\r\n", id);
+    
+    /* LSM6DSO Accelerometer and gyroscope configuration */
+    acc_gyro->enable_x();
+    acc_gyro->enable_g();
+    printf("/***** LSM6DSO accelerometer and gyroscope sensor configuration *****/\r\n");
+    
+    acc_gyro->read_id(&id);
+    printf("LSM6DSO accelerometer & gyroscope = 0x%X\r\n", id);
+    
+    acc_gyro->set_x_odr(LSM6DSO_ODR_XL);
+    acc_gyro->get_x_odr(&read_reg);
+    printf("LSM6DSO ODR_XL = %1.3f [Hz]\r\n", read_reg);
+    
+    acc_gyro->set_x_fs(LSM6DSO_FS_XL);
+    acc_gyro->get_x_fs(&read_reg);
+    printf("LSM6DSO FS_XL = %1.3f [g]\r\n", read_reg);
+    
+    acc_gyro->set_x_power_mode(LSM6DSO_XL_HM_MODE, LSM6DSO_XL_ULP_EN);
+    acc_gyro->get_x_power_mode(&read_reg_int, &read_reg_int_1);
+    printf("LSM6DSO XL_HM_MODE = %1d\r\n", read_reg_int);
+    printf("LSM6DSO XL_ULP_EN = %1d\r\n", read_reg_int_1);
+    
+    acc_gyro->set_g_odr(LSM6DSO_ODR_G);
+    acc_gyro->get_g_odr(&read_reg);
+    printf("LSM6DSO ODR_G = %1.3f [Hz]\r\n", read_reg);
+    
+    acc_gyro->set_g_fs(LSM6DSO_FS_XL);
+    acc_gyro->get_g_fs(&read_reg);
+    printf("LSM6DSO FS_G = %1.3f [dps]\r\n", read_reg);
+    
+    /* Print Flash memory information */
+    print_flash_info();
+    
+    /* Information for the user */
+    printf("Press blue button to start data acquisition\r\n");
+    printf("Press 'R' to read previously measured data\r\n");
+    
+    /* Acquisition loop */
+    while(1) {
+        // Start saving data when button is pushed
+        if (button1_pressed) {
+            button1_pressed = false;
+            save_data = true;
+            erase_flash(false);
+            printf("Acquiring data...\r\n");
+            printf("Press blue button to stop data acquisition\r\n");
+            Flash_addr = FLASH_BANK2_BASE;
+        }
+        
+        if (save_data) {
+            // Acquisition task
+            save_data = acquisition_task(true);
+        }
+        else {
+            // Read task
+            read_task();
+        }
+    }
+}
+
+/* Acquisition task */
+bool acquisition_task(bool verbose)
+{
+    int32_t m_axes[3];
+    int32_t acc_axes[3];
+    int32_t acc_axes_1[3];
+    int32_t gyro_axes[3];
+    float pressure_value, hum_value, temp_value, temp_value_1;
+    char buffer[32];
+    
+    uint32_t buffer_size = FLASH_PAGE_SIZE/4;
+    uint32_t data_ind = 0;
+    uint32_t data_buffer[buffer_size];
+    
+    uint32_t Flash_addr = FLASH_BANK2_BASE;
+
+    while (Flash_addr <= FLASH_BANK2_END-FLASH_PAGE_SIZE+1) {
+        // Read sensors data
+        magnetometer->get_m_axes(m_axes);
+        press_temp->get_pressure(&pressure_value);
+        accelerometer->get_x_axes(acc_axes);
+        hum_temp->get_temperature(&temp_value);
+        hum_temp->get_humidity(&hum_value);
+        temp->get_temperature(&temp_value_1);
+        acc_gyro->get_x_axes(acc_axes_1);
+        acc_gyro->get_g_axes(gyro_axes);
+        
+        // Save data to Flash memory
+        for (int i=0; i<3; i++) {
+            // Write page in Flash memory
+            if (data_ind >= buffer_size) {
+                write_flash(Flash_addr, &data_buffer[0], buffer_size, false);
+                Flash_addr += FLASH_PAGE_SIZE;
+                data_ind = 0;
+            }
+            
+            // Write data to buffer
+            data_buffer[data_ind] = (uint32_t) m_axes[i];
+            data_ind++;
+        }
+        
+        // Print data in terminal
+        if (verbose) {
+            printf("LIS2MDL: [mag/mgauss] %6d, %6d, %6d\r\n", ((uint32_t) m_axes[0]), ((uint32_t) m_axes[1]), ((uint32_t) m_axes[2]));
+            printf("LPS22HH: [press/mbar] %1.3f, [alt/m] %1.3f\r\n", pressure_value, pressure_to_altitude(pressure_value));
+            printf("HTS221: [temp/deg C] %1.3f, [hum/%%] %1.3f\r\n", temp_value, hum_value);
+            printf("STTS751 [temp/deg C] %1.3f\r\n", temp_value_1);
+            printf("LIS2DW12: [acc/mg] %6d, %6d, %6d\r\n", ((uint32_t) acc_axes[0]), ((uint32_t) acc_axes[1]), ((uint32_t) acc_axes[2]));
+            printf("LSM6DSO: [acc/mg] %6d, %6d, %6d\r\n", ((uint32_t) acc_axes_1[0]), ((uint32_t) acc_axes_1[1]), ((uint32_t) acc_axes_1[2]));
+            printf("LSM6DSO: [gyro/mdps] %6d, %6d, %6d\r\n", ((uint32_t) gyro_axes[0]), ((uint32_t) gyro_axes[1]), ((uint32_t) gyro_axes[2]));
+        }
+        
+        // Wait for acquisition period
+        wait(1/FS);
+        
+        // Stop saving data when button is pushed
+        if (button1_pressed) {
+            button1_pressed = false;
+            // Save remaining data to Flash memory
+            write_flash(Flash_addr, &data_buffer[0], data_ind, false);
+            printf("Data acquisition stopped\r\n");
+            printf("Press 'R' to read the data\r\n");
+            return false;
+        }
+    }
+    printf("Data acquisition stopped\r\n");
+    printf("Press 'R' to read the data\r\n");
+    return false;
+}
+
+/* Read task */
+void read_task()
+{
+    char pc_input;
+    uint32_t Flash_rdata[3];
+    bool flash_empty = false;
+    
+    // Read terminal input
+    if (pc.readable()) {
+        pc_input = pc.getc();
+    }
+    else {
+        pc_input = ' ';
+    }
+    
+    // Read Flash memory if 'R' is pressed
+    if ((pc_input == 'r') || (pc_input == 'R')) {
+        // Data labels
+        printf("mag_X\tmag_Y\tmag_Z\r\n");
+        
+        // Read 1st Flash data
+        uint32_t Flash_addr_temp = FLASH_BANK2_BASE;
+        read_flash(Flash_addr_temp, &Flash_rdata[0], LIS2MDL_DATA_SIZE);
+        
+        // Read Flash data
+        while ((Flash_addr_temp <= FLASH_BANK2_END-LIS2MDL_DATA_SIZE+1) && !flash_empty) {
+            // Print read data in the terminal
+            printf("%6d\t%6d\t%6d\r\n", Flash_rdata[0], Flash_rdata[1], Flash_rdata[2]);
+            Flash_addr_temp += LIS2MDL_DATA_SIZE;
+            
+            // Check if the next address is not empty (erased Flash only contains 0)
+            if (Flash_addr_temp <= FLASH_BANK2_END-LIS2MDL_DATA_SIZE+1) {
+                read_flash(Flash_addr_temp, &Flash_rdata[0], LIS2MDL_DATA_SIZE);
+                if ((Flash_rdata[0] == 0) && (Flash_rdata[1] == 0) && (Flash_rdata[2] == 0)) {
+                    flash_empty = true;
+                }
+            }
+        }
+    }
+}
+
+/* Print Flash memory info */
+void print_flash_info()
+{
+    printf("**************************************************\n\r");
+    printf("/***** Flash memory info *****/\r\n");
+    printf("Flash size: %d [B]\r\n", FLASH_SIZE);
+    printf("Flash page size: %d [B]\r\n", FLASH_PAGE_SIZE);
+    printf("Flash nb of pages: %d \r\n", FLASH_SIZE/FLASH_PAGE_SIZE);
+    printf("Flash bank 1 base address: 0x%X\r\n", FLASH_BASE);
+    printf("Flash bank 1 end address: 0x%X\r\n", FLASH_BANK1_END);
+    printf("Flash bank 2 base address: 0x%X\r\n", FLASH_BANK2_BASE);
+    printf("Flash bank 2 end address: 0x%X\r\n", FLASH_BANK2_END);
+    printf("**************************************************\n\r");
+}
+
 /* Erase content of Flash memory */
 bool erase_flash(bool verbose)
 {
@@ -110,19 +456,32 @@
 }
 
 /* Write Flash memory */
-bool write_flash(uint32_t Flash_addr, uint32_t Flash_wdata, bool verbose)
+bool write_flash(uint32_t Flash_addr, uint32_t* Flash_wdata, int32_t n_words, bool verbose)
 {
+    clock_t time;
+    if (verbose) {time = clock();}
+    
     // Unlock Flash memory
     HAL_FLASH_Unlock();
     
     // Write Flash memory
-    if (HAL_OK != HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Flash_addr, Flash_wdata)) {
-        if (verbose) {printf("Flash write failed!\r\n");}
-        HAL_FLASH_Lock();
-        return false;
+    for (int i=0; i<n_words; i++) {
+        if (HAL_OK != HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Flash_addr, Flash_wdata[i])) {
+            if (verbose) {printf("Flash write failed!\r\n");}
+            HAL_FLASH_Lock();
+            return false;
+        }
+        Flash_addr += 4;
     }
     if (verbose) {printf("Flash write succesful!\r\n");}
+    
     HAL_FLASH_Lock();
+    
+    if (verbose) {
+        time = clock() - time;
+        printf("Time to write: %1.6f [s]\r\n", (((double) time)/CLOCKS_PER_SEC));
+    }
+    
     return true;
 }
 
@@ -132,21 +491,6 @@
     memcpy(Flash_rdata, (uint32_t*) Flash_addr, n_bytes);
 }
 
-/* Print Flash memory info */
-void print_flash_info()
-{
-    printf("**************************************************\n\r");
-    printf("/***** Flash memory info *****/\r\n");
-    printf("Flash size: %d [B]\r\n", FLASH_SIZE);
-    printf("Flash page size: %d [B]\r\n", FLASH_PAGE_SIZE);
-    printf("Flash nb of pages: %d \r\n", FLASH_SIZE/FLASH_PAGE_SIZE);
-    printf("Flash bank 1 base address: 0x%X\r\n", FLASH_BASE);
-    printf("Flash bank 1 end address: 0x%X\r\n", FLASH_BANK1_END);
-    printf("Flash bank 2 base address: 0x%X\r\n", FLASH_BANK2_BASE);
-    printf("Flash bank 2 end address: 0x%X\r\n", FLASH_BANK2_END);
-    printf("**************************************************\n\r");
-}
-
 /* Enables button when bouncing is over */
 void button1_enabled_cb(void)
 {
@@ -163,153 +507,45 @@
     }
 }
 
-/* Acquisition task */
-bool acquisition_task(uint32_t* Flash_addr)
+/* Helper function for printing floats & doubles */
+static char *print_double(char *str, double v)
 {
-    int32_t m_axes[3];
-    
-    while (*Flash_addr < FLASH_BANK2_END) {
-        // Read magnetometer data
-        magnetometer->get_m_axes(m_axes);
-        
-        // Save data to Flash memory
-        for (int i=0; i<3; i++) {
-            //printf("Writing to address: 0x%X\r\n", *Flash_addr);
-            write_flash(*Flash_addr, (uint32_t) m_axes[i], false);
-            *Flash_addr += 4;
+    int decimalDigits = 6;
+    int i = 1;
+    int intPart, fractPart;
+    int len;
+    char *ptr;
+
+    /* prepare decimal digits multiplicator */
+    for (; decimalDigits != 0; i *= 10, decimalDigits--);
+
+    /* calculate integer & fractinal parts */
+    intPart = (int)v;
+    fractPart = (int)((v - (double)(int)v) * i);
+
+    /* fill in integer part */
+    sprintf(str, "%i.", intPart);
+
+    /* prepare fill in of fractional part */
+    len = strlen(str);
+    ptr = &str[len];
+
+    /* fill in leading fractional zeros */
+    for (i /= 10; i > 1; i /= 10, ptr++) {
+        if (fractPart >= i) {
+            break;
         }
-        
-        // Print data in terminal
-        //printf("LIS2MDL [mag/mgauss]:  %6d, %6d, %6d\r\n", ((uint32_t) m_axes[0]), ((uint32_t) m_axes[1]), ((uint32_t) m_axes[2]));
-        
-        // Wait for acquisition period
-        wait(1/FS);
-        
-        // Stop saving data when button is pushed
-        if (button1_pressed) {
-            button1_pressed = false;
-            printf("Data acquisition stopped\r\n");
-            printf("Press 'R' to read the data\r\n");
-            
-            // Save last address in Flash memory
-            write_flash(FLASH_BANK2_BASE, *Flash_addr, false);
-            return false;
-        }
+        *ptr = '0';
     }
-    return false;
-}
 
-/* Read task */
-void read_task()
-{
-    char pc_input;
-    uint32_t Flash_rdata[3];
-    uint32_t Flash_addr;
-    
-    // Read terminal input
-    if (pc.readable()) {
-        pc_input = pc.getc();
-        //printf("Read character: %c\r\n", pc_input);
-    }
-    else {
-        pc_input = 'a';
-    }
-    
-    // Read Flash memory if 'R' is pressed
-    if ((pc_input == 'r') || (pc_input == 'R')) {
-        // Read last written Flash address in Flash memory
-        read_flash(FLASH_BANK2_BASE, &Flash_addr, 4);
-        
-        // Data names
-        printf("mag_X\tmag_Y\tmag_Z\r\n");
-        
-        // Read Flash data
-        uint32_t Flash_addr_temp = FLASH_BANK2_BASE + 4;
-        while (Flash_addr_temp < Flash_addr) {
-            //printf("Reading from address: 0x%X\r\n", Flash_addr_temp);
-            read_flash(Flash_addr_temp, &Flash_rdata[0], 12);
-            Flash_addr_temp += 12;
-            printf("%6d\t%6d\t%6d\r\n", Flash_rdata[0], Flash_rdata[1], Flash_rdata[2]);
-        }
-    }
+    /* fill in (rest of) fractional part */
+    sprintf(ptr, "%i", fractPart);
+
+    return str;
 }
 
-/* Main */
-int main()
+/* Pressure to altitude conversion */
+float pressure_to_altitude(double pressure)
 {
-    uint8_t id;
-    float read_reg;
-    uint8_t read_reg_int;
-    
-    bool save_data = false;
-    uint32_t Flash_addr = FLASH_BANK2_BASE;
-
-    /* Serial link configuration */
-    pc.baud(115200);
-    
-    /* Button configuration */
-    button1.fall(callback(button1_onpressed_cb)); // Attach ISR to handle button press event
-    
-    // Reset message
-    printf("\n\r**************************************************\n\r");
-    printf("LELEC2811 LIS2MDL Magnetometer Program\n\r");
-    printf("**************************************************\n\r");
-
-    /* Enable LIS2MDL magnetometer sensor */
-    magnetometer->enable();
-    
-    /* LIS2MDL magnetometer sensor configuration */
-    printf("/***** LIS2MDL magnetometer configuration *****/\r\n");
-    
-    magnetometer->read_id(&id);
-    printf("LIS2MDL magnetometer = 0x%X\r\n", id);
-    
-    magnetometer->set_m_odr(LIS2MDL_ODR);
-    magnetometer->get_m_odr(&read_reg);
-    printf("LIS2MDL ODR = %1.1f [Hz]\r\n", read_reg);
-    
-    magnetometer->set_m_lp(LIS2MDL_LP);
-    magnetometer->get_m_lp(&read_reg_int);
-    printf("LIS2MDL LP = %1d\r\n", read_reg_int);
-    
-    magnetometer->set_m_lpf(LIS2MDL_LPF);
-    magnetometer->get_m_lpf(&read_reg_int);
-    printf("LIS2MDL LPF = %1d\r\n", read_reg_int);
-    
-    magnetometer->set_m_comp_temp_en(LIS2MDL_COMP_TEMP_EN);
-    magnetometer->get_m_comp_temp_en(&read_reg_int);
-    printf("LIS2MDL COMP_TEMP_EN = %1d\r\n", read_reg_int);
-    
-    magnetometer->set_m_off_canc(LIS2MDL_OFF_CANC);
-    magnetometer->get_m_off_canc(&read_reg_int);
-    printf("LIS2MDL OFF_CANC = %1d\r\n", read_reg_int);
-    
-    /* Print Flash memory information */
-    print_flash_info();
-    
-    /* Information for the user */
-    printf("Press blue button to start data acquisition\r\n");
-    printf("Press 'R' to read previously measured data\r\n");
-    
-    /* Acquisition loop */
-    while(1) {
-        // Start saving data when button is pushed
-        if (button1_pressed) {
-            button1_pressed = false;
-            save_data = true;
-            erase_flash(false);
-            printf("Acquiring data...\r\n");
-            printf("Press blue button to stop data acquisition\r\n");
-            Flash_addr = FLASH_BANK2_BASE + 4;
-        }
-        
-        if (save_data) {
-            // Acquisition task
-            save_data = acquisition_task(&Flash_addr);
-        }
-        else {
-            // Read task
-            read_task();
-        }
-    }
-}
\ No newline at end of file
+    return 44330.77 * (1-pow(pressure/P0, 0.1902632));
+}