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