diff --git a/Doxyfile b/Doxyfile index f73a35c0..e76f943e 100644 --- a/Doxyfile +++ b/Doxyfile @@ -32,13 +32,13 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "MetaWear Cpp API" +PROJECT_NAME = "MetaWear C++ API" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.2.2 +PROJECT_NUMBER = 0.3.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -779,7 +779,7 @@ FILE_PATTERNS = # be searched for input files as well. # The default value is: NO. -RECURSIVE = NO +RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a @@ -804,7 +804,7 @@ EXCLUDE_SYMLINKS = NO # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = */cpp/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the diff --git a/README.md b/README.md index eb98c0d0..8d5d6553 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,34 @@ This project is a C++ implementation of the MetaWear protocol. If compiled as a shared library, it can be used with any language that supports calling C functions from a shared library, such as C# and Python. The library only constructs the bytes for communicating with the MetaWear platform, it **does not** contain any Bluetooth LE code. Users will need to fill in the appropriate Bluetooth LE functions for their target device. # Build # -Building the project has been tested on Linux using GCC 4.8.3 and make, and on Windows with Visual Studio Community 2015. +Building the project has been tested on Linux with GCC 4.8.5 and Clang 3.7.0, and on Windows with Visual Studio Community 2015. -## GCC and Make ## +```sh +> gcc --version +gcc (SUSE Linux) 4.8.5 +Copyright (C) 2015 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +> clang++ --version +clang version 3.7.0 (tags/RELEASE_370/final 246586) +Target: x86_64-suse-linux +Thread model: posix +``` + +## GCC and Clang ## Linux users can build the project by invoking make. The default action is to build the shared library for your platform. ```sh > make ``` -Upon a successful compile, the library will be placed in the newly created dist directory. +You can change the C++ compiler by overriding the CXX make variable. +```sh +> make CXX=clang++ +``` + +Upon a successful compile, the library will be placed in the newly created "dist" directory. ```sh > tree dist @@ -20,8 +38,8 @@ dist/ └── lib └── x64 ├── libmetawear.so -> libmetawear.so.0 - ├── libmetawear.so.0 -> libmetawear.so.0.2.2 - └── libmetawear.so.0.2.2 + ├── libmetawear.so.0 -> libmetawear.so.0.3.0 + └── libmetawear.so.0.3.0 ``` @@ -31,16 +49,18 @@ Unit tests for the library are written in Python (min v3.4.1) and can be invoked ```sh > make test python3 -m unittest discover -s test -................................................................................... +................................................................................ +................................................................................ +...... ---------------------------------------------------------------------- -Ran 83 tests in 0.018s +Ran 166 tests in 0.047s OK ``` ## Visual Studio ## -A VIsual Studio solution building the C# wrapper is available as a separate project, link [here](https://github.com/mbientlab/MetaWear-CSharpWrapper). The C++ source code is built as Windows Runtime Component with the following changes to the project properties: +A Visual Studio solution building the C# wrapper is available as a separate project, link [here](https://github.com/mbientlab/MetaWear-CSharpWrapper). The C++ source code is built as Windows Runtime Component with the following changes to the project properties: 1. Disable the **Precompiled Headers** compile option 2. Disable **Generate Windows Metadata** linker option -3. Add **METAWEAR_DLL_EXPORTS** to the preprocessor list +3. Add **METAWEAR_DLL_EXPORTS** to the preprocessor list \ No newline at end of file diff --git a/project_version.mk b/project_version.mk index a897b08a..09bef31c 100644 --- a/project_version.mk +++ b/project_version.mk @@ -1,4 +1,4 @@ -VERSION=0.2.77 +VERSION=0.3.0 VERSION_MAJOR=0 -VERSION_MINOR=2 -VERSION_STEP=77 +VERSION_MINOR=3 +VERSION_STEP=0 diff --git a/src/metawear/core/connection.h b/src/metawear/core/connection.h index 97b169ef..9e03eaed 100644 --- a/src/metawear/core/connection.h +++ b/src/metawear/core/connection.h @@ -1,7 +1,6 @@ /** * @copyright MbientLab License * @file connection.h - * @brief Methods and types for communicating with the metawear board */ #pragma once @@ -14,20 +13,54 @@ extern "C" { #endif -/** High QWORD of the MetaWear gatt service UUID */ -const uint64_t METAWEAR_GATT_SERVICE_UUID_HIGH= 0x326a900085cb9195; -/** Low QWORD of the MetaWear gatt service uuid */ -const uint64_t METAWEAR_GATT_SERVICE_UUID_LOW= 0xd9dd464cfbbae75a; +/** + * UUIDs identifying a gatt characteristic and its parent service + */ +typedef struct { + uint64_t service_uuid_high; ///< High 64 bits of the parent service uuid + uint64_t service_uuid_low; ///< Low 64 bits of the parent service uuid + uint64_t uuid_high; ///< High 64 bits of the characteristic uuid + uint64_t uuid_low; ///< Low 64 bits of the characteristic uuid +} MblMwGattChar; + +/** UUIDs for the MetaWear notification characteristic */ +const MblMwGattChar METAWEAR_SERVICE_NOTIFY_CHAR = { 0x326a900085cb9195, 0xd9dd464cfbbae75a, 0x326a900685cb9195, 0xd9dd464cfbbae75a }; -/** High QWORD of the MetaWear command gatt characteristic */ -const uint64_t METAWEAR_GATT_CHAR_COMMAND_UUID_HIGH= 0x326a900185cb9195; -/** Low QWORD of the MetaWear command gatt characteristic */ -const uint64_t METAWEAR_GATT_CHAR_COMMAND_UUID_LOW= 0xd9dd464cfbbae75a; +/** + * Wrapper class containing functions for communicating with the MetaWear through a Bluetooth Low Energy connection. + */ +typedef struct { + /** + * Writes the characteristic and value to the device + * @param characteristic Gatt characteristic to write + * @param value Value to write as a byte array + * @param length Length of the byte array + */ + void (*write_gatt_char)(const MblMwGattChar *characteristic, const uint8_t *value, uint8_t length); + /** + * Reads the value of the characteristic from the device + * @param characteristic Gatt characteristic to read + */ + void (*read_gatt_char)(const MblMwGattChar *characteristic); +} MblMwBtleConnection; -/** High QWORD of the MetaWear notification gatt characteristic */ -const uint64_t METAWEAR_GATT_CHAR_NOTIFY_UUID_HIGH= 0x326a900685cb9195; -/** Low QWORD of the MetaWear notification gatt characteristic */ -const uint64_t METAWEAR_GATT_CHAR_NOTIFY_UUID_LOW= 0xd9dd464cfbbae75a; +/** + * Handles changes from the MetaWear notify characteristic. All characteristic changes from the notify characteristic must be forwarded + * to this function + * @param board Board the characteristic change is from + * @param value Byte array containing the new characteristic value + * @param len Length of the array + * @see METAWEAR_SERVICE_NOTIFY_CHAR + */ +METAWEAR_API int32_t mbl_mw_connection_notify_char_changed(MblMwMetaWearBoard *board, const uint8_t *value, uint8_t len); +/** + * Handles responses from reading gatt characteristics. All characteristic values read must be forwaded to this function. + * @param board Board the response is from + * @param characteristic Characteristic that was read + * @param value Byte array containing the characteristic value + * @param length Length of the array + */ +METAWEAR_API void mbl_mw_connection_char_read(MblMwMetaWearBoard *board, const MblMwGattChar *characteristic, const uint8_t *value, uint8_t length); #ifdef __cplusplus } diff --git a/src/metawear/core/data.h b/src/metawear/core/data.h index 2e929d10..c3d82c6a 100644 --- a/src/metawear/core/data.h +++ b/src/metawear/core/data.h @@ -1,13 +1,18 @@ +/** + * @copyright MbientLab License + * @file data.h + * @brief Functions and types for data received from an MblMwDataSignal + */ #pragma once /** * Enumeration of sensor data types */ typedef enum { - MBL_MW_DT_ID_UINT32= 0, ///< Data is a uint32_t - MBL_MW_DT_ID_FLOAT, ///< Data is a float - MBL_MW_DT_ID_CARTESIAN_FLOAT, ///< Data is a CartesianFloat - MBL_MW_DT_ID_INT32 + MBL_MW_DT_ID_UINT32= 0, ///< Data is an unsigned integer + MBL_MW_DT_ID_FLOAT, ///< Data is a float + MBL_MW_DT_ID_CARTESIAN_FLOAT, ///< Data is a CartesianFloat + MBL_MW_DT_ID_INT32 ///< Data is a signed integer } MblMwDataTypeId; /** @@ -18,4 +23,8 @@ typedef struct { MblMwDataTypeId type_id; ///< ID represnting the data type the value pointer points to } MblMwData; -typedef void (*MblMwFnData)(const MblMwData* data); \ No newline at end of file +/** + * Definition for callback functions that handle data from an MblMwDataSignal + * @param data Data returned from the signal + */ +typedef void (*MblMwFnData)(const MblMwData* data); diff --git a/src/metawear/core/dataprocessor_fwd.h b/src/metawear/core/dataprocessor_fwd.h index cc0a4ddf..beebbef0 100644 --- a/src/metawear/core/dataprocessor_fwd.h +++ b/src/metawear/core/dataprocessor_fwd.h @@ -1,9 +1,22 @@ +/** + * @copyright MbientLab License + * @file dataprocessor_fwd.h + * @brief Forward declaration for the MblMwDataProcessor type + */ #pragma once #ifdef __cplusplus struct MblMwDataProcessor; #else +/** + * Data signal from the on board data processor. An MblMwDataProcessor pointer can be casted as an + * MblMwDataSignal pointer and used with any function tht accepts an MblMwdDataSignal. + */ typedef struct MblMwDataProcessor MblMwDataProcessor; #endif -typedef void (*MblMwFnDataProcessor)(MblMwDataProcessor* new_processor); +/** + * Definition for callback functions that accept an MblMwDataProcessor pointer + * @param processor Processor to be used with the function + */ +typedef void (*MblMwFnDataProcessor)(MblMwDataProcessor* processor); diff --git a/src/metawear/core/datasignal.h b/src/metawear/core/datasignal.h index 61506f74..f21820de 100644 --- a/src/metawear/core/datasignal.h +++ b/src/metawear/core/datasignal.h @@ -1,7 +1,7 @@ /** * @copyright MbientLab License * @file datasignal.h - * @brief Generic functions for handling sensor data + * @brief Functions for controlling a MblMwDataSignal */ #pragma once @@ -15,7 +15,8 @@ extern "C" { /** * Subscribes to a data stream, processing messages with the given handler - * @param signal Data signal to subscribe to + * @param signal Data signal to subscribe to + * @param received_data Callback function to handle data received from the signal */ METAWEAR_API void mbl_mw_datasignal_subscribe(MblMwDataSignal *signal, MblMwFnData received_data); diff --git a/src/metawear/core/datasignal_fwd.h b/src/metawear/core/datasignal_fwd.h index d7858d16..ef3ef4c8 100644 --- a/src/metawear/core/datasignal_fwd.h +++ b/src/metawear/core/datasignal_fwd.h @@ -1,17 +1,16 @@ /** -* @copyright MbientLab License -* @file datasignal_fwd.h -* @brief Forward declarations for datasignal types -*/ + * @copyright MbientLab License + * @file datasignal_fwd.h + * @brief Forward declaration for the MblMwDataSignal type + */ #pragma once #ifdef __cplusplus struct MblMwDataSignal; #else /** - * Represents a data producer + * A event fired from the MetaWear board that also contains data. An MblMwDataSignal pointer can be casted as an + * MblMwEvent pointer and used with any function that accepts an MblMwEvent pointer. */ typedef struct MblMwDataSignal MblMwDataSignal; #endif - -typedef void(*MblMwFnDataSignal)(MblMwDataSignal* new_signal); \ No newline at end of file diff --git a/src/metawear/core/event.h b/src/metawear/core/event.h index f530f212..48127545 100644 --- a/src/metawear/core/event.h +++ b/src/metawear/core/event.h @@ -1,3 +1,9 @@ +/** + * @copyright MbientLab License + * @file event.h + * @brief Functions for the MblMwEvent type + */ + #pragma once #include "callback.h" @@ -9,10 +15,25 @@ extern "C" { #endif +/** + * Retrieves the MblMwMetaWearBoard the event belongs to + * @param event Event to lookup + * @return Pointer to the owner + */ METAWEAR_API MblMwMetaWearBoard* mbl_mw_event_get_owner(const MblMwEvent *event); +/** + * Enables command recording. All MetaWear commands called after this point will be executed + * when the owning event is fired + * @param event Event to record commands for + */ METAWEAR_API void mbl_mw_event_record_commands(MblMwEvent *event); +/** + * Ends command recording. This function is non-blocking and will asynchronously alert the caller + * when the operation is completed. + * @param event Event to end recording for + * @param commands_recorded Callback function to be executed when commands have been recorded + */ METAWEAR_API void mbl_mw_event_end_record(MblMwEvent *event, MblMwFnVoid commands_recorded); -METAWEAR_API void mbl_mw_event_remove_commands(MblMwEvent *event); #ifdef __cplusplus } diff --git a/src/metawear/core/event_fwd.h b/src/metawear/core/event_fwd.h index 0bba009d..d0a34cda 100644 --- a/src/metawear/core/event_fwd.h +++ b/src/metawear/core/event_fwd.h @@ -1,7 +1,15 @@ +/** + * @copyright MbientLab License + * @file event_fwd.h + * @brief Forward declaration of the MblMwEvent type + */ #pragma once #ifdef __cplusplus struct MblMwEvent; #else +/** + * Represents an event fired from the MetaWear board. + */ typedef struct MblMwEvent MblMwEvent; -#endif \ No newline at end of file +#endif diff --git a/src/metawear/core/metawearboard.h b/src/metawear/core/metawearboard.h index 69a187cf..7854a1db 100644 --- a/src/metawear/core/metawearboard.h +++ b/src/metawear/core/metawearboard.h @@ -1,17 +1,18 @@ /** -* @copyright MbientLab License -* @file metawearboard.h -*/ + * @copyright MbientLab License + * @file metawearboard.h + */ #pragma once #include #include "callback.h" +#include "connection.h" #include "dllmarker.h" #include "metawearboard_fwd.h" #include "module.h" -const int32_t MBL_MW_MODULE_TYPE_NA = -1; +const int32_t MBL_MW_MODULE_TYPE_NA = -1; ///< Constant signifying a module is not available #ifdef __cplusplus extern "C" { @@ -19,25 +20,42 @@ extern "C" { /** * Creates an instance of the MblMwMetaWearBoard struct + * @param connection Connection struct the new MblMwMetaWearBoard variable will use for btle communication * @return Pointer to the newly created struct */ -METAWEAR_API MblMwMetaWearBoard* mbl_mw_create_metawear_board(MblMwFnByteArray send_command); +METAWEAR_API MblMwMetaWearBoard* mbl_mw_metawearboard_create(const MblMwBtleConnection *connection); /** * Frees the memory allocated for the struct * @param board Pointer to the memory to free */ -METAWEAR_API void mbl_mw_free_metawear_board(MblMwMetaWearBoard *board); +METAWEAR_API void mbl_mw_metawearboard_free(MblMwMetaWearBoard *board); +/** + * Initialize the board. This function is non-blocking and will alert the caller when the operation is complete. + * @param board Board to initialize + * @param initialized Callback function to be executed when the board is initialized + */ METAWEAR_API void mbl_mw_metawearboard_initialize(MblMwMetaWearBoard *board, MblMwFnVoid initialized); -METAWEAR_API int32_t mbl_mw_metawearboard_is_initialized(const MblMwMetaWearBoard *board); -METAWEAR_API int32_t mbl_mw_metawearboard_get_module_type(const MblMwMetaWearBoard *board, uint8_t module); +/** + * Removes all data processors and timers from the MetaWear board + * @param board Board to tear down + */ +METAWEAR_API void mbl_mw_metawearboard_tear_down(MblMwMetaWearBoard *board); /** - * Handles responses from the MetaWearBoard and must be called for every response received - * @param board Pointer to the board the response is from - * @param response Byte array holding the response - * @param len Length of the array + * Checks if the board is initialized + * @param board Board to check + * @return Zero if not initialized, non-zero if it is + */ +METAWEAR_API int32_t mbl_mw_metawearboard_is_initialized(const MblMwMetaWearBoard *board); +/** + * Checks module type i.e. what kind of accelerometer is being used + * @param board Board to check + * @param module Module to lookup + * @return Module type used by the board, MBL_MW_MODULE_TYPE_NA if module is not available + * @see MBL_MW_MODULE_ACC_TYPE_MMA8452Q + * @see MBL_MW_MODULE_ACC_TYPE_BMI160 */ -METAWEAR_API int32_t mbl_mw_metawearboard_handle_response(MblMwMetaWearBoard *board, const uint8_t *response, uint8_t len); +METAWEAR_API int32_t mbl_mw_metawearboard_lookup_module(const MblMwMetaWearBoard *board, uint8_t module); #ifdef __cplusplus } diff --git a/src/metawear/core/metawearboard_fwd.h b/src/metawear/core/metawearboard_fwd.h index 916e1832..4e0decfd 100644 --- a/src/metawear/core/metawearboard_fwd.h +++ b/src/metawear/core/metawearboard_fwd.h @@ -15,6 +15,4 @@ struct MblMwMetaWearBoard; * Software representation of a physical MetaWear board */ typedef struct MblMwMetaWearBoard MblMwMetaWearBoard; -#endif - -typedef void(*MblMwFnByteArray)(const uint8_t* command, uint8_t len); \ No newline at end of file +#endif \ No newline at end of file diff --git a/src/metawear/core/settings.h b/src/metawear/core/settings.h index 0e5a6a10..5b0064aa 100644 --- a/src/metawear/core/settings.h +++ b/src/metawear/core/settings.h @@ -1,3 +1,8 @@ +/** + * @copyright MbientLab License + * @file settings.h + * @brief Configures Bluetooth Low Energy advertisement and connection settings + */ #pragma once #include @@ -8,16 +13,46 @@ extern "C" { #endif +/** + * Sets the advertisement name + * @param board Board to modify + * @param device_name Byte array containing the device name, max 8 ASCII characters + * @param len Length of the array + */ METAWEAR_API void mbl_mw_settings_set_device_name(const MblMwMetaWearBoard *board, const uint8_t *device_name, uint8_t len); - +/** + * Sets the advertising interval + * @param board Board to set the ad interval + * @param interval Advertisement interval, between [0, 65535] milliseconds + * @param timeout Advertisement timeout, between [0, 180] seconds where 0 indicates no timeout + */ METAWEAR_API void mbl_mw_settings_set_ad_interval(const MblMwMetaWearBoard *board, uint16_t interval, uint8_t timeout); - +/** + * Sets advertising transmitting power. If a non valid value is set, the nearest valid value will be used instead + * @param board Board to set the TX power + * @param tx_power Valid values are: 4, 0, -4, -8, -12, -16, -20, -30 + */ METAWEAR_API void mbl_mw_settings_set_tx_power(const MblMwMetaWearBoard *board, int8_t tx_power); - +/** + * Starts advertising + * @param board Board to start btle advertisement + */ METAWEAR_API void mbl_mw_settings_start_advertising(const MblMwMetaWearBoard *board); - +/** + * Sets scan response + * @param board Board to modify + * @param response Scan response as a byte array + * @param len Length of the array + */ METAWEAR_API void mbl_mw_settings_set_scan_response(const MblMwMetaWearBoard *board, const uint8_t *response, uint8_t len); - +/** + * Sets connection parameters + * @param board Board to modify + * @param min_conn_interval Connection interval lower bound, min 7.5ms + * @param max_conn_interval Connection interval upper bound, max 4000ms + * @param latency Number of connection intervals to skip, betwen [0, 1000] + * @param timeout Max time between data exchanges until the connection is considered to be lost, between [10, 32000]ms + */ METAWEAR_API void mbl_mw_settings_set_connection_parameters(const MblMwMetaWearBoard *board, float min_conn_interval, float max_conn_interval, uint16_t latency, uint16_t timeout); diff --git a/src/metawear/core/status.h b/src/metawear/core/status.h index 9d0fd9a2..31de2ab7 100644 --- a/src/metawear/core/status.h +++ b/src/metawear/core/status.h @@ -12,4 +12,9 @@ const int32_t MBL_MW_STATUS_OK= 0; /** Data unexpectedly received from a sensor. This could happen if the library connects to an already setup board */ const int32_t MBL_MW_STATUS_WARNING_UNEXPECTED_SENSOR_DATA= 1; +/** Invalid processor passed into a dataprocessor function */ const int32_t MBL_MW_STATUS_WARNING_INVALID_PROCESSOR_TYPE= 2; +/** Processor not supported on the board */ +const int32_t MBL_MW_STATUS_ERROR_UNSUPPORTED_PROCESSOR = 4; +/** Invalid response receieved from the MetaWear notify characteristic */ +const int32_t MBL_MW_STATUS_WARNING_INVALID_RESPONSE = 8; diff --git a/src/metawear/core/timer.h b/src/metawear/core/timer.h index 10f57909..175426a2 100644 --- a/src/metawear/core/timer.h +++ b/src/metawear/core/timer.h @@ -1,3 +1,8 @@ +/** + * @copyright MbientLab License + * @file timer.h + * @brief On board timer for scheduling MetaWear commands + */ #pragma once #include @@ -10,13 +15,42 @@ extern "C" { #endif +/** + * Creates a timer that will run for a set number of repetitions. A pointer representing the timer will be passed to the user + * through a callback function + * @param board Board the timer belongs to + * @param period How often to + * @param repetitions Number of events the timer will fire + * @param delay Zero if the tiemr should immediately fire, non-zero to delay the first event + * @param received_timer Callback function to be executed when the timer is created + */ METAWEAR_API void mbl_mw_timer_create(MblMwMetaWearBoard *board, uint32_t period, uint16_t repetitions, uint8_t delay, MblMwTimerPtr received_timer); +/** + * Creates a timer that will run indefinitely. A pointer representing the timer will be passed to the user + * through a callback function + * @param board Board the timer belongs to + * @param period How often to + * @param delay Zero if the tiemr should immediately fire, non-zero to delay the first event + * @param received_timer Callback function to be executed when the timer is created + */ METAWEAR_API void mbl_mw_timer_create_indefinite(MblMwMetaWearBoard *board, uint32_t period, uint8_t delay, MblMwTimerPtr received_timer); +/** + * Starts a timer + * @param timer Timer to start + */ METAWEAR_API void mbl_mw_timer_start(const MblMwTimer* timer); +/** + * Stops a timer + * @param timer Timer to stop + */ METAWEAR_API void mbl_mw_timer_stop(const MblMwTimer* timer); +/** + * Removes the timer from the board + * @param timer Timer to remove + */ METAWEAR_API void mbl_mw_timer_remove(MblMwTimer* timer); #ifdef __cplusplus diff --git a/src/metawear/core/timer_fwd.h b/src/metawear/core/timer_fwd.h index c91dbf73..e51679c0 100644 --- a/src/metawear/core/timer_fwd.h +++ b/src/metawear/core/timer_fwd.h @@ -1,9 +1,22 @@ +/** + * @copyright MbientLab License + * @file timer_fwd.h + * @brief Forward declaration of the MblMwTimer type + */ #pragma once #ifdef __cplusplus struct MblMwTimer; #else +/** + * On board timer that periodically fires events. An MblMwTimer pointer can be casted as an MblMwEvent pointer + * and used with any function that accepts an MblMwEvent pointer. + */ typedef struct MblMwTimer MblMwTimer; #endif -typedef void (*MblMwTimerPtr)(MblMwTimer* new_timer); +/** + * Definition for callback functions that accept an MblMwTimer pointer + * @param timer Timer to be used with the function + */ +typedef void (*MblMwTimerPtr)(MblMwTimer* timer); diff --git a/src/metawear/impl/cpp/metawearboard.cpp b/src/metawear/impl/cpp/metawearboard.cpp index d9d381be..3a0ce30b 100644 --- a/src/metawear/impl/cpp/metawearboard.cpp +++ b/src/metawear/impl/cpp/metawearboard.cpp @@ -1,12 +1,15 @@ #include +#include #include +#include #include +#include #include +#include #include "metawear/core/metawearboard.h" #include "metawear/core/status.h" -#include "metawear/core/cpp/connection_def.h" #include "metawear/core/cpp/datasignal_private.h" #include "metawear/core/cpp/event_register.h" #include "metawear/core/cpp/metawearboard_def.h" @@ -30,11 +33,81 @@ using std::exception; using std::forward_as_tuple; using std::free; +using std::memcpy; using std::piecewise_construct; +using std::string; using std::unordered_map; using std::vector; -static const vector> MODULE_DISCOVERY_CMDS= { +int32_t response_handler_data_no_id(MblMwMetaWearBoard *board, const uint8_t *response, uint8_t len) { + try { + ResponseHeader header(response[0], response[1]); + MblMwData* data = data_response_converters.at(board->sensor_data_signals.at(header)->interpreter)(board, response + 2, len - 2); + + board->data_signal_handlers.at(header)(data); + + free(data->value); + free(data); + + return MBL_MW_STATUS_OK; + } catch (exception) { + return MBL_MW_STATUS_WARNING_UNEXPECTED_SENSOR_DATA; + } +} + +int32_t response_handler_data_with_id(MblMwMetaWearBoard *board, const uint8_t *response, uint8_t len) { + try { + ResponseHeader header(response[0], response[1], response[2]); + MblMwData* data = data_response_converters.at(board->sensor_data_signals.at(header)->interpreter)(board, response + 3, len - 3); + + board->data_signal_handlers.at(header)(data); + + free(data->value); + free(data); + + return MBL_MW_STATUS_OK; + } catch (exception) { + return MBL_MW_STATUS_WARNING_UNEXPECTED_SENSOR_DATA; + } +} + +static int32_t timer_created(MblMwMetaWearBoard *board, const uint8_t *response, uint8_t len) { + auto signal = board->pending_timers.front(); + signal->header.data_id = response[2]; + board->timer_signals.emplace(signal->header, signal); + board->pending_timers.pop(); + + board->timer_callbacks.front()(signal); + board->timer_callbacks.pop(); + + return MBL_MW_STATUS_OK; +} + +static int32_t event_command_recorded(MblMwMetaWearBoard *board, const uint8_t *response, uint8_t len) { + board->event_owner->event_command_ids.push_back(response[2]); + + if ((uint8_t)board->event_owner->event_command_ids.size() == board->event_owner->num_expected_cmds) { + board->event_owner = nullptr; + board->event_recorded_callback(); + } + + return MBL_MW_STATUS_OK; +} + +static int32_t dataprocessor_created(MblMwMetaWearBoard *board, const uint8_t *response, uint8_t len) { + auto next_processor = board->pending_dataprocessors.front(); + board->pending_dataprocessors.pop(); + next_processor->header.data_id = response[2]; + board->sensor_data_signals.emplace(next_processor->header, next_processor); + + auto next_callback = board->dataprocessor_callbacks.front(); + board->dataprocessor_callbacks.pop(); + next_callback(next_processor); + + return MBL_MW_STATUS_OK; +} + +const vector> MODULE_DISCOVERY_CMDS= { {MBL_MW_MODULE_SWITCH, READ_INFO_REGISTER}, {MBL_MW_MODULE_LED, READ_INFO_REGISTER}, {MBL_MW_MODULE_ACCELEROMETER, READ_INFO_REGISTER}, @@ -57,58 +130,128 @@ static const vector> MODULE_DISCOVERY_CMDS= { {MBL_MW_MODULE_DEBUG, READ_INFO_REGISTER} }; +const uint64_t DEVICE_INFO_SERVICE_UUID_HIGH = 0x0000180a00001000; +const uint64_t DEVICE_INFO_SERVICE_UUID_LOW = 0x800000805f9b34fb; + +const MblMwGattChar METAWEAR_COMMAND_CHAR = { METAWEAR_SERVICE_NOTIFY_CHAR.service_uuid_high, METAWEAR_SERVICE_NOTIFY_CHAR.service_uuid_low, + 0x326a900185cb9195, 0xd9dd464cfbbae75a }; +const MblMwGattChar DEV_INFO_FIRMWARE_CHAR = { DEVICE_INFO_SERVICE_UUID_HIGH, DEVICE_INFO_SERVICE_UUID_LOW, 0x00002a2600001000, 0x800000805f9b34fb }, + DEV_INFO_MODEL_CHAR = { DEVICE_INFO_SERVICE_UUID_HIGH, DEVICE_INFO_SERVICE_UUID_LOW, 0x00002a2400001000, 0x800000805f9b34fb }; + +const vector BOARD_DEV_INFO_CHARS = { + DEV_INFO_FIRMWARE_CHAR, + DEV_INFO_MODEL_CHAR +}; + MblMwMetaWearBoard::MblMwMetaWearBoard() : data_token(nullptr) { - sensor_data_signals[SWITCH_RESPONSE_HEADER]= new MblMwDataSignal(SWITCH_RESPONSE_HEADER, this, ResponseConvertor::UINT32, + sensor_data_signals[SWITCH_RESPONSE_HEADER]= new MblMwDataSignal(SWITCH_RESPONSE_HEADER, this, DataInterpreter::UINT32, 1, 1, 0, 0); + + responses[SWITCH_RESPONSE_HEADER]= response_handler_data_no_id; + responses.emplace(piecewise_construct, forward_as_tuple(MBL_MW_MODULE_GPIO, READ_REGISTER(ORDINAL(GpioRegister::READ_AI_ABS_REF))), + forward_as_tuple(response_handler_data_with_id)); + responses.emplace(piecewise_construct, forward_as_tuple(MBL_MW_MODULE_GPIO, READ_REGISTER(ORDINAL(GpioRegister::READ_AI_ADC))), + forward_as_tuple(response_handler_data_with_id)); + responses.emplace(piecewise_construct, forward_as_tuple(MBL_MW_MODULE_GPIO, READ_REGISTER(ORDINAL(GpioRegister::READ_DI))), + forward_as_tuple(response_handler_data_with_id)); + responses.emplace(piecewise_construct, forward_as_tuple(MBL_MW_MODULE_GPIO, ORDINAL(GpioRegister::PIN_CHANGE_NOTIFY)), + forward_as_tuple(response_handler_data_with_id)); + responses.emplace(piecewise_construct, forward_as_tuple(MBL_MW_MODULE_DATA_PROCESSOR, ORDINAL(DataProcessorRegister::NOTIFY)), + forward_as_tuple(response_handler_data_with_id)); + + responses.emplace(piecewise_construct, forward_as_tuple(MBL_MW_MODULE_TIMER, ORDINAL(TimerRegister::TIMER_ENTRY)), + forward_as_tuple(timer_created)); + + responses.emplace(piecewise_construct, forward_as_tuple(MBL_MW_MODULE_EVENT, ORDINAL(EventRegister::ENTRY)), + forward_as_tuple(event_command_recorded)); + + responses.emplace(piecewise_construct, forward_as_tuple(MBL_MW_MODULE_DATA_PROCESSOR, ORDINAL(DataProcessorRegister::ADD)), + forward_as_tuple(dataprocessor_created)); + responses.emplace(piecewise_construct, forward_as_tuple(MBL_MW_MODULE_DATA_PROCESSOR, READ_REGISTER(ORDINAL(DataProcessorRegister::STATE))), + forward_as_tuple(response_handler_data_with_id)); } MblMwMetaWearBoard::~MblMwMetaWearBoard() { - for (auto it= sensor_data_signals.begin(); it != sensor_data_signals.end(); it++) { - delete (it->second); - } - - for (auto it= timer_signals.begin(); it != timer_signals.end(); it++) { - delete (it->second); + for (auto it: sensor_data_signals) { + it.second->remove= false; + delete it.second; } - for (auto it = module_config.begin(); it != module_config.end(); it++) { - free(it->second); + for (auto it: timer_signals) { + it.second->remove= false; + delete it.second; } - for (auto it = data_processors.begin(); it != data_processors.end(); it++) { - delete (it->second); + for (auto it: module_config) { + free(it.second); } } -MblMwMetaWearBoard* mbl_mw_create_metawear_board(MblMwFnByteArray send_command) { - auto new_board= new MblMwMetaWearBoard; - new_board->send_command = send_command; +MblMwMetaWearBoard* mbl_mw_metawearboard_create(const MblMwBtleConnection *connection) { + auto new_board= new MblMwMetaWearBoard(); + memcpy(&new_board->btle_conn, connection, sizeof(MblMwBtleConnection)); return new_board; } -void mbl_mw_free_metawear_board(MblMwMetaWearBoard *board) { +void mbl_mw_metawearboard_free(MblMwMetaWearBoard *board) { delete board; } static inline void queue_next_query(MblMwMetaWearBoard *board) { board->module_discovery_index++; - send_command_wrapper(board, MODULE_DISCOVERY_CMDS[board->module_discovery_index].data(), + send_command(board, MODULE_DISCOVERY_CMDS[board->module_discovery_index].data(), (uint8_t) MODULE_DISCOVERY_CMDS[board->module_discovery_index].size()); } +static inline void queue_next_gatt_char(MblMwMetaWearBoard *board) { + board->dev_info_index++; + board->btle_conn.read_gatt_char(&BOARD_DEV_INFO_CHARS[board->dev_info_index]); +} + void mbl_mw_metawearboard_initialize(MblMwMetaWearBoard *board, MblMwFnVoid initialized) { board->initialized = initialized; board->module_discovery_index= -1; - queue_next_query(board); + board->dev_info_index = -1; + queue_next_gatt_char(board); } -int32_t mbl_mw_metawearboard_handle_response(MblMwMetaWearBoard *board, const uint8_t *response, uint8_t len) { - uint8_t resp_register_id= response[1] & 0x7f; +void mbl_mw_metawearboard_tear_down(MblMwMetaWearBoard *board) { + vector dp_keys; - if (resp_register_id == INFO_REGISTER) { - board->module_info.emplace(piecewise_construct, forward_as_tuple(response[0]), forward_as_tuple(response, len)); + for (auto it: board->sensor_data_signals) { + if (typeid(*(it.second)) == typeid(MblMwDataProcessor)) { + dp_keys.push_back(it.first); + it.second->remove= false; + delete it.second; + } + } + for (auto it: dp_keys) { + board->sensor_data_signals.erase(it); + } + + for (auto it: board->timer_signals) { + it.second->remove= false; + delete it.second; + } + board->timer_signals.clear(); - if (board->module_discovery_index == (uint8_t) (MODULE_DISCOVERY_CMDS.size() - 1)) { + uint8_t command[2]= { MBL_MW_MODULE_DATA_PROCESSOR, ORDINAL(DataProcessorRegister::REMOVE_ALL) }; + SEND_COMMAND; + + command[0]= MBL_MW_MODULE_EVENT; + command[1]= ORDINAL(EventRegister::REMOVE_ALL); + SEND_COMMAND; +} + +int32_t mbl_mw_connection_notify_char_changed(MblMwMetaWearBoard *board, const uint8_t *value, uint8_t length) { + ResponseHeader header(value[0], value[1]); + + if (board->responses.count(header) != 0) { + return board->responses.at(header)(board, value, length); + } else if (header.register_id == READ_INFO_REGISTER) { + board->module_info.emplace(piecewise_construct, forward_as_tuple(value[0]), forward_as_tuple(value, length)); + + if (board->module_discovery_index == (uint8_t)(MODULE_DISCOVERY_CMDS.size() - 1)) { init_accelerometer_module(board); init_barometer_module(board); init_gyro_module(board); @@ -119,85 +262,90 @@ int32_t mbl_mw_metawearboard_handle_response(MblMwMetaWearBoard *board, const ui } else { queue_next_query(board); } - } else if ((response[0] == MBL_MW_MODULE_SWITCH && resp_register_id == ORDINAL(SwitchRegister::STATE)) || - (response[0] == MBL_MW_MODULE_ACCELEROMETER && resp_register_id == ORDINAL(AccelerometerBmi160Register::DATA_INTERRUPT)) || - (response[0] == MBL_MW_MODULE_ACCELEROMETER && resp_register_id == ORDINAL(AccelerometerMma8452qRegister::DATA_VALUE)) || - (response[0] == MBL_MW_MODULE_AMBIENT_LIGHT && resp_register_id == ORDINAL(AmbientLightLtr329Register::OUTPUT)) || - (response[0] == MBL_MW_MODULE_BAROMETER && resp_register_id == ORDINAL(BarometerBmp280Register::PRESSURE)) || - (response[0] == MBL_MW_MODULE_BAROMETER && resp_register_id == ORDINAL(BarometerBmp280Register::ALTITUDE)) || - (response[0] == MBL_MW_MODULE_GYRO && resp_register_id == ORDINAL(GyroBmi160Register::DATA))) { - - try { - ResponseHeader header(response[0], resp_register_id); - MblMwData* data= board->response_processors.at(header)(board, response + 2, len - 2); - - board->data_signal_handlers.at(header)(data); - - free(data->value); - free(data); - } catch (exception) { - return MBL_MW_STATUS_WARNING_UNEXPECTED_SENSOR_DATA; - } - } else if ((response[0] == MBL_MW_MODULE_TEMPERATURE && resp_register_id == ORDINAL(MultiChannelTempRegister::TEMPERATURE)) || - (response[0] == MBL_MW_MODULE_GPIO && resp_register_id == ORDINAL(GpioRegister::READ_AI_ABS_REF)) || - (response[0] == MBL_MW_MODULE_GPIO && resp_register_id == ORDINAL(GpioRegister::READ_AI_ADC)) || - (response[0] == MBL_MW_MODULE_GPIO && resp_register_id == ORDINAL(GpioRegister::READ_DI)) || - (response[0] == MBL_MW_MODULE_GPIO && resp_register_id == ORDINAL(GpioRegister::PIN_CHANGE_NOTIFY)) || - (response[0] == MBL_MW_MODULE_DATA_PROCESSOR && resp_register_id == ORDINAL(DataProcessorRegister::NOTIFY))) { - try { - ResponseHeader header(response[0], resp_register_id, response[2]); - MblMwData* data= board->response_processors.at(header)(board, response + 3, len - 3); - - board->data_signal_handlers.at(header)(data); - - free(data->value); - free(data); - } catch (exception) { - return MBL_MW_STATUS_WARNING_UNEXPECTED_SENSOR_DATA; - } - } else if ((response[0] == MBL_MW_MODULE_TIMER && resp_register_id == ORDINAL(TimerRegister::TIMER_ENTRY))) { - auto signal= board->pending_timers.front(); - signal->header.data_id= response[2]; - board->timer_signals.emplace(signal->header, signal); - board->pending_timers.pop(); - - board->timer_callbacks.front()(signal); - board->timer_callbacks.pop(); - } else if (response[0] == MBL_MW_MODULE_EVENT && response[1] == ORDINAL(EventRegister::ENTRY)) { - auto top_event_owner= board->event_owner.front(); - top_event_owner->event_command_ids.push_back(response[2]); - if ((uint8_t) top_event_owner->event_command_ids.size() == top_event_owner->num_expected_cmds) { - board->event_owner.pop(); - - auto top_event_callback = board->event_recorded_callbacks.front(); - board->event_recorded_callbacks.pop(); - top_event_callback(); - - if (!board->event_owner.empty()) { - for(auto it: board->event_owner.front()->commands) { - send_command_wrapper(board, it.data(), (uint8_t) it.size()); + + return MBL_MW_STATUS_OK; + } else { + return MBL_MW_STATUS_WARNING_INVALID_RESPONSE; + } +} + +void mbl_mw_connection_char_read(MblMwMetaWearBoard *board, const MblMwGattChar *characteristic, const uint8_t *value, uint8_t length) { + bool valid = false; + + if (characteristic->uuid_high == DEV_INFO_FIRMWARE_CHAR.uuid_high && characteristic->uuid_low == DEV_INFO_FIRMWARE_CHAR.uuid_low) { + if (board->firmware_revision.empty()) { + board->firmware_revision.assign(string(value, value + length)); + } else { + Version current; + current.assign(string(value, value + length)); + + if (board->firmware_revision == current) { + board->initialized(); + return; + } else { + for (auto it: board->sensor_data_signals) { + it.second->remove= false; + delete it.second; } + for (auto it: board->timer_signals) { + it.second->remove= false; + delete it.second; + } + for (auto it: board->module_config) { + free(it.second); + } + + board->sensor_data_signals.clear(); + board->timer_signals.clear(); + board->module_config.clear(); + board->module_info.clear(); } } - } else if (response[0] == MBL_MW_MODULE_DATA_PROCESSOR && response[1] == ORDINAL(DataProcessorRegister::ADD)) { - auto next_processor = board->pending_dataprocessors.front(); - board->pending_dataprocessors.pop(); - next_processor->header.data_id = response[2]; - board->data_processors.emplace(next_processor->header, next_processor); - - auto next_callback = board->dataprocessor_callbacks.front(); - board->dataprocessor_callbacks.pop(); - next_callback(next_processor); + valid = true; + } else if (characteristic->uuid_high == DEV_INFO_MODEL_CHAR.uuid_high && characteristic->uuid_low == DEV_INFO_MODEL_CHAR.uuid_low) { + board->module_number.assign(value, value + length); + valid = true; } - return MBL_MW_STATUS_OK; + if (valid) { + if (board->dev_info_index == (uint8_t)(BOARD_DEV_INFO_CHARS.size() - 1)) { + queue_next_query(board); + } else { + queue_next_gatt_char(board); + } + } +} + +void send_command(const MblMwMetaWearBoard* board, const uint8_t* command, uint8_t len) { + if (!board->event_config.empty()) { + board->event_owner->num_expected_cmds++; + vector event_entry = { MBL_MW_MODULE_EVENT, ORDINAL(EventRegister::ENTRY), + board->event_config.at(0), board->event_config.at(1), board->event_config.at(2), command[0], command[1], + (uint8_t)(len - 2) }; + + if (board->data_token != nullptr) { + uint8_t event_data[2] = { + (uint8_t)(0x01 | (board->data_token->data_length << 1) | (board->data_token->data_offset << 4)), + board->data_token->dest_offset + }; + event_entry.insert(event_entry.end(), event_data, event_data + sizeof(event_data)); + } + board->event_owner->commands.emplace_back(event_entry); + + vector event_parameters(command + 2, command + len); + uint8_t prefix[2] = { MBL_MW_MODULE_EVENT, ORDINAL(EventRegister::CMD_PARAMETERS) }; + event_parameters.insert(event_parameters.begin(), prefix, prefix + sizeof(prefix)); + board->event_owner->commands.emplace_back(event_parameters); + } else { + board->btle_conn.write_gatt_char(&METAWEAR_COMMAND_CHAR, command, len); + } } int32_t mbl_mw_metawearboard_is_initialized(const MblMwMetaWearBoard *board) { return board->module_discovery_index == (uint8_t)(MODULE_DISCOVERY_CMDS.size() - 1); } -int32_t mbl_mw_metawearboard_get_module_type(const MblMwMetaWearBoard *board, uint8_t module) { +int32_t mbl_mw_metawearboard_lookup_module(const MblMwMetaWearBoard *board, uint8_t module) { try { if (board->module_info.at(module).present) { return board->module_info.at(module).implementation; diff --git a/src/metawear/peripheral/cpp/haptic.cpp b/src/metawear/peripheral/cpp/haptic.cpp index 0d944ca1..e92a64b4 100644 --- a/src/metawear/peripheral/cpp/haptic.cpp +++ b/src/metawear/peripheral/cpp/haptic.cpp @@ -1,4 +1,4 @@ -#include "metawear/core/cpp/connection_def.h" +#include "metawear/core/cpp/metawearboard_def.h" #include "metawear/peripheral/haptic.h" #include diff --git a/src/metawear/peripheral/cpp/ibeacon.cpp b/src/metawear/peripheral/cpp/ibeacon.cpp index 6b588f8c..605e605b 100644 --- a/src/metawear/peripheral/cpp/ibeacon.cpp +++ b/src/metawear/peripheral/cpp/ibeacon.cpp @@ -1,4 +1,4 @@ -#include "metawear/core/cpp/connection_def.h" +#include "metawear/core/cpp/metawearboard_def.h" #include "metawear/peripheral/ibeacon.h" #include diff --git a/src/metawear/peripheral/cpp/led.cpp b/src/metawear/peripheral/cpp/led.cpp index 51eee6cc..1511a78c 100644 --- a/src/metawear/peripheral/cpp/led.cpp +++ b/src/metawear/peripheral/cpp/led.cpp @@ -1,4 +1,4 @@ -#include "metawear/core/cpp/connection_def.h" +#include "metawear/core/cpp/metawearboard_def.h" #include "metawear/peripheral/led.h" #include @@ -39,7 +39,7 @@ void mbl_mw_led_load_preset_pattern(MblMwLedPattern* pattern, MblMwLedPreset pre void mbl_mw_led_write_pattern(const MblMwMetaWearBoard *board, const MblMwLedPattern *pattern, MblMwLedColor color) { uint8_t command[17]= { - LED_MODULE, LED_CONFIG, color, 2, + LED_MODULE, LED_CONFIG, static_cast(color), 2, pattern->high_intensity, pattern->low_intensity }; diff --git a/src/metawear/peripheral/cpp/neopixel.cpp b/src/metawear/peripheral/cpp/neopixel.cpp index f0b23a63..1363a0db 100644 --- a/src/metawear/peripheral/cpp/neopixel.cpp +++ b/src/metawear/peripheral/cpp/neopixel.cpp @@ -1,4 +1,4 @@ -#include "metawear/core/cpp/connection_def.h" +#include "metawear/core/cpp/metawearboard_def.h" #include "metawear/peripheral/neopixel.h" #include @@ -52,7 +52,7 @@ void mbl_mw_neopixel_set_color(const MblMwMetaWearBoard *board, uint8_t strand, void mbl_mw_neopixel_rotate(const MblMwMetaWearBoard *board, uint8_t strand, uint8_t count, uint16_t period_ms, MblMwNeoPixelRotDirection direction) { uint8_t command[7]= {NEOPIXEL_MODULE, NEOPIXEL_ROTATE, strand, - (direction != MBL_MW_NP_ROT_DIR_TOWARDS) ? MBL_MW_NP_ROT_DIR_AWAY : MBL_MW_NP_ROT_DIR_TOWARDS, + static_cast((direction != MBL_MW_NP_ROT_DIR_TOWARDS) ? MBL_MW_NP_ROT_DIR_AWAY : MBL_MW_NP_ROT_DIR_TOWARDS), count}; memcpy(command + 5, &period_ms, 2); diff --git a/src/metawear/sensor/accelerometer.h b/src/metawear/sensor/accelerometer.h index cf60592d..68cd6305 100644 --- a/src/metawear/sensor/accelerometer.h +++ b/src/metawear/sensor/accelerometer.h @@ -1,3 +1,8 @@ +/** + * @copyright MbientLab License + * @file accelerometer.h + * @brief Generic class providing high level access to an accelerometer + */ #pragma once #include @@ -10,16 +15,51 @@ extern "C" { #endif -METAWEAR_API const MblMwDataSignal* mbl_mw_acc_get_acceleration_data_signal(const MblMwMetaWearBoard *board); +/** + * Retrieves the data signal representing acceleration data + * @param board Board to retrieve the signal from + * @return Pointer to the acceleration data signal + */ +METAWEAR_API MblMwDataSignal* mbl_mw_acc_get_acceleration_data_signal(const MblMwMetaWearBoard *board); +/** + * Sets the output data rate. If an invalid odr is used, the closest valid value will be used. + * @param board Board to configure + * @param odr Output data rate, in Hz + */ METAWEAR_API void mbl_mw_acc_set_odr(MblMwMetaWearBoard *board, float odr); +/** + * Sets the full scale range. IF an invalid range is used, the closet valid value will be used. + * @param board Board to configure + * @param range Sampling range, in g's + */ METAWEAR_API void mbl_mw_acc_set_range(MblMwMetaWearBoard *board, float range); +/** + * Writes the acceleration settings to the board + * @param board Board to configure + */ METAWEAR_API void mbl_mw_acc_write_acceleration_config(const MblMwMetaWearBoard* board); +/** + * Switches the accelerometer to active mode + * @param board Board the accelerometer is on + */ METAWEAR_API void mbl_mw_acc_start(const MblMwMetaWearBoard *board); +/** + * Switches the accelerometer to standby mode + * @param board Board the accelerometer is on + */ METAWEAR_API void mbl_mw_acc_stop(const MblMwMetaWearBoard *board); +/** + * Enables acceleration sampling + * @param board Board to enable acceleration sampling on + */ METAWEAR_API void mbl_mw_acc_enable_acceleration_sampling(const MblMwMetaWearBoard *board); +/** + * Disables acceleration sampling + * @param board Board to disable acceleration sampling on + */ METAWEAR_API void mbl_mw_acc_disable_acceleration_sampling(const MblMwMetaWearBoard *board); #ifdef __cplusplus diff --git a/src/metawear/sensor/accelerometer_bmi160.h b/src/metawear/sensor/accelerometer_bmi160.h index cd9d1645..c851d33f 100644 --- a/src/metawear/sensor/accelerometer_bmi160.h +++ b/src/metawear/sensor/accelerometer_bmi160.h @@ -16,7 +16,7 @@ extern "C" { #endif -const uint8_t MBL_MW_MODULE_ACC_TYPE_BMI160 = 1; +const uint8_t MBL_MW_MODULE_ACC_TYPE_BMI160 = 1; ///< Constant identifying the BMI160 accelerometer module type /** * Available g-ranges on the BMI160 accelerometer @@ -51,7 +51,7 @@ typedef enum { * @param board Pointer to the board to retrieve the signal from * @return Pointer to the board's BMI160 acceleration data signal */ -METAWEAR_API const MblMwDataSignal* mbl_mw_acc_bmi160_get_acceleration_data_signal(const MblMwMetaWearBoard *board); +METAWEAR_API MblMwDataSignal* mbl_mw_acc_bmi160_get_acceleration_data_signal(const MblMwMetaWearBoard *board); /** * Sets the output data rate diff --git a/src/metawear/sensor/accelerometer_mma8452q.h b/src/metawear/sensor/accelerometer_mma8452q.h index 91c6d59b..645bcf5e 100644 --- a/src/metawear/sensor/accelerometer_mma8452q.h +++ b/src/metawear/sensor/accelerometer_mma8452q.h @@ -16,7 +16,7 @@ extern "C" { #endif -const uint8_t MBL_MW_MODULE_ACC_TYPE_MMA8452Q = 0; +const uint8_t MBL_MW_MODULE_ACC_TYPE_MMA8452Q = 0; ///< Constant identifying the MMA8452Q accelerometer type /* typedef enum { @@ -59,7 +59,7 @@ typedef enum { * @param board Pointer to the board to retrieve the signal from * @return Pointer to the board's MMA8452Q acceleration data signal */ -METAWEAR_API const MblMwDataSignal* mbl_mw_acc_mma8452q_get_acceleration_data_signal(const MblMwMetaWearBoard *board); +METAWEAR_API MblMwDataSignal* mbl_mw_acc_mma8452q_get_acceleration_data_signal(const MblMwMetaWearBoard *board); /** * Sets the output data rate diff --git a/src/metawear/sensor/ambientlight_ltr329.h b/src/metawear/sensor/ambientlight_ltr329.h index 34d43837..28953bb0 100644 --- a/src/metawear/sensor/ambientlight_ltr329.h +++ b/src/metawear/sensor/ambientlight_ltr329.h @@ -59,7 +59,7 @@ typedef enum { * @param board Pointer to the board to retrieve the signal from * @return Pointer to the board's LTR329 illuminance data signal */ -METAWEAR_API const MblMwDataSignal* mbl_mw_als_ltr329_get_illuminance_data_signal(const MblMwMetaWearBoard *board); +METAWEAR_API MblMwDataSignal* mbl_mw_als_ltr329_get_illuminance_data_signal(const MblMwMetaWearBoard *board); /** * Sets the sensor gain diff --git a/src/metawear/sensor/barometer_bmp280.h b/src/metawear/sensor/barometer_bmp280.h index 8269d229..338fa8f6 100644 --- a/src/metawear/sensor/barometer_bmp280.h +++ b/src/metawear/sensor/barometer_bmp280.h @@ -58,13 +58,13 @@ typedef enum { * @param board Pointer to the board to retrieve the signal from * @return Pointer to the board's BMP280 pressure data signal */ -METAWEAR_API const MblMwDataSignal* mbl_mw_baro_bmp280_get_pressure_data_signal(const MblMwMetaWearBoard *board); +METAWEAR_API MblMwDataSignal* mbl_mw_baro_bmp280_get_pressure_data_signal(const MblMwMetaWearBoard *board); /** * Retrieves the data signal representing BMP280 altitude data * @param board Pointer to the board to retrieve the signal from * @return Pointer to the board's BMP280 altitude data signal */ -METAWEAR_API const MblMwDataSignal* mbl_mw_baro_bmp280_get_altitude_data_signal(const MblMwMetaWearBoard *board); +METAWEAR_API MblMwDataSignal* mbl_mw_baro_bmp280_get_altitude_data_signal(const MblMwMetaWearBoard *board); /** * Set the oversampling mode diff --git a/src/metawear/sensor/cpp/accelerometer.cpp b/src/metawear/sensor/cpp/accelerometer.cpp index 48e1592f..eaff457f 100644 --- a/src/metawear/sensor/cpp/accelerometer.cpp +++ b/src/metawear/sensor/cpp/accelerometer.cpp @@ -43,7 +43,7 @@ void init_accelerometer_module(MblMwMetaWearBoard *board) { } } -const MblMwDataSignal* mbl_mw_acc_get_acceleration_data_signal(const MblMwMetaWearBoard *board) { +MblMwDataSignal* mbl_mw_acc_get_acceleration_data_signal(const MblMwMetaWearBoard *board) { switch(board->module_info.at(MBL_MW_MODULE_ACCELEROMETER).implementation) { case MBL_MW_MODULE_ACC_TYPE_MMA8452Q: return mbl_mw_acc_mma8452q_get_acceleration_data_signal(board); diff --git a/src/metawear/sensor/cpp/accelerometer_bmi160.cpp b/src/metawear/sensor/cpp/accelerometer_bmi160.cpp index aecbdc1b..68d77d1e 100644 --- a/src/metawear/sensor/cpp/accelerometer_bmi160.cpp +++ b/src/metawear/sensor/cpp/accelerometer_bmi160.cpp @@ -2,7 +2,6 @@ #include "accelerometer_bmi160_register.h" #include "metawear/core/types.h" -#include "metawear/core/cpp/connection_def.h" #include "metawear/core/cpp/constant.h" #include "metawear/core/cpp/datasignal_private.h" #include "metawear/core/cpp/metawearboard_def.h" @@ -40,10 +39,11 @@ static void* create_acc_bmi160_config() { void init_accelerometer_bmi160(MblMwMetaWearBoard *board) { MblMwDataSignal *acc_signal= new MblMwDataSignal(BMI160_ACCEL_RESPONSE_HEADER, board, - ResponseConvertor::BMI160_ACCELERATION, 3, 2, 1, 0); + DataInterpreter::BMI160_ACCELERATION, 3, 2, 1, 0); acc_signal->number_to_firmware = bmi160_to_firmware; board->sensor_data_signals[BMI160_ACCEL_RESPONSE_HEADER]= acc_signal; board->module_config[MBL_MW_MODULE_ACCELEROMETER]= create_acc_bmi160_config(); + board->responses[BMI160_ACCEL_RESPONSE_HEADER]= response_handler_data_no_id; } void AccBmi160Config::set_output_data_rate(MblMwAccBmi160Odr odr) { @@ -58,36 +58,7 @@ float AccBmi160Config::get_scale() const { return FSR_SCALE.at(acc_range); } -MblMwData* convert_to_bmi160_acceleration(const MblMwMetaWearBoard *board, const uint8_t *response, uint8_t len) { - CartesianShort unscaled; - memcpy(&unscaled, response, sizeof(unscaled)); - - float scale= ((AccBmi160Config*) board->module_config.at(MBL_MW_MODULE_ACCELEROMETER))->get_scale(); - - CartesianFloat *value = (CartesianFloat*)malloc(sizeof(CartesianFloat)); - value->x = unscaled.x / scale; - value->y = unscaled.y / scale; - value->z = unscaled.z / scale; - - CREATE_MESSAGE(MBL_MW_DT_ID_CARTESIAN_FLOAT); -} - -MblMwData* convert_to_bmi160_acceleration_single_axis(const MblMwMetaWearBoard *board, const uint8_t *response, uint8_t len) { - int32_t unscaled; - if ((response[len - 1] & 0x80) == 0x80) { - unscaled= -1; - } else { - unscaled= 0; - } - memcpy(&unscaled, response, min(len, (uint8_t) sizeof(unscaled))); - - float *value = (float*)malloc(sizeof(float)); - *value = unscaled / ((AccBmi160Config*) board->module_config.at(MBL_MW_MODULE_ACCELEROMETER))->get_scale(); - - CREATE_MESSAGE(MBL_MW_DT_ID_FLOAT); -} - -const MblMwDataSignal* mbl_mw_acc_bmi160_get_acceleration_data_signal(const MblMwMetaWearBoard *board) { +MblMwDataSignal* mbl_mw_acc_bmi160_get_acceleration_data_signal(const MblMwMetaWearBoard *board) { if (board->module_info.at(MBL_MW_MODULE_ACCELEROMETER).implementation != MBL_MW_MODULE_ACC_TYPE_BMI160) { return NULL; } diff --git a/src/metawear/sensor/cpp/accelerometer_mma8452q.cpp b/src/metawear/sensor/cpp/accelerometer_mma8452q.cpp index 35aa0591..3382329e 100644 --- a/src/metawear/sensor/cpp/accelerometer_mma8452q.cpp +++ b/src/metawear/sensor/cpp/accelerometer_mma8452q.cpp @@ -1,7 +1,6 @@ #include "accelerometer_mma8452q_private.h" #include "accelerometer_mma8452q_register.h" -#include "metawear/core/cpp/connection_def.h" #include "metawear/core/cpp/constant.h" #include "metawear/core/cpp/datasignal_private.h" #include "metawear/core/cpp/metawearboard_def.h" @@ -65,13 +64,14 @@ struct Mma8452qAccBitField { void init_accelerometer_mma8452q(MblMwMetaWearBoard *board) { MblMwDataSignal *acc_signal= new MblMwDataSignal(MMA8452Q_ACCEL_RESPONSE_HEADER, board, - ResponseConvertor::MMA8452Q_ACCELERATION, 3, 2, 1, 0); + DataInterpreter::MMA8452Q_ACCELERATION, 3, 2, 1, 0); acc_signal->number_to_firmware = mma8452q_to_firmware; board->sensor_data_signals[MMA8452Q_ACCEL_RESPONSE_HEADER]= acc_signal; board->module_config[MBL_MW_MODULE_ACCELEROMETER]= create_mma8452q_config(); + board->responses[MMA8452Q_ACCEL_RESPONSE_HEADER]= response_handler_data_no_id; } -const MblMwDataSignal* mbl_mw_acc_mma8452q_get_acceleration_data_signal(const MblMwMetaWearBoard *board) { +MblMwDataSignal* mbl_mw_acc_mma8452q_get_acceleration_data_signal(const MblMwMetaWearBoard *board) { if (board->module_info.at(MBL_MW_MODULE_ACCELEROMETER).implementation != MBL_MW_MODULE_ACC_TYPE_MMA8452Q) { return NULL; } diff --git a/src/metawear/sensor/cpp/ambientlight_ltr329.cpp b/src/metawear/sensor/cpp/ambientlight_ltr329.cpp index 5b6d630f..945e6347 100644 --- a/src/metawear/sensor/cpp/ambientlight_ltr329.cpp +++ b/src/metawear/sensor/cpp/ambientlight_ltr329.cpp @@ -1,6 +1,5 @@ #include "metawear/core/cpp/datasignal_private.h" #include "metawear/core/cpp/metawearboard_def.h" -#include "metawear/core/cpp/connection_def.h" #include "metawear/sensor/ambientlight_ltr329.h" #include "ambientlight_ltr329_register.h" @@ -8,9 +7,11 @@ #include #include +using std::forward_as_tuple; using std::malloc; using std::memcpy; using std::memset; +using std::piecewise_construct; struct Ltr329Config { uint8_t:2; @@ -29,10 +30,11 @@ void init_ambient_light_module(MblMwMetaWearBoard *board) { board->module_config.emplace(MBL_MW_MODULE_AMBIENT_LIGHT, new_config); board->sensor_data_signals[LTR329_ILLUMINANCE_RESPONSE_HEADER]= new MblMwDataSignal(LTR329_ILLUMINANCE_RESPONSE_HEADER, - board, ResponseConvertor::UINT32, 1, 4, 0, 0); + board, DataInterpreter::UINT32, 1, 4, 0, 0); + board->responses[LTR329_ILLUMINANCE_RESPONSE_HEADER]= response_handler_data_no_id; } -const MblMwDataSignal* mbl_mw_als_ltr329_get_illuminance_data_signal(const MblMwMetaWearBoard *board) { +MblMwDataSignal* mbl_mw_als_ltr329_get_illuminance_data_signal(const MblMwMetaWearBoard *board) { return board->sensor_data_signals.at(LTR329_ILLUMINANCE_RESPONSE_HEADER); } diff --git a/src/metawear/sensor/cpp/barometer_bmp280.cpp b/src/metawear/sensor/cpp/barometer_bmp280.cpp index 52c2a955..e38e847f 100644 --- a/src/metawear/sensor/cpp/barometer_bmp280.cpp +++ b/src/metawear/sensor/cpp/barometer_bmp280.cpp @@ -1,6 +1,5 @@ #include "metawear/core/cpp/datasignal_private.h" #include "metawear/core/cpp/metawearboard_def.h" -#include "metawear/core/cpp/connection_def.h" #include "metawear/sensor/barometer_bmp280.h" #include "barometer_bmp280_register.h" @@ -35,21 +34,23 @@ void init_barometer_module(MblMwMetaWearBoard *board) { board->module_config.emplace(MBL_MW_MODULE_BAROMETER, new_config); MblMwDataSignal *baro_pa_signal= new MblMwDataSignal(BARO_PRESSURE_RESPONSE_HEADER, board, - ResponseConvertor::BMP280_PRESSURE, 1, 4, 0, 0); + DataInterpreter::BMP280_PRESSURE, 1, 4, 0, 0); baro_pa_signal->number_to_firmware = bmp280_to_firmware; board->sensor_data_signals[BARO_PRESSURE_RESPONSE_HEADER]= baro_pa_signal; + board->responses[BARO_PRESSURE_RESPONSE_HEADER]= response_handler_data_no_id; MblMwDataSignal *baro_m_signal= new MblMwDataSignal(BARO_ALTITUDE_RESPONSE_HEADER, board, - ResponseConvertor::BMP280_ALTITUDE, 1, 4, 1, 0); + DataInterpreter::BMP280_ALTITUDE, 1, 4, 1, 0); baro_m_signal->number_to_firmware = bmp280_to_firmware; board->sensor_data_signals[BARO_ALTITUDE_RESPONSE_HEADER]= baro_m_signal; + board->responses[BARO_ALTITUDE_RESPONSE_HEADER]= response_handler_data_no_id; } -const MblMwDataSignal* mbl_mw_baro_bmp280_get_pressure_data_signal(const MblMwMetaWearBoard *board) { +MblMwDataSignal* mbl_mw_baro_bmp280_get_pressure_data_signal(const MblMwMetaWearBoard *board) { return board->sensor_data_signals.at(BARO_PRESSURE_RESPONSE_HEADER); } -const MblMwDataSignal* mbl_mw_baro_bmp280_get_altitude_data_signal(const MblMwMetaWearBoard *board) { +MblMwDataSignal* mbl_mw_baro_bmp280_get_altitude_data_signal(const MblMwMetaWearBoard *board) { return board->sensor_data_signals.at(BARO_ALTITUDE_RESPONSE_HEADER); } diff --git a/src/metawear/sensor/cpp/gpio.cpp b/src/metawear/sensor/cpp/gpio.cpp index d711ede1..266f070e 100644 --- a/src/metawear/sensor/cpp/gpio.cpp +++ b/src/metawear/sensor/cpp/gpio.cpp @@ -1,7 +1,6 @@ #include "metawear/sensor/gpio.h" #include "gpio_register.h" -#include "metawear/core/cpp/connection_def.h" #include "metawear/core/cpp/datasignal_private.h" #include "metawear/core/cpp/metawearboard_def.h" @@ -14,7 +13,7 @@ static inline void insert_gpio_data_signal(MblMwMetaWearBoard* board, ResponseHe } if (board->sensor_data_signals.count(header) == 0) { - MblMwDataSignal *gpio_signal= new MblMwDataSignal(header, board, ResponseConvertor::UINT32, 1, data_len, 0, 0); + MblMwDataSignal *gpio_signal= new MblMwDataSignal(header, board, DataInterpreter::UINT32, 1, data_len, 0, 0); board->sensor_data_signals[header]= gpio_signal; } } @@ -57,11 +56,11 @@ void mbl_mw_gpio_read_analog_input(const MblMwMetaWearBoard* board, uint8_t pin, switch(mode) { case MBL_MW_GPIO_ANALOG_READ_MODE_ABS_REF: command[1]= READ_REGISTER(ORDINAL(GpioRegister::READ_AI_ABS_REF)); - send_command_wrapper(board, command, sizeof(command)); + send_command(board, command, sizeof(command)); break; case MBL_MW_GPIO_ANALOG_READ_MODE_ADC: command[1]= READ_REGISTER(ORDINAL(GpioRegister::READ_AI_ADC)); - send_command_wrapper(board, command, sizeof(command)); + send_command(board, command, sizeof(command)); break; } } @@ -72,45 +71,45 @@ void mbl_mw_gpio_set_pull_mode(const MblMwMetaWearBoard* board, uint8_t pin, Mbl switch(mode) { case MBL_MW_GPIO_PULL_MODE_UP: command[1]= ORDINAL(GpioRegister::PULL_UP_DI); - send_command_wrapper(board, command, sizeof(command)); + send_command(board, command, sizeof(command)); break; case MBL_MW_GPIO_PULL_MODE_DOWN: command[1]= ORDINAL(GpioRegister::PULL_DOWN_DI); - send_command_wrapper(board, command, sizeof(command)); + send_command(board, command, sizeof(command)); break; case MBL_MW_GPIO_PULL_MODE_NONE: command[1]= ORDINAL(GpioRegister::NO_PULL_DI); - send_command_wrapper(board, command, sizeof(command)); + send_command(board, command, sizeof(command)); break; } } void mbl_mw_gpio_read_digital_input(const MblMwMetaWearBoard* board, uint8_t pin) { uint8_t command[3]= {MBL_MW_MODULE_GPIO, READ_REGISTER(ORDINAL(GpioRegister::READ_DI)), pin}; - send_command_wrapper(board, command, sizeof(command)); + send_command(board, command, sizeof(command)); } void mbl_mw_gpio_set_digital_output(const MblMwMetaWearBoard* board, uint8_t pin) { uint8_t command[3]= {MBL_MW_MODULE_GPIO, ORDINAL(GpioRegister::SET_DO), pin}; - send_command_wrapper(board, command, sizeof(command)); + send_command(board, command, sizeof(command)); } void mbl_mw_gpio_clear_digital_output(const MblMwMetaWearBoard* board, uint8_t pin) { uint8_t command[3]= {MBL_MW_MODULE_GPIO, ORDINAL(GpioRegister::CLEAR_DO), pin}; - send_command_wrapper(board, command, sizeof(command)); + send_command(board, command, sizeof(command)); } void mbl_mw_gpio_set_pin_change_type(const MblMwMetaWearBoard* board, uint8_t pin, MblMwGpioPinChangeType type) { uint8_t command[4]= {MBL_MW_MODULE_GPIO, ORDINAL(GpioRegister::PIN_CHANGE), pin, (uint8_t) type}; - send_command_wrapper(board, command, sizeof(command)); + send_command(board, command, sizeof(command)); } void mbl_mw_gpio_start_pin_monitoring(const MblMwMetaWearBoard* board, uint8_t pin) { uint8_t command[4]= {MBL_MW_MODULE_GPIO, ORDINAL(GpioRegister::PIN_CHANGE_NOTIFY_ENABLE), pin, 1}; - send_command_wrapper(board, command, sizeof(command)); + send_command(board, command, sizeof(command)); } void mbl_mw_gpio_stop_pin_monitoring(const MblMwMetaWearBoard* board, uint8_t pin) { uint8_t command[4]= {MBL_MW_MODULE_GPIO, ORDINAL(GpioRegister::PIN_CHANGE_NOTIFY_ENABLE), pin, 0}; - send_command_wrapper(board, command, sizeof(command)); + send_command(board, command, sizeof(command)); } diff --git a/src/metawear/sensor/cpp/gyro_bmi160.cpp b/src/metawear/sensor/cpp/gyro_bmi160.cpp index e84799cb..c11a22c4 100644 --- a/src/metawear/sensor/cpp/gyro_bmi160.cpp +++ b/src/metawear/sensor/cpp/gyro_bmi160.cpp @@ -1,9 +1,9 @@ #include "metawear/core/types.h" -#include "metawear/core/cpp/connection_def.h" #include "metawear/core/cpp/datasignal_private.h" #include "metawear/core/cpp/metawearboard_def.h" #include "metawear/sensor/gyro_bmi160.h" +#include "gyro_bmi160_private.h" #include "gyro_bmi160_register.h" #include @@ -17,16 +17,6 @@ using std::piecewise_construct; static const float FSR_SCALE[5]= {16.4f, 32.8f, 65.6f, 131.2f, 262.4f}; -struct GyroBmi160Config { - uint8_t gyr_odr:4; - uint8_t gyr_bwp:2; - uint8_t:2; - uint8_t gyr_range:3; - uint8_t:5; - - float get_scale() const; -}; - float GyroBmi160Config::get_scale() const { return FSR_SCALE[gyr_range]; } @@ -35,31 +25,7 @@ static float bmi160_to_firmware(MblMwDataSignal* source, float value) { return (value * ((GyroBmi160Config*)source->owner->module_config.at(MBL_MW_MODULE_GYRO))->get_scale()); } -MblMwData* convert_to_bmi160_rotation(const MblMwMetaWearBoard *board, const uint8_t *response, uint8_t len) { - CartesianShort unscaled; - memcpy(&unscaled, response, sizeof(unscaled)); - - float scale = ((GyroBmi160Config*) board->module_config.at(MBL_MW_MODULE_GYRO))->get_scale(); - - CartesianFloat *value = (CartesianFloat*)malloc(sizeof(CartesianFloat)); - value->x = unscaled.x / scale; - value->y = unscaled.y / scale; - value->z = unscaled.z / scale; - - CREATE_MESSAGE(MBL_MW_DT_ID_CARTESIAN_FLOAT); -} - -MblMwData* convert_to_bmi160_rotation_single_axis(const MblMwMetaWearBoard *board, const uint8_t *response, uint8_t len) { - int16_t unscaled; - memcpy(&unscaled, response, sizeof(unscaled)); - - float *value = (float*)malloc(sizeof(float)); - *value = unscaled / ((GyroBmi160Config*)board->module_config.at(MBL_MW_MODULE_GYRO))->get_scale(); - - CREATE_MESSAGE(MBL_MW_DT_ID_FLOAT); -} - -const MblMwDataSignal* mbl_mw_gyro_bmi160_get_rotation_data_signal(const MblMwMetaWearBoard *board) { +MblMwDataSignal* mbl_mw_gyro_bmi160_get_rotation_data_signal(const MblMwMetaWearBoard *board) { return board->sensor_data_signals.at(GYRO_ROT_RESPONSE_HEADER); } @@ -72,10 +38,11 @@ void init_gyro_module(MblMwMetaWearBoard *board) { new_config->gyr_range = MBL_MW_GYRO_BMI160_FSR_2000DPS; board->module_config.emplace(MBL_MW_MODULE_GYRO, new_config); - MblMwDataSignal *gyro_signal= new MblMwDataSignal(GYRO_ROT_RESPONSE_HEADER, board, ResponseConvertor::BMI160_ROTATION, + MblMwDataSignal *gyro_signal= new MblMwDataSignal(GYRO_ROT_RESPONSE_HEADER, board, DataInterpreter::BMI160_ROTATION, 3, 2, 1, 0); gyro_signal->number_to_firmware = bmi160_to_firmware; board->sensor_data_signals[GYRO_ROT_RESPONSE_HEADER]= gyro_signal; + board->responses[GYRO_ROT_RESPONSE_HEADER]= response_handler_data_no_id; } void mbl_mw_gyro_bmi160_set_odr(MblMwMetaWearBoard *board, MblMwGyroBmi160Odr odr) { diff --git a/src/metawear/sensor/cpp/multichanneltemperature.cpp b/src/metawear/sensor/cpp/multichanneltemperature.cpp index b67a0cfb..abb90c0f 100644 --- a/src/metawear/sensor/cpp/multichanneltemperature.cpp +++ b/src/metawear/sensor/cpp/multichanneltemperature.cpp @@ -1,6 +1,5 @@ #include -#include "metawear/core/cpp/connection_def.h" #include "metawear/core/cpp/datasignal_private.h" #include "metawear/core/cpp/metawearboard_def.h" @@ -20,13 +19,15 @@ void init_multichannel_temp_module(MblMwMetaWearBoard *board) { ResponseHeader header(MBL_MW_MODULE_TEMPERATURE, ORDINAL(MultiChannelTempRegister::TEMPERATURE), extra_byte); header.register_id = READ_REGISTER(header.register_id); - MblMwDataSignal *temp_signal= new MblMwDataSignal(header, board, ResponseConvertor::TEMPERATURE, 1, 2, 1, 0); + MblMwDataSignal *temp_signal= new MblMwDataSignal(header, board, DataInterpreter::TEMPERATURE, 1, 2, 1, 0); temp_signal->number_to_firmware= temp_to_firmware; board->sensor_data_signals[header]= temp_signal; } + + board->responses[TEMPERATURE_RESPONSE_HEADER] = response_handler_data_with_id; } -const MblMwDataSignal* mbl_mw_multi_chnl_temp_get_temperature_data_signal(const MblMwMetaWearBoard *board, uint8_t channel) { +MblMwDataSignal* mbl_mw_multi_chnl_temp_get_temperature_data_signal(const MblMwMetaWearBoard *board, uint8_t channel) { ResponseHeader header(MBL_MW_MODULE_TEMPERATURE, READ_REGISTER(ORDINAL(MultiChannelTempRegister::TEMPERATURE)), channel); try { diff --git a/src/metawear/sensor/cpp/multichanneltemperature_register.h b/src/metawear/sensor/cpp/multichanneltemperature_register.h index d16f4e37..57cabc52 100644 --- a/src/metawear/sensor/cpp/multichanneltemperature_register.h +++ b/src/metawear/sensor/cpp/multichanneltemperature_register.h @@ -5,4 +5,6 @@ enum class MultiChannelTempRegister : uint8_t { TEMPERATURE = 1, MODE -}; \ No newline at end of file +}; + +const ResponseHeader TEMPERATURE_RESPONSE_HEADER(MBL_MW_MODULE_TEMPERATURE, READ_REGISTER(ORDINAL(MultiChannelTempRegister::TEMPERATURE))); diff --git a/src/metawear/sensor/cpp/switch.cpp b/src/metawear/sensor/cpp/switch.cpp index 55efcef5..d7eeae5d 100644 --- a/src/metawear/sensor/cpp/switch.cpp +++ b/src/metawear/sensor/cpp/switch.cpp @@ -3,6 +3,6 @@ #include "switch_register.h" -const MblMwDataSignal* mbl_mw_switch_get_state_data_signal(const MblMwMetaWearBoard *board) { +MblMwDataSignal* mbl_mw_switch_get_state_data_signal(const MblMwMetaWearBoard *board) { return board->sensor_data_signals.at(SWITCH_RESPONSE_HEADER); } diff --git a/src/metawear/sensor/gpio.h b/src/metawear/sensor/gpio.h index d0ea03b8..d80be5ea 100644 --- a/src/metawear/sensor/gpio.h +++ b/src/metawear/sensor/gpio.h @@ -1,3 +1,8 @@ +/** + * @copyright MbientLab License + * @file gpio.h + * @brief Interacts with the general purpose I/O pins on the board + */ #pragma once #include @@ -10,39 +15,104 @@ extern "C" { #endif +/** + * Pin configuration types + */ typedef enum { MBL_MW_GPIO_PULL_MODE_UP= 0, MBL_MW_GPIO_PULL_MODE_DOWN, MBL_MW_GPIO_PULL_MODE_NONE } MblMwGpioPullMode; +/** + * Read modes for analog input + */ typedef enum { - MBL_MW_GPIO_ANALOG_READ_MODE_ABS_REF= 0, - MBL_MW_GPIO_ANALOG_READ_MODE_ADC + MBL_MW_GPIO_ANALOG_READ_MODE_ABS_REF= 0, ///< Read input voltage as an absolute reference + MBL_MW_GPIO_ANALOG_READ_MODE_ADC ///< Read input voltage as a supply ratio } MblMwGpioAnalogReadMode; +/** + * Pin change types + */ typedef enum { - MBL_MW_GPIO_PIN_CHANGE_TYPE_RISING= 1, - MBL_MW_GPIO_PIN_CHANGE_TYPE_FALLING, - MBL_MW_GPIO_PIN_CHANGE_TYPE_ANY + MBL_MW_GPIO_PIN_CHANGE_TYPE_RISING= 1, ///< Notify on rising edge of a change + MBL_MW_GPIO_PIN_CHANGE_TYPE_FALLING, ///< Notify on falling edge of a change + MBL_MW_GPIO_PIN_CHANGE_TYPE_ANY ///< Notify on any edge of a change } MblMwGpioPinChangeType; +/** + * Retrieves a data signal representing analog data + * @param board Board to receive data from + * @param pin GPIO pin to read + * @param mode Read mode to use + */ METAWEAR_API MblMwDataSignal* mbl_mw_gpio_get_analog_input_data_signal(MblMwMetaWearBoard* board, uint8_t pin, MblMwGpioAnalogReadMode mode); +/** + * Retrieves a data signal representing digital data + * @param board Board to receive data from + * @param pin GPIO pin to read + */ METAWEAR_API MblMwDataSignal* mbl_mw_gpio_get_digital_input_data_signal(MblMwMetaWearBoard* board, uint8_t pin); +/** + * Retrieves a data signal representing changes in digital data + * @param board Board to receive data from + * @param pin GPIO pin to monitor + */ METAWEAR_API MblMwDataSignal* mbl_mw_gpio_get_pin_monitor_data_signal(MblMwMetaWearBoard* board, uint8_t pin); +/** + * Read analog input voltage + * @param board Board the pin is on + * @param pin GPIO pin to read + * @param mode Analog read mode + */ METAWEAR_API void mbl_mw_gpio_read_analog_input(const MblMwMetaWearBoard* board, uint8_t pin, MblMwGpioAnalogReadMode mode); +/** + * Sets the pin pull mode + * @param board Board the pin is on + * @param pin GPIO pin to modify + * @param mode New pull mode + */ METAWEAR_API void mbl_mw_gpio_set_pull_mode(const MblMwMetaWearBoard* board, uint8_t pin, MblMwGpioPullMode mode); - +/** + * Read digtal input state + * @param board Board the pin is on + * @param pin GPIO pin to read + */ METAWEAR_API void mbl_mw_gpio_read_digital_input(const MblMwMetaWearBoard* board, uint8_t pin); - +/** + * Sets the digital output state + * @param board Board the pin is on + * @param pin GPIO pin to set + */ METAWEAR_API void mbl_mw_gpio_set_digital_output(const MblMwMetaWearBoard* board, uint8_t pin); +/** + * Clears the digital output state + * @param board Board the pin is on + * @param pin GPIO pin to clear + */ METAWEAR_API void mbl_mw_gpio_clear_digital_output(const MblMwMetaWearBoard* board, uint8_t pin); +/** + * Sets the pin change type to monitor + * @param board Board the pin is on + * @param pin GPIO pin to set + * @param type Change type to monitor + */ METAWEAR_API void mbl_mw_gpio_set_pin_change_type(const MblMwMetaWearBoard* board, uint8_t pin, MblMwGpioPinChangeType type); - +/** + * Start pin monitoring + * @param board Board the pin is on + * @param pin GPIO pin to monitor + */ METAWEAR_API void mbl_mw_gpio_start_pin_monitoring(const MblMwMetaWearBoard* board, uint8_t pin); +/** + * Stop pin monitoring + * @param board Board the pin is on + * @param pin GPIO pin to stop monitoring + */ METAWEAR_API void mbl_mw_gpio_stop_pin_monitoring(const MblMwMetaWearBoard* board, uint8_t pin); #ifdef __cplusplus diff --git a/src/metawear/sensor/gyro_bmi160.h b/src/metawear/sensor/gyro_bmi160.h index ca8e44f0..e1140baf 100644 --- a/src/metawear/sensor/gyro_bmi160.h +++ b/src/metawear/sensor/gyro_bmi160.h @@ -46,7 +46,7 @@ typedef enum { * @param board Pointer to the board to retrieve the signal from * @return Pointer to the board's BMI160 rotation data signal */ -METAWEAR_API const MblMwDataSignal* mbl_mw_gyro_bmi160_get_rotation_data_signal(const MblMwMetaWearBoard *board); +METAWEAR_API MblMwDataSignal* mbl_mw_gyro_bmi160_get_rotation_data_signal(const MblMwMetaWearBoard *board); /** * Sets the output data rate diff --git a/src/metawear/sensor/multichanneltemperature.h b/src/metawear/sensor/multichanneltemperature.h index 9f640ca9..40ca3f19 100644 --- a/src/metawear/sensor/multichanneltemperature.h +++ b/src/metawear/sensor/multichanneltemperature.h @@ -1,3 +1,9 @@ +/** + * @copyright MbientLab License + * @file multichanneltemperature.h + * @brief Interacts with various temperature sources. + * @details The functions in the file only work for boards running firmware v1.0.4 or higher + */ #pragma once #include @@ -10,31 +16,71 @@ extern "C" { #endif +/** + * Enumeration of the available temperature sourcs. Note that not all sources are present + * on all boards + */ typedef enum { - MBL_MW_TEMP_SOURCE_INVALID= -1, - MBL_MW_TEMP_SOURCE_NRF_DIE= 0, - MBL_MW_TEMP_SOURCE_EXT_THERM, - MBL_MW_TEMP_SOURCE_BMP280, - MBL_MW_TEMP_SOURCE_PRESET_THERM + MBL_MW_TEMP_SOURCE_INVALID= -1, ///< Invalid temperature source + MBL_MW_TEMP_SOURCE_NRF_DIE= 0, ///< Temperature from the nRF chip + MBL_MW_TEMP_SOURCE_EXT_THERM, ///< Tempertaure from an external thermistor + MBL_MW_TEMP_SOURCE_BMP280, ///< Temperature from the BMP280 sensor + MBL_MW_TEMP_SOURCE_PRESET_THERM ///< Temperature from an internal thremistor } MblMwTemperatureSource; -const uint8_t MBL_MW_METAWEAR_R_CHANNEL_ON_DIE = 0, - MBL_MW_METAWEAR_R_CHANNEL_EXT_THERMISTOR = 1; +/** + * Channel IDs for the temperature sources on the MetaWear R board + */ +typedef enum { + MBL_MW_METAWEAR_R_CHANNEL_ON_DIE= 0, ///< Temperature from the nRF chip + MBL_MW_METAWEAR_R_CHANNEL_EXT_THERMISTOR ///< Temperature from an external thermistor +} MblMwMetaWearRChannel; -const uint8_t MBL_MW_METAWEAR_RPRO_CHANNEL_ON_DIE = 0, - MBL_MW_METAWEAR_RPRO_CHANNEL_ON_BOARD_THERMISTOR = 1, - MBL_MW_METAWEAR_RPRO_CHANNEL_EXT_THERMISTOR = 2, - MBL_MW_METAWEAR_RPRO_CHANNEL_BMP280 = 3; +/** + * CHannel IDs for the temperature sources on the MetaWear RPro board + */ +typedef enum { + MBL_MW_METAWEAR_RPRO_CHANNEL_ON_DIE = 0, ///< Temperature from the nRF chip + MBL_MW_METAWEAR_RPRO_CHANNEL_ON_BOARD_THERMISTOR, ///< Temperature from the on board thermistor + MBL_MW_METAWEAR_RPRO_CHANNEL_EXT_THERMISTOR, ///< Temperature from an external thermistor + MBL_MW_METAWEAR_RPRO_CHANNEL_BMP280 ///< Temperature from the BMP280 sensor +} MblMwMetaWearRProChannel; -METAWEAR_API const MblMwDataSignal* mbl_mw_multi_chnl_temp_get_temperature_data_signal(const MblMwMetaWearBoard *board, uint8_t channel); +/** + * Retrieves the data signal representing a temperature source + * @param board Board to retrieve the signal from + * @param channel Channel ID of the temperature source + */ +METAWEAR_API MblMwDataSignal* mbl_mw_multi_chnl_temp_get_temperature_data_signal(const MblMwMetaWearBoard *board, uint8_t channel); +/** + * Configure the external thermistor + * @param board Board the external thermistor is attached to + * @param channel Channel ID of the external thermistor + * @param data_pin GPIO pin reading the data + * @param pulldown_pin GPIO pin the pulldown resistor is connected to + * @param active_high Zero if the pulldown pin is not active high, non-zero if active high + */ METAWEAR_API void mbl_mw_multi_chnl_temp_configure_ext_thermistor(const MblMwMetaWearBoard *board, uint8_t channel, uint8_t data_pin, uint8_t pulldown_pin, uint8_t active_high); +/** + * Read temperature from a temperature source + * @param board Board to read temperature from + * @param channel Channel ID of the temperature source + */ METAWEAR_API void mbl_mw_multi_chnl_temp_read_temperature(const MblMwMetaWearBoard *board, uint8_t channel); - +/** + * Retrieve the temperature source type corresponding to a channel ID + * @param board Board to lookup the temperature source on + * @param channel Channel ID to lookup + * @return Source type of the channel ID, MBL_MW_TEMP_SOURCE_INVALID if channel ID is out of range + */ METAWEAR_API MblMwTemperatureSource mbl_mw_multi_chnl_temp_get_source(const MblMwMetaWearBoard *board, uint8_t channel); - +/** + * Retrieve the number of available channels + * @return Number of channel IDs + */ METAWEAR_API uint8_t mbl_mw_multi_chnl_temp_get_num_channels(const MblMwMetaWearBoard *board); #ifdef __cplusplus diff --git a/src/metawear/sensor/switch.h b/src/metawear/sensor/switch.h index b4c284ae..7979520a 100644 --- a/src/metawear/sensor/switch.h +++ b/src/metawear/sensor/switch.h @@ -20,7 +20,7 @@ extern "C" { * @param board Pointer to the board to retrieve the signal from * @return Pointer to the switch data signal */ -METAWEAR_API const MblMwDataSignal* mbl_mw_switch_get_state_data_signal(const MblMwMetaWearBoard *board); +METAWEAR_API MblMwDataSignal* mbl_mw_switch_get_state_data_signal(const MblMwMetaWearBoard *board); #ifdef __cplusplus } diff --git a/test/common.py b/test/common.py index 51cba445..26f96eb9 100644 --- a/test/common.py +++ b/test/common.py @@ -1,5 +1,5 @@ -from mbientlab.metawear import * -from ctypes import byref, cast, c_float, c_ubyte, c_uint, CDLL, create_string_buffer, POINTER +from mbientlab.metawear.core import * +from ctypes import * import copy import os import unittest @@ -12,12 +12,15 @@ class TestMetaWearBase(unittest.TestCase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.libmetawear= CDLL(os.environ["METAWEAR_LIB_SO_NAME"]) - self.send_command_fn= FnByteArray(self.commandLogger) self.initialized_fn= FnVoid(self.initialized) self.sensor_data_handler= FnDataPtr(self.sensorDataHandler) self.timer_signal_ready= FnVoidPtr(self.timerSignalReady) self.commands_recorded_fn= FnVoid(self.commandsRecorded) + self.send_command_fn= FnGattCharPtrByteArray(self.commandLogger) + self.read_gatt_char_fn= FnGattCharPtr(self.read_gatt_char) + self.btle_connection= BtleConnection(write_gatt_char = self.send_command_fn, read_gatt_char = self.read_gatt_char_fn) + self.metawear_rg_services= { 0x01: create_string_buffer(b'\x01\x80\x00\x00', 4), 0x02: create_string_buffer(b'\x02\x80\x00\x00', 4), @@ -40,6 +43,7 @@ def __init__(self, *args, **kwargs): 0x14: create_string_buffer(b'\x14\x80', 2), 0xfe: create_string_buffer(b'\xfe\x80\x00\x00', 4) } + self.metawear_rg_model= create_string_buffer(b'1', 1) self.metawear_r_services= { 0x01: create_string_buffer(b'\x01\x80\x00\x00', 4), @@ -63,6 +67,7 @@ def __init__(self, *args, **kwargs): 0x14: create_string_buffer(b'\x14\x80', 2), 0xfe: create_string_buffer(b'\xFE\x80\x00\x00', 4) } + self.metawear_r_model= create_string_buffer(b'0', 1) self.metawear_rpro_services= { 0x01: create_string_buffer(b'\x01\x80\x00\x00', 4), @@ -86,8 +91,13 @@ def __init__(self, *args, **kwargs): 0x14: create_string_buffer(b'\x14\x80\x00\x00', 4), 0xfe: create_string_buffer(b'\xFE\x80\x00\x00', 4) } + self.metawear_rpro_model= create_string_buffer(b'1', 1) + + self.firmware_revision= create_string_buffer(b'1.1.0', 5) self.command_history= [] + self.full_history= [] + self.eventId= 0 self.timerId= 0 self.dataprocId= 0 @@ -96,11 +106,11 @@ def __init__(self, *args, **kwargs): self.initialized= False def setUp(self): - self.board= self.libmetawear.mbl_mw_create_metawear_board(self.send_command_fn) + self.board= self.libmetawear.mbl_mw_metawearboard_create(byref(self.btle_connection)) self.libmetawear.mbl_mw_metawearboard_initialize(self.board, self.initialized_fn) def tearDown(self): - self.libmetawear.mbl_mw_free_metawear_board(self.board) + self.libmetawear.mbl_mw_metawearboard_free(self.board) def commandsRecorded(self): self.recorded= True @@ -111,21 +121,34 @@ def timerSignalReady(self, timer_signal): def initialized(self): self.initialized= True - def commandLogger(self, command, length): + def read_gatt_char(self, characteristic): + if (characteristic.contents.uuid_high == 0x00002a2400001000 and characteristic.contents.uuid_low == 0x800000805f9b34fb): + if (self.boardType == TestMetaWearBase.METAWEAR_RG_BOARD): + model_number= self.metawear_rg_model + elif (self.boardType == TestMetaWearBase.METAWEAR_R_BOARD): + model_number= self.metawear_r_model + elif (self.boardType == TestMetaWearBase.METAWEAR_RPRO_BOARD): + model_number= self.metawear_rpro_model + + self.libmetawear.mbl_mw_connection_char_read(self.board, characteristic, model_number.raw, len(model_number.raw)) + elif (characteristic.contents.uuid_high == 0x00002a2600001000 and characteristic.contents.uuid_low == 0x800000805f9b34fb): + self.libmetawear.mbl_mw_connection_char_read(self.board, characteristic, self.firmware_revision.raw, len(self.firmware_revision.raw)) + + def commandLogger(self, characteristic, command, length): self.command= [] for i in range(0, length): self.command.append(command[i]) + self.full_history.append(self.command) if (command[1] == 0x80): if (self.boardType == TestMetaWearBase.METAWEAR_RG_BOARD and command[0] in self.metawear_rg_services): service_response= self.metawear_rg_services[command[0]] - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, service_response.raw, len(service_response)) elif (self.boardType == TestMetaWearBase.METAWEAR_R_BOARD and command[0] in self.metawear_r_services): service_response= self.metawear_r_services[command[0]] - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, service_response.raw, len(service_response)) elif (self.boardType == TestMetaWearBase.METAWEAR_RPRO_BOARD and command[0] in self.metawear_rpro_services): service_response= self.metawear_rpro_services[command[0]] - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, service_response.raw, len(service_response)) + + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, service_response.raw, len(service_response)) else: # ignore module discovey commands self.command_history.append(self.command) @@ -133,17 +156,17 @@ def commandLogger(self, command, length): response= create_string_buffer(b'\x0c\x02', 3) response[2]= self.timerId self.timerId+= 1 - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, response.raw, len(response.raw)) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, response.raw, len(response.raw)) elif (command[0] == 0xa and command[1] == 0x3): response= create_string_buffer(b'\x0a\x02', 3) response[2]= self.eventId self.eventId+= 1 - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, response.raw, len(response.raw)) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, response.raw, len(response.raw)) elif (command[0] == 0x9 and command[1] == 0x2): response= create_string_buffer(b'\x09\x02', 3) response[2]= self.dataprocId self.dataprocId+= 1 - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, response.raw, len(response.raw)) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, response.raw, len(response.raw)) def sensorDataHandler(self, data): if (data.contents.type_id == DataTypeId.UINT32): diff --git a/test/testaccelerometer_bmi160.py b/test/testaccelerometer_bmi160.py index 4f680fa1..bd039014 100644 --- a/test/testaccelerometer_bmi160.py +++ b/test/testaccelerometer_bmi160.py @@ -1,5 +1,6 @@ from common import TestMetaWearBase -from mbientlab.metawear import AccelerometerBmi160, CartesianFloat +from mbientlab.metawear.core import CartesianFloat +from mbientlab.metawear.sensor import AccelerometerBmi160 from ctypes import create_string_buffer class TestAccBmi160Config(TestMetaWearBase): @@ -65,7 +66,7 @@ def test_get_acceleration_data_g(self): self.libmetawear.mbl_mw_datasignal_subscribe(self.accel_data_signal, self.sensor_data_handler) self.libmetawear.mbl_mw_acc_bmi160_set_range(self.board, AccelerometerBmi160.FSR_4G) - status= self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, response.raw, len(response)) + status= self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, response.raw, len(response)) self.assertEqual(self.data_cartesian_float, expected) def test_subscribe_acceleration_data(self): diff --git a/test/testaccelerometer_mma8452q.py b/test/testaccelerometer_mma8452q.py index 17e20a26..5ed8ed8b 100644 --- a/test/testaccelerometer_mma8452q.py +++ b/test/testaccelerometer_mma8452q.py @@ -1,6 +1,7 @@ import copy from common import TestMetaWearBase -from mbientlab.metawear import AccelerometerMma8452q, CartesianFloat +from mbientlab.metawear.core import CartesianFloat +from mbientlab.metawear.sensor import AccelerometerMma8452q from ctypes import create_string_buffer class TestMma8452qConfiguration(TestMetaWearBase): @@ -57,7 +58,7 @@ def test_get_acceleration_data_g(self): expected= CartesianFloat(x= -1.450, y= -2.555, z= 0.792) self.libmetawear.mbl_mw_datasignal_subscribe(self.accel_data_signal, self.sensor_data_handler) - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, response.raw, len(response)) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, response.raw, len(response)) self.assertEqual(self.data_cartesian_float, expected) diff --git a/test/testambientlight_ltr329.py b/test/testambientlight_ltr329.py index ff657079..ccb35eb2 100644 --- a/test/testambientlight_ltr329.py +++ b/test/testambientlight_ltr329.py @@ -1,5 +1,5 @@ from common import TestMetaWearBase -from mbientlab.metawear import AmbientLightLtr329 +from mbientlab.metawear.sensor import AmbientLightLtr329 from ctypes import * class TestALsLtr329Config(TestMetaWearBase): @@ -51,7 +51,7 @@ def test_get_illuminance_data(self): expected= 11571949 self.libmetawear.mbl_mw_datasignal_subscribe(self.ltr329_data_signal, self.sensor_data_handler) - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, response.raw, len(response)) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, response.raw, len(response)) self.assertEqual(self.data_uint32.value, expected) def test_stream_illuminance_data(self): diff --git a/test/testbarometer_bmp280.py b/test/testbarometer_bmp280.py index 5ab41c95..8306e46f 100644 --- a/test/testbarometer_bmp280.py +++ b/test/testbarometer_bmp280.py @@ -1,6 +1,6 @@ from common import TestMetaWearBase from ctypes import create_string_buffer -from mbientlab.metawear import BarometerBmp280 +from mbientlab.metawear.sensor import BarometerBmp280 class TestBaroBmp280Config(TestMetaWearBase): def setUp(self): @@ -63,7 +63,7 @@ def test_get_pressure_data(self): expected= 101173.828125 self.libmetawear.mbl_mw_datasignal_subscribe(self.pa_data_signal, self.sensor_data_handler) - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, response.raw, len(response)) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, response.raw, len(response)) self.assertAlmostEqual(self.data_float.value, expected) def test_pressure_subscribe(self): @@ -92,7 +92,7 @@ def test_get_altitude_data(self): expected= -480.8828125 self.libmetawear.mbl_mw_datasignal_subscribe(self.m_data_signal, self.sensor_data_handler) - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, response.raw, len(response)) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, response.raw, len(response)) self.assertAlmostEqual(self.data_float.value, expected) def test_altitude_subscribe(self): diff --git a/test/testdataprocessor.py b/test/testdataprocessor.py index ff8f2088..25f69167 100644 --- a/test/testdataprocessor.py +++ b/test/testdataprocessor.py @@ -1,6 +1,9 @@ from common import TestMetaWearBase -from ctypes import c_float -from mbientlab.metawear import * +from ctypes import * +from mbientlab.metawear.core import FnVoid, FnVoidPtr, Status +from mbientlab.metawear.peripheral import Led +from mbientlab.metawear.processor import * +from mbientlab.metawear.sensor import Gpio, MultiChannelTemperature class TestSwitchLedController(TestMetaWearBase): def test_chain_setup(self): @@ -22,23 +25,23 @@ def test_chain_setup(self): self.math_handler= FnVoidPtr(self.math_processor_created) switch_signal= self.libmetawear.mbl_mw_switch_get_state_data_signal(self.board) - self.libmetawear.mbl_mw_dataprocessor_create_counter(switch_signal, self.counter_handler) + self.libmetawear.mbl_mw_dataprocessor_counter_create(switch_signal, self.counter_handler) def counter_processor_created(self, signal): - self.libmetawear.mbl_mw_dataprocessor_create_math(signal, MathProcessor.OPERATION_MODULUS, c_float(2), self.math_handler) + self.libmetawear.mbl_mw_dataprocessor_math_create(signal, Math.OPERATION_MODULUS, c_float(2), self.math_handler) def math_processor_created(self, signal): self.modulus_signal= signal self.comparator_odd_handler= FnVoidPtr(self.comparator_odd_created) - self.libmetawear.mbl_mw_dataprocessor_create_comparator(self.modulus_signal, ComparatorProcessor.OPERATION_EQ, + self.libmetawear.mbl_mw_dataprocessor_comparator_create(self.modulus_signal, Comparator.OPERATION_EQ, c_float(1), self.comparator_odd_handler) def comparator_odd_created(self, signal): self.comp_odd_signal= signal self.comparator_even_handler= FnVoidPtr(self.comparator_even_created) - self.libmetawear.mbl_mw_dataprocessor_create_comparator(self.modulus_signal, ComparatorProcessor.OPERATION_EQ, + self.libmetawear.mbl_mw_dataprocessor_comparator_create(self.modulus_signal, Comparator.OPERATION_EQ, c_float(0), self.comparator_even_handler) def comparator_even_created(self, signal): @@ -73,27 +76,27 @@ def test_freefall_setup(self): self.rss_handler= FnVoidPtr(self.rss_processor_created) accel_signal= self.libmetawear.mbl_mw_acc_get_acceleration_data_signal(self.board) - self.libmetawear.mbl_mw_dataprocessor_create_rss(accel_signal, self.rss_handler) + self.libmetawear.mbl_mw_dataprocessor_rss_create(accel_signal, self.rss_handler) def rss_processor_created(self, signal): self.avg_handler= FnVoidPtr(self.average_processor_created) - self.libmetawear.mbl_mw_dataprocessor_create_average(signal, 4, self.avg_handler) + self.libmetawear.mbl_mw_dataprocessor_average_create(signal, 4, self.avg_handler) def average_processor_created(self, signal): self.threshold_handler= FnVoidPtr(self.threshold_processor_created) - self.libmetawear.mbl_mw_dataprocessor_create_threshold(signal, ThresholdProcessor.MODE_BINARY, c_float(0.5), c_float(0), + self.libmetawear.mbl_mw_dataprocessor_threshold_create(signal, Threshold.MODE_BINARY, c_float(0.5), c_float(0), self.threshold_handler) def threshold_processor_created(self, signal): self.threshold_signal= signal self.comparator_below_handler= FnVoidPtr(self.comparator_below_created) - self.libmetawear.mbl_mw_dataprocessor_create_comparator(signal, ComparatorProcessor.OPERATION_EQ, c_float(-1), + self.libmetawear.mbl_mw_dataprocessor_comparator_create(signal, Comparator.OPERATION_EQ, c_float(-1), self.comparator_below_handler) def comparator_below_created(self, signal): self.comparator_above_handler= FnVoidPtr(self.comparator_above_created) - self.libmetawear.mbl_mw_dataprocessor_create_comparator(self.threshold_signal, ComparatorProcessor.OPERATION_EQ, + self.libmetawear.mbl_mw_dataprocessor_comparator_create(self.threshold_signal, Comparator.OPERATION_EQ, c_float(1), self.comparator_above_handler) def comparator_above_created(self, signal): @@ -107,44 +110,50 @@ def setUp(self): self.rms_handler= FnVoidPtr(self.rms_processor_created) accel_signal= self.libmetawear.mbl_mw_acc_get_acceleration_data_signal(self.board) - self.libmetawear.mbl_mw_dataprocessor_create_rms(accel_signal, self.rms_handler) + self.libmetawear.mbl_mw_dataprocessor_rms_create(accel_signal, self.rms_handler) def test_activity_setup(self): self.expected_cmds= [ [0x09, 0x02, 0x03, 0x04, 0xff, 0xa0, 0x07, 0xa5, 0x00], [0x09, 0x02, 0x09, 0x03, 0x00, 0x20, 0x02, 0x07], + [0x09, 0x02, 0x09, 0x03, 0x01, 0x60, 0x0f, 0x03], [0x09, 0x02, 0x09, 0x03, 0x01, 0x60, 0x08, 0x03, 0x30, 0x75, 0x00, 0x00], - [0x09, 0x02, 0x09, 0x03, 0x02, 0x60, 0x0c, 0x0b, 0x00, 0x00, 0xc8, 0xaf], - [0x09, 0x07, 0x02, 0x01], + [0x09, 0x02, 0x09, 0x03, 0x03, 0x60, 0x0c, 0x0b, 0x00, 0x00, 0xc8, 0xaf], + [0x09, 0x07, 0x03, 0x01], [0x09, 0x03, 0x01] ] self.assertEqual(self.command_history, self.expected_cmds) def test_time_processor_data(self): - response= create_string_buffer(b'\x09\x03\x02\x4f\xee\xf4\x01', 7) + response= create_string_buffer(b'\x09\x03\x03\x4f\xee\xf4\x01', 7) expected= 2003.7236328125 - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, response.raw, len(response)) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, response.raw, len(response)) self.assertAlmostEqual(self.data_float.value, expected) def test_time_processor_unsubscribe(self): - expected= [0x09, 0x07, 0x02, 0x00] + expected= [0x09, 0x07, 0x03, 0x00] self.libmetawear.mbl_mw_datasignal_unsubscribe(self.time_signal) self.assertEqual(self.command, expected) def rms_processor_created(self, signal): self.accum_handler= FnVoidPtr(self.accum_processor_created) - self.libmetawear.mbl_mw_dataprocessor_create_accumulator_size(signal, c_ubyte(4), self.accum_handler) + self.libmetawear.mbl_mw_dataprocessor_accumulator_create_size(signal, c_ubyte(4), self.accum_handler) def accum_processor_created(self, signal): + self.accum_signal= signal + self.buffer_handler= FnVoidPtr(self.buffer_processor_created) + self.libmetawear.mbl_mw_dataprocessor_buffer_create(signal, self.buffer_handler) + + def buffer_processor_created(self, signal): self.time_handler= FnVoidPtr(self.time_processor_created) - self.libmetawear.mbl_mw_dataprocessor_create_time_delay(signal, TimeProcessor.MODE_ABSOLUTE, 30000, self.time_handler) + self.libmetawear.mbl_mw_dataprocessor_time_create(self.accum_signal, Time.MODE_ABSOLUTE, 30000, self.time_handler) def time_processor_created(self, signal): self.time_signal= signal self.delta_handler= FnVoidPtr(self.delta_processor_created) - self.libmetawear.mbl_mw_dataprocessor_create_delta(signal, DeltaProcessor.MODE_DIFFERENTIAL, c_float(180000), + self.libmetawear.mbl_mw_dataprocessor_delta_create(signal, Delta.MODE_DIFFERENTIAL, c_float(180000), self.delta_handler) def delta_processor_created(self, signal): @@ -159,7 +168,7 @@ def setUp(self): self.f_mult_handler= FnVoidPtr(self.f_mult_processor_created) self.temp_signal= self.libmetawear.mbl_mw_multi_chnl_temp_get_temperature_data_signal(self.board, c_ubyte(MultiChannelTemperature.METAWEAR_RPRO_CHANNEL_ON_DIE)) - self.libmetawear.mbl_mw_dataprocessor_create_math(self.temp_signal, MathProcessor.OPERATION_MULTIPLY, c_float(18), + self.libmetawear.mbl_mw_dataprocessor_math_create(self.temp_signal, Math.OPERATION_MULTIPLY, c_float(18), self.f_mult_handler) def test_temperature_setup(self): @@ -185,7 +194,7 @@ def test_temperature_data(self): for resp in responses: with self.subTest(response=resp[2]): - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, resp[0].raw, len(resp[0])) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, resp[0].raw, len(resp[0])) self.assertAlmostEqual(self.data_float.value, resp[1]) def test_temperature_unsubscribe(self): @@ -203,17 +212,17 @@ def test_temperature_unsubscribe(self): def f_mult_processor_created(self, signal): self.f_divide_handler= FnVoidPtr(self.f_divide_processor_created) - self.libmetawear.mbl_mw_dataprocessor_create_math(signal, MathProcessor.OPERATION_DIVIDE, c_float(10), + self.libmetawear.mbl_mw_dataprocessor_math_create(signal, Math.OPERATION_DIVIDE, c_float(10), self.f_divide_handler) def f_divide_processor_created(self, signal): self.f_add_handler= FnVoidPtr(self.f_add_processor_created) - self.libmetawear.mbl_mw_dataprocessor_create_math(signal, MathProcessor.OPERATION_ADD, c_float(32), self.f_add_handler) + self.libmetawear.mbl_mw_dataprocessor_math_create(signal, Math.OPERATION_ADD, c_float(32), self.f_add_handler) def f_add_processor_created(self, signal): self.fahrenheit_signal= signal; self.k_add_handler= FnVoidPtr(self.k_add_processor_created) - self.libmetawear.mbl_mw_dataprocessor_create_math(self.temp_signal, MathProcessor.OPERATION_ADD, c_float(273.15), + self.libmetawear.mbl_mw_dataprocessor_math_create(self.temp_signal, Math.OPERATION_ADD, c_float(273.15), self.k_add_handler) def k_add_processor_created(self, signal): @@ -233,11 +242,11 @@ def test_collector_setup(self): self.sample_handler= FnVoidPtr(self.sample_processor_created) gpio_adc_signal= self.libmetawear.mbl_mw_gpio_get_analog_input_data_signal(self.board, c_ubyte(0), Gpio.ANALOG_READ_MODE_ADC) - self.libmetawear.mbl_mw_dataprocessor_create_sample_delay(gpio_adc_signal, c_ubyte(16), self.sample_handler) + self.libmetawear.mbl_mw_dataprocessor_sample_create(gpio_adc_signal, c_ubyte(16), self.sample_handler) def sample_processor_created(self, signal): self.passthrough_handler= FnVoidPtr(self.passthrough_processor_created) - self.libmetawear.mbl_mw_dataprocessor_create_passthrough(signal, PassthroughProcessor.MODE_COUNT, c_ushort(0), + self.libmetawear.mbl_mw_dataprocessor_passthrough_create(signal, Passthrough.MODE_COUNT, c_ushort(0), self.passthrough_handler) def passthrough_processor_created(self, signal): @@ -250,7 +259,7 @@ def setUp(self): self.pulse_handler= FnVoidPtr(self.pulse_processor_created) gpio_adc_signal= self.libmetawear.mbl_mw_gpio_get_analog_input_data_signal(self.board, c_ubyte(0), Gpio.ANALOG_READ_MODE_ADC) - self.libmetawear.mbl_mw_dataprocessor_create_pulse_detector(gpio_adc_signal, PulseProcessor.OUTPUT_PEAK, c_float(500), + self.libmetawear.mbl_mw_dataprocessor_pulse_create(gpio_adc_signal, Pulse.OUTPUT_PEAK, c_float(500), c_ushort(10), self.pulse_handler) def test_pulse_setup(self): @@ -266,7 +275,7 @@ def test_pulse_data(self): expected= 789 response= create_string_buffer(b'\x09\x03\x00\x15\x03\x00\x00', 7) - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, response.raw, len(response)) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, response.raw, len(response)) self.assertEqual(self.data_uint32.value, expected) def test_pulse_unsubscribe(self): @@ -279,87 +288,64 @@ def pulse_processor_created(self, signal): self.pulse_signal= signal self.libmetawear.mbl_mw_datasignal_subscribe(self.pulse_signal, self.sensor_data_handler) -class TestGpioFeedback(TestMetaWearBase): - def test_feedback_setup(self): - self.expected_cmds= [ - [0x09, 0x02, 0x05, 0x86, 0x00, 0x20, 0x01, 0x02, 0x00, 0x00], - [0x09, 0x02, 0x05, 0x86, 0x00, 0x20, 0x09, 0x07, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00], - [0x09, 0x02, 0x09, 0x03, 0x01, 0x60, 0x06, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00], - [0x09, 0x02, 0x09, 0x03, 0x02, 0x60, 0x02, 0x1c], - [0x09, 0x02, 0x09, 0x03, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00], - [0x09, 0x02, 0x09, 0x03, 0x01, 0x60, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00], - [0x09, 0x02, 0x09, 0x03, 0x05, 0x60, 0x02, 0x1c], - [0x09, 0x02, 0x09, 0x03, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00], - [0x0a, 0x02, 0x09, 0x03, 0x00, 0x09, 0x04, 0x05], - [0x0a, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00], - [0x0a, 0x02, 0x09, 0x03, 0x00, 0x09, 0x04, 0x05], - [0x0a, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00], - [0x0a, 0x02, 0x09, 0x03, 0x00, 0x09, 0x05, 0x09, 0x05, 0x04], - [0x0a, 0x03, 0x01, 0x09, 0x07, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00], - [0x0a, 0x02, 0x09, 0x03, 0x02, 0x09, 0x04, 0x05], - [0x0a, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00], - [0x0a, 0x02, 0x09, 0x03, 0x04, 0x09, 0x04, 0x03], - [0x0a, 0x03, 0x00, 0x01, 0x00], - [0x0a, 0x02, 0x09, 0x03, 0x05, 0x09, 0x04, 0x05], - [0x0a, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00], - [0x0a, 0x02, 0x09, 0x03, 0x07, 0x09, 0x04, 0x03], - [0x0a, 0x03, 0x00, 0x01, 0x00] - ] +class TestGpioFeedbackSetup(TestMetaWearBase): + def setUp(self): + super().setUp() self.passthrough_handler= FnVoidPtr(self.passthrough_processor_created) self.gpio_abs_ref_signal= self.libmetawear.mbl_mw_gpio_get_analog_input_data_signal(self.board, c_ubyte(0), Gpio.ANALOG_READ_MODE_ABS_REF) - self.libmetawear.mbl_mw_dataprocessor_create_passthrough(self.gpio_abs_ref_signal, PassthroughProcessor.MODE_COUNT, + self.libmetawear.mbl_mw_dataprocessor_passthrough_create(self.gpio_abs_ref_signal, Passthrough.MODE_COUNT, c_ushort(0), self.passthrough_handler) def passthrough_processor_created(self, signal): self.offset_passthrough= signal self.math_handler= FnVoidPtr(self.math_processor_created) - self.libmetawear.mbl_mw_dataprocessor_create_math(self.gpio_abs_ref_signal, MathProcessor.OPERATION_SUBTRACT, c_float(0), self.math_handler) + self.libmetawear.mbl_mw_dataprocessor_math_create(self.gpio_abs_ref_signal, Math.OPERATION_SUBTRACT, c_float(0), self.math_handler) def math_processor_created(self, signal): self.abs_ref_offset= signal self.gt_comparator_handler= FnVoidPtr(self.gt_comparator_processor_created) - self.libmetawear.mbl_mw_dataprocessor_create_comparator(signal, ComparatorProcessor.OPERATION_GT, c_float(0), + self.libmetawear.mbl_mw_dataprocessor_comparator_create(signal, Comparator.OPERATION_GT, c_float(0), self.gt_comparator_handler) def gt_comparator_processor_created(self, signal): self.gt_comparator= signal self.gt_counter_handler= FnVoidPtr(self.gt_counter_processor_created) - self.libmetawear.mbl_mw_dataprocessor_create_counter(signal, self.gt_counter_handler) + self.libmetawear.mbl_mw_dataprocessor_counter_create(signal, self.gt_counter_handler) def gt_counter_processor_created(self, signal): self.gt_comparator_counter= signal self.gt_counter_comparator_handler= FnVoidPtr(self.gt_counter_comparator_processor_created) - self.libmetawear.mbl_mw_dataprocessor_create_comparator(signal, ComparatorProcessor.OPERATION_EQ, c_float(16), + self.libmetawear.mbl_mw_dataprocessor_comparator_create(signal, Comparator.OPERATION_EQ, c_float(16), self.gt_counter_comparator_handler) def gt_counter_comparator_processor_created(self, signal): self.gt_comparator_counter_comparator= signal self.lte_comparator_handler= FnVoidPtr(self.lte_comparator_processor_created) - self.libmetawear.mbl_mw_dataprocessor_create_comparator(self.abs_ref_offset, ComparatorProcessor.OPERATION_LTE, + self.libmetawear.mbl_mw_dataprocessor_comparator_create(self.abs_ref_offset, Comparator.OPERATION_LTE, c_float(0), self.lte_comparator_handler) def lte_comparator_processor_created(self, signal): self.lte_comparator= signal self.lte_counter_handler= FnVoidPtr(self.lte_counter_processor_created) - self.libmetawear.mbl_mw_dataprocessor_create_counter(signal, self.lte_counter_handler) + self.libmetawear.mbl_mw_dataprocessor_counter_create(signal, self.lte_counter_handler) def lte_counter_processor_created(self, signal): self.lte_comparator_counter= signal self.lte_counter_comparator_handler= FnVoidPtr(self.lte_counter_comparator_processor_created) - self.libmetawear.mbl_mw_dataprocessor_create_comparator(signal, ComparatorProcessor.OPERATION_EQ, c_float(16), + self.libmetawear.mbl_mw_dataprocessor_comparator_create(signal, Comparator.OPERATION_EQ, c_float(16), self.lte_counter_comparator_handler) def lte_counter_comparator_processor_created(self, signal): self.libmetawear.mbl_mw_event_record_commands(self.offset_passthrough) - self.libmetawear.mbl_mw_dataprocessor_set_counter_state(self.lte_comparator_counter, 0) - self.libmetawear.mbl_mw_dataprocessor_set_counter_state(self.gt_comparator_counter, 0) + self.libmetawear.mbl_mw_dataprocessor_counter_set_state(self.lte_comparator_counter, 0) + self.libmetawear.mbl_mw_dataprocessor_counter_set_state(self.gt_comparator_counter, 0) self.libmetawear.mbl_mw_dataprocessor_math_modify_rhs_signal(self.abs_ref_offset, self.offset_passthrough) self.libmetawear.mbl_mw_event_end_record(self.offset_passthrough, self.commands_recorded_fn) self.libmetawear.mbl_mw_event_record_commands(self.gt_comparator) - self.libmetawear.mbl_mw_dataprocessor_set_counter_state(self.lte_comparator_counter, 0) + self.libmetawear.mbl_mw_dataprocessor_counter_set_state(self.lte_comparator_counter, 0) self.libmetawear.mbl_mw_event_end_record(self.gt_comparator, self.commands_recorded_fn) self.libmetawear.mbl_mw_event_record_commands(self.gt_comparator_counter_comparator) @@ -367,14 +353,95 @@ def lte_counter_comparator_processor_created(self, signal): self.libmetawear.mbl_mw_event_end_record(self.gt_comparator_counter_comparator, self.commands_recorded_fn) self.libmetawear.mbl_mw_event_record_commands(self.lte_comparator) - self.libmetawear.mbl_mw_dataprocessor_set_counter_state(self.gt_comparator_counter, 0) + self.libmetawear.mbl_mw_dataprocessor_counter_set_state(self.gt_comparator_counter, 0) self.libmetawear.mbl_mw_event_end_record(self.lte_comparator, self.commands_recorded_fn) self.libmetawear.mbl_mw_event_record_commands(signal) self.libmetawear.mbl_mw_dataprocessor_passthrough_set_count(self.offset_passthrough, c_ushort(1)) self.libmetawear.mbl_mw_event_end_record(signal, self.commands_recorded_fn) - self.assertEqual(self.command_history, self.expected_cmds) +class TestGpioFeedback(TestGpioFeedbackSetup): + def test_feedback_setup(self): + expected_cmds= [ + [0x09, 0x02, 0x05, 0x86, 0x00, 0x20, 0x01, 0x02, 0x00, 0x00], + [0x09, 0x02, 0x05, 0x86, 0x00, 0x20, 0x09, 0x07, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00], + [0x09, 0x02, 0x09, 0x03, 0x01, 0x60, 0x06, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00], + [0x09, 0x02, 0x09, 0x03, 0x02, 0x60, 0x02, 0x1c], + [0x09, 0x02, 0x09, 0x03, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00], + [0x09, 0x02, 0x09, 0x03, 0x01, 0x60, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00], + [0x09, 0x02, 0x09, 0x03, 0x05, 0x60, 0x02, 0x1c], + [0x09, 0x02, 0x09, 0x03, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00], + [0x0a, 0x02, 0x09, 0x03, 0x00, 0x09, 0x04, 0x05], + [0x0a, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00], + [0x0a, 0x02, 0x09, 0x03, 0x00, 0x09, 0x04, 0x05], + [0x0a, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00], + [0x0a, 0x02, 0x09, 0x03, 0x00, 0x09, 0x05, 0x09, 0x05, 0x04], + [0x0a, 0x03, 0x01, 0x09, 0x07, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00], + [0x0a, 0x02, 0x09, 0x03, 0x02, 0x09, 0x04, 0x05], + [0x0a, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00], + [0x0a, 0x02, 0x09, 0x03, 0x04, 0x09, 0x04, 0x03], + [0x0a, 0x03, 0x00, 0x01, 0x00], + [0x0a, 0x02, 0x09, 0x03, 0x05, 0x09, 0x04, 0x05], + [0x0a, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00], + [0x0a, 0x02, 0x09, 0x03, 0x07, 0x09, 0x04, 0x03], + [0x0a, 0x03, 0x00, 0x01, 0x00] + ] + + self.assertEqual(self.command_history, expected_cmds) + + def test_remove_out_of_order(self): + expected_cmds= [ + [0x09, 0x06, 0x07], + [0x0a, 0x04, 0x06], + [0x09, 0x06, 0x06], + [0x09, 0x06, 0x05], + [0x0a, 0x04, 0x05], + [0x09, 0x06, 0x04], + [0x0a, 0x04, 0x04], + [0x09, 0x06, 0x03], + [0x09, 0x06, 0x02], + [0x0a, 0x04, 0x03], + [0x09, 0x06, 0x01] + ] + + self.libmetawear.mbl_mw_dataprocessor_remove(self.lte_comparator) + self.libmetawear.mbl_mw_dataprocessor_remove(self.abs_ref_offset) + remove_cmds= self.command_history[22:].copy() + + self.assertEqual(remove_cmds, expected_cmds) + + def test_remove_passthrough(self): + expected_cmds= [ + [0x09, 0x06, 0x00], + [0x0a, 0x04, 0x00], + [0x0a, 0x04, 0x01], + [0x0a, 0x04, 0x02] + ] + + self.libmetawear.mbl_mw_dataprocessor_remove(self.offset_passthrough) + remove_cmds= self.command_history[22:].copy() + + self.assertEqual(remove_cmds, expected_cmds) + + def test_remove_math(self): + expected_cmds= [ + [0x09, 0x06, 0x04], + [0x0a, 0x04, 0x04], + [0x09, 0x06, 0x03], + [0x09, 0x06, 0x02], + [0x0a, 0x04, 0x03], + [0x09, 0x06, 0x07], + [0x0a, 0x04, 0x06], + [0x09, 0x06, 0x06], + [0x09, 0x06, 0x05], + [0x0a, 0x04, 0x05], + [0x09, 0x06, 0x01] + ] + + self.libmetawear.mbl_mw_dataprocessor_remove(self.abs_ref_offset) + remove_cmds= self.command_history[22:].copy() + + self.assertEqual(remove_cmds, expected_cmds) class TestPassthroughSetCount(TestMetaWearBase): def setUp(self): @@ -389,12 +456,12 @@ def processor_created(self, signal): self.status= self.libmetawear.mbl_mw_dataprocessor_passthrough_set_count(signal, c_ushort(20)) def test_valid_set_count(self): - self.libmetawear.mbl_mw_dataprocessor_create_passthrough(self.baro_pa_signal, PassthroughProcessor.MODE_COUNT, + self.libmetawear.mbl_mw_dataprocessor_passthrough_create(self.baro_pa_signal, Passthrough.MODE_COUNT, c_ushort(10), self.processor_handler) self.assertEqual(self.status, Status.OK) def test_invalid_set_count(self): - self.libmetawear.mbl_mw_dataprocessor_create_sample_delay(self.baro_pa_signal, c_ubyte(16), self.processor_handler) + self.libmetawear.mbl_mw_dataprocessor_sample_create(self.baro_pa_signal, c_ubyte(16), self.processor_handler) self.assertEqual(self.status, Status.WARNING_INVALID_PROCESSOR_TYPE) class TestAccumulatorSetSum(TestMetaWearBase): @@ -410,11 +477,11 @@ def processor_created(self, signal): self.status= self.libmetawear.mbl_mw_dataprocessor_set_accumulator_state(signal, c_float(101325)) def test_valid_set_state(self): - self.libmetawear.mbl_mw_dataprocessor_create_accumulator(self.baro_pa_signal, self.processor_handler) + self.libmetawear.mbl_mw_dataprocessor_accumulator_create(self.baro_pa_signal, self.processor_handler) self.assertEqual(self.status, Status.OK) def test_invalid_set_count(self): - self.libmetawear.mbl_mw_dataprocessor_create_time_delay(self.baro_pa_signal, TimeProcessor.MODE_DIFFERENTIAL, 30000, + self.libmetawear.mbl_mw_dataprocessor_time_create(self.baro_pa_signal, Time.MODE_DIFFERENTIAL, 30000, self.processor_handler) self.assertEqual(self.status, Status.WARNING_INVALID_PROCESSOR_TYPE) @@ -428,14 +495,14 @@ def setUp(self): self.baro_pa_signal= self.libmetawear.mbl_mw_baro_bmp280_get_pressure_data_signal(self.board) def processor_created(self, signal): - self.status= self.libmetawear.mbl_mw_dataprocessor_set_counter_state(signal, 128) + self.status= self.libmetawear.mbl_mw_dataprocessor_counter_set_state(signal, 128) def test_valid_set_state(self): - self.libmetawear.mbl_mw_dataprocessor_create_counter(self.baro_pa_signal, self.processor_handler) + self.libmetawear.mbl_mw_dataprocessor_counter_create(self.baro_pa_signal, self.processor_handler) self.assertEqual(self.status, Status.OK) def test_invalid_set_count(self): - self.libmetawear.mbl_mw_dataprocessor_create_comparator(self.baro_pa_signal, ComparatorProcessor.OPERATION_LT, + self.libmetawear.mbl_mw_dataprocessor_comparator_create(self.baro_pa_signal, Comparator.OPERATION_LT, c_float(101325), self.processor_handler) self.assertEqual(self.status, Status.WARNING_INVALID_PROCESSOR_TYPE) @@ -449,14 +516,14 @@ def setUp(self): self.baro_pa_signal= self.libmetawear.mbl_mw_baro_bmp280_get_pressure_data_signal(self.board) def processor_created(self, signal): - self.status= self.libmetawear.mbl_mw_dataprocessor_reset_average(signal) + self.status= self.libmetawear.mbl_mw_dataprocessor_average_reset(signal) def test_valid_reset(self): - self.libmetawear.mbl_mw_dataprocessor_create_average(self.baro_pa_signal, c_ubyte(8), self.processor_handler) + self.libmetawear.mbl_mw_dataprocessor_average_create(self.baro_pa_signal, c_ubyte(8), self.processor_handler) self.assertEqual(self.status, Status.OK) def test_invalid_reset(self): - self.libmetawear.mbl_mw_dataprocessor_create_pulse_detector(self.baro_pa_signal, PulseProcessor.OUTPUT_AREA, + self.libmetawear.mbl_mw_dataprocessor_pulse_create(self.baro_pa_signal, Pulse.OUTPUT_AREA, c_float(101325), c_ushort(64), self.processor_handler) self.assertEqual(self.status, Status.WARNING_INVALID_PROCESSOR_TYPE) @@ -470,14 +537,14 @@ def setUp(self): self.baro_pa_signal= self.libmetawear.mbl_mw_baro_bmp280_get_pressure_data_signal(self.board) def processor_created(self, signal): - self.status= self.libmetawear.mbl_mw_dataprocessor_delta_set_previous_value(signal, c_float(101325)) + self.status= self.libmetawear.mbl_mw_dataprocessor_delta_set_reference(signal, c_float(101325)) def test_valid_set_previous(self): - self.libmetawear.mbl_mw_dataprocessor_create_delta(self.baro_pa_signal, DeltaProcessor.MODE_DIFFERENTIAL, + self.libmetawear.mbl_mw_dataprocessor_delta_create(self.baro_pa_signal, Delta.MODE_DIFFERENTIAL, c_float(25331.25), self.processor_handler) self.assertEqual(self.status, Status.OK) def test_invalid_set_previous(self): - self.libmetawear.mbl_mw_dataprocessor_create_math(self.baro_pa_signal, MathProcessor.OPERATION_DIVIDE, c_float(1000), + self.libmetawear.mbl_mw_dataprocessor_math_create(self.baro_pa_signal, Math.OPERATION_DIVIDE, c_float(1000), self.processor_handler) self.assertEqual(self.status, Status.WARNING_INVALID_PROCESSOR_TYPE) diff --git a/test/testevent.py b/test/testevent.py index 5198c016..3445be78 100644 --- a/test/testevent.py +++ b/test/testevent.py @@ -1,5 +1,5 @@ from common import TestMetaWearBase -from mbientlab.metawear import Gpio +from mbientlab.metawear.sensor import Gpio class TestEvent(TestMetaWearBase): def test_schedule_read_temp(self): @@ -53,24 +53,3 @@ def test_schedule_read_temp_gpio(self): self.libmetawear.mbl_mw_event_end_record(self.timerSignals[1], self.commands_recorded_fn) self.assertEqual(self.command_history, expected_cmds) - - - -class TestEventRemove(TestMetaWearBase): - def test_remove_commands(self): - expected_cmds= [ - [0x0a, 0x04, 0x0], - [0x0a, 0x04, 0x1] - ] - - self.libmetawear.mbl_mw_timer_create(self.board, 89875517, 8736, 0, self.timer_signal_ready) - - self.libmetawear.mbl_mw_event_record_commands(self.timerSignals[0]) - self.libmetawear.mbl_mw_gpio_read_digital_input(self.board, 3) - self.libmetawear.mbl_mw_multi_chnl_temp_read_temperature(self.board, 2) - self.libmetawear.mbl_mw_event_end_record(self.timerSignals[0], self.commands_recorded_fn) - - self.libmetawear.mbl_mw_event_remove_commands(self.timerSignals[0]) - - del self.command_history[0:5] - self.assertEqual(self.command_history, expected_cmds) diff --git a/test/testgpio.py b/test/testgpio.py index 622fb233..3bd83a6f 100644 --- a/test/testgpio.py +++ b/test/testgpio.py @@ -1,6 +1,6 @@ from common import TestMetaWearBase from ctypes import create_string_buffer -from mbientlab.metawear import Gpio +from mbientlab.metawear.sensor import Gpio class TestGpioDigitalConfig(TestMetaWearBase): def test_set_digital_out(self): @@ -51,7 +51,7 @@ def test_pin_monitor(self): for test in tests: with self.subTest(changetype=test['change_type']): - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, test['response'].raw, len(test['response'])) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, test['response'].raw, len(test['response'])) self.assertEqual(self.data_uint32.value, test['expected']) def test_pin_monitor_start(self): @@ -83,7 +83,7 @@ def test_handle_digital_state(self): for test in tests: with self.subTest(changetype=test['state']): - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, test['response'].raw, len(test['response'])) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, test['response'].raw, len(test['response'])) self.assertEqual(self.data_uint32.value, test['expected']) class TestGpioAnalogData(TestMetaWearBase): @@ -110,5 +110,5 @@ def test_handle_analog_data(self): pin_monitor_signal= self.libmetawear.mbl_mw_gpio_get_analog_input_data_signal(self.board, 1, test['mode']); self.libmetawear.mbl_mw_datasignal_subscribe(pin_monitor_signal, self.sensor_data_handler) - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, test['response'].raw, len(test['response'])) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, test['response'].raw, len(test['response'])) self.assertEqual(self.data_uint32.value, test['expected']) diff --git a/test/testgyro_bmi160.py b/test/testgyro_bmi160.py index fb51c36a..9e55969b 100644 --- a/test/testgyro_bmi160.py +++ b/test/testgyro_bmi160.py @@ -1,7 +1,8 @@ import copy from common import TestMetaWearBase from ctypes import create_string_buffer -from mbientlab.metawear import GyroBmi160, CartesianFloat +from mbientlab.metawear.core import CartesianFloat +from mbientlab.metawear.sensor import GyroBmi160 class TestGyroBmi160Config(TestMetaWearBase): def setUp(self): @@ -81,6 +82,6 @@ def test_rotation_data_handler(self): self.libmetawear.mbl_mw_datasignal_subscribe(self.gyro_rot_data_signal, self.sensor_data_handler) self.libmetawear.mbl_mw_gyro_bmi160_set_range(self.board, GyroBmi160.FSR_500DPS) - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, response.raw, len(response)) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, response.raw, len(response)) self.assertEqual(self.data_cartesian_float, expected) diff --git a/test/testled.py b/test/testled.py index 37cf15d0..4e55955c 100644 --- a/test/testled.py +++ b/test/testled.py @@ -1,6 +1,6 @@ from ctypes import byref from common import TestMetaWearBase -from mbientlab.metawear import Led +from mbientlab.metawear.peripheral import Led class TestLedControl(TestMetaWearBase): def test_play(self): diff --git a/test/testmetawearboard.py b/test/testmetawearboard.py index 90005d53..74a5096c 100644 --- a/test/testmetawearboard.py +++ b/test/testmetawearboard.py @@ -1,6 +1,7 @@ from common import TestMetaWearBase from ctypes import create_string_buffer -from mbientlab.metawear import Status +from mbientlab.metawear.core import Status +from testdataprocessor import TestGpioFeedbackSetup class TestMetaWearBoard(TestMetaWearBase): def test_no_response_handler(self): @@ -16,8 +17,69 @@ def test_no_response_handler(self): for resp in responses: with self.subTest(response=resp): - status= self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, resp.raw, len(resp)) + status= self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, resp.raw, len(resp)) self.assertEqual(status, Status.WARNING_UNEXPECTED_SENSOR_DATA) def test_service_discovery(self): self.assertEqual(self.initialized, True) + +class TestMetaWearBoardInitialize(TestMetaWearBase): + def test_reinitialize(self): + expected_cmds= [ + [0x01, 0x80], [0x02, 0x80], [0x03, 0x80], [0x04, 0x80], + [0x05, 0x80], [0x06, 0x80], [0x07, 0x80], [0x08, 0x80], + [0x09, 0x80], [0x0a, 0x80], [0x0b, 0x80], [0x0c, 0x80], + [0x0d, 0x80], [0x0f, 0x80], [0x10, 0x80], [0x11, 0x80], + [0x12, 0x80], [0x13, 0x80], [0x14, 0x80], [0xfe, 0x80] + ] + + self.libmetawear.mbl_mw_metawearboard_initialize(self.board, self.initialized_fn) + self.assertEqual(self.full_history, expected_cmds) + + def test_reinitialize_new_firmware(self): + expected_cmds= [ + [0x01, 0x80], [0x02, 0x80], [0x03, 0x80], [0x04, 0x80], + [0x05, 0x80], [0x06, 0x80], [0x07, 0x80], [0x08, 0x80], + [0x09, 0x80], [0x0a, 0x80], [0x0b, 0x80], [0x0c, 0x80], + [0x0d, 0x80], [0x0f, 0x80], [0x10, 0x80], [0x11, 0x80], + [0x12, 0x80], [0x13, 0x80], [0x14, 0x80], [0xfe, 0x80], + [0x01, 0x80], [0x02, 0x80], [0x03, 0x80], [0x04, 0x80], + [0x05, 0x80], [0x06, 0x80], [0x07, 0x80], [0x08, 0x80], + [0x09, 0x80], [0x0a, 0x80], [0x0b, 0x80], [0x0c, 0x80], + [0x0d, 0x80], [0x0f, 0x80], [0x10, 0x80], [0x11, 0x80], + [0x12, 0x80], [0x13, 0x80], [0x14, 0x80], [0xfe, 0x80] + ] + + self.firmware_revision= create_string_buffer(b'1.1.4', 5) + self.libmetawear.mbl_mw_metawearboard_initialize(self.board, self.initialized_fn) + self.assertEqual(self.full_history, expected_cmds) + +class TestTearDown(TestGpioFeedbackSetup): + def test_dataproc_event(self): + expected_cmds= [ + [0x09, 0x08], + [0x0a, 0x05] + ] + + self.libmetawear.mbl_mw_metawearboard_tear_down(self.board) + tear_down_cmds= self.command_history[22:].copy() + + self.assertEqual(tear_down_cmds, expected_cmds) + +class TestTimerTearDown(TestMetaWearBase): + def test_timer(self): + expected_cmds= [ + [0x0c, 0x05, 0x00], + [0x0c, 0x05, 0x01], + [0x0c, 0x05, 0x02], + [0x0c, 0x05, 0x03], + [0x09, 0x08], + [0x0a, 0x05] + ] + + self.libmetawear.mbl_mw_timer_create(self.board, 667408, -1, 0, self.timer_signal_ready) + self.libmetawear.mbl_mw_timer_create(self.board, 1000, -1, 0, self.timer_signal_ready) + self.libmetawear.mbl_mw_timer_create(self.board, 1000, 10, 0, self.timer_signal_ready) + self.libmetawear.mbl_mw_timer_create_indefinite(self.board, 1000, 0, self.timer_signal_ready) + + self.libmetawear.mbl_mw_metawearboard_tear_down(self.board) diff --git a/test/testmultichanneltemperature.py b/test/testmultichanneltemperature.py index 19f5e8cd..20de59be 100644 --- a/test/testmultichanneltemperature.py +++ b/test/testmultichanneltemperature.py @@ -1,6 +1,6 @@ from common import TestMetaWearBase from ctypes import create_string_buffer -from mbientlab.metawear import MultiChannelTemperature +from mbientlab.metawear.sensor import MultiChannelTemperature class TestMultiChannelTemperatureMwr(TestMetaWearBase): def setUp(self): @@ -36,7 +36,7 @@ def test_get_temperature_data(self): with self.subTest(response=resp): temp_signal= self.libmetawear.mbl_mw_multi_chnl_temp_get_temperature_data_signal(self.board, resp[2]) self.libmetawear.mbl_mw_datasignal_subscribe(temp_signal, self.sensor_data_handler) - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, resp[0].raw, len(resp[0])) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, resp[0].raw, len(resp[0])) self.assertAlmostEqual(self.data_float.value, resp[1]) def test_get_num_channels(self): @@ -97,7 +97,7 @@ def test_get_temperature_data(self): with self.subTest(response=resp): temp_signal= self.libmetawear.mbl_mw_multi_chnl_temp_get_temperature_data_signal(self.board, resp[2]) self.libmetawear.mbl_mw_datasignal_subscribe(temp_signal, self.sensor_data_handler) - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, resp[0].raw, len(resp[0])) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, resp[0].raw, len(resp[0])) self.assertAlmostEqual(self.data_float.value, resp[1]) def test_get_num_channels(self): diff --git a/test/testneopixel.py b/test/testneopixel.py index e17a4de9..e4f97afa 100644 --- a/test/testneopixel.py +++ b/test/testneopixel.py @@ -1,5 +1,5 @@ from common import TestMetaWearBase -from mbientlab.metawear import NeoPixel +from mbientlab.metawear.peripheral import NeoPixel class TestNeoPixelInit(TestMetaWearBase): def test_init_slow_strand(self): diff --git a/test/testswitch.py b/test/testswitch.py index f678cdc5..08871587 100644 --- a/test/testswitch.py +++ b/test/testswitch.py @@ -24,7 +24,7 @@ def test_mbl_mw_switch_get_data_pushed(self): expected= 1 self.libmetawear.mbl_mw_datasignal_subscribe(self.switch_data_signal, self.sensor_data_handler) - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, response.raw, len(response)) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, response.raw, len(response)) self.assertEqual(self.data_uint32.value, expected) def test_mbl_mw_switch_get_data_released(self): @@ -32,5 +32,5 @@ def test_mbl_mw_switch_get_data_released(self): expected= 0 self.libmetawear.mbl_mw_datasignal_subscribe(self.switch_data_signal, self.sensor_data_handler) - self.libmetawear.mbl_mw_metawearboard_handle_response(self.board, response.raw, len(response)) + self.libmetawear.mbl_mw_connection_notify_char_changed(self.board, response.raw, len(response)) self.assertEqual(self.data_uint32.value, expected) diff --git a/test/testtimer.py b/test/testtimer.py index 8bfb1b31..dda3d2f0 100644 --- a/test/testtimer.py +++ b/test/testtimer.py @@ -31,13 +31,20 @@ def test_stop(self): def test_remove(self): expected_cmds= [ [0x0c, 0x04, 0x7], - [0x0c, 0x05, 0x7] + [0x0c, 0x05, 0x7], + [0x0a, 0x04, 0x0], + [0x0a, 0x04, 0x1] ] self.timerId= 7 self.libmetawear.mbl_mw_timer_create(self.board, 667408, -1, 0, self.timer_signal_ready) + self.libmetawear.mbl_mw_event_record_commands(self.timerSignals[0]) + self.libmetawear.mbl_mw_gpio_read_digital_input(self.board, 3) + self.libmetawear.mbl_mw_multi_chnl_temp_read_temperature(self.board, 2) + self.libmetawear.mbl_mw_event_end_record(self.timerSignals[0], self.commands_recorded_fn) + self.libmetawear.mbl_mw_timer_remove(self.timerSignals[0]) - # Ignore the add timer command - self.command_history.pop(0) + # Ignore the add timer and events commands + del self.command_history[0:5] self.assertEqual(self.command_history, expected_cmds) diff --git a/wrapper/python/mbientlab/metawear.py b/wrapper/python/mbientlab/metawear.py deleted file mode 100644 index 76f0ca71..00000000 --- a/wrapper/python/mbientlab/metawear.py +++ /dev/null @@ -1,282 +0,0 @@ -from ctypes import * -import uuid - -# Constants indicating status codes -class Status: - OK= 0 - WARNING_UNEXPECTED_SENSOR_DATA= 1 - WARNING_INVALID_PROCESSOR_TYPE= 2 - -# Constants identifying the message data types -class DataTypeId: - UINT32= 0 - FLOAT= 1 - CARTESIAN_FLOAT= 2 - -# Python wrapper for the MblMwMessage struct -class Data(Structure): - _fields_= [ - ("value", c_void_p), - ("type_id", c_int) - ] - -FnByteArray= CFUNCTYPE(None, POINTER(c_ubyte), c_ubyte) -FnVoid= CFUNCTYPE(None) -FnVoidPtr= CFUNCTYPE(None, c_void_p) -FnDataPtr= CFUNCTYPE(None, POINTER(Data)) - -# UUIDs for the MetaWear gatt services and characteristics -class Gatt: - SERVICE_UUID= uuid.UUID('{326A9000-85CB-9195-D9DD-464CFBBAE75A}') - CHAR_COMMAND_UUID= uuid.UUID('{326A9001-85CB-9195-D9DD-464CFBBAE75A}') - CHAR_NOTIFICATION_UUID= uuid.UUID('{326A9006-85CB-9195-D9DD-464CFBBAE75A}') - -# Constants for configuring the BMI160 accelerometer -class AccelerometerBmi160: - ODR_0_78125HZ= 0 - ODR_1_5625HZ= 1 - ODR_3_125HZ= 2 - ODR_6_25HZ= 3 - ODR_12_5HZ= 4 - ODR_25HZ= 5 - ODR_50HZ= 6 - ODR_100HZ= 7 - ODR_200HZ= 8 - ODR_400HZ= 9 - ODR_800HZ= 10 - ODR_1600HZ= 11 - - FSR_2G= 0 - FSR_4G= 1 - FSR_8G= 2 - FSR_16G= 3 - -# Constants for configuring the MMA8452Q accelerometer -class AccelerometerMma8452q: - ODR_800HZ= 0 - ODR_400HZ= 1 - ODR_200HZ= 2 - ODR_100HZ= 3 - ODR_50HZ= 4 - ODR_12_5HZ= 5 - ODR_6_25HZ= 6 - ODR_1_56HZ= 7 - - FSR_2G= 0 - FSR_4G= 1 - FSR_8G= 2 - -# Constants for configuring the LTR329 ambient light sensor -class AmbientLightLtr329: - GAIN_1X= 0 - GAIN_2X= 1 - GAIN_4X= 2 - GAIN_8X= 3 - GAIN_48X= 4 - GAIN_96X= 5 - - INTEGRATION_TIME_100MS= 0 - INTEGRATION_TIME_50MS= 1 - INTEGRATION_TIME_200MS= 2 - INTEGRATION_TIME_400MS= 3 - INTEGRATION_TIME_150MS= 4 - INTEGRATION_TIME_250MS= 5 - INTEGRATION_TIME_300MS= 6 - INTEGRATION_TIME_350MS= 7 - - MEASUREMENT_RATE_50MS= 0 - MEASUREMENT_RATE_100MS= 1 - MEASUREMENT_RATE_200MS= 2 - MEASUREMENT_RATE_500MS= 3 - MEASUREMENT_RATE_1000MS= 4 - MEASUREMENT_RATE_2000MS= 5 - -# Constants for configuring the BMP280 barometer -class BarometerBmp280: - OVERSAMPLING_SKIP= 0, - OVERSAMPLING_ULTRA_LOW_POWER= 1 - OVERSAMPLING_LOW_POWER= 2 - OVERSAMPLING_STANDARD= 3 - OVERSAMPLING_HIGH= 4 - OVERSAMPLING_ULTRA_HIGH= 5 - - IIR_FILTER_OFF= 0 - IIR_FILTER_AVG_2= 1 - IIR_FILTER_AVG_4= 2 - IIR_FILTER_AVG_8= 3 - IIR_FILTER_AVG_16= 4 - - STANDBY_TIME_0_5MS= 0 - STANDBY_TIME_62_5MS= 1 - STANDBY_TIME_125MS= 2 - STANDBY_TIME_250MS= 3 - STANDBY_TIME_500MS= 4 - STANDBY_TIME_1000MS= 5 - STANDBY_TIME_2000MS= 6 - STANDBY_TIME_4000MS= 7 - -# Constants for configuring the BMI160 gyro -class GyroBmi160: - ODR_25HZ= 6 - ODR_50HZ= 7 - ODR_100HZ= 8 - ODR_200HZ= 9 - ODR_400HZ= 10 - ODR_800HZ= 11 - ODR_1600HZ= 12 - ODR_3200HZ= 13 - - FSR_2000DPS= 0 - FSR_1000DPS= 1 - FSR_500DPS= 2 - FSR_250DPS= 3 - FSR_125DPS= 4 - -# Constants and types for configuring the Led -class Led: - # Python wrapper for the MblMwLedPattern struct - class Pattern(Structure): - _fields_= [ - ("rise_time_ms", c_ushort), - ("high_time_ms", c_ushort), - ("fall_time_ms", c_ushort), - ("pulse_duration_ms", c_ushort), - ("high_intensity", c_ubyte), - ("low_intensity", c_ubyte), - ("repeat_count", c_ubyte) - ] - - REPEAT_INDEFINITELY= 0xff - - COLOR_GREEN= 0 - COLOR_RED= 1 - COLOR_BLUE= 2 - - PRESET_BLINK= 0 - PRESET_PULSE= 1 - PRESET_SOLID= 2 - -# Constants for configuring NeoPixel strands -class NeoPixel: - COLOR_ORDERING_WS2811_RGB= 0 - COLOR_ORDERING_WS2811_RBG= 1 - COLOR_ORDERING_WS2811_GRB= 2 - COLOR_ORDERING_WS2811_GBR= 3 - - ROT_DIRECTION_TOWARDS= 0 - ROT_DIRECTION_AWAY= 1 - -class MultiChannelTemperature: - SOURCE_INVALID= -1 - SOURCE_NRF_DIE= 0 - SOURCE_EXT_THERM= 1 - SOURCE_BMP280= 2 - SOURCE_PRESET_THERM= 3 - - METAWEAR_R_CHANNEL_ON_DIE= 0 - METAWEAR_R_CHANNEL_EXT_THERMISTOR= 1 - - METAWEAR_RPRO_CHANNEL_ON_DIE= 0 - METAWEAR_RPRO_CHANNEL_ON_BOARD_THERMISTOR= 1 - METAWEAR_RPRO_CHANNEL_EXT_THERMISTOR= 2 - METAWEAR_RPRO_CHANNEL_BMP280= 3 - -class Gpio: - PULL_MODE_UP= 0 - PULL_MODE_DOWN= 1 - PULL_MODE_NONE= 2 - - ANALOG_READ_MODE_ABS_REF= 0 - ANALOG_READ_MODE_ADC= 1 - - PIN_CHANGE_TYPE_RISING= 1 - PIN_CHANGE_TYPE_FALLING= 2 - PIN_CHANGE_TYPE_ANY= 3 - -class MathProcessor: - OPERATION_ADD= 1 - OPERATION_MULTIPLY= 2 - OPERATION_DIVIDE= 3 - OPERATION_MODULUS= 4 - OPERATION_EXPONENT= 5 - OPERATION_SQRT= 6 - OPERATION_LSHIFT= 7 - OPERATION_RSHIFT= 8 - OPERATION_SUBTRACT= 9 - OPERATION_ABS_VALUE= 10 - -class ComparatorProcessor: - OPERATION_EQ = 0 - OPERATION_NEQ = 1 - OPERATION_LT = 2 - OPERATION_LTE = 3 - OPERATION_GT = 4 - OPERATION_GTE = 5 - -class ThresholdProcessor: - MODE_ABSOLUTE= 0 - MODE_BINARY= 1 - -class TimeProcessor: - MODE_ABSOLUTE= 0 - MODE_DIFFERENTIAL= 1 - -class PassthroughProcessor: - MODE_ALL= 0 - MODE_CONDITIONAL= 1 - MODE_COUNT= 2 - -class DeltaProcessor: - MODE_ABSOLUTE= 0 - MODE_DIFFERENTIAL= 1 - MODE_BINARY= 2 - -class PulseProcessor: - OUTPUT_WIDTH= 0 - OUTPUT_AREA= 1 - OUTPUT_PEAK= 2 - -# Python wrapper for the MblMwDataCartesianFloat struct -class CartesianFloat(Structure): - _fields_= [ - ("x", c_float), - ("y", c_float), - ("z", c_float) - ] - - # taken from https://www.python.org/dev/peps/pep-0485/#proposed-implementation - def is_close(fst, snd): - return abs(fst - snd) <= max( 0.001 * max(abs(fst), abs(snd)), 0.0 ) - - def __eq__(self, other): - return CartesianFloat.is_close(self.x, other.x) and CartesianFloat.is_close(self.y, other.y) and \ - CartesianFloat.is_close(self.z, other.z) - - def __ne__(self, other): - return not self.__eq__(other) - - def __str__(self): - return "(%.3f, %.3f, %.3f)" % (self.x, self.y, self.z) - - def __deepcopy__(self, memo): - return CartesianFloat(x= self.x, y= self.y, z= self.z) - -# Python wrapper for the MblMwDataCartesianShort struct -class CartesianShort(Structure): - _fields_= [ - ("x", c_short), - ("y", c_short), - ("z", c_short) - ] - - def __eq__(self, other): - return (self.x == other.x) and (self.y == other.y) and (self.z == other.z) - - def __ne__(self, other): - return not self.__eq__(other) - - def __str__(self): - return "(%d, %d, %d)" % (self.x, self.y, self.z) - - def __deepcopy__(self, memo): - return CartesianFloat(x= self.x, y= self.y, z= self.z)