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.

Basics

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:

EmgData0Characteristic  
    Sample1
    Sample2
EmgData1Characteristic  
    Sample3
    Sample4
EmgData2Characteristic  
    Sample5
    Sample6
EmgData3Characteristic  
    Sample7
    Sample8
EmgData0Characteristic  
    Sample9
    Sample10
etc  

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!

Newsletter

Enter your email address and get all latest content delivered to your inbox every now and then.