Hello! Welcome to a new series I like to call #MyoCraft. I’ll be coming at you once a week (every weekend) with a neat script, code snippet, or cool project built for the Myo armband. Sometimes it’ll be an awesome script that’s just a bit too raw for general use. Other times, we’ll have a useful technique or a bit of best practice. Or maybe it will require a custom hardware hack. Whatever! We’ve made some sweet things around Thalmic Labs that we’d like to show off, but you’ve been working on something that seems like it would be a good fit, let me know on Twitter at @thalmicdev, or at by email at MyoCraft@thalmic.com. We’d love to highlight all the great things our community has come up with.

Anyway, let’s get down to it. This week week I’ve got something based on a new feature we snuck into the latest version of Myo Script: Media Keys.

Here’s the script:

  
  


scriptId = 'com.jakechapeskie.media'

    minMyoConnectVersion ='0.8.1'  
    scriptDetailsUrl = 'https://github.com/JakeChapeskie/MyoScripts'  
    scriptTitle = 'Media Keys'

    ROLL_MOTION_THRESHOLD = 7 -- degrees  
    SLOW_MOVE_PERIOD = 20  
    rollReference=0  
    moveSince=0  
    enabled=false  
    myo.setLockingPolicy("standard")

    function onForegroundWindowChange(app, title)  
        return true
    end

    function getMyoRollDegrees()  
        local RollValue = math.deg(myo.getRoll())
        return RollValue
    end  
    function onUnlock()  
        enabled=false
    end  
    function degreeDiff(value, base)  
        local diff = value - base

        if diff > 180 then
            diff = diff - 360
        elseif diff < -180 then
            diff = diff + 360
        end

        return diff
    end  
    function conditionallySwapWave(pose)  
        if myo.getArm() == "left" then
            if pose == "waveIn" then
                pose = "waveOut"
            elseif pose == "waveOut" then
                pose = "waveIn"
            end
        end
        return pose
    end  
    function onPoseEdge(pose, edge)  
        pose=conditionallySwapWave(pose)
        local now = myo.getTimeMilliseconds()
        --Hold to activate
        if edge == "on" then
            if pose == "fist" then
                moveActive = edge == "on"
                rollReference = getMyoRollDegrees()
                moveSince = now
                enabled=true
            elseif pose =="waveIn" then
                myo.mediaKey("previous")
            elseif pose =="waveOut" then
                myo.mediaKey("next")
            elseif pose =="fingersSpread" then
                myo.mediaKey("play_pause")
            else
                enabled=false
            end
        end
    end

    function onPeriodic()  
        local now = myo.getTimeMilliseconds()
        if (myo.isUnlocked()) and enabled then
            local relativeRoll = degreeDiff(getMyoRollDegrees(), rollReference)
            if math.abs(relativeRoll)> ROLL_MOTION_THRESHOLD then
                if now - moveSince > SLOW_MOVE_PERIOD then
                    if relativeRoll>0 then
                        myo.mediaKey("volume_up")
                    else
                        myo.mediaKey("volume_down")
                    end    
                    moveSince = now
                end
            end
        end
    end 

The key is this new function: myo.mediaKey(keyName). It lets you trigger any of those special media keys some keyboards have right from Myo Script.

media-keys-resized

That means you could use your Myo armband to control ANY media application that listens for those keys! And it doesn’t have to be in the foreground!

That’s pretty sweet, but there is a slight hiccup. For a script to be active when the application it controls is not in the foreground, it basically needs to be active all the time. That’s this block here:

  
 


function onForegroundWindowChange(app, title)  
        return true
    end

To use this script, you need to make sure it’s on the BOTTOM of your application manager. It will start there, but it also needs to STAY THERE. The way Myo Connect works is that it asks each script in the Application Manager, from top to bottom, if it wants to be active or not. The first one that returns true gets it. Since this script always returns true, nothing below it could ever possibly become active.
So, any time you install a new connector you need to make sure you go in and move it up above this one or it won’t work. Obviously that’s not ideal, and we’re working on solutions, but for now that’s how it is. Don’t forget!

You can grab the completed script here.

That’s it for #MyoCraft this week! See you next Saturday!

Newsletter

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