"Sensors Reader" Sample Application for X-NUCLEO-IKS01A1 Expansion Board
Dependencies: X_NUCLEO_IKS01A1 mbed
Fork of Sensors_Reader by
main.cpp
00001 /** 00002 ****************************************************************************** 00003 * @file main.cpp 00004 * @author AST / EST 00005 * @version V0.0.1 00006 * @date 14-April-2015 00007 * @brief Example application for using the X_NUCLEO_IKS01A1 00008 * MEMS Inertial & Environmental Sensor Nucleo expansion board. 00009 ****************************************************************************** 00010 * @attention 00011 * 00012 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> 00013 * 00014 * Redistribution and use in source and binary forms, with or without modification, 00015 * are permitted provided that the following conditions are met: 00016 * 1. Redistributions of source code must retain the above copyright notice, 00017 * this list of conditions and the following disclaimer. 00018 * 2. Redistributions in binary form must reproduce the above copyright notice, 00019 * this list of conditions and the following disclaimer in the documentation 00020 * and/or other materials provided with the distribution. 00021 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00022 * may be used to endorse or promote products derived from this software 00023 * without specific prior written permission. 00024 * 00025 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00026 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00028 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00029 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00030 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00031 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00032 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00033 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00034 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00035 * 00036 ****************************************************************************** 00037 */ 00038 00039 /** 00040 * @mainpage X_NUCLEO_IKS01A1 MEMS Inertial & Environmental Sensor Nucleo Expansion Board Firmware Package 00041 * 00042 * <b>Introduction</b> 00043 * 00044 * This firmware package includes Components Device Drivers, Board Support Package 00045 * and example application for STMicroelectronics X_NUCLEO_IKS01A1 MEMS Inertial & Environmental Nucleo 00046 * Expansion Board 00047 * 00048 * <b>Example Application</b> 00049 * 00050 */ 00051 00052 00053 /*** Includes ----------------------------------------------------------------- ***/ 00054 #include "mbed.h" 00055 #include "assert.h" 00056 #include "x_nucleo_iks01a1.h" 00057 00058 #include <Ticker.h> 00059 00060 00061 /*** Constants ---------------------------------------------------------------- ***/ 00062 namespace { 00063 const int MS_INTERVALS = 1000; 00064 } 00065 00066 00067 /*** Macros ------------------------------------------------------------------- ***/ 00068 #define APP_LOOP_PERIOD 3000 // in ms 00069 00070 #if defined(TARGET_STM) 00071 #define LED_OFF (0) 00072 #else 00073 #define LED_OFF (1) 00074 #endif 00075 #define LED_ON (!LED_OFF) 00076 00077 00078 /*** Typedefs ----------------------------------------------------------------- ***/ 00079 typedef struct { 00080 int32_t AXIS_X; 00081 int32_t AXIS_Y; 00082 int32_t AXIS_Z; 00083 } AxesRaw_TypeDef; 00084 00085 00086 /*** Static variables --------------------------------------------------------- ***/ 00087 #ifdef DBG_MCU 00088 /* betzw: enable debugging while using sleep modes */ 00089 #include "DbgMCU.h" 00090 static DbgMCU enable_dbg; 00091 #endif // DBG_MCU 00092 00093 static X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(); 00094 static GyroSensor *gyroscope = mems_expansion_board->GetGyroscope(); 00095 static MotionSensor *accelerometer = mems_expansion_board->GetAccelerometer(); 00096 static MagneticSensor *magnetometer = mems_expansion_board->magnetometer; 00097 static HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor;; 00098 static PressureSensor *pressure_sensor = mems_expansion_board->pt_sensor; 00099 static TempSensor *temp_sensor1 = mems_expansion_board->ht_sensor; 00100 static TempSensor *temp_sensor2 = mems_expansion_board->pt_sensor; 00101 00102 static Ticker ticker; 00103 static DigitalOut myled(LED1, LED_OFF); 00104 00105 static volatile bool timer_irq_triggered = false; 00106 static volatile bool ff_irq_triggered = false; 00107 00108 00109 /*** Helper Functions (1/2) ------------------------------------------------------------ ***/ 00110 00111 00112 /*** Interrupt Handler Top-Halves ------------------------------------------------------ ***/ 00113 /* Called in interrupt context, therefore just set a trigger variable */ 00114 static void timer_irq(void) { 00115 timer_irq_triggered = true; 00116 } 00117 00118 /* Called in interrupt context, therefore just set a trigger variable */ 00119 static void ff_irq(void) { 00120 ff_irq_triggered = true; 00121 00122 /* Disable IRQ until handled */ 00123 mems_expansion_board->gyro_lsm6ds3->Disable_Free_Fall_Detection_IRQ(); 00124 } 00125 00126 00127 /*** Interrupt Handler Bottom-Halves ------------------------------------------------- ***/ 00128 /* Handle Free Fall Interrupt 00129 (here we are in "normal" context, i.e. not in IRQ context) 00130 */ 00131 static void handle_ff_irq(void) { 00132 printf("\nFree Fall Detected!\n\n"); 00133 00134 /* Re-enable IRQ */ 00135 mems_expansion_board->gyro_lsm6ds3->Enable_Free_Fall_Detection_IRQ(); 00136 } 00137 00138 00139 /*** Helper Functions (2/2) ------------------------------------------------------------ ***/ 00140 /* print floats & doubles */ 00141 static char *printDouble(char* str, double v, int decimalDigits=2) 00142 { 00143 int i = 1; 00144 int intPart, fractPart; 00145 int len; 00146 char *ptr; 00147 00148 /* prepare decimal digits multiplicator */ 00149 for (;decimalDigits!=0; i*=10, decimalDigits--); 00150 00151 /* calculate integer & fractinal parts */ 00152 intPart = (int)v; 00153 fractPart = (int)((v-(double)(int)v)*i); 00154 00155 /* fill in integer part */ 00156 sprintf(str, "%i.", intPart); 00157 00158 /* prepare fill in of fractional part */ 00159 len = strlen(str); 00160 ptr = &str[len]; 00161 00162 /* fill in leading fractional zeros */ 00163 for (i/=10;i>1; i/=10, ptr++) { 00164 if(fractPart >= i) break; 00165 *ptr = '0'; 00166 } 00167 00168 /* fill in (rest of) fractional part */ 00169 sprintf(ptr, "%i", fractPart); 00170 00171 return str; 00172 } 00173 00174 /* Initialization function */ 00175 static void init(void) { 00176 uint8_t id1, id2; 00177 00178 /* Determine ID of Humidity & Temperature Sensor */ 00179 CALL_METH(humidity_sensor, read_id, &id1, 0x0); 00180 CALL_METH(temp_sensor1, read_id, &id2, 0x0); 00181 printf("Humidity | Temperature Sensor ID = %s (0x%x | 0x%x)\n", 00182 ((id1 == I_AM_HTS221) ? "HTS221 " : "UNKNOWN"), 00183 id1, id2 00184 ); 00185 assert(id1 == id2); 00186 00187 /* Determine ID of Gyro & Motion Sensor */ 00188 assert((mems_expansion_board->gyro_lsm6ds0 == NULL) || 00189 (mems_expansion_board->gyro_lsm6ds3 == NULL)); 00190 CALL_METH(gyroscope, read_id, &id1, 0x0); 00191 CALL_METH(accelerometer, read_id, &id2, 0x0); 00192 printf("Gyroscope | Motion Sensor ID = %s (0x%x | 0x%x)\n", 00193 ((id1 == I_AM_LSM6DS3_XG) ? "LSM6DS3" : 00194 ((id1 == I_AM_LSM6DS0_XG) ? "LSM6DS0" : "UNKNOWN")), 00195 id1, id2 00196 ); 00197 assert(id1 == id2); 00198 00199 /* Register Free Fall Detection IRQ Handler & Enable Detection */ 00200 if(mems_expansion_board->gyro_lsm6ds3 != NULL) { 00201 mems_expansion_board->gyro_lsm6ds3->Attach_Free_Fall_Detection_IRQ(ff_irq); 00202 mems_expansion_board->gyro_lsm6ds3->Enable_Free_Fall_Detection(); 00203 } 00204 } 00205 00206 /* Main cycle function */ 00207 static void main_cycle(void) { 00208 float TEMPERATURE_Value; 00209 float HUMIDITY_Value; 00210 float PRESSURE_Value; 00211 float PRESSURE_Temp_Value; 00212 AxesRaw_TypeDef MAG_Value; 00213 AxesRaw_TypeDef ACC_Value; 00214 AxesRaw_TypeDef GYR_Value; 00215 char buffer1[32]; 00216 char buffer2[32]; 00217 char buffer3[32]; 00218 char buffer4[32]; 00219 unsigned int ret = 0; 00220 00221 /* Switch LED On */ 00222 myled = LED_ON; 00223 printf("===\n"); 00224 00225 /* Determine Environmental Values */ 00226 ret |= (!CALL_METH(temp_sensor1, get_temperature, &TEMPERATURE_Value, 0.0f) ? 0x0 : 0x1); 00227 ret |= (!CALL_METH(humidity_sensor, get_humidity, &HUMIDITY_Value, 0.0f) ? 0x0 : 0x2);; 00228 ret |= (!CALL_METH(pressure_sensor, get_pressure, &PRESSURE_Value, 0.0f) ? 0x0 : 0x4);; 00229 ret |= (!CALL_METH(temp_sensor2, get_fahrenheit, &PRESSURE_Temp_Value, 0.0f) ? 0x0 : 0x8);; 00230 ret |= (!CALL_METH(magnetometer, get_m_axes, (int32_t *)&MAG_Value, 0) ? 0x0 : 0x10);; 00231 ret |= (!CALL_METH(accelerometer, get_x_axes, (int32_t *)&ACC_Value, 0) ? 0x0 : 0x20);; 00232 ret |= (!CALL_METH(gyroscope, get_g_axes, (int32_t *)&GYR_Value, 0) ? 0x0 : 0x40); 00233 00234 /* Print Values Out */ 00235 printf("I2C [errors]: 0x%.2x X Y Z\n", ret); 00236 printf("MAG [mgauss]: %9ld %9ld %9ld\n", 00237 MAG_Value.AXIS_X, MAG_Value.AXIS_Y, MAG_Value.AXIS_Z); 00238 printf("ACC [mg]: %9ld %9ld %9ld\n", 00239 ACC_Value.AXIS_X, ACC_Value.AXIS_Y, ACC_Value.AXIS_Z); 00240 printf("GYR [mdps]: %9ld %9ld %9ld\n", 00241 GYR_Value.AXIS_X, GYR_Value.AXIS_Y, GYR_Value.AXIS_Z); 00242 printf("---\nTEMP | HUMIDITY: %s°C | %s%%\nTEMP | PRESSURE: %s°F | %smbar\n", 00243 printDouble(buffer1, TEMPERATURE_Value), 00244 printDouble(buffer2, HUMIDITY_Value), 00245 printDouble(buffer4, PRESSURE_Temp_Value), 00246 printDouble(buffer3, PRESSURE_Value)); 00247 00248 /* Switch LED Off */ 00249 myled = LED_OFF; 00250 } 00251 00252 00253 /*** Main function ------------------------------------------------------------- ***/ 00254 /* Generic main function/loop for enabling WFE in case of 00255 interrupt based cyclic execution 00256 */ 00257 int main() 00258 { 00259 /* Start & initialize */ 00260 printf("\n--- Starting new run ---\n"); 00261 init(); 00262 00263 /* Start timer irq */ 00264 ticker.attach_us(timer_irq, MS_INTERVALS * APP_LOOP_PERIOD); 00265 00266 while (true) { 00267 if(timer_irq_triggered) { 00268 timer_irq_triggered = false; 00269 main_cycle(); 00270 } else if(ff_irq_triggered) { 00271 ff_irq_triggered = false; 00272 handle_ff_irq(); 00273 } else { 00274 __WFE(); /* it is recommended that SEVONPEND in the 00275 System Control Register is NOT set */ 00276 } 00277 } 00278 }
Generated on Thu Jul 14 2022 01:54:41 by 1.7.2