"Sensors Reader" Sample Application for X-NUCLEO-IKS01A1 Expansion Board

Dependencies:   X_NUCLEO_IKS01A1 mbed

Fork of Sensors_Reader by ST Expansion SW Team

X-NUCLEO-IKS01A1 MEMS Inertial & Environmental Sensor Nucleo Expansion Board Firmware Package

Introduction

This firmware package includes Components Device Drivers, Board Support Package and example applications for STMicroelectronics X-NUCLEO-IKS01A1 MEMS Inertial & Environmental Nucleo Expansion Board.

Example Application

First of all, the example application outputs information retrieved from the Expansion Board over UART. Launch a terminal application (e.g.: PuTTY on Windows, Minicom on Linux) and set the UART port to 9600 bps, 8 bit, No Parity, 1 stop bit.

The "Sensors Reader" program is a more complex example of how to use the X-NUCLEO-IKS01A1 expansion board featuring among others:

  • Support for LSM6DS3 3D Accelerometer & Gyroscope (on DIL 24-pin socket) including free-fall detection
  • Usage of LED & Ticker
  • Exploitation of wait for event
  • (Top-/Bottom-Half) Interrupt handling

Files at this revision

API Documentation at this revision

Comitter:
Wolfgang Betz
Date:
Mon Aug 17 09:34:10 2015 +0200
Child:
59:68a883e589a8
Child:
60:570500315ab8
Commit message:
Improve application names

Changed in this revision

