2. Python 2.7

Welcome to the Python on Windows tutorial. Below you will be able to run some basic examples, in Windows 10 and Python 2.7, to interface with your MetaSensor.

You are expected to have at least a basic understanding of Python as a language. There are many amazing websites such as https://www.learnpython.org/ to teach you if you are new to Python.

The Python SDK itself is a wrapper around the C++ SDK, calling into the C++ code using the ctypes library. You will want to keep a reference to the ctype documentation and C++ SDK documentation handy.

2.1. Prerequsites

You should have completed the instructions in the previous section related to the Windows Installation.

We will be using the Git Bash terminal to run the Python examples below.

First, let’s check that you have Python 2.7 installed:

  1. Open Git CMD or Windows Command Prompt
  2. Run the command
>>> which python
_images/python-1.jpg

If Python is not installed, please go back to the previous section.

2.1.1. Install Pip

Note

You may already have pip installed (possibly by Visual Studio). Please check this using the command which pip and bypass this section if pip is already installed.

We use pip to install dependencies and the Matlab libraries. Pip is a package management system used to install and manage software packages written in Python.

  1. Download get-pip.py to a folder on your computer.
  2. Open a command prompt window and navigate to the folder containing get-pip.py.
  3. Then run python get-pip.py. This will install pip.
>>> python get-pip.py
_images/python-2.jpg
  1. Verify a successful installation by opening a command prompt window and navigating to your Python installation’s script directory (default is C:/Python27/Scripts or C:/Python27amd64/Scripts).
>>> which pip

Type pip freeze from this location to launch the Python interpreter.

>>> pip freeze
_images/python-3.jpg

pip freeze displays the version number of all modules installed in your Python non-standard library; On a fresh install, pip freeze will display little content.

  1. Check your pip version and make sure it is installed in the Script folder.
>>> pip -V
_images/python-24.jpg
  1. Don’t forget to make sure your PATH ENVIRONMENT VARIABLE is up to date with your Python path. You can consult the Windows Installation section for more details. See the previous section to learn more.

2.1.2. Upgrade Pip

It is essential that your pip be up to date. For good measure, run the commands below:

Warning

You may need to run this as sudo or administrator. In order to do this, right-click your shell and Run as administrator.

_images/python-0.jpg
>>> python -m pip install --upgrade pip
_images/python-4.jpg

2.1.3. Install MetaWear

MetaWear is available on Pip. This means you can run the command below to install the MetaWear Python library directly:

>>>  pip install metawear
_images/python-5.jpg

Please take a look at the official website for PyPi to learn more about the MetaWear package: https://pypi.org/project/metawear/

_images/python-12.jpg

2.1.4. Upgrade MetaWear

You may need to upgrade metawear. For good measure, always run:

>>> pip install metawear --upgrade
_images/python-30.jpg

2.1.5. Check Warble

Pip will install support packages (libraries) in the C:/Python27/Libsite-packages folder.

Now is a good time to check warble and metawear are correctly installed by navigating to the directory and checking what is installed:

_images/python-25.jpg

This can also be done with the previously used pip freeze command.

_images/python-26.jpg

2.1.6. Download Examples

Head over to our Python Github page: https://github.com/mbientlab/MetaWear-SDK-Python

_images/python-6.jpg

You can clone the repository or simply download as a ZIP file:

>>>  git clone https://github.com/mbientlab/MetaWear-SDK-Python.git
_images/python-7.jpg

Make sure the MetaWear-SDK-Cpp submodule is also downloaded. If it is not present, use the command git clone --recurse-submodules https://github.com/mbientlab/MetaWear-SDK-Python

2.2. Scan and Connect

This tutorial will take you through your first MetaWear Python App.

Note

Make sure you have a MetaWear device with you, fully-charged, and that you have that device’s MAC address handy.

We will ignore most of the items in the Github repository for now and instead we will focus on the examples folder. Head over to the examples folder:

_images/python-8.jpg

Using your favorite editor, take a look at the scan_connect.py example.

This python code will scan for nearby Bluetooth devices and print out a list of available devices. You can then choose a device you want to connect to:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
print("scanning for devices...")
devices = {}
def handler(result):
    devices[result.mac] = result.name

BleScanner.set_handler(handler)
BleScanner.start()

sleep(10.0)
BleScanner.stop()

