Myo with Python

Welcome to our tutorial on connecting Myo to Python and subsequently reading the data from the bracelet. By the end of this tutorial, you will be able to connect the armband read and plot the data.

This tutorial is based on the code from this repository.

  1. Download Myo SDK and save it in a chosen location. You can download it from Here
  2. In order for the SDK to be visible by the system you might need to ass it to the system path
    • For Windows:
      • Open Edit the system environment variables
      • Navigate to Environment variables
      • On the upper window, select Path and press edit
      • Then select browse and navigate to folder …\myo-sdk-win-0.9.0\bin
      • restart your PC
  3. Verify that the bracelet is connected using Myo Connect app
  4. In terminal use pip to install the necessary library pip install 'myo-python>=1.0.0'
    • In case you have Conda installed, and the command fails, to specify that pure Python should run the line you can use:

python -m pip install 'myo-python>=1.0.0'

Now, the set-up for the bracelet is complete, and we can start with coding. The section focuses purely on connecting the bracelet. The second one shows how to read, save and plot the obtained data.

The first script is very simple: it verifies whether a bracelet has been connected. If that is the case, print the name of the device, and the bracelet vibrates. Otherwise, a message indicating that no Myo device was connected is printed.

# Import the Myo library
import myo
 
 
# Create Listener class that inherits from myo.DeviceListener
class Listener(myo.DeviceListener):
    # Method triggers on when the Myo is paired
    def on_paired(self, event):
        # Print message with the device name
        print("Hello, {}!".format(event.device_name))
        # Trigger short vibration on the bracelet
        event.device.vibrate(myo.VibrationType.short)
 
    # Method triggers when Myo is not connected
    def on_unpaired(self, event):
        print("No paired device present")
        return False  # Stop the hub
 
 
if __name__ == '__main__':
    # Initialize the Myo library, by specifying the path to the SDK
    myo.init(sdk_path='path to ../myo-sdk-win-0.9.0')
    # Create a hub to manage Myo devices
    hub = myo.Hub()
    # Create instance of the Listener class
    listener = Listener()
    # Start an infinite loop to run the hub with the specified listener
    while hub.run(listener.on_event, 500):
        pass

The following script connects to the bracelet, waits till the pose Fist is detected and then starts reading and storing the data from the bracelet in csv file. Upon detecting Fingers spread the data is saved, a plot is produced, and the program terminates.

The aim of this code is to showcase all on_something functions that can be used to record data, as well as show how pose detection (for standard poses) can be implemented in Python.

# imports for time myo, time interval, saving and plotting data
import myo
from myo.utils import TimeInterval
import csv
import matplotlib.pyplot as plt
 
 
class Listener(myo.DeviceListener):
 
    def __init__(self):
        # the time in interval is in seconds
        self.interval = TimeInterval(None, 0.05)
        # define variables for saving the data
        self.orientation_data = []
        self.emg_data = []
        self.rssi = None
 
    def on_connected(self, event):
        # Request the signal strength from the device
        event.device.request_rssi()
        print("Hello, {}!".format(event.device_name))
        # Enable streaming the emg values
        event.device.stream_emg(True)
 
    # If received signal strength changes print information about it
    def on_rssi(self, event):
        self.rssi = event.rssi
        print("received signal strength = {}".format(self.rssi))
 
    def on_emg(self, event):
        # Save only after the interval passed
        if not self.interval.check_and_reset():
            return
        self.emg_data.append(event.emg)
 
    def on_orientation(self, event):
        if not self.interval.check_and_reset():
            return
        self.orientation_data.append(event.orientation)
 
    def save_emg_to_csv(self, filename):
        with open(filename, 'w', newline='') as csvfile:
            writer = csv.writer(csvfile)
            writer.writerows(self.emg_data)
        print(f'Data saved to {filename}.')
 
    def save_orientation_to_csv(self, filename):
        with open(filename, 'w', newline='') as csvfile:
            # make a header for the csv file
            fieldnames = ['w', 'x', 'y', 'z']
            writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
            writer.writeheader()
            for row in self.orientation_data:
                writer.writerow({'w': row[0], 'x': row[1], 'y': row[2], 'z': row[3]})
        print(f'Data saved to {filename}.')
 
    def plot_emg_data(self):
        fig, axs = plt.subplots(8, 1, figsize=(10, 20), sharex=True)
        fig.suptitle('EMG Data')
        # plot 8 plots: each for every sensor
        for i in range(8):
            axs[i].plot([sample[i] for sample in self.emg_data])
            axs[i].set_ylabel(f'Channel {i + 1}')
 
        plt.tight_layout()
        plt.subplots_adjust(top=0.95)
        plt.show()
 
 
if __name__ == '__main__':
    myo.init()
    hub = myo.Hub()
    listener = Listener()
    # As long as the program runs collect data
    # When the program is stopped collect the data and plot emg data
    try:
        print("Collecting data. Please perform gestures...")
        while hub.run(listener.on_event, 500):
            pass
    except KeyboardInterrupt:
        pass
    finally:
        hub.stop()
        # Save the data to a CSV file
        listener.save_emg_to_csv('csv/myo_emg_data.csv')
        listener.save_orientation_to_csv('csv/myo_orient_data.csv')
 
        # Create a plot
        listener.plot_emg_data()

In this tutorial, we covered connecting Myo using Python and learned how to read and plot the data from the bracelet. We hope this tutorial was helpful and that you are now able to collect data from Myo armband. If you have any questions or feedback, please feel free to reach out to us. Happy learning!