Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 #include <math.h> 00058 00059 #include <Ticker.h> 00060 00061 00062 /*** Constants ---------------------------------------------------------------- ***/ 00063 namespace { 00064 const int MS_INTERVALS = 1000; 00065 const double RAD_TO_DEG = 57.2957786; 00066 const double PI = 3.14159265; 00067 } 00068 00069 00070 /*** Macros ------------------------------------------------------------------- ***/ 00071 #define APP_LOOP_PERIOD 3000 // in ms 00072 00073 #if defined(TARGET_STM) 00074 #define LED_OFF (0) 00075 #else 00076 #define LED_OFF (1) 00077 #endif 00078 #define LED_ON (!LED_OFF) 00079 00080 00081 /*** Typedefs ----------------------------------------------------------------- ***/ 00082 typedef struct { 00083 int32_t AXIS_X; 00084 int32_t AXIS_Y; 00085 int32_t AXIS_Z; 00086 } AxesRaw_TypeDef; 00087 00088 /*** Serial declaration --------------------------------------------------------- ***/ 00089 Serial ser(USBTX,USBRX,115200); 00090 00091 /*** Static variables --------------------------------------------------------- ***/ 00092 #ifdef DBG_MCU 00093 /* betzw: enable debugging while using sleep modes */ 00094 #include "DbgMCU.h" 00095 static DbgMCU enable_dbg; 00096 #endif // DBG_MCU 00097 00098 static X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(); 00099 static GyroSensor *gyroscope = mems_expansion_board->GetGyroscope(); 00100 static MotionSensor *accelerometer = mems_expansion_board->GetAccelerometer(); 00101 static MagneticSensor *magnetometer = mems_expansion_board->magnetometer; 00102 00103 static Ticker ticker; 00104 static DigitalOut myled(LED1, LED_OFF); 00105 00106 static volatile bool timer_irq_triggered = false; 00107 static volatile bool ff_irq_triggered = false; 00108 00109 00110 /*** Helper Functions (1/2) ------------------------------------------------------------ ***/ 00111 00112 00113 /*** Interrupt Handler Top-Halves ------------------------------------------------------ ***/ 00114 /* Called in interrupt context, therefore just set a trigger variable */ 00115 static void timer_irq(void) { 00116 timer_irq_triggered = true; 00117 } 00118 00119 /* Called in interrupt context, therefore just set a trigger variable */ 00120 static void ff_irq(void) { 00121 ff_irq_triggered = true; 00122 00123 /* Disable IRQ until handled */ 00124 mems_expansion_board->gyro_lsm6ds3->Disable_Free_Fall_Detection_IRQ(); 00125 } 00126 00127 00128 /*** Interrupt Handler Bottom-Halves ------------------------------------------------- ***/ 00129 /* Handle Free Fall Interrupt 00130 (here we are in "normal" context, i.e. not in IRQ context) 00131 */ 00132 static void handle_ff_irq(void) { 00133 printf("\nFree Fall Detected!\n\n"); 00134 00135 /* Re-enable IRQ */ 00136 mems_expansion_board->gyro_lsm6ds3->Enable_Free_Fall_Detection_IRQ(); 00137 } 00138 00139 00140 /*** Helper Functions (2/2) ------------------------------------------------------------ ***/ 00141 /* print floats & doubles */ 00142 static char *printDouble(char* str, double v, int decimalDigits=2) 00143 { 00144 int i = 1; 00145 int intPart, fractPart; 00146 int len; 00147 char *ptr; 00148 00149 /* prepare decimal digits multiplicator */ 00150 for (;decimalDigits!=0; i*=10, decimalDigits--); 00151 00152 /* calculate integer & fractinal parts */ 00153 intPart = (int)v; 00154 fractPart = (int)((v-(double)(int)v)*i); 00155 00156 /* fill in integer part */ 00157 sprintf(str, "%i.", intPart); 00158 00159 /* prepare fill in of fractional part */ 00160 len = strlen(str); 00161 ptr = &str[len]; 00162 00163 /* fill in leading fractional zeros */ 00164 for (i/=10;i>1; i/=10, ptr++) { 00165 if(fractPart >= i) break; 00166 *ptr = '0'; 00167 } 00168 00169 /* fill in (rest of) fractional part */ 00170 sprintf(ptr, "%i", fractPart); 00171 00172 return str; 00173 } 00174 00175 /* Initialization function */ 00176 static void init(void) { 00177 uint8_t id1, id2; 00178 00179 /* Determine ID of Gyro & Motion Sensor */ 00180 assert((mems_expansion_board->gyro_lsm6ds0 == NULL) || 00181 (mems_expansion_board->gyro_lsm6ds3 == NULL)); 00182 CALL_METH(gyroscope, read_id, &id1, 0x0); 00183 CALL_METH(accelerometer, read_id, &id2, 0x0); 00184 printf("Gyroscope | Motion Sensor ID = %s (0x%x | 0x%x)\n", 00185 ((id1 == I_AM_LSM6DS3_XG) ? "LSM6DS3" : 00186 ((id1 == I_AM_LSM6DS0_XG) ? "LSM6DS0" : "UNKNOWN")), 00187 id1, id2 00188 ); 00189 assert(id1 == id2); 00190 00191 /* Register Free Fall Detection IRQ Handler & Enable Detection */ 00192 if(mems_expansion_board->gyro_lsm6ds3 != NULL) { 00193 mems_expansion_board->gyro_lsm6ds3->Attach_Free_Fall_Detection_IRQ(ff_irq); 00194 mems_expansion_board->gyro_lsm6ds3->Enable_Free_Fall_Detection(); 00195 } 00196 } 00197 00198 /* Main cycle function */ 00199 static void main_cycle(void) { 00200 AxesRaw_TypeDef MAG_Value; 00201 AxesRaw_TypeDef ACC_Value; 00202 AxesRaw_TypeDef GYR_Value; 00203 char buffer1[32]; 00204 char buffer2[32]; 00205 char buffer3[32]; 00206 char buffer4[32]; 00207 unsigned int ret = 0; 00208 00209 /* Declaration of sensors variables */ 00210 double accX,accY,accZ; 00211 double gyroX,gyroY,gyroZ; 00212 00213 00214 /* Switch LED On */ 00215 myled = LED_ON; 00216 printf("===\n"); 00217 00218 /* Determine Environmental Values */ 00219 ret |= (!CALL_METH(magnetometer, get_m_axes, (int32_t *)&MAG_Value, 0) ? 0x0 : 0x10);; 00220 ret |= (!CALL_METH(accelerometer, get_x_axes, (int32_t *)&ACC_Value, 0) ? 0x0 : 0x20);; 00221 ret |= (!CALL_METH(gyroscope, get_g_axes, (int32_t *)&GYR_Value, 0) ? 0x0 : 0x40); 00222 00223 /* Print Values Out */ 00224 printf("I2C [errors]: 0x%.2x X Y Z\n", ret); 00225 printf("MAG [mgauss]: %9ld %9ld %9ld\n", 00226 MAG_Value.AXIS_X, MAG_Value.AXIS_Y, MAG_Value.AXIS_Z); 00227 printf("ACC [mg]: %9ld %9ld %9ld\n", 00228 ACC_Value.AXIS_X, ACC_Value.AXIS_Y, ACC_Value.AXIS_Z); 00229 printf("GYR [mdps]: %9ld %9ld %9ld\n", 00230 GYR_Value.AXIS_X, GYR_Value.AXIS_Y, GYR_Value.AXIS_Z); 00231 00232 accX = ACC_Value.AXIS_X; 00233 accY = ACC_Value.AXIS_Y; 00234 accZ = ACC_Value.AXIS_Z; 00235 gyroX = GYR_Value.AXIS_X; 00236 gyroY = GYR_Value.AXIS_Y; 00237 gyroZ = GYR_Value.AXIS_Z; 00238 00239 #ifdef RESTRICT_PITCH // Eq. 25 and 26 00240 double roll = atan2(accY, accZ) * RAD_TO_DEG; 00241 double pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG; 00242 #else // Eq. 28 and 29 00243 double roll = atan(accY / sqrt(accX * accX + accZ * accZ)) * RAD_TO_DEG; 00244 double pitch = atan2(-accX, accZ) * RAD_TO_DEG; 00245 #endif 00246 double yaw = atan2(-accZ, sqrt(accY * accY + accZ * accZ)) * 180.0/PI; 00247 00248 /* Print Serially *//* 00249 ser.printf("%lf",pitch); 00250 ser.printf(":"); 00251 ser.printf("%lf",roll); 00252 ser.printf(":"); 00253 ser.printf("%lf\n",yaw); 00254 */ 00255 ser.printf("1"); 00256 ser.printf(":"); 00257 ser.printf("2"); 00258 ser.printf(":"); 00259 ser.printf("3\n"); 00260 00261 00262 /* Switch LED Off */ 00263 myled = LED_OFF; 00264 } 00265 00266 00267 /*** Main function ------------------------------------------------------------- ***/ 00268 /* Generic main function/loop for enabling WFE in case of 00269 interrupt based cyclic execution 00270 */ 00271 int main() 00272 { 00273 /* Start & initialize */ 00274 printf("\n--- Starting new run ---\n"); 00275 init(); 00276 00277 /* Start timer irq */ 00278 ticker.attach_us(timer_irq, MS_INTERVALS * APP_LOOP_PERIOD); 00279 00280 while (true) { 00281 if(timer_irq_triggered) { 00282 timer_irq_triggered = false; 00283 main_cycle(); 00284 } else if(ff_irq_triggered) { 00285 ff_irq_triggered = false; 00286 handle_ff_irq(); 00287 } else { 00288 __WFE(); /* it is recommended that SEVONPEND in the 00289 System Control Register is NOT set */ 00290 } 00291 } 00292 }
Generated on Sun Jul 17 2022 21:14:44 by