i = 0
for address, name in six.iteritems(devices):
    print("[%d] %s (%s)" % (i, address, name))
    i+= 1

msg = "Select your device (-1 to rescan): "
selection = int(raw_input(msg) if platform.python_version_tuple()[0] == '2' else input(msg))

Run the code:

>>>  # usage: python scan_connect.py
>>>  python scan_connect.py
_images/python-9.jpg

Select the device you want to connect to. The MAC address for my favorite MetaSensor is D8:B5:11:21:96:06.

>>>  Select your device (-1 to rescan): 1

The code will then connect to this device for 5 seconds, retrieve device information, and disconnect.

_images/python-10.jpg

As you can see, your Windows machine connected to the MetaSensor using Bluetooth and retrieved some information about the devices such as the firmware version and the manufacturer name.

Congratulations, you ran your first Python script!

2.3. Dealing with Errors

2.3.1. Errors

If you run into errors, it means you missed an installation step.

  1. Go back to the begining of this tutorial and re-install everything carefully.
  2. Try restarting your Bluetooth adapter by disabling it under the Device Manager (or by un-plugging your Bluetooth dongle if applicable).
  3. Try reseting or firmware updating your MetaSensor using the Android or iOS MetaBase App. This solves 99% of problems! See the troubleshooting section.
  4. Always try running the scan_connect.py example first. It is simple and will make sure everything is working properly on your system.
  5. Upgrade pip and metawear. Make sure Visual Studio is up to date as well.

2.3.2. Missing Modules

If you are missing modules, simply install them using pip:

>>> pip install [module name]

2.3.3. Sudo and Administrator

Sudo is a program for Unix-like computer operating systems that allows users to run programs with the security privileges of another user, by default the superuser.

Some setup might require that you run your scripts using sudo. If so, simply add sudo to the beggining of your python command sudo python scan_connect.py.

On Windows, you may need to run your Git or Cmd shell as administrator.

2.3.4. Running Python Scripts

Be sure you are running out scripts from a command line or GUI that can interpret and run Python.

Warning

DO NOT USE Git Bash to run your Python scripts.

Use Git CMD or the Windows Command Prompt or another acceptable shell to run your Python scripts.

Git Bash may not allow inputs and therefore will fail:

_images/python-28.jpg

Git CMD can execute Python scripts:

_images/python-27.jpg

The Windows Command Prompt can execute Python if you have followed the tutorial properly:

_images/python-29.jpg

2.3.5. Virtual Machines (VMs)

If you are running in a virtual environment, you will need to take extra care to make sure the Bluetooth drivers and adapters are working in the VM before you do anything else.

For example, VirtualBox guest OS doesn’t recognize the Bluetooth adapter by default. There are many great tutorials to get this working like this one here.

_images/vm-0.png

Steps you can take:

  1. Disable Bluetooth Adapter on Host OS
  2. Launch Guest OS
  3. Enable Bluetooth Adapter on Host OS
  4. Enable Bluetooth Adapter in the usb device list (Guest OS): Devices->usb->check my device

You may also need to install the VirtualBox extension Pack or similar support software, see more information here.

MbientLab is not responsible for VM support. Please consult the forum for the appropriate VM software you are using if you run into issues.

2.3.6. Documentation

As our Python API is based on the CPP library, we recommend that you have two documents open:

  1. The CPP documentation: https://mbientlab.com/cppdocs/latest
  2. The CPP API reference: https://mbientlab.com/documents/metawear/cpp/latest

2.4. Blinking LED

The led.py example makes the LED on your MetaSensor blink a green color.

Note

For this example you can refer to the API documentation for LEDs here and the API references for the LED here.

Try it out by running:

>>>  python led.py D8:B5:11:21:96:06

This script connects to a specific MetaSensor by specifying the MAC address on the cmd line.

1
2
3
4
5
6
7
8
device = MetaWear(sys.argv[1])
device.connect()
print("Connected")

pattern= LedPattern(repeat_count= Const.LED_REPEAT_INDEFINITELY)
libmetawear.mbl_mw_led_load_preset_pattern(byref(pattern), LedPreset.SOLID)
libmetawear.mbl_mw_led_write_pattern(device.board, byref(pattern), LedColor.GREEN)
libmetawear.mbl_mw_led_play(device.board)

