blob: ca42fa845c0f61874d75155f20c8d25d7f79e10f [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- This is broken by doc revisioning.
-->
<link rel="shortcut icon" href="../../../../img/favicon.ico">
<title>Develop an Application for an Onboard Sensor - Apache Mynewt</title>
<link href="../../../../css/bootstrap-3.0.3.min.css" rel="stylesheet">
<link rel="stylesheet" href="../../../../css/highlight.css">
<link href="../../../../css/base.css" rel="stylesheet">
<link href="../../../../css/custom.css" rel="stylesheet">
<link href="../../../../css/v2.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
<script>
(function(i, s, o, g, r, a, m) {
i["GoogleAnalyticsObject"] = r;
(i[r] =
i[r] ||
function() {
(i[r].q = i[r].q || []).push(arguments);
}),
(i[r].l = 1 * new Date());
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m);
})(window, document, "script", "//www.google-analytics.com/analytics.js", "ga");
ga("create", "UA-72162311-1", "auto");
ga("send", "pageview");
</script>
</head>
<body class="Develop an Application for an Onboard Sensor">
<div class="container">
<div class="row v2-main-banner">
<a class="logo-cell" href="/">
<img class="logo" src="/img/logo.png">
</a>
<div class="tagline-cell">
<h4 class="tagline">An OS to build, deploy and securely manage billions of devices</h4>
</div>
<div class="news-cell">
<div class="well">
<h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.12.0, Apache NimBLE 1.7.0 </a> released (April 4, 2024)
</div>
</div>
</div>
</div>
<nav id="navbar" class="navbar navbar-inverse affix-top" data-spy="affix" data-offset-top="150" role="navigation">
<div class="container">
<!-- Collapsed navigation -->
<div class="navbar-header">
<!-- Expander button -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- Expanded navigation -->
<div class="navbar-collapse collapse">
<!-- Main navigation -->
<ul class="nav navbar-nav navbar-right">
<li
class=""
>
<a href="/"><i class="fa fa-home" style="font-size: larger;"></i></a>
</li>
<li
class="important"
>
<a href="/quick-start/">Quick Start</a>
</li>
<li
class=""
>
<a href="/about/">About</a>
</li>
<li
class=""
>
<a href="/talks/">Talks</a>
</li>
<li
class="active"
>
<a href="/documentation/">Documentation</a>
</li>
<li
class=""
>
<a href="/download/">Download</a>
</li>
<li
class=""
>
<a href="/community/">Community</a>
</li>
<li
class=""
>
<a href="/events/">Events</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-md-3 v2-sidebar sidebar-container"><div id="docSidebar" class="hidden-print" role="complementary">
<div class="top">
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../../search.html" method="get">
<div class="form-group">
<input type="text" name="q" class="form-control" placeholder="Search documentation" />
</div>
</form>
</div>
</div>
<ul class="toc-nav">
<li class="doc-version"><select class="form-control" onchange="if (this.value) window.location.href=this.value">
<option value="/latest">
Version: master
</option>
<option value="/v1_12_0/" >
Version: 1.12.0
</option>
<option value="/v1_11_0/" >
Version: 1.11.0
</option>
<option value="/v1_10_0/" >
Version: 1.10.0
</option>
<option value="/v1_9_0/" >
Version: 1.9.0
</option>
<option value="/v1_8_0/" >
Version: 1.8.0
</option>
<option value="/v1_7_0/" >
Version: 1.7.0
</option>
<option value="/v1_6_0/" >
Version: 1.6.0
</option>
<option value="/v1_5_0/" >
Version: 1.5.0
</option>
<option value="/v1_4_0/" >
Version: 1.4.0
</option>
<option value="/v1_3_0/os/introduction" selected="selected" >
Version: 1.3.0
</option>
<option value="/v1_2_0/os/introduction" >
Version: 1.2.0
</option>
<option value="/v1_1_0/os/introduction" >
Version: 1.1.0
</option>
<option value="/v1_0_0/os/introduction" >
Version: 1.0.0
</option>
<option value="/v0_9_0/os/introduction" >
Version: 0.9.0
</option>
</select></li>
<li ><a href="../../../introduction/">Mynewt Documentation</a>
<ul>
<li ><a href="../../../get_started/get_started/">Basic Setup</a>
</li>
<li >
<a href="../../../get_started/vocabulary/">Concepts</a>
</li>
<li ><a href="../../tutorials/">Tutorials</a>
<ul>
<li ><a href="../../blinky/">Project Blinky</a>
</li>
<li ><a href="../../repo/add_repos/">Work with repositories</a>
</li>
<li ><a href="../../project-slinky/">Project Slinky for Remote Comms</a>
</li>
<li><a href="
../../ble_bare_bones/
">Bluetooth Low Energy</a>
</li>
<li><a href="
../../lora/lorawanapp/
">LoRa</a>
</li>
<li><a href="
../../event_queue/
">OS Fundamentals</a>
</li>
<li><a href="
../../add_newtmgr/
">Remote Device Management</a>
</li>
<li><a href="
../sensors/
">Sensors</a>
<ul>
<li ><a href="../sensors/">Sensor Framework</a>
<ul>
<li >
<a href="../sensor_nrf52_bno055/">Enable an Off-Board Sensor in an Existing Application</a>
</li>
<li >
<a href="../sensor_offboard_config/">Change the Default Configuration For a Sensor</a>
</li>
<li class="active">
<a href="./">Develop an Application for an Onboard Sensor</a>
</li>
<li ><a href="../sensor_oic_overview/">Enable OIC Sensor Data Monitoring</a>
</li>
</ul>
</li>
<li><a href="
../../air_quality_sensor/
">Air-quality Sensor project</a>
</li>
<li >
<a href="../../nrf52_adc/">Add an Analog Sensor</a>
</li>
</ul>
</li>
<li><a href="
../../segger_rtt/
">Tooling</a>
</li>
<li><a href="
../../codesize/
">Other</a>
</li>
</ul>
</li>
<li ><a href="../../../os_user_guide/">OS User Guide</a>
</li>
<li><a href="
../../../../network/ble/ble_intro/
">BLE User Guide</a>
</li>
<li ><a href="../../../../newt/newt_intro/">Newt Tool Guide</a>
</li>
<li ><a href="../../../../newtmgr/overview/">Newt Manager Guide</a>
</li>
<li >
<a href="../../../../known_issues/">Known Issues</a>
</li>
</ul>
</li>
<li><a href="
../../../../newt/install/prev_releases/
">Appendix</a>
</li>
</ul>
</div></div>
<div class="col-md-9" role="main">
<div class="doc-header">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="/documentation/">Docs</a></li>
<li>&raquo; <a href="os/tutorials/sensors/sensors/">Sensor Framework</a></li>
<li>&raquo; Sensors</li>
<li>&raquo; <a href="os/tutorials/tutorials/">Tutorials</a></li>
<li>&raquo; <a href="os/introduction/">Mynewt Documentation</a></li>
<li>&raquo; Develop an Application for an Onboard Sensor</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/apache/mynewt-site/blob/master/docs/os/tutorials/sensors/sensor_thingy_lis2dh12_onb.md"
class="icon icon-github"> Edit on GitHub</a>
</li>
</ul>
</div>
</div>
<div class="alert alert-warning">
<p>
Version 1.3.0 is not the most recent version of the Apache Mynewt
documentation. Click <a href="/latest">here</a> to read the latest
version.
</p>
</div>
<h2 id="developing-an-application-for-an-onboard-sensor">Developing an Application for an Onboard Sensor</h2>
<p>This tutorial shows you how to develop a simple application for an onboard sensor. The Mynewt sensor framework enables you to easily and quickly develop Mynewt sensor applications. We assume that you have completed the <a href="/os/tutorials/sensors/sensor_nrf52_bno055.md">Enabling an Off-Board Sensor in an Existing Application Tutorial</a> and are familiar with the sensor framework and sensor shell command. </p>
<p><br>
This tutorial shows you how to:</p>
<ul>
<li>Develop an application for the Nordic Thingy LIS2DH12 accelerometer onboard sensor with the sensor framework <code>sensor</code> shell command enabled to view sensor data. </li>
<li>Extend the application to use the sensor framework API to read the sensor data and output the data to the Mynewt console.</li>
</ul>
<h3 id="prerequisites">Prerequisites</h3>
<ul>
<li>Meet the prerequisites listed in the <a href="/os/tutorials/sensors/sensors.md">Sensor Tutorials Overview</a>. </li>
<li>Have a Nordic Thingy. </li>
<li><a href="https://www.segger.com/jlink-debug-probes.html">Segger J-Link Debug Probe</a>.</li>
<li><a href="https://www.segger.com/jlink-adapters.html#CM_9pin">J-Link 9 pin Cortex-M Adapter</a> that allows JTAG, SWD and SWO connections between J-Link and Cortex M based target hardware systems.</li>
<li>Install the <a href="https://www.segger.com/jlink-software.html">Segger JLINK Software and documentation pack</a>.</li>
<li>Complete the <a href="/os/tutorials/sensors/sensor_nrf52_bno055.md">Enabling an Off-Board Sensor in an Existing Application Tutorial</a>.</li>
</ul>
<h3 id="developing-a-sensor-enabled-application-with-shell-support">Developing a Sensor Enabled Application with Shell Support</h3>
<p>We first develop a simple application with the LIS2DH12 onboard sensor on the Nordic Thingy and the <code>sensor</code> shell command enabled.</p>
<p><br></p>
<h4 id="step-1-creating-a-new-app-package">Step 1: Creating a New App Package</h4>
<p>We name the new app package <code>my_sensor_app</code>. From your project base directory, run the <code>newt pkg new</code> command to create a new app package. This tutorial uses ~/dev/myproj for the project.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>$ cd ~/dev/myproj
$ newt pkg new -t app apps/my_sensor_app
Download package template for package type app.
Package successfuly installed into ~/dev/myproj/apps/my_sensor_app
</code></pre></div>
<p><br>
The newt tool creates a skeleton <code>my_sensor_app</code> package directory in the <code>~/dev/myproj/apps/</code> directory. Go to the <code>my_sensor_app</code> directory to update the package <code>pkg.yml</code> and source files. </p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>$ cd apps/my_sensor_app
</code></pre></div>
<p><br></p>
<h4 id="step-2-adding-the-package-dependencies">Step 2: Adding the Package Dependencies</h4>
<p>The my_sensor_app package requires the sensor framework, <code>hw/sensor</code>, package as a package dependency. Note that the BSP creates the sensor devices for the onboard sensors, so the <code>hw/sensor/creator</code> package that creates off-board sensor is not needed. </p>
<p>Add the highlighted line to the <code>pkg.yml</code> file to add the <code>hw/sensor</code> package as package dependency:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>pkg.deps:
- &quot;@apache-mynewt-core/kernel/os&quot;
- &quot;@apache-mynewt-core/sys/console/full&quot;
- &quot;@apache-mynewt-core/sys/log/full&quot;
- &quot;@apache-mynewt-core/sys/stats/full&quot;
<span style="background-color: #ffffcc"> - &quot;@apache-mynewt-core/hw/sensor&quot;
</span></code></pre></div>
<p><br></p>
<h4 id="step-3-using-the-skeleton-mainc-file">Step 3: Using the Skeleton main.c File</h4>
<p>The newt tool creates a skeleton main.c file in the <code>my_sensor_app/src</code> directory. The skeleton <code>main()</code> code shown is all you need to build an application that only uses the <code>sensor</code> shell command to read sensor data. You do not need to make any changes to the file. The sensor framework implements the <code>sensor</code> shell command and the shell package processes shell command events from the OS default event queue. </p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">int</span>
<span style="color: #000000">main</span>(<span style="color: #A90D91">int</span> <span style="color: #000000">argc</span>, <span style="color: #A90D91">char</span> <span style="color: #000000">**argv</span>)
{
<span style="color: #177500">/* Perform some extra setup if we&#39;re running in the simulator. */</span>
<span style="color: #633820">#ifdef ARCH_sim</span>
<span style="color: #000000">mcu_sim_parse_args</span>(<span style="color: #000000">argc</span>, <span style="color: #000000">argv</span>);
<span style="color: #633820">#endif</span>
<span style="color: #177500">/* Initialize all packages. */</span>
<span style="color: #000000">sysinit</span>();
<span style="color: #177500">/* As the last thing, process events from default event queue. */</span>
<span style="color: #A90D91">while</span> (<span style="color: #1C01CE">1</span>) {
<span style="color: #000000">os_eventq_run</span>(<span style="color: #000000">os_eventq_dflt_get</span>());
}
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">0</span>;
}
</code></pre></div>
<p><br></p>
<h4 id="step-4-creating-the-target-for-the-my_sensor_app-application">Step 4: Creating the Target for the my_sensor_app Application</h4>
<p>You create a target for the my_sensor_app to run on the Nordic Thingy. The following syscfg settings must be set:</p>
<ul>
<li><code>I2C_0=1</code> : Enables the I2C interface 0 for the nRF52 Thingy BSP HAL setting to communicate with the onboard sensor.</li>
<li>
<p><code>LIS2DH12_ONB=1</code>: Enables the lis2dh12 onboard sensor support in the nRF52 Thingy BSP. </p>
<p>A BSP with onboard sensors defines a syscfg setting for each onboard sensor it supports and uses the naming convention <code>&lt;SENSORNAME&gt;_ONB</code>. The <code>&lt;SENSORNAME&gt;_ONB</code> setting specifies whether the sensor named SENSORNAME is enabled. The setting is disabled by default. The BSP includes the sensor device driver package <code>hw/drivers/sensors/&lt;sensorname&gt;</code> and creates and configures the onboard sensor named SENSORNAME when the <code>&lt;SENSORNAME&gt;_ONB</code> setting is enabled by the application.</p>
</li>
<li>
<p><code>SHELL_TASK=1</code>: Enables the shell task for the shell command support.
Note that the <code>hw/sensor</code> package enables the <code>SENSOR_CLI</code> setting by default. </p>
</li>
<li><code>SENSOR_OIC=0</code>: Disables the OIC sensor server support in the sensor framework.</li>
<li><code>CONSOLE_RTT=1</code>: Enables console communication via the SEGGER RTT. The nRF52 Thingy does not have a UART so we use the RTT for the console.</li>
<li><code>CONSOLE_UART=0</code>: Disables the console communication via a UART.</li>
</ul>
<p><strong>Note:</strong> The lis2dh12 sensor device driver package, <code>/hw/driver/sensors/lis2dh12</code>, currently does not support a shell command to view information on the device.</p>
<p><br>
1. Run the following newt commands to create the target and set the application and BSP.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>$ newt target create thingy_my_sensor
Target targets/thingy_my_sensor successfully created
$ newt target set thingy_my_sensor bsp=@apache-mynewt-core/hw/bsp/nrf52-thingy
Target targets/thingy_my_sensor successfully set target.bsp to @apache-mynewt-core/hw/bsp/nrf52-thingy
$ newt target set thingy_my_sensor app=apps/my_sensor_app
Target targets/thingy_my_sensor successfully set target.app to apps/my_sensor_app
$ newt target set thingy_my_sensor build_profile=debug
Target targets/thingy_my_sensor successfully set target.build_profile to debug
</code></pre></div>
<p><br>
2. Run the following <code>newt target set</code> command to set the syscfg settings:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>$ newt target set thingy_my_sensor syscfg=I2C_0=1:LIS2DH12_ONB=1:SHELL_TASK=1:CONSOLE_RTT=1:CONSOLE_UART=0:SENSOR_OIC=0
Target targets/thingy_my_sensor successfully set target.syscfg to I2C_0=1:LIS2DH12_ONB=1:SHELL_TASK=1:CONSOLE_RTT=1:CONSOLE_UART=0:SENSOR_OIC=0
</code></pre></div>
<p><br></p>
<h4 id="step-5-creating-and-building-the-bootloader-target">Step 5: Creating and Building the Bootloader Target</h4>
<p>Create a target for the bootloader for the nRF52 Thingy. We name the target <code>thingy_boot</code>.</p>
<p><br>
1. Run the following <code>newt target</code> commands to create the target:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>$ newt target create thingy_boot
Target targets/thingy_boot successfully created
$ newt target set thingy_boot bsp=@apache-mynewt-core/hw/bsp/nrf52-thingy
Target targets/thingy_boot successfully set target.bsp to @apache-mynewt-core/hw/bsp/nrf52-thingy
$ newt target set thingy_boot app=@apache-mynewt-core/apps/boot
Target targets/thingy_boot successfully set target.app to @apache-mynewt-core/apps/boot
$ newt target set thingy_boot build_profile=optimized
Target targets/thingy_boot successfully set target.build_profile to optimized
</code></pre></div>
<p><br>
2. Run the <code>newt build</code> command to build the bootloader target:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>$ newt build thingy_boot
Building target targets/thingy_boot
...
Archiving thingy_boot-sysinit-app.a
Archiving util_mem.a
Linking ~/dev/myproj/bin/targets/thingy_boot/app/apps/boot/boot.elf
Target successfully built: targets/thingy_boot
</code></pre></div>
<p><br></p>
<h4 id="step-6-connecting-the-thingy-to-your-computer">Step 6: Connecting the Thingy to your Computer</h4>
<p>Perform the following steps to connect the Thingy to your computer:</p>
<p><br>
1. Move the power switch to the left to power ON the Thingy:</p>
<p><br>
<img alt="Thingy" src="/os/tutorials/pics/thingy.jpg" title="Thingy On" />
<br></p>
<p><br>
2. Connect the debug probe to the JTAG port on the board using the Jlink 9-pin adapter and cable, and connect the probe to your computer.</p>
<p><br>
<img alt="J-Link debug probe to Thingy" src="/os/tutorials/pics/thingy_jlink.jpg" title="Connecting J-Link debug probe to Thingy" />
<br></p>
<p>
<br>
<br>
#### Step 7: Loading the Image and Connecting to the Console via RTT
To run the application, you need to load the bootloader on to the device, load the application image, and start a GDB debug process for RTT to attach to.
<br>
1. Run the `newt load` command to load the bootloader:
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>$ newt load thingy_boot
Loading bootloader
</code></pre></div>
<br>
2. Run the `newt run` command to build and create an image for the my_sensor_app, load the image, and start a GDB process to debug the application:
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>$ newt run thingy_my_sensor 1.0.0
Assembling repos/apache-mynewt-core/hw/bsp/nrf52-thingy/src/arch/cortex_m4/gcc_startup_nrf52_split.s
Compiling repos/apache-mynewt-core/hw/cmsis-core/src/cmsis_nvic.c
Assembling repos/apache-mynewt-core/hw/bsp/nrf52-thingy/src/arch/cortex_m4/gcc_startup_nrf52.s
Compiling repos/apache-mynewt-core/encoding/base64/src/hex.c
Compiling apps/my_sensor_app/src/main.c
...
Archiving thingy_my_sensor-sysinit-app.a
Archiving time_datetime.a
Archiving util_cbmem.a
Archiving util_crc.a
Archiving util_mem.a
Archiving util_parse.a
Linking ~/dev/myproj/bin/targets/thingy_my_sensor/app/apps/my_sensor_app/my_sensor_app.elf
App image succesfully generated: ~/dev/myproj/bin/targets/thingy_my_sensor/app/apps/my_sensor_app/my_sensor_app.img
Loading app image into slot 1
[~/dev/myproj/repos/apache-mynewt-core/hw/bsp/nrf52-thingy/nrf52-thingy_debug.sh ~/dev/myproj/repos/apache-mynewt-core/hw/bsp/nrf52-thingy ~/dev/myproj/bin/targets/thingy_my_sensor/app/apps/my_sensor_app/my_sensor_app]
Debugging ~/dev/myproj/bin/targets/thingy_my_sensor/app/apps/my_sensor_app/my_sensor_app.elf
GNU gdb (GNU Tools for ARM Embedded Processors) 7.8.0.20150604-cvs
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &lt;http://gnu.org/licenses/gpl.html&gt;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type &quot;show copying&quot;
and &quot;show warranty&quot; for details.
This GDB was configured as &quot;--host=x86_64-apple-darwin10 --target=arm-none-eabi&quot;.
Type &quot;show configuration&quot; for configuration details.
For bug reporting instructions, please see:
&lt;http://www.gnu.org/software/gdb/bugs/&gt;.
Find the GDB manual and other documentation resources online at:
&lt;http://www.gnu.org/software/gdb/documentation/&gt;.
For help, type &quot;help&quot;.
Type &quot;apropos word&quot; to search for commands related to &quot;word&quot;...
Reading symbols from ~/dev/myproj/bin/targets/thingy_my_sensor/app/apps/my_sensor_app/my_sensor_app.elf...done.
os_tick_idle (ticks=24)
at repos/apache-mynewt-core/hw/mcu/nordic/nrf52xxx/src/hal_os_tick.c:204
204 if (ticks &gt; 0) {
Resetting target
0x000000dc in ?? ()
(gdb)
</code></pre></div>
<br>
3. Enter `c <return>` in the (gdb) prompt to continue.
<br>
4. Run the following telnet command to connect to the Mynewt console via RTT and enter &lt;return&gt; to get the shell prompt after you are connected.
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>$ telnet localhost 19021
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is &#39;^]&#39;.
SEGGER J-Link V6.14h - Real time terminal output
SEGGER J-Link ARM V10.0, SN=600000268
Process: JLinkGDBServer
011468 compat&gt;
</code></pre></div>
<br>
#### Step 8: Viewing the list of Sensors and Sensor Data
<br>
1. Enter `sensor list` to see the sensors that are registered with the sensor manager. You should see the `lis2dh12_0` sensor. This sensor is only configured for the accelerometer (0x1).
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>011468 compat&gt; sensor list
sensor list
029706 sensor dev = lis2dh12_0, configured type = 0x1
029707 compat&gt;
</code></pre></div>
<br>
2. Enter the `sensor read` command to read some data samples from the accelerometer:
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>029707 compat&gt; sensor read lis2dh12_0 0x1 -n 5
sensor read lis2dh12_0 0x1 -n 5
042537 ts: [ secs: 331 usecs: 102682 cputime: 331436945 ]
042537 x = 9.806650176 y = 58.839900992 z = -9894.910156
042537 ts: [ secs: 331 usecs: 104832 cputime: 331439095 ]
042537 x = 19.613300352 y = 98.066497804 z = -9924.330078
042537 ts: [ secs: 331 usecs: 106988 cputime: 331441251 ]
042537 x = 9.806650176 y = 49.033248902 z = -9904.716796
042538 ts: [ secs: 331 usecs: 109137 cputime: 331443400 ]
042538 x = 9.806650176 y = 29.419950496 z = -9904.716796
042538 ts: [ secs: 331 usecs: 111288 cputime: 331445551 ]
042538 x = 58.839900992 y = 0.000000000 z = -9816.457031
042538 compat&gt;
</code></pre></div>
<br>
### Extending the Application to Use the Sensor API to Read Sensor Data
As this tutorial demonstrates so far, the Mynewt sensor framework enables you to easily and quickly develop an application with a sensor and view the sensor data from the `sensor` shell command. We now extend the application to use the sensor API to read the sensor data.
There are two sensor functions that you can use to read data from a sensor device:
* `sensor_register_listener()`: This function allows you to register a listener for a sensor device. You specify a bit mask of the types of sensor data to listen for and a callback to call when data is read from the sensor device. The listener callback is called whenever the `sensor_read()` function reads data for a sensor type from a sensor device that the listener is listening for.
The sensor framework supports polling of sensor devices. For a sensor device that has a polling rate configured, the sensor framework poller reads sensor data for all the configured sensor types from the sensor device at each polling interval and calls the registered listener callbacks with the sensor data.
* `sensor_read()`: This function reads sensor data from a sensor device and calls the specified user callback to receive the sensor data. You specify a bit mask of the types of sensor data to read from a sensor device and a callback. This callback is called for each sensor type you specify to read.
We first extend the application to a register a sensor listener to demonstrate how to use the sensor framework polling support. We then extend the application to use the `sensor_read()` function instead of a listener. An application may not need to poll sensors. For example, an application that processes remote requests for sensor data might only read the sensor data when it receives a request.
<br>
#### Step 1: Modifying main.c to Add a Sensor Listener
Add the following code to the `my_sensor_app/src/main.c` file:
<br>
1. Add the highlighted include files:
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>#include &quot;sysinit/sysinit.h&quot;
#include &quot;os/os.h&quot;
<span style="background-color: #ffffcc">#include &lt;defs/error.h&gt;
</span><span style="background-color: #ffffcc">#include &lt;sensor/sensor.h&gt;
</span><span style="background-color: #ffffcc">#include &lt;sensor/accel.h&gt;
</span><span style="background-color: #ffffcc">#include &lt;console/console.h&gt;
</span></code></pre></div>
<br>
2. Add the `struct sensor * my_sensor`. This is the handle for the sensor that the sensor API uses to perform operations on the sensor. We set this variable when we lookup the sensor.
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">sensor</span> <span style="color: #000000">*my_sensor</span>;
</code></pre></div>
<br>
3. Declare and initialize a sensor listener. You specify a bit mask for the sensor types to listen for, the callback function, and an opaque argument to pass to the callback. You initialize the type to SENSOR_TYPE_ACCELEROMETER, the listener callback to the `read_accelerometer()` function, and the callback opaque argument to the LISTENER_CB value.
**Note**: We define LISTENER_CB and READ_CB values because we also use the `read_accelerometer()` function as the callback for the `sensor_read()` function later in the tutorial. The LISTENER_CB or the READ_CB value is passed to the `read_accelerometer()` function to indicate whether it is invoked as a listener or a `sensor_read()` callback.
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #633820">#define LISTENER_CB 1</span>
<span style="color: #633820">#define READ_CB 2</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">int</span> <span style="color: #000000">read_accelerometer</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">sensor</span><span style="color: #000000">*</span> <span style="color: #000000">sensor</span>, <span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>, <span style="color: #A90D91">void</span> <span style="color: #000000">*databuf</span>, <span style="color: #000000">sensor_type_t</span> <span style="color: #000000">type</span>);
<span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">sensor_listener</span> <span style="color: #000000">listener</span> <span style="color: #000000">=</span> {
.<span style="color: #000000">sl_sensor_type</span> <span style="color: #000000">=</span> <span style="color: #000000">SENSOR_TYPE_ACCELEROMETER</span>,
.<span style="color: #000000">sl_func</span> <span style="color: #000000">=</span> <span style="color: #000000">read_accelerometer</span>,
.<span style="color: #000000">sl_arg</span> <span style="color: #000000">=</span> (<span style="color: #A90D91">void</span> <span style="color: #000000">*</span>)<span style="color: #000000">LISTENER_CB</span>,
};
</code></pre></div>
<br>
4. Add the code for the `read_accelerometer()` function. The sensor data is stored in the `databuf` and `type` specifies the type of sensor data.
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">static</span> <span style="color: #A90D91">int</span>
<span style="color: #000000">read_accelerometer</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">sensor</span><span style="color: #000000">*</span> <span style="color: #000000">sensor</span>, <span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>, <span style="color: #A90D91">void</span> <span style="color: #000000">*databuf</span>, <span style="color: #000000">sensor_type_t</span> <span style="color: #000000">type</span>)
{
<span style="color: #A90D91">char</span> <span style="color: #000000">tmpstr</span>[<span style="color: #1C01CE">13</span>];
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">sensor_accel_data</span> <span style="color: #000000">*sad</span>;
<span style="color: #A90D91">if</span> (<span style="color: #000000">!databuf</span>) {
<span style="color: #A90D91">return</span> <span style="color: #000000">SYS_EINVAL</span>;
}
<span style="color: #000000">sad</span> <span style="color: #000000">=</span> (<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">sensor_accel_data</span> <span style="color: #000000">*</span>)<span style="color: #000000">databuf</span>;
<span style="color: #A90D91">if</span> (<span style="color: #000000">!sad-&gt;sad_x_is_valid</span> <span style="color: #000000">||</span>
<span style="color: #000000">!sad-&gt;sad_y_is_valid</span> <span style="color: #000000">||</span>
<span style="color: #000000">!sad-&gt;sad_z_is_valid</span>) {
<span style="color: #A90D91">return</span> <span style="color: #000000">SYS_EINVAL</span>;
}
<span style="color: #000000">console_printf</span>(<span style="color: #C41A16">&quot;%s: [ secs: %ld usecs: %d cputime: %u ]\n&quot;</span>,
((<span style="color: #A90D91">int</span>)<span style="color: #000000">arg</span> <span style="color: #000000">==</span> <span style="color: #000000">LISTENER_CB</span>) <span style="color: #000000">?</span> <span style="color: #C41A16">&quot;LISTENER_CB&quot;</span> <span style="color: #000000">:</span> <span style="color: #C41A16">&quot;READ_CB&quot;</span>,
(<span style="color: #A90D91">long</span> <span style="color: #A90D91">int</span>)<span style="color: #000000">sensor-&gt;s_sts</span>.<span style="color: #000000">st_ostv</span>.<span style="color: #000000">tv_sec</span>,
(<span style="color: #A90D91">int</span>)<span style="color: #000000">sensor-&gt;s_sts</span>.<span style="color: #000000">st_ostv</span>.<span style="color: #000000">tv_usec</span>,
(<span style="color: #A90D91">unsigned</span> <span style="color: #A90D91">int</span>)<span style="color: #000000">sensor-&gt;s_sts</span>.<span style="color: #000000">st_cputime</span>);
<span style="color: #000000">console_printf</span>(<span style="color: #C41A16">&quot;x = %s &quot;</span>, <span style="color: #000000">sensor_ftostr</span>(<span style="color: #000000">sad-&gt;sad_x</span>, <span style="color: #000000">tmpstr</span>, <span style="color: #1C01CE">13</span>));
<span style="color: #000000">console_printf</span>(<span style="color: #C41A16">&quot;y = %s &quot;</span>, <span style="color: #000000">sensor_ftostr</span>(<span style="color: #000000">sad-&gt;sad_y</span>, <span style="color: #000000">tmpstr</span>, <span style="color: #1C01CE">13</span>));
<span style="color: #000000">console_printf</span>(<span style="color: #C41A16">&quot;z = %s\n\n&quot;</span>, <span style="color: #000000">sensor_ftostr</span>(<span style="color: #000000">sad-&gt;sad_z</span>, <span style="color: #000000">tmpstr</span>, <span style="color: #1C01CE">13</span>));
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">0</span>;
}
</code></pre></div>
<br>
5. Set the poll rate for the sensor to two seconds. The `sensor_set_poll_rate_ms()` function sets the poll rate for a named sensor.
**Note:** You set the poll rate for a sensor programmatically and must set the poll rate to a non zero value in order for the sensor manager to poll the sensor. You may set a different poll rate for each sensor. The sensor framework also defines a `SENSOR_MGR_WAKEUP_RATE` syscfg setting that specifies the default rate that the sensor manager polls. The sensor manager uses the poll rate for a sesnor if a sensor is configured to poll more frequently than the `SENSOR_MGR_WAKEUP_RATE` setting value.
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="background-color: #ffffcc">#define MY_SENSOR_DEVICE &quot;lis2dh12_0&quot;
</span><span style="background-color: #ffffcc">#define MY_SENSOR_POLL_TIME 2000
</span>
int
main(int argc, char **argv)
{
<span style="background-color: #ffffcc"> int rc
</span> ...
/* Initialize all packages. */
sysinit();
<span style="background-color: #ffffcc"> rc = sensor_set_poll_rate_ms(MY_SENSOR_DEVICE, MY_SENSOR_POLL_TIME);
</span><span style="background-color: #ffffcc"> assert(rc == 0);
</span>
/* As the last thing, process events from default event queue. */
while (1) {
os_eventq_run(os_eventq_dflt_get());
}
return 0;
}
</code></pre></div>
<br>
6. Look up the sensor by name to get the handle for the sensor and register a listener for the sensor.
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>int
main(int argc, char **argv)
{
...
rc = sensor_set_poll_rate_ms(MY_SENSOR_DEVICE, MY_SENSOR_POLL_TIME);
assert(rc == 0);
<span style="background-color: #ffffcc"> my_sensor = sensor_mgr_find_next_bydevname(MY_SENSOR_DEVICE, NULL);
</span><span style="background-color: #ffffcc"> assert(my_sensor != NULL);
</span><span style="background-color: #ffffcc"> rc = sensor_register_listener(my_sensor, &amp;listener);
</span><span style="background-color: #ffffcc"> assert(rc == 0);
</span>
/* As the last thing, process events from default event queue. */
while (1) {
os_eventq_run(os_eventq_dflt_get());
}
return 0;
}
</code></pre></div>
<br>
#### Step 2: Rebuilding the Application and Connecting to Console
<br>
1. Run the `newt run` command to rebuild the application, create a new image, load the image, and start a GDB process:
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>$ newt run thingy_my_sensor 2.0.0
Compiling apps/my_sensor_app/src/main.c
Archiving apps_my_sensor_app.a
Linking ~/dev/myproj/bin/targets/thingy_my_sensor/app/apps/my_sensor_app/my_sensor_app.elf
App image succesfully generated: ~/dev/myproj/bin/targets/thingy_my_sensor/app/apps/my_sensor_app/my_sensor_app.img
Loading app image into slot 1
[~/dev/myproj/repos/apache-mynewt-core/hw/bsp/nrf52-thingy/nrf52-thingy_debug.sh ~/dev/myproj/repos/apache-mynewt-core/hw/bsp/nrf52-thingy ~/dev/myproj/bin/targets/thingy_my_sensor/app/apps/my_sensor_app/my_sensor_app]
Debugging ~/dev/myproj/bin/targets/thingy_my_sensor/app/apps/my_sensor_app/my_sensor_app.elf
GNU gdb (GNU Tools for ARM Embedded Processors) 7.8.0.20150604-cvs
...
Reading symbols from ~/dev/myproj/bin/targets/thingy_my_sensor/app/apps/my_sensor_app/my_sensor_app.elf...done.
os_tick_idle (ticks=12)
at repos/apache-mynewt-core/hw/mcu/nordic/nrf52xxx/src/hal_os_tick.c:204
204 if (ticks &gt; 0) {
Resetting target
0x000000dc in ?? ()
(gdb) c
Continuing.
</code></pre></div>
<br>
2. Connect to the console via RTT:
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>$ telnet localhost 19021
Connected to localhost.
Escape character is &#39;^]&#39;.
SEGGER J-Link V6.14h - Real time terminal output
J-Link OB-SAM3U128-V2-NordicSemi compiled Mar 2 2017 12:22:13 V1.0, SN=682562963
Process: JLinkGDBServer
000003 LISTENER_CB: [ secs: 0 usecs: 23407 cputime: 331783 ]
000003 x = 117.67980192 y = -19.61330035 z = -9885.103515
000259 LISTENER_CB: [ secs: 2 usecs: 21190 cputime: 2327645 ]
000259 x = 117.67980192 y = -9.806650176 z = -9914.523437
000515 LISTENER_CB: [ secs: 4 usecs: 17032 cputime: 4323487 ]
000515 x = 78.453201280 y = 0.000000000 z = -9924.330078
000771 LISTENER_CB: [ secs: 6 usecs: 13131 cputime: 6319586 ]
000771 x = 117.67980192 y = -19.61330035 z = -9914.523437
001027 LISTENER_CB: [ secs: 8 usecs: 8810 cputime: 8315265 ]
001027 x = 127.48645020 y = 0.000000000 z = -9924.330078
001283 LISTENER_CB: [ secs: 10 usecs: 4964 cputime: 10311419 ]
001283 x = 58.839900992 y = -9.806650176 z = -9885.103515
</code></pre></div>
You should see the accelerometer sensor data output from the listener callback.
<br>
#### Step 3: Modifying main.c to Use sensor_read() Instead of a Listener
Lets extend the application to use the `sensor_read()` function instead of a listener. We setup an OS callout to call the `sensor_read()` function for illustration purposes. A real application will most likely read the sensor data when it gets a request or some other event.
<br>
1. Add an OS callout and initialize an OS timer to fire every 5 seconds. The timer callback calls the `sensor_read()` function to read the sensor data. The `read_accelerometer()` callback is called when the sensor data is read. The READ_CB value is passed to the `read_accelerometer()` function and indicates that the callback is from the `sensor_read()` function and not from the listener.
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #177500">/*</span>
<span style="color: #177500"> * Event callback function for timer events. The callback reads the sensor data</span>
<span style="color: #177500"> */</span>
<span style="color: #633820">#define READ_SENSOR_INTERVAL (5 * OS_TICKS_PER_SEC)</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_callout</span> <span style="color: #000000">sensor_callout</span>;
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">timer_ev_cb</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*ev</span>)
{
<span style="color: #000000">assert</span>(<span style="color: #000000">ev</span> <span style="color: #000000">!=</span> <span style="color: #A90D91">NULL</span>);
<span style="color: #177500">/*</span>
<span style="color: #177500"> * Read the accelerometer sensor. Pass the READ_CB value for the callback opaque</span>
<span style="color: #177500"> * arg to indicate that it is the sensor_read() callback.</span>
<span style="color: #177500"> */</span>
<span style="color: #000000">sensor_read</span>(<span style="color: #000000">my_sensor</span>, <span style="color: #000000">SENSOR_TYPE_ACCELEROMETER</span>, <span style="color: #000000">read_accelerometer</span>,
(<span style="color: #A90D91">void</span> <span style="color: #000000">*</span>)<span style="color: #000000">READ_CB</span>, <span style="color: #000000">OS_TIMEOUT_NEVER</span>);
<span style="color: #000000">os_callout_reset</span>(<span style="color: #000000">&amp;sensor_callout</span>, <span style="color: #000000">READ_SENSOR_INTERVAL</span>);
<span style="color: #A90D91">return</span>;
}
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">init_timer</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #177500">/*</span>
<span style="color: #177500"> * Initialize the callout for a timer event.</span>
<span style="color: #177500"> */</span>
<span style="color: #000000">os_callout_init</span>(<span style="color: #000000">&amp;sensor_callout</span>, <span style="color: #000000">os_eventq_dflt_get</span>(),
<span style="color: #000000">timer_ev_cb</span>, <span style="color: #A90D91">NULL</span>);
<span style="color: #000000">os_callout_reset</span>(<span style="color: #000000">&amp;sensor_callout</span>, <span style="color: #000000">READ_SENSOR_INTERVAL</span>);
<span style="color: #A90D91">return</span>;
}
</code></pre></div>
<br>
2. Remove the listener registration and call the `init_timer()` function in `main()`. You can delete the `sensor_register_listener()` function call, but we call the `sensor_unregister_listener()` function to illustrate how to use this function.
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>int
main(int argc, char **argv)
{
...
assert(my_sensor != NULL);
rc = sensor_register_listener(my_sensor, &amp;listener);
assert(rc == 0);
<span style="background-color: #ffffcc"> rc = sensor_unregister_listener(my_sensor, &amp;listener);
</span><span style="background-color: #ffffcc"> assert(rc == 0);
</span>
<span style="background-color: #ffffcc"> init_timer();
</span>
/* As the last thing, process events from default event queue. */
while (1) {
os_eventq_run(os_eventq_dflt_get());
}
return 0;
}
</code></pre></div>
<br>
#### Step 4: Rebuilding the Application and Connecting to Console
<br>
1. Run the `newt run` command to rebuild the application, create an new image, and start a GDB process:
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>$ newt run thingy_my_sensor 3.0.0
Compiling apps/my_sensor_app/src/main.c
Archiving apps_my_sensor_app.a
Linking ~/dev/myproj/bin/targets/thingy_my_sensor/app/apps/my_sensor_app/my_sensor_app.elf
App image succesfully generated: ~/dev/myproj/bin/targets/thingy_my_sensor/app/apps/my_sensor_app/my_sensor_app.img
Loading app image into slot 1
[~/dev/myproj/repos/apache-mynewt-core/hw/bsp/nrf52-thingy/nrf52-thingy_debug.sh ~/dev/myproj/repos/apache-mynewt-core/hw/bsp/nrf52-thingy ~/dev/myproj/bin/targets/thingy_my_sensor/app/apps/my_sensor_app/my_sensor_app]
Debugging ~/dev/myproj/bin/targets/thingy_my_sensor/app/apps/my_sensor_app/my_sensor_app.elf
GNU gdb (GNU Tools for ARM Embedded Processors) 7.8.0.20150604-cvs
...
Reading symbols from ~/dev/myproj/bin/targets/thingy_my_sensor/app/apps/my_sensor_app/my_sensor_app.elf...done.
os_tick_idle (ticks=12)
at repos/apache-mynewt-core/hw/mcu/nordic/nrf52xxx/src/hal_os_tick.c:204
204 if (ticks &gt; 0) {
Resetting target
0x000000dc in ?? ()
(gdb) c
Continuing.
</code></pre></div>
<br>
3. Connect to the console via RTT:
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>$ telnet localhost 19021
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is &#39;^]&#39;.
SEGGER J-Link V6.14h - Real time terminal output
J-Link OB-SAM3U128-V2-NordicSemi compiled Mar 2 2017 12:22:13 V1.0, SN=682562963
Process: JLinkGDBServer
000629 compat&gt; READ_CB: [ secs: 5 usecs: 4088 cputime: 5295643 ]
000642 x = 98.066497804 y = 0.000000000 z = -9806.650390
001282 READ_CB: [ secs: 9 usecs: 992459 cputime: 10284014 ]
001282 x = 117.67980192 y = -39.22660064 z = -9894.910156
001922 READ_CB: [ secs: 14 usecs: 981159 cputime: 15272714 ]
001922 x = 78.453201280 y = -29.41995049 z = -9885.103515
002562 READ_CB: [ secs: 19 usecs: 970088 cputime: 20261643 ]
002562 x = 107.87315366 y = -29.41995049 z = -9885.103515
</code></pre></div>
You should see the accelerometer sensor data output from the sensor read data callback.
<div class="row">
<ul class="nav nav-pills" style="margin-bottom: 10px">
<li>
</li>
<li class="pull-right">
</li>
</ul>
</div>
<footer class="row">
<div class="col-xs-12">
<p class="copyright">Apache Mynewt is available under Apache License, version 2.0.</p>
</div>
<div class="col-xs-12">
<div class="logos">
<a href="https://www.apache.org/">
<img src="/img/asf_logo_wide_small.png" alt="Apache" title="Apache">
</a>
<p>
Copyright © 2015-2021 The Apache Software Foundation.<br>
<small class="footnote">
Apache Mynewt, Mynewt, Apache, the Apache feather logo, and the Apache Mynewt
project logo are either registered trademarks or trademarks of the Apache
Software Foundation in the United States and other countries.
</small>
</p>
<a href="">
<img src="https://www.countit.com/images/add_to_slack.png" alt="Slack Icon" title="Join our Slack Community" />
</a>
</div>
</div>
<a href="https://www.apache.org/licenses/">
<button class="button-footer-asf">
License
</button>
</a>
<a href="https://www.apache.org/foundation/sponsorship.html">
<button class="button-footer-asf">
Sponsorship
</button>
</a>
<a href="https://www.apache.org/foundation/thanks.html">
<button class="button-footer-asf">
Thanks
</button>
</a>
<a href="https://www.apache.org/security/">
<button class="button-footer-asf">
Security
</button>
</a>
<a href="https://apache.org/events/current-event">
<button class="button-footer-asf">
ASF Events
</button>
</a>
</footer>
</div>
</div>
</div>
<script src="../../../../js/jquery-1.10.2.min.js"></script>
<script src="../../../../js/bootstrap-3.0.3.min.js"></script>
<script src="../../../../js/highlight.pack.js"></script>
<script src="../../../../js/base.js"></script>
<script src="../../../../js/custom.js"></script>
<script src="search/main.js"></script>
</body>
</html>