# # 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()
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