In this example we make use of the fundamental C libraries used by Python by referencing API calls for LED animations.

First, you will notice the import of the C bindings at the top of the file:

1
2
from mbientlab.metawear import MetaWear, libmetawear
from mbientlab.metawear.cbindings import *

Second you will notice a few API calls such as mbl_mw_led_load_preset_pattern, mbl_mw_led_write_pattern and mbl_mw_led_play.

So if we take a quick look, this line sets the LED to be a solid color:

1
libmetawear.mbl_mw_led_load_preset_pattern(byref(pattern), LedPreset.SOLID)

and this line sets the color:

1
libmetawear.mbl_mw_led_write_pattern(device.board, byref(pattern), LedColor.GREEN)

We could change the line to the following to set the LED color blue:

1
libmetawear.mbl_mw_led_write_pattern(device.board, byref(pattern), LedColor.BLUE)

When you run the script, the MetaSensor will light up green for a few seconds.

_images/python-11.jpg

2.5. Streaming Accelerometer

The stream_data.py example illustrates how to stream accelerometer data at 25Hz with 16G range from a single sensor.

Note

For this example you can refer to the API documentation for sensor data streaming here and the API references for sensor data streaming here.

>>>  python stream_data.py D8:B5:11:21:96:06
_images/python-13.jpg _images/python-14.jpg

2.6. Multiple Devices

The multi_device.py example illustrates how to work with multiple devices at the same time.

Note

For this example you can refer to the API documentation for sensor data streaming here and the API references for sensor data streaming here.

This time we run it on two devices by adding two MACs to the cmd line:

>>>  python stream_data.py D8:B5:11:21:96:06 F6:99:FD:A4:64:80
_images/python-15.jpg

As you can see, data streams from the two devices at the same time. Each device is uniquely identified using its MAC and a timestamp is also available (though it is not printed to the output).

_images/python-16.jpg

2.7. Data Fuser

The data_fuser.py example illustrates how to combine data signals together to push the boundaries of the Bluetooth throughput.

Note

For this example you can refer to the API documentation for the data fuser here and the API references for the data processor here.

In this example, we combine the gyroscope and the acceleromter data into one signal.

This is the best way to combine quaternion signals at 100Hz with accelerometer at 25Hz given that the Bluetooth low energy bandwith will be maxed out.

Now we run the example:

>>>  python data_fuser.py F9:B5:F9:81:3F:77
_images/python-31.jpg

As you can see, the gyro and acc data come in the same packet in “fused” mode.

2.8. Data Processor

The data_processor.py example illustrates how to stream accelerometer data that is averaged using the data processor average function.

Note

For this example you can refer to the API documentation for the data processor here and the API references for the data processor here.

In the average_create function, we take the accelerometer signal and we average 4 values together. This technique can also be used to downsample data.

Now we run the example:

>>>  python stream_data.py D8:B5:11:21:96:06

The example was modified to run for less than a second:

_images/python-17.jpg

2.9. Log Accelerometer

The log_acc.py example illustrates the logging functionality of the MetaSensor using accelerometer data.

Note

For this example you can refer to the API documentation for the logger here and the API references for the logger here.

Let’s run the script:

>>>  python log_acc.py E3:AD:97:B0:74:F8
_images/python-19.jpg

2.10. Log Temperature and Timer

The log_temp.py example illustrates how to log temperature data in the MetaSensor memory and retrieve it later.

Note

For this example you can refer to the API documentation for the timer here and events here.

Note

For this example you can refer to the API references for the logger here and events here.

The reason the accelerometer logging example is simpler than its temperature logging counterpart is thanks to the digital features of the BOSCH BMI160 sensor that allow us to set the sampling frequency instead of relying on the event and timer modules.

Since the thermistor is an analog sensor, it does not come with features like the sampling frequency register of the digital accelerometer.

Instead, we use the internal timer feature of the MetaSensor to set the frequency (time interval) at which a new reading from the temperature sensor will occur. We use the event feature of the MetaSensor to create a trigger to read the analog temperature sensors upon timer expiration.

Let’s go ahead and run the example:

>>>  python log_temp.py E3:AD:97:B0:74:F8
_images/python-20.jpg

2.11. Events and the Data Processor

The acc_threshold_detector.py example illustrates a number of features including processor filter chains and events.

