Skip to content
PerlinWarp edited this page Oct 19, 2021 · 5 revisions

On Windows, do not run python programs inside of the Git Bash terminal. I recommend the new Windows Terminal

Serial Exceptions

 raise SerialException("could not open port {!r}: {!r}".format(self.portstr, ctypes.WinError()))
serial.serialutil.SerialException: could not open port 'COM3': PermissionError(13, 'Access is denied.', None, 5)

This is a Windows only problem where a serial port can only be accessed from one thread.

  • Make sure that no other programs are currently using this serial port. This includes Myo Connect.
  • If the Myo's bar light is on and you just exited a program that was connected to the Myo, you may need to reboot the Myo.
    Plug it into charge and then disconnect it.

If these 2 solutions did not work, it could be due to the code: A Myo object made can only be accessed inside the thread it was made in.

For example:

# ------------ Myo Setup ---------------
q = multiprocessing.Queue()

def worker(q):
	m = Myo(mode=emg_mode.PREPROCESSED)
	m.connect()

	def add_to_queue(emg, movement):
		q.put(emg)

	"""worker function"""
	while carryOn:
		m.run()
	print("Worker Stopped")

# -------- Main Program Loop -----------
p = multiprocessing.Process(target=worker, args=(q,))
p.start()
# Vibrate to know we connected okay
m.vibrate(1)

Will error on Windows, as m is being accessed in the main program loop but was made in the worker thread. To fix it we need to move m.vibrate(1) into the worker thread:

# ------------ Myo Setup ---------------
q = multiprocessing.Queue()

def worker(q):
	m = Myo(mode=emg_mode.PREPROCESSED)
	m.connect()

	def add_to_queue(emg, movement):
		q.put(emg)

	m.add_emg_handler(add_to_queue)

	def print_battery(bat):
		print("Battery level:", bat)

	m.add_battery_handler(print_battery)

	# Orange logo and bar LEDs
	m.set_leds([128, 0, 0], [128, 0, 0])
	# Vibrate to know we connected okay
	m.vibrate(1)

	"""worker function"""
	while carryOn:
		m.run()
	print("Worker Stopped")

# -------- Main Program Loop -----------
p = multiprocessing.Process(target=worker, args=(q,))
p.start()

The Myo sends data all the time, so there needs to be a thread listening to it all the time. The thread should just get data and put it in a queue so another thread can deal with it, so there shouldn't be much need to access m from multiple threads.

When making a game you might want to get the Myo to vibrate when you score, this can be solved by sending a message to the worker thread. See the multiprocessing docs for help on doing this.

Runtime Error

    raise RuntimeError('''
RuntimeError:
        An attempt has been made to start a new process before the
        current process has finished its bootstrapping phase.

        This probably means that you are not using fork to start your
        child processes and you have forgotten to use the proper idiom
        in the main module:

            if __name__ == '__main__':
                freeze_support()
                ...

        The "freeze_support()" line can be omitted if the program
        is not going to be frozen to produce an executable.

Make sure you start the worker process inside of if __name__ == "main":" e.g.

if __name__ == "__main__":
	p = multiprocessing.Process(target=worker, args=(q,))
	p.start()