Esempio n. 1
0
#
# Copyright (c) 2018 Matthias Gazzari
#
# Licensed under the MIT license. See the LICENSE file for details.
#

import argparse
from myo_raw import MyoRaw

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('--tty',
                   default=None,
                   help='The Myo dongle device (autodetected if omitted)')
group.add_argument('--native',
                   default=False,
                   action='store_true',
                   help='Use a native Bluetooth stack')
parser.add_argument(
    '--mac',
    default=None,
    help='The Myo MAC address (arbitrarily detected if omitted)')
args = parser.parse_args()

myo = MyoRaw(args.tty, args.native, args.mac)
myo.deep_sleep()
Esempio n. 2
0
class Myo():
    def __init__(self, stream, tty, native, mac):
        # Instantiate
        self.myo = MyoRaw(tty, native, mac)
        self.stream = stream

        self.recording = False
        self.recording_type = self.init_recording()

        # Recording
        self.emg_file = None
        self.emg_writer = None

        # Setup
        self.setup()

    def close(self):
        self.myo.disconnect()
        self.record(False)

    def setup(self):
        # Add handles to process EMG and battery level data
        self.myo.add_handler(DataCategory.EMG, self.handle_emg)
        self.myo.add_handler(DataCategory.BATTERY, self.handle_battery)

        # Subscribe to all data services in full RAW mode (200 Hz)
        self.myo.subscribe(EMGMode.RAW)

        # Disable sleep to a void disconnects while retrieving data
        self.myo.set_sleep_mode(1)

        # Vibrate to signalise a successful setup
        # myo.vibrate(1)

    def run(self):
        self.myo.run(1)

    def disconnect(self):
        self.myo.disconnect()

    def sleep(self):
        self.myo.deep_sleep()

    def handle_emg(self, timestamp, emg, moving, characteristic_num):
        emg = list(emg)
        _, ca_data, _ = self.stream.plot(emg, recording=self.recording)

        record_data = ca_data if len(ca_data) > 0 else emg

        if self.recording:
            csv_data = [timestamp]
            csv_data.extend(record_data)
            try:
                self.emg_writer.writerow(csv_data)
            except AttributeError:
                print("Error! Unable to write to CSV!")

        if VERBOSE:
            print(f"[myo] {self.recording_type}: {timestamp}, {record_data}")

    def handle_battery(self, timestamp, battery_level):
        if battery_level < 5:
            self.myo.set_leds([255, 0, 0], [255, 0, 0])  # red logo, red bar
        else:
            self.myo.set_leds([128, 128, 255],
                              [128, 128, 255])  # purple logo, purple bar

        if VERBOSE:
            print(f"[myo] battery level: {timestamp}, {battery_level}")

    def init_recording(self):
        if self.stream.pca is not None:
            return "pca"
        elif self.stream.ica is not None:
            return "ica"
        return "raw"

    def record(self, state=False, toggle=False):
        if toggle:
            recording = not self.recording
        else:
            recording = state

        if recording:
            filename = f"recordings/{self.recording_type}/{time.strftime('%Y%m%d-%H%M%S')}.csv"
            os.makedirs(os.path.dirname(filename), exist_ok=True)
            self.emg_file = open(filename, "w", newline="")
            self.emg_writer = csv.writer(self.emg_file,
                                         csv.unix_dialect,
                                         quoting=csv.QUOTE_MINIMAL)
            if self.recording_type == "raw":
                self.emg_writer.writerow(CSV_HEADER_EMG)
            else:
                self.emg_writer.writerow(
                    CSV_HEADER_CA[:self.stream.ca_components + 1])
        elif self.emg_file is not None:
            self.emg_file.close()
            self.emg_file = None
            self.emg_writer = None

        self.recording = recording