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