X_NUCLEO_IKS01A1.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/X_NUCLEO_IKS01A1.lib	Mon Aug 17 09:34:10 2015 +0200
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/ST-Expansion-SW-Team/code/X_NUCLEO_IKS01A1/#c900ba2aa497
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Aug 17 09:34:10 2015 +0200
@@ -0,0 +1,278 @@
+/**
+ ******************************************************************************
+ * @file    main.cpp
+ * @author  AST / EST
+ * @version V0.0.1
+ * @date    14-April-2015
+ * @brief   Example application for using the X_NUCLEO_IKS01A1 
+ *          MEMS Inertial & Environmental Sensor Nucleo expansion board.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+*/ 
+
+/**
+ * @mainpage X_NUCLEO_IKS01A1 MEMS Inertial & Environmental Sensor Nucleo Expansion Board Firmware Package
+ *
+ * <b>Introduction</b>
+ *
+ * This firmware package includes Components Device Drivers, Board Support Package
+ * and example application for STMicroelectronics X_NUCLEO_IKS01A1 MEMS Inertial & Environmental Nucleo
+ * Expansion Board
+ * 
+ * <b>Example Application</b>
+ *
+ */
+
+
+/*** Includes ----------------------------------------------------------------- ***/
+#include "mbed.h"
+#include "assert.h"
+#include "x_nucleo_iks01a1.h"
+
+#include <Ticker.h>
+
+
+/*** Constants ---------------------------------------------------------------- ***/
+namespace {
+	const int MS_INTERVALS = 1000;
+}
+
+
+/*** Macros ------------------------------------------------------------------- ***/
+#define APP_LOOP_PERIOD 3000 // in ms
+
+#if defined(TARGET_STM)
+#define LED_OFF (0)
+#else
+#define LED_OFF (1)
+#endif
+#define LED_ON  (!LED_OFF)
+
+
+/*** Typedefs ----------------------------------------------------------------- ***/
+typedef struct {
+    int32_t AXIS_X;
+    int32_t AXIS_Y;
+    int32_t AXIS_Z;
+} AxesRaw_TypeDef;
+
+
+/*** Static variables --------------------------------------------------------- ***/
+#ifdef DBG_MCU
+/* betzw: enable debugging while using sleep modes */
+#include "DbgMCU.h"
+static DbgMCU enable_dbg;
+#endif // DBG_MCU
+
+static X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance();
+static GyroSensor *gyroscope = mems_expansion_board->GetGyroscope();
+static MotionSensor *accelerometer = mems_expansion_board->GetAccelerometer();
+static MagneticSensor *magnetometer = mems_expansion_board->magnetometer;
+static HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor;;
+static PressureSensor *pressure_sensor = mems_expansion_board->pressure_sensor;
+static TempSensor *temp_sensor1 = mems_expansion_board->ht_sensor;
+static TempSensor *temp_sensor2 = mems_expansion_board->pressure_sensor;
+
+static Ticker ticker;
+static DigitalOut myled(LED1, LED_OFF);
+
+static volatile bool timer_irq_triggered = false;
+static volatile bool ff_irq_triggered = false;
+
+
+/*** Helper Functions (1/2) ------------------------------------------------------------ ***/
+
+
+/*** Interrupt Handler Top-Halves ------------------------------------------------------ ***/
+/* Called in interrupt context, therefore just set a trigger variable */
+static void timer_irq(void) {
+	timer_irq_triggered = true;
+}
+
+/* Called in interrupt context, therefore just set a trigger variable */
+static void ff_irq(void) {
+	ff_irq_triggered = true;
+
+	/* Disable IRQ until handled */
+	mems_expansion_board->gyro_lsm6ds3->Disable_Free_Fall_Detection_IRQ();
+}
+
+
+/*** Interrupt Handler Bottom-Halves ------------------------------------------------- ***/
+/* Handle Free Fall Interrupt
+   (here we are in "normal" context, i.e. not in IRQ context)
+*/
+static void handle_ff_irq(void) {
+    printf("\nFree Fall Detected!\n\n");
+
+    /* Re-enable IRQ */
+    mems_expansion_board->gyro_lsm6ds3->Enable_Free_Fall_Detection_IRQ();
+}
+
+
+/*** Helper Functions (2/2) ------------------------------------------------------------ ***/
+/* print floats & doubles */
+static char *printDouble(char* str, double v, int decimalDigits=2)
+{
+  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;
+	  *ptr = '0';
+  }
+
+  /* fill in (rest of) fractional part */
+  sprintf(ptr, "%i", fractPart);
+
+  return str;
+}
+
+/* Initialization function */
+static void init(void) {
+	uint8_t id1, id2;
+
+	/* Determine ID of Humidity & Temperature Sensor */
+	CALL_METH(humidity_sensor, ReadID, &id1, 0x0);
+	CALL_METH(temp_sensor1, ReadID, &id2, 0x0);
+    	printf("Humidity  | Temperature Sensor ID = %s (0x%x | 0x%x)\n", 
+	       ((id1 == I_AM_HTS221) ? "HTS221 " : "UNKNOWN"),
+	       id1, id2
+	       );
+	assert(id1 == id2);
+
+	/* Determine ID of Gyro & Motion Sensor */
+	assert((mems_expansion_board->gyro_lsm6ds0 == NULL) ||
+	       (mems_expansion_board->gyro_lsm6ds3 == NULL));
+	CALL_METH(gyroscope, ReadID, &id1, 0x0);
+	CALL_METH(accelerometer, ReadID, &id2, 0x0);
+    	printf("Gyroscope | Motion Sensor ID      = %s (0x%x | 0x%x)\n", 
+	       ((id1 == I_AM_LSM6DS3_XG) ? "LSM6DS3" : 
+		((id1 == I_AM_LSM6DS0_XG) ? "LSM6DS0" : "UNKNOWN")),
+	       id1, id2
+	       );
+	assert(id1 == id2);
+
+	/* Register Free Fall Detection IRQ Handler & Enable Detection */
+	if(mems_expansion_board->gyro_lsm6ds3 != NULL) {
+		mems_expansion_board->gyro_lsm6ds3->Attach_Free_Fall_Detection_IRQ(ff_irq);
+		mems_expansion_board->gyro_lsm6ds3->Enable_Free_Fall_Detection();
+	}
+}
+
+/* Main cycle function */
+static void main_cycle(void) {
+	float TEMPERATURE_Value;
+	float HUMIDITY_Value;
+	float PRESSURE_Value;
+	float PRESSURE_Temp_Value;
+	AxesRaw_TypeDef MAG_Value;
+	AxesRaw_TypeDef ACC_Value;
+	AxesRaw_TypeDef GYR_Value;
+	char buffer1[32];
+	char buffer2[32];
+	char buffer3[32];
+	char buffer4[32];
+	unsigned int ret = 0;
+	
+	/* Switch LED On */
+	myled = LED_ON;
+	printf("===\n");
+
+	/* Determine Environmental Values */
+	ret |= (!CALL_METH(temp_sensor1, GetTemperature, &TEMPERATURE_Value, 0.0f) ? 0x0 : 0x1);
+	ret |= (!CALL_METH(humidity_sensor, GetHumidity, &HUMIDITY_Value, 0.0f) ? 0x0 : 0x2);;
+	ret |= (!CALL_METH(pressure_sensor, GetPressure, &PRESSURE_Value, 0.0f) ? 0x0 : 0x4);;
+	ret |= (!CALL_METH(temp_sensor2, GetFahrenheit, &PRESSURE_Temp_Value, 0.0f) ? 0x0 : 0x8);;
+	ret |= (!CALL_METH(magnetometer, Get_M_Axes, (int32_t *)&MAG_Value, 0) ? 0x0 : 0x10);;
+	ret |= (!CALL_METH(accelerometer, Get_X_Axes, (int32_t *)&ACC_Value, 0) ? 0x0 : 0x20);;
+	ret |= (!CALL_METH(gyroscope, Get_G_Axes, (int32_t *)&GYR_Value, 0) ? 0x0 : 0x40);
+
+	/* Print Values Out */
+        printf("I2C [errors]: 0x%.2x    X         Y         Z\n", ret); 
+        printf("MAG [mgauss]: %9ld %9ld %9ld\n", 
+	       MAG_Value.AXIS_X, MAG_Value.AXIS_Y, MAG_Value.AXIS_Z);
+        printf("ACC [mg]:     %9ld %9ld %9ld\n", 
+	       ACC_Value.AXIS_X, ACC_Value.AXIS_Y, ACC_Value.AXIS_Z);
+        printf("GYR [mdps]:   %9ld %9ld %9ld\n", 
+	       GYR_Value.AXIS_X, GYR_Value.AXIS_Y, GYR_Value.AXIS_Z);
+        printf("---\nTEMP | HUMIDITY: %s°C |  %s%%\nTEMP | PRESSURE: %s°F | %4smbar\n", 
+	       printDouble(buffer1, TEMPERATURE_Value), 
+	       printDouble(buffer2, HUMIDITY_Value), 
+	       printDouble(buffer4, PRESSURE_Temp_Value),
+	       printDouble(buffer3, PRESSURE_Value));
+	
+	/* Switch LED Off */
+	myled = LED_OFF;
+}
+
+
+/*** Main function ------------------------------------------------------------- ***/
+/* Generic main function/loop for enabling WFE in case of 
+   interrupt based cyclic execution
+*/
+int main()
+{
+	/* Start & initialize */
+	printf("\n--- Starting new run ---\n");
+	init();
+
+	/* Start timer irq */
+	ticker.attach_us(timer_irq, MS_INTERVALS * APP_LOOP_PERIOD);
+
+	while (true) {
+		if(timer_irq_triggered) {
+			timer_irq_triggered = false;
+			main_cycle();
+		} else if(ff_irq_triggered) {
+			ff_irq_triggered = false;
+			handle_ff_irq();
+		} else {
+			__WFE(); /* it is recommended that SEVONPEND in the 
+				    System Control Register is NOT set */
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Aug 17 09:34:10 2015 +0200
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/da0ca467f8b5
\ No newline at end of file