North (formerly Thalmic Labs), the creator of the Myo armband, was acquired by Google in June 2020. Myo sales ended in October 2018 and Myo software, hardware and SDKs are no longer available or supported. Learn more.

#MyoCraft: EMG in the Bluetooth Protocol

#MyoCraft: EMG in the Bluetooth Protocol

For this #MyoCraft, I wanted to take the time to touch on something a bit different than usual. As you know, we published the Bluetooth protocol the Myo armband uses a while ago. A lot of developers have jumped in and started building implementations for new platforms, but a common stumbling block is the EMG data. I thought I'd take the time this week to explain how it actually works, to avoid any further confusion.


The Myo armband has 8 separate electromyography (EMG) sensors, which we use to read your muscles and figure out what your hand is doing. If you want to get the EMG data yourself, you may care about what reading corresponds to which sensor. Here's the order it comes in:

![EMG Sensors Order](

That's also the order if you get the EMG data through the calls in the SDK, incidentally.

Bluetooth Setup

EMG data is off by default (since it's quite bandwidth and battery intensive to stream). To turn it on, you have to (like all commands) write to the CommandCharacteristic, in this case setting the emg_mode of your myohw_command_set_mode_t to one of the three supported values: myohw_emg_mode_none, myohw_emg_mode_send_emg, or myohw_emg_mode_send_emg_raw. To enable EMG, you want myohw_emg_mode_send_emg. It's basically the same as myohw_emg_mode_send_emg_raw, except we've removed interference from nearby electrical signals, which can otherwise throw your data off quite a bit. myohw_emg_mode_none will turn EMG streaming back off (which will also happen automatically whenever the Myo armband is disconnected).

You can set the IMU parameter of myohw_command_set_mode_t to whatever you like, but it's worth nothing that if you've set emg_mode to myohw_emg_mode_send_emg_raw the classifier will be disabled (meaning no poses), since it depends on powerline interference being filtered out.

Once you have turned on EMG data, you can subscribe to each of the four EmgDataXCharacteristics. These are notify characteristics, not indicate, meaning there is no acknowledgement (in return, we get higher throughput). This means in a noisy environment it's possible to lose packets.

Emg Data Characteristics

Now we get to the meat of this article, and the issue that most people seem to run into: "Given that there are 8 sensor pods, why are there four EmgDataXCharacteristics that each give two arrays full of 8 int8_ts? That seems like way too much data."

The thing is, you can't send enough data over a single characteristic to get up to 200Hz. So we broke it up into four, and sent two sequential readings in each update. That means the way you interpret the data is like this:


There is no timestamp included with the data, but you don't really need it. The samples are read at a consistent rate (every 5ms), so you can figure out the time just based on what characteristic and array the data comes from. If a transmission gets lost, you'll just have a gap.

That's it! Let us know if you use the EMG data to make something cool, we're always looking for awesome projects to show off to the community. And if you open source an implementation of our Bluetooth protocol for a new platform, we'd love to feature it in The Lab.

Good luck, and happy coding!

You've successfully subscribed to The Lab!