Note

For this example you can refer to the API documentation for the data processor here and events here.

Note

For this example you can refer to the API references for the data processor here and events here.

The idea behind this script is to create a shock detector by combining x, y, z accelerometer data using an averager and root mean square and then using a threshold detector.

This is a great way to detect potholes when the sensor is placed in a car.

  1. Setup the accelerometer:
1
2
3
4
5
libmetawear.mbl_mw_acc_bmi160_set_odr(d.board, AccBmi160Odr._50Hz)
libmetawear.mbl_mw_acc_set_range(d.board, 2.0)
libmetawear.mbl_mw_acc_write_acceleration_config(d.board)

acc_signal = libmetawear.mbl_mw_acc_get_acceleration_data_signal(d.board)
  1. Create an RMS filter of the X,Y,Z data from the accelerometer (combining the data):
1
rms = create_voidp(lambda fn: libmetawear.mbl_mw_dataprocessor_rms_create(acc_signal, None,  fn), "RMS")
  1. Average the data (to remove noise and error):
1
avg = create_voidp(lambda fn: libmetawear.mbl_mw_dataprocessor_average_create(rms, 8, None, fn), "averager")
  1. Set up a threshold detector for value = 1 (detecting a shock):
1
ths = create_voidp(lambda fn: libmetawear.mbl_mw_dataprocessor_threshold_create(avg, ThresholdMode.BINARY, 1.0, 0.0, None, fn), "threshold detector")
  1. Log the shock signal in memory:
1
ths_logger = create_voidp(lambda fn: libmetawear.mbl_mw_datasignal_log(ths, None, fn), "threshold logger")
  1. Start the process:
1
2
3
libmetawear.mbl_mw_acc_enable_acceleration_sampling(d.board)
libmetawear.mbl_mw_acc_start(d.board)
libmetawear.mbl_mw_logging_start(d.board, 0)

The rest is straightforward; the script waits 10 seconds before cleaning up the logger, stopping the accelerometer, downloading the data from memory and resetting the device.

Once item to note here is that the average has to be reset. This is done using an event in which the event resets the averager:

1
2
3
libmetawear.mbl_mw_event_record_commands(avg)
libmetawear.mbl_mw_dataprocessor_average_reset(avg)
end_event_record(avg)

Let’s go ahead and run the example:

>>>  python acc_threshold_detector.py E3:AD:97:B0:74:F8
_images/python-21.jpg

2.12. Macros

The macro_setup.py and macro_remove.py example showcase the macro system which enables users to “permanently” command the MetaSensor.

A macro is a command that stays in the memory of the MetaSensor and will continue to operate until the MetaSensor is either firmware updated or the macros are erased and the board is reset.

Note

For this example you can refer to the API documentation for macros here and the API references for macros here.

The macro_setup.py script is similar to the acc_threshold_detector.py script in the sense that it chains filters. However, it does so in a macro which means the MetaSensor will perform the shock detection even if the sensor loses power or is reset.

Additionally, the chain includes an event that uses the LED so that when a shock is detected, the LED blinks blue.

Let’s go ahead and run the example:

>>>  python macro_setup.py E3:AD:97:B0:74:F8
_images/python-22.jpg

If your MetaSensor sustains a small shock, the LED will blink blue; try it out!

When we are done, use the clean-up script to remove the macro and reset the MetaSensor:

>>>  python macro_setup.py E3:AD:97:B0:74:F8
_images/python-23.jpg

2.13. Logging Anonymously

The anonymous_datasignal.py example illustrates how to retrieve data from the sensors memory when the log was started by another device.

Note

For this example you can refer to the API documentation for anonymous signals here and the API references for anonymous signals here.

First run the MetaBase App on any device such as your iPhone and set the device D8:B5:11:21:96:06 to start logging data (any data, any frequency).

In this example, I used the MetaBase App on an iPhone 8 to log Ambient Light at 0.5Hz.

I waited a few minutes, then I ran the command below to download the data on the Windows machine:

>>>  python anonymous_datasignal.py D8:B5:11:21:96:06
_images/python-18.jpg

2.14. Next steps

Check out a few more examples in the folder and read through them. Then go and build your own Python script!

Please read our C docs to learn about all of the capabilities of the MetaSensors: https://mbientlab.com/cppdocs/latest/index.html