1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_sensor: 2*61c4878aSAndroid Build Coastguard Worker 3*61c4878aSAndroid Build Coastguard Worker========= 4*61c4878aSAndroid Build Coastguard Workerpw_sensor 5*61c4878aSAndroid Build Coastguard Worker========= 6*61c4878aSAndroid Build Coastguard WorkerThis is the main documentation file for pw_sensor. It is under construction. 7*61c4878aSAndroid Build Coastguard Worker 8*61c4878aSAndroid Build Coastguard Worker.. toctree:: 9*61c4878aSAndroid Build Coastguard Worker :maxdepth: 1 10*61c4878aSAndroid Build Coastguard Worker 11*61c4878aSAndroid Build Coastguard Worker py/docs 12*61c4878aSAndroid Build Coastguard Worker 13*61c4878aSAndroid Build Coastguard WorkerDefining types 14*61c4878aSAndroid Build Coastguard Worker============== 15*61c4878aSAndroid Build Coastguard WorkerPigweed provides a data-definition layer for sensors. This allows the properties 16*61c4878aSAndroid Build Coastguard Workerof a sensor to be declared once and shared across multiple languages or runtimes. 17*61c4878aSAndroid Build Coastguard WorkerMore information is available in :ref:`module-pw_sensor-py`. 18*61c4878aSAndroid Build Coastguard Worker 19*61c4878aSAndroid Build Coastguard WorkerOnce we define our units, measurements, attributes, and triggers we can import 20*61c4878aSAndroid Build Coastguard Workerthem and use them in our language-specific sensor code. 21*61c4878aSAndroid Build Coastguard Worker 22*61c4878aSAndroid Build Coastguard WorkerHere's an example sensor definition YAML file for a custom sensor made by a 23*61c4878aSAndroid Build Coastguard Workercompany called "MyOrg" with a part ID "MyPaRt12345". This sensor supports 24*61c4878aSAndroid Build Coastguard Workerreading acceleration and its internal die temperature. We can also configure 25*61c4878aSAndroid Build Coastguard Workerthe sample rate for the acceleration readings. 26*61c4878aSAndroid Build Coastguard Worker 27*61c4878aSAndroid Build Coastguard Worker.. code-block:: yaml 28*61c4878aSAndroid Build Coastguard Worker 29*61c4878aSAndroid Build Coastguard Worker deps: 30*61c4878aSAndroid Build Coastguard Worker - "third_party/pigweed/pw_sensor/attributes.yaml" 31*61c4878aSAndroid Build Coastguard Worker - "third_party/pigweed/pw_sensor/channels.yaml" 32*61c4878aSAndroid Build Coastguard Worker - "third_party/pigweed/pw_sensor/units.yaml" 33*61c4878aSAndroid Build Coastguard Worker compatible: 34*61c4878aSAndroid Build Coastguard Worker org: "MyOrg" 35*61c4878aSAndroid Build Coastguard Worker part: "MyPaRt12345" 36*61c4878aSAndroid Build Coastguard Worker channels: 37*61c4878aSAndroid Build Coastguard Worker acceleration: [] 38*61c4878aSAndroid Build Coastguard Worker die_temperature: [] 39*61c4878aSAndroid Build Coastguard Worker attributes: 40*61c4878aSAndroid Build Coastguard Worker - attribute: "sample_rate" 41*61c4878aSAndroid Build Coastguard Worker channel: "acceleration" 42*61c4878aSAndroid Build Coastguard Worker units: "frequency" 43*61c4878aSAndroid Build Coastguard Worker representation: "unsigned" 44*61c4878aSAndroid Build Coastguard Worker 45*61c4878aSAndroid Build Coastguard WorkerNow that we have our sensor spec in a YAML file we can use it in our C++ code: 46*61c4878aSAndroid Build Coastguard Worker 47*61c4878aSAndroid Build Coastguard Worker.. tab-set:: 48*61c4878aSAndroid Build Coastguard Worker 49*61c4878aSAndroid Build Coastguard Worker .. tab-item:: Bazel 50*61c4878aSAndroid Build Coastguard Worker 51*61c4878aSAndroid Build Coastguard Worker Compiling one or more sensor YAML files into a header is done by a call to 52*61c4878aSAndroid Build Coastguard Worker the ``pw_sensor_library`` rule. It looks like: 53*61c4878aSAndroid Build Coastguard Worker 54*61c4878aSAndroid Build Coastguard Worker .. code-block:: 55*61c4878aSAndroid Build Coastguard Worker 56*61c4878aSAndroid Build Coastguard Worker load("@pigweed//pw_sensor:sensor.bzl", "pw_sensor_library") 57*61c4878aSAndroid Build Coastguard Worker 58*61c4878aSAndroid Build Coastguard Worker pw_sensor_library( 59*61c4878aSAndroid Build Coastguard Worker name = "my_sensor_lib", 60*61c4878aSAndroid Build Coastguard Worker out_header = "my_app/generated/sensor_constants.h", 61*61c4878aSAndroid Build Coastguard Worker srcs = [ 62*61c4878aSAndroid Build Coastguard Worker "my_sensor0.yaml", 63*61c4878aSAndroid Build Coastguard Worker "my_sensor1.yaml", 64*61c4878aSAndroid Build Coastguard Worker ], 65*61c4878aSAndroid Build Coastguard Worker inputs = [ 66*61c4878aSAndroid Build Coastguard Worker "@pigweed//pw_sensor:attributes.yaml", 67*61c4878aSAndroid Build Coastguard Worker "@pigweed//pw_sensor:channels.yaml", 68*61c4878aSAndroid Build Coastguard Worker "@pigweed//pw_sensor:triggers.yaml", 69*61c4878aSAndroid Build Coastguard Worker "@pigweed//pw_sensor:units.yaml", 70*61c4878aSAndroid Build Coastguard Worker ], 71*61c4878aSAndroid Build Coastguard Worker generator_includes = ["@pigweed//"], 72*61c4878aSAndroid Build Coastguard Worker deps = [ 73*61c4878aSAndroid Build Coastguard Worker "@pigweed//pw_sensor:pw_sensor_types", 74*61c4878aSAndroid Build Coastguard Worker "@pigweed//pw_containers:flag_map", 75*61c4878aSAndroid Build Coastguard Worker "@pigweed//pw_tokenizer:pw_tokenizer", 76*61c4878aSAndroid Build Coastguard Worker ], 77*61c4878aSAndroid Build Coastguard Worker ) 78*61c4878aSAndroid Build Coastguard Worker 79*61c4878aSAndroid Build Coastguard Worker .. tab-item:: GN 80*61c4878aSAndroid Build Coastguard Worker 81*61c4878aSAndroid Build Coastguard Worker Compiling one or more sensor YAML files into a header is done by a call to 82*61c4878aSAndroid Build Coastguard Worker the ``pw_sensor_library`` template. It looks like: 83*61c4878aSAndroid Build Coastguard Worker 84*61c4878aSAndroid Build Coastguard Worker .. code-block:: 85*61c4878aSAndroid Build Coastguard Worker 86*61c4878aSAndroid Build Coastguard Worker import("$dir_pw_sensor/sensor.gni") 87*61c4878aSAndroid Build Coastguard Worker 88*61c4878aSAndroid Build Coastguard Worker pw_sensor_library("my_sensor_lib") { 89*61c4878aSAndroid Build Coastguard Worker out_header = "my_app/generated/sensor_constants.h" 90*61c4878aSAndroid Build Coastguard Worker sources = [ 91*61c4878aSAndroid Build Coastguard Worker "my_sensor0.yaml", 92*61c4878aSAndroid Build Coastguard Worker "my_sensor1.yaml", 93*61c4878aSAndroid Build Coastguard Worker ] 94*61c4878aSAndroid Build Coastguard Worker inputs = [ 95*61c4878aSAndroid Build Coastguard Worker "$dir_pw_sensor/attributes.yaml", 96*61c4878aSAndroid Build Coastguard Worker "$dir_pw_sensor/channels.yaml", 97*61c4878aSAndroid Build Coastguard Worker "$dir_pw_sensor/triggers.yaml", 98*61c4878aSAndroid Build Coastguard Worker "$dir_pw_sensor/units.yaml", 99*61c4878aSAndroid Build Coastguard Worker ] 100*61c4878aSAndroid Build Coastguard Worker generator_includes = [ getenv["PW_ROOT"] ] 101*61c4878aSAndroid Build Coastguard Worker public_deps = [ 102*61c4878aSAndroid Build Coastguard Worker "$dir_pw_sensor:pw_sensor_types", 103*61c4878aSAndroid Build Coastguard Worker "$dir_pw_containers:flag_map", 104*61c4878aSAndroid Build Coastguard Worker "$dir_pw_tokenizer:pw_tokenizer", 105*61c4878aSAndroid Build Coastguard Worker ] 106*61c4878aSAndroid Build Coastguard Worker } 107*61c4878aSAndroid Build Coastguard Worker 108*61c4878aSAndroid Build Coastguard Worker .. tab-item:: CMake 109*61c4878aSAndroid Build Coastguard Worker 110*61c4878aSAndroid Build Coastguard Worker Compiling one or more sensor YAML files into a header is done by a call to 111*61c4878aSAndroid Build Coastguard Worker the ``pw_sensor_library`` function. It looks like: 112*61c4878aSAndroid Build Coastguard Worker 113*61c4878aSAndroid Build Coastguard Worker .. code-block:: 114*61c4878aSAndroid Build Coastguard Worker 115*61c4878aSAndroid Build Coastguard Worker include($ENV{PW_ROOT}/pw_sensor/sensor.cmake) 116*61c4878aSAndroid Build Coastguard Worker 117*61c4878aSAndroid Build Coastguard Worker # Generate an interface library called my_sensor_lib which exposes a 118*61c4878aSAndroid Build Coastguard Worker # header file that can be included as 119*61c4878aSAndroid Build Coastguard Worker # "my_app/generated/sensor_constants.h". 120*61c4878aSAndroid Build Coastguard Worker pw_sensor_library(my_sensor_lib 121*61c4878aSAndroid Build Coastguard Worker OUT_HEADER 122*61c4878aSAndroid Build Coastguard Worker my_app/generated/sensor_constants.h 123*61c4878aSAndroid Build Coastguard Worker INPUTS 124*61c4878aSAndroid Build Coastguard Worker $ENV{PW_ROOT}/attributes.yaml 125*61c4878aSAndroid Build Coastguard Worker $ENV{PW_ROOT}/channels.yaml 126*61c4878aSAndroid Build Coastguard Worker $ENV{PW_ROOT}/triggers.yaml 127*61c4878aSAndroid Build Coastguard Worker $ENV{PW_ROOT}/units.yaml 128*61c4878aSAndroid Build Coastguard Worker GENERATOR_INCLUDES 129*61c4878aSAndroid Build Coastguard Worker $ENV{PW_ROOT} 130*61c4878aSAndroid Build Coastguard Worker SOURCES 131*61c4878aSAndroid Build Coastguard Worker my_sensor0.yaml 132*61c4878aSAndroid Build Coastguard Worker my_sensor1.yaml 133*61c4878aSAndroid Build Coastguard Worker PUBLIC_DEPS 134*61c4878aSAndroid Build Coastguard Worker pw_sensor.types 135*61c4878aSAndroid Build Coastguard Worker pw_containers 136*61c4878aSAndroid Build Coastguard Worker pw_tokenizer 137*61c4878aSAndroid Build Coastguard Worker ) 138*61c4878aSAndroid Build Coastguard Worker 139*61c4878aSAndroid Build Coastguard WorkerThe final product is an interface library that can be linked and used in your 140*61c4878aSAndroid Build Coastguard Workerapplication. As an example: 141*61c4878aSAndroid Build Coastguard Worker 142*61c4878aSAndroid Build Coastguard Worker.. code-block:: 143*61c4878aSAndroid Build Coastguard Worker 144*61c4878aSAndroid Build Coastguard Worker #include "my_app/generated/sensor_constants.h" 145*61c4878aSAndroid Build Coastguard Worker 146*61c4878aSAndroid Build Coastguard Worker int main() { 147*61c4878aSAndroid Build Coastguard Worker PW_LOG_INFO( 148*61c4878aSAndroid Build Coastguard Worker PW_LOG_TOKEN_FMT() " is measured in " PW_LOG_TOKEN_FMT(), 149*61c4878aSAndroid Build Coastguard Worker pw::sensor::channels::kAcceleration::kMeasurementName, 150*61c4878aSAndroid Build Coastguard Worker pw::sensor::GetMeasurementUnitNameFromType( 151*61c4878aSAndroid Build Coastguard Worker pw::sensor::channels::kAcceleration::kUnitType 152*61c4878aSAndroid Build Coastguard Worker ) 153*61c4878aSAndroid Build Coastguard Worker ); 154*61c4878aSAndroid Build Coastguard Worker } 155*61c4878aSAndroid Build Coastguard Worker 156*61c4878aSAndroid Build Coastguard Worker-------------- 157*61c4878aSAndroid Build Coastguard WorkerUnder the hood 158*61c4878aSAndroid Build Coastguard Worker-------------- 159*61c4878aSAndroid Build Coastguard Worker 160*61c4878aSAndroid Build Coastguard WorkerIn order to communicate with Pigweed's sensor stack, there are a few type 161*61c4878aSAndroid Build Coastguard Workerdefinitions that are used: 162*61c4878aSAndroid Build Coastguard Worker 163*61c4878aSAndroid Build Coastguard Worker* Unit types - created with ``PW_SENSOR_UNIT_TYPE``. These can be thought of as 164*61c4878aSAndroid Build Coastguard Worker defining things like "meters", "meters per second square", 165*61c4878aSAndroid Build Coastguard Worker "radians per second", etc. 166*61c4878aSAndroid Build Coastguard Worker* Measurement types - created with ``PW_SENSOR_MEASUREMENT_TYPE``. These are 167*61c4878aSAndroid Build Coastguard Worker different things you can measure with a given unit. Examples: "height", 168*61c4878aSAndroid Build Coastguard Worker "width", and "length" would all use "meters" as a unit but are different 169*61c4878aSAndroid Build Coastguard Worker measurement types. 170*61c4878aSAndroid Build Coastguard Worker* Attribute types - created with ``PW_SENSOR_ATTRIBUTE_TYPE``. These are 171*61c4878aSAndroid Build Coastguard Worker configurable aspects of the sensor. They are things like sample rates, tigger 172*61c4878aSAndroid Build Coastguard Worker thresholds, etc. Attributes are unitless until they are paired with the 173*61c4878aSAndroid Build Coastguard Worker measurement type that they modify. As an example "range" attribute for 174*61c4878aSAndroid Build Coastguard Worker acceleration measurements would be in "m/s^2", while a "range" attribute for 175*61c4878aSAndroid Build Coastguard Worker rotational velocity would be in "rad/s". 176*61c4878aSAndroid Build Coastguard Worker* Attribute instances - created with ``PW_SENSOR_ATTRIBUTE_INSTANCE``. These 177*61c4878aSAndroid Build Coastguard Worker lump together an attribute with the measurement it applies to along with a 178*61c4878aSAndroid Build Coastguard Worker unit to use. Example: Attribute("sample rate") + Measurement("acceleration") + 179*61c4878aSAndroid Build Coastguard Worker Unit("frequency"). 180*61c4878aSAndroid Build Coastguard Worker* Trigger types - created with ``PW_SENSOR_TRIGGER_TYPE``. These are events that 181*61c4878aSAndroid Build Coastguard Worker affect the streaming API. These can be events like "fifo full", "tap", 182*61c4878aSAndroid Build Coastguard Worker "double tap" 183*61c4878aSAndroid Build Coastguard Worker 184*61c4878aSAndroid Build Coastguard WorkerDevelopers don't need to actually touch these, as they're automatically called 185*61c4878aSAndroid Build Coastguard Workerfrom the generated sensor library above. The important thing from the input YAML 186*61c4878aSAndroid Build Coastguard Workerfile is that our final generated header will include the following types: 187*61c4878aSAndroid Build Coastguard Worker``attributes::kSampleRate``, ``channels::kAcceleration``, 188*61c4878aSAndroid Build Coastguard Worker``channels::kDieTemperature``, and ``units::kFrequency``. All of these are used 189*61c4878aSAndroid Build Coastguard Workerby our sensor. 190*61c4878aSAndroid Build Coastguard Worker 191*61c4878aSAndroid Build Coastguard WorkerA later change will also introduce the ``PW_SENSOR_ATTRIBUTE_INSTANCE``. 192