(30 gadget day 8) 你爱我有几分 — Mindwave mobile

Mindwave EEG

Mindwave mobile EEG是一个一直以来我觉得Dev friendly做的最好的产品。
虽然开发起来依然不如Estimote,MYO之类的新Gadget那么方便,带maven带gradle,但就凭这么多年,当年的代码在android 5.0上依然可以跑,就足以欣喜啦。

那究竟它可以做什么?EEG是啥我就不说了,见Wiki。Mindwave mobile提供的SDK基于基础的alpha,beta数据,提供更有价值的注意力,冷静度,甚至眨眼的数据。当然,alpha,beta也是可以通过SDK获取的原始数据。

下面是官方应用的截图。
图片描述

client

这东西的开发很简单,尤其是android端。下载官方的SDK,把jar扔到你的项目里,就可以写代码啦。代码也很简单,拿到蓝牙Adapter,设置一个处理事件的Handler,连上设备。

    btAdapter = BluetoothAdapter.getDefaultAdapter();
    if (btAdapter != null) {
        tgDevice = new TGDevice(btAdapter, handler);
        tgDevice.connect(true);
    }

在发生了连接事件以后,启动设备以获取各种类型的脑波数据。除了设备状态转变以外,其他数据就都是业务数据了。其中也有两类:设备本身的数据质量,数据本身。数据质量里有一种很重要的MSG_POOR_SIGNAL,用来表示当前信号质量,这个数据主要用来描述EEG和大脑之间的接触良好成都。

private final Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        if (msg.what == TGDevice.MSG_STATE_CHANGE) {
            switch (msg.arg1) {
                case TGDevice.STATE_CONNECTED:
                    Log.i(TAG, "connected");
                    tgDevice.start();
                    break;
                ...
        } else {
            switch (msg.what) {
                    case TGDevice.MSG_POOR_SIGNAL:
                        signalTextView.setText(String.valueOf(100 - msg.arg1));
                    case TGDevice.MSG_ATTENTION:
                        Log.v(TAG, "Attention: " + msg.arg1);
                    ...

        }

你爱我有几分

前几天听到一个笑话:某工程师的妹子问他“你爱我有几分?”,答曰“8.5分”,“你爱你前女友几分?”,答曰“9分”。

但不说情商为何物,只缘分数还有小数点。不过从科学角度,我们倒是可以把注意力当做一种衡量标准。比如某PM问用户“你爱我们产品有几分?”,这时,用户的注意力就可以当做一种比较“本质”的回答。

Attention driven design

所以也许,用户的大脑状态可以是另外一种产品设计的基础。例如,我希望用户看到我的产品之后两分钟内都能保持高度注意力,那就可以用这样的技术来测试,甚至在产品设计阶段做简单的用户调研。

比如下面的图是我在写程序时候的注意力分布图。如果采用WakaTime类似的技术记录下我所有在IDE里的操作,就能够分析出IDE里每个功能的使用对应我的注意力,从而对功能设计作出调整。

图片描述

当然,根据每一条代码对应的注意力,也许就能作为代码检查的另外一种依据。“糊涂的代码”是个认真的说法。

Mindwave in cloud

作为QS的支持者,我当然希望我的所有数据都能数据化并保存下来。Mindwave mobile给我提供了很大的便利,很容易的将我简单的脑波数据保存下来。

具体的用处嘛,既然Apple watch都出了ResearchKit,就不用解释啦~但另一个可能的用处,也许就是我可以“出卖”我的数据。比如A网站是个codeshool类的产品,产品想知道某些教学视频到底做的好不好,有没有趣味,作为真实用户的我就可以根据需求用我真实的,具有严格时间戳的脑波数据来换取一部分好处。

我管它叫Cloudmind,目前是基于Leancloud+chartjs,可以持续积累数据。但由于没啥内容外加代码太惨,暂时就不扔出来啦。

关于这个功能我是认真的。所以,如果有哪个产品想获得我使用时的脑波数据以用于产品设计,请联系我哈~

最后,来看看我眨眼的样子:)

图片描述

图片描述

(30 gadget day 7) 姑娘,请问您的相位是多少 - SmartScope

今天嘛…本来想写structure sensor的,结果发现SDK超难用。然后想写Muse EEG,结果发现Muse的SDK需要把数据从Mac proxy过去才能用。妈蛋,你们SDK做这么烂怎么跟Mindwave拼…

最后只得挖出SmartScope。官网逛了一圈,唯一的感觉就是,这产品要挂了。完全没有人维护的社区,基本没功能的Demo app,据说ship产品以后就开源的github账号拥有0个repo。anyway,有啥东西可以用示波器来玩呢…

好吧,事先提醒下,今天没代码…

SmartScope

SmartScope当年在kickstart上众筹的时候,就让我一见倾心买了连接ipad的版本。结果几个月之后才发现他们一直在发一个mail催我补缴运费,我一直没理。好,货到了,发现ipad的连接线却没有…就这样抵运费了,真的好么…它就长这样。

图片描述

Foc.us

说到电流,立刻就想到了Foc.us,那个可以把电流注入到你大脑里的玩意儿。那就用这玩意儿看看它呗。打开Foc.us,连通,开始放电。

图片描述
图片描述

选择个正弦波。

图片描述

看这个波的样子。

图片描述

看起来只要把频率调一调就能看到一条漂亮的正弦波啦。看ze里,看ze里!

图片描述

所以结论就是…foc.us说的是实话…

naked iBeacon

好吧,文章这么短不好。我们再找个有电路的玩意儿~手头有几个没电了的Estimote,来妞儿,打开让我看看!嗯,正好有新的CR2450,来,复活吧!

图片描述

但问题来了…哪里有inspect的地方呢…好不容易找到四个触点。好吧,就让我们以猜公母结束吧,猜猜哪两个是一对儿~打开一条Math线,设置为A-B。捅来捅去吧。math线接近0的就是同一边儿的。好吧,知道你们也不在乎…

图片描述

知道为啥我不介绍其他类似decoder的功能么?因为他们还在coming soon!!!还在coming soon…

晚安~又混过去一天!

(30 gadget day 6) 主人,早上好 - iBeacon

咳咳,今天遍寻各处都想不到写个啥。于是只能假装我没玩过这个“新鲜”的gadget啦——iBeacon!

问候

办公室人少,每次去的时候都略显孤单。于是决定写一个跟自己打招呼的玩意儿,让我每次进门的时候都能收到一个“亲切的问候”,比如。

图片描述

iBeacon with Web

据说微信的JS SDK要开放iBeacon的部分了。所以嘛,先prototype一下咋用js来玩ibeacon。我先猜测下哈,微信的SDK是估计是把native的ibeacon数据通过微信转换以后bridge进H5应用里,也就是假设某个ibeacon对应的是吉野家某个门店的大门口,然后用户无论通过何种入口(摇一摇,扫二维码等),进入了一个开发者设定的H5页面里。在这个页面通过类似wx.beacons接口拿到了周围的ibeacon数据。这种数据应该是某个url,某个商家,某个门店,某个位置这样的,而不是类似UUID,major,minor这样的标准ibeacon id。

我想做的更简单一点。native app拿ibeacon数据,把数据同步给服务器,服务器确定是否要触发事件,如果需要则发给H5应用。这样的问题就是,要总连着网。so what,嗯。

iBeacon检测

家里的Estimote iBeacon都没了,只能用不熟悉的Kontakt的啦!他们长这样。

图片描述

去官网看文档,跳到Android的GetStart,直接搜“download”,果断看到“Go to the Kontakt.io Android SDK 1.0.5 on GitHub”,看到两个jar,直觉都当下来,回来看文档,都拷进去就好。

然后肯定就是加Permission啦,文档搜一搜,发现相比Estimote,Kontakt对权限分的更细一些,如果你不用他的云服务就不用加Internet权限。还有不大明白为啥针对萝莉炮要再加个Service,这都不能检测下么。

<service android:name="com.kontakt.sdk.android.manager.BeaconService" android:exported="false"/>
<service android:name="com.kontakt.sdk.android.manager.BeaconServiceL" android:exported="false"/>

然后就是看具体怎么用啦。无非也就是创建个BeaconManager,收各种回调哈。

        beaconManager = BeaconManager.newInstance(this);
        beaconManager.setMonitorPeriod(MonitorPeriod.MINIMAL);
        beaconManager.setForceScanConfiguration(ForceScanConfiguration.DEFAULT);
        beaconManager.registerMonitoringListener(new BeaconManager.MonitoringListener() {
            @Override
            public void onMonitorStart() {}

            @Override
            public void onMonitorStop() {}

            @Override
            public void onBeaconsUpdated(final Region region, final List<Beacon> beacons) {}

            @Override
            public void onBeaconAppeared(final Region region, final Beacon beacon) {}

这里文档有点问题,新的1.0.5的SDK里已经不是Beacon这个类而变成BeaconDevice了。connect函数里也有不一致的地方。startMonitoring的参数要清空就好了。不然就自己弄个Set,找个Everywhere的Region装进去。

    private void connect() {
        try {
            beaconManager.connect(new OnServiceBoundListener() {
                @Override
                public void onServiceBound() {
                    try {
                        beaconManager.startMonitoring();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            });
        } catch (RemoteException e) {
            throw new IllegalStateException(e);
        }
    }

数据中心

我一直希望把自己的各种数据尽量实时的扔到云里去,这样几十年以后就能知道现在的我是怎么活的啦。这里我也不希望搞个啥local server之类的,直接上云服务吧。以前介绍过PubNub就是个和Firebase类似的实时数据库。客户端和服务器端可以用超高抽象的handler来操纵数据。

这次我用PubNub来实现。GetStart就跳过了。看名字就知道这玩意儿是在做PubSub类似的技术。所以程序也很简单,一端Pub一端Sub。既然是手机端发现iBeacon那肯定是手机端来Pub喽。服务端就把事先知道的iBeacon都Sub上就好了。channel就用每个beacon的uuid:major:minor合起来hash一下哈。

Pubnub pubnub = new Pubnub("xxyyzz", "status");

try {
  pubnub.subscribe("hello_world", new Callback() {
...
// 也可以直接抄一下昨天hue的api body,挺像的
pubnub.publish("xxyyzz", "{"status":"on"}" , callback);

我来啦~

前端页面引入PubNub的库,每个设备都显示自己对应的页面,然后就Sub着就好啦。一旦有消息进来,就根据status选择性display那张图哈。

困死了困死了>.<

另外,求各种带API的硬件Gadget…库存快枯竭了…

EOF

(30 gadget day 5) 那棵灯 – HueMyo party

Philips的hue灯泡算是智能灯泡的鼻祖了,这次就来玩玩这个哈。

meethue

meethue.com是hue的门户啦,有各种的使用说明。开发者的入口在哪呢…找了半天发现右边有竖着的developer…

图片描述

好吧,进去以后直奔Get started。大概扫一圈以后发现这个hue的bridge设计的还真不错,直接通过http就能访问到api的测试后台。

图片描述

  • 认证
    只要改url和body就能直接控制灯泡。然后发现都是unauthorized。于是回来看文档,发现需要按一下bridge的button,然后立刻发个下面的请求就能认证上。之后的所有请求就都ok了。以后就可以用/api/newdeveloper/lights/1/state来控制这个id为1的灯泡啦。很标准的JSON RESTful API,设计的不错!
    不过这个不意味着我跑到任何一家有hue的地方,按一下按钮执行一个程序以后就可以躲门口随便玩他家的灯泡了…
POST http://<bridge ip address>/api
{"devicetype":"test user","username":"newdeveloper"}
  • 修改灯泡状态
    每个灯泡都有一个url作为它的endpoint,可以对它肆意GET POST PUT。比如让它打开就curl一下。色温(sat)亮度(bri)和颜色(hue)控制起来超容易!
url -X PUT -H 'Content-Type: application/json' -d '{"on":false, "sat":255, "bri":255,"hue":10000}' http://192.168.31.xxx/api/newdeveloper/lights/1/state

MYO控制HUE

哈,MYO又出现了!上次只拿了pose的数据,这次我想让灯泡跟着挥手变换颜色,那就要获得当前手臂的角度啦。代码的区别只是多加个回调就好啦。能拿到一个4维的数据。xyzw。

        @Override
        public void onOrientationData(Myo myo, long timestamp, Quaternion rotation) {
            ((TextView) findViewById(R.id.hello)).setText(
                    "Z:" + rotation.z() + " W:" + rotation.w() + " X:" + rotation.x() + " Y:" + rotation.y());

        }

通过观察发现挥手的时候变换的很多的是w轴,而且右手挥动的过程正好是-0.5到0.5的过程。好啦,现在把这个数据随时记录下来,每秒钟发个PUT过去改灯泡的状态。咱就用OkHttp搞好啦,类似这样。

    String updateHue(int bright, int hue) throws IOException {
        OkHttpClient client = new OkHttpClient();
        RequestBody body = RequestBody.create(JSON,
                "{"on":true,"bri":150}");
        Request request = new Request.Builder()
                .url("http://192.168.31.xxx/api/newdeveloper/lights/1/state")
                .post(body)
                .build();
        Response response = client.newCall(request).execute();
        return response.body().string();
    }

Party!

好啦,就这样!

图片描述

Party呀

(30 gadget day 4) 那边有把吉他,所以 - MYO (2)

今天我终于把MYO搞好了。之前无论如何都Update不动,搜了下发现可以用“直连线”强制升级。Anyway,让我们开始想想这玩意儿能玩啥吧!

又到了这个点儿,家里又只剩下YubiKey等超弱智设备陪着我。就只能打打擦边球了,用手机来充当Gadget吧…

看了一圈MYO的market,发现基本之前想的一些场景都有人实现了。比如用手势来操作chrome,操作鼠标,地图,游戏,甚至trello。

好,吧,惆怅了,写个啥呢…

有把吉他

图片描述

抬望眼,看到有把吉他在远处蓬头垢面的看着我。再看我…再看我就拿你开Live!

嗯,万事具备,只差我不会弹,and没有粉丝了…

好,吧,那写个粉丝呗。请想象一下…“爷弹了个和弦,观众就掌声雷动!” O.O >..<||

图片描述

(30 gadget day 3) 绝对的小个子-littlebits cloudbit

做技术启蒙教育的可能都听说过littlebits,一堆小小的工作单元,通过磁力轻松的连接起来,就可以实现一些简单的电路逻辑。比如,把电源-按键-LED串在一起,就能实现一个“按键让灯亮”的小电路,也不用担心电路接错了会烧坏元件啥的。

图片描述

逗我玩么…

当然,爷会只玩这么白痴的东西么…如果有孩子了的话还是有可能的…转个推

@Tomy 偶然发现一个程序猿的各种 SNS 帐号都在2012年之后停止了更新,博客、微博、Twitter、V2EX 都没有了音讯,就连 Github 2013年后都没再提交代码了!!怀着恐慌的心情 Google 了下 ID,发现了他在2014年海淘了几袋奶粉的晒单……心情的跌宕起伏,是为记

好吧,我承认这是混字数。你走开!我之所以买了一套littlebits呢,就是看中了新推出的cloudbits——一个可以联网控制的元件。

图片描述
图片描述

Cloudbit

玩IFTTT的同学应该都注意到有一些菜谱里面出现了这个小笑脸,这玩意儿就是cloudbits。

图片描述

简单的说,Cloudbits就是一个可以联网控制的littlebits组件,而就是这么简单的设计,给littlebits带来了无限的可能性。littlebits官网首页的展示视频里有一个小情景:猫猫按了一下littlebits的按钮,主人手机就蹦出来一个“feed me”,主人点一下feed,猫粮就掉下来了,这个情景的实现就完全倚赖cloudbits的推出。

Cloudbit get started

setup的过程如下:

  1. 登陆Cloudbit控制后台
  2. 按指示连接到Cloudbit的wifi
  3. 帮助Cloudbit登陆本地wifi
  4. 切换回本地wifi,等待cloudbit的灯从绿色闪烁变为绿色持续(这个过程我搞了好几次,可以试试拔掉Cloudbit再插上,TroubleShotting里也有一些有用的东西)

p.s.
悲剧的是我发现我这个单元的reset按键坏了,基本可以判断总是按接通状态。于是…就总是处于reset,reset的循环中…最后就只能把那reset键给拆了…

图片描述

反正最终的结果就是这样

图片描述

这个大按钮的作用呢,就是让这个Cloudbit想外发送数据(其实就是提供电压,还可以调节输出电压的数值,当然是从0到100这样的方式)。

Develop with Cloudbit

具体的玩法就不说啦,里面核心的就是如何将Cloudbit的输入输出与网络服务结合起来。先看API文档吧,没想到API已经到v2版本了。

Auth

littleBits的API支持标准的OAuth2,DeviceID和Token从后台就能看到。用这两个值就可以完成认证。

图片描述

Endpoints

                                ---Responds---
                              OAuth   HTTP
path                          Scope   Code  Payload ◆       Make LB Cloud...
----                          -----   ----  ---------       ----------------
/devices
  GET                         read    200   [<devices>]    return a list of the user’s devices

    /{device_id}
      GET                     read    200   <device>       return device model
      PUT                     admin   200   <device>       update device model
      POST                    admin   201   <device>       activate device, is then associated to the user
      DELETE                  admin   200   <device>       deactivate device, is then associated to no body

          /output
            POST              write   200                  output some voltage on the given device

/subscriptions
  GET                         read    200   [<subs>]       return device's subscriptions
  POST                        read    201                  publish given device events to given endpoint
  DELETE                      read    200                  stop publishing given device events to a given endpoint

赞这个“文档”,极简又足够清楚。先拿一下这设备的信息。

curl -i -XGET -H "Authorization: Bearer e352c8d9f7a9103c59xxxxxxxcdb6c5b28fbd6c2c438936xxx" -H "Accept: application/vnd.littlebits.v2+json" https://api-http.littlebitscloud.cc/devices/00exxxxxxx39

response

{"label":"office","id":"00exxxxxxx39","user_id":35515,"is_connected":true,"ap":{"ssid":"senz_xiaomi","mac":"8C:BE:BE:28:15:6B","strength":"100","server_id":"7yY9Dniw","socket_id":"7JeMsZ2w"},"subscriptions":[],"subscribers":[],"input_interval_ms":750}

看起来没啥用呢…再回来看Doc,output的部分看起来容易用哈。

curl -i -XPOST -H "Authorization: Bearer e352c8xxxxxxfbd6c2c438936e0b97cebb8b7" -H "Accept: application/vnd.littlebits.v2+json" https://api-http.littlebitscloud.cc/devices/00exxxx39/output -d percent=50 -d duration_ms=1000

结果呢,就是灯亮了1秒钟!宏大吧!>.<

(30 gadget day 2) 最简单也最复杂的Gadget - YubiKey

晚上翻出myo准备继续写的时候,被提示需要升级,于是就update呗。于是…就update了一个小时,现在还在转…

图片描述

其他设备都在办公室,于是智能在家里翻箱倒柜…先是翻出了Chromecast,拿在手里很开心的开始看Cast文档。看了一会迫不及待的拿出来试。于是…

图片描述

找了一圈基本确认Cast决定今天不见我以后,继续寻觅下一个下手的目标。于是找到了这只TI的“智能手表”。好吧,谁还认识它?

图片描述
图片描述

这次我谨慎审视了下,自然的决定了放弃。因为很显然我基本12个小时内找不到它的专用充电器…好~吧~于是最后翻到了它:YubiKey。

图片描述

YubiKey呢,是个99.999%的人都不会有兴趣的Gadget,而且剩下的0.001%里顶多按过两三次以后就扔那了(><)

一次一密(OTP)

一次一密是一种简单粗暴有效的加密方式。基本的概念就是,每次加密用的钥匙都来个新的,跟上次用的没啥关系的。这样基本只能用遍历破解。

YubiKey OTP

YubiKey的使用很简单,插在电脑上,它就会亮。按一下那个唯一的按键,它就会往你光标在的位置“吐”一串密码。当然要登录的服务器得支持YubiKey的认证方式(所以基本没几个服务可以用,但是有LastPass)。

图片描述

YubiKey的OTP实现如下。顶上紫色的是最终产生的一个字符串。其中前面一部分是用户ID,用来对应用户的公钥。后面部分是一个由counter何session key组合产生的密码。由于每次按键都会使得内部的counter自增,所以同一个密码是不能被拿来验证两次的。另外,由于这玩意儿里面的firmware是写死的,所以也基本不用担心算法被篡改的问题。

otp_details.png

YubiCloud

刚才说到服务器要支持YubiKey的认证方式,YubiCloud就是Yubico给出的解决方案。流程很简单如下图。

图片描述

只要在验证的步骤中增加一步跟YubiCloud交互的过程就ok了。一般这种应用会要求三个凭证来作为用户身份验证:用户名,密码,YubiKey产生的OTP。先验证密码的好处是,可以不至于每次输错密码都要重新产生一个OTP。

YubiCloud提供了几个写好的Server-YubiCloud的SDK,同时也给出了兼容这个协议的独立认证服务器实现参考,还有个第三方的go写的哟。

U2F

前段时间Gmail宣布支持U2F,因为有软件的Authenticator,硬件版本的U2F对于大部分二次验证用户来说…没啥用…但…对于在笔记本上使用二次验证的用户来说,买一个他家出的U2F SECURITY KEY,可能还是可以应对“手机没电”,“清空了Authenticator数据”,“手机丢了”等情况的。况且,日子还要过,逼还要装,怎能跟那些厮一样,打开个App看密码…

好吧,我承认今天的blog过于水了…就请看在之前找题材痛苦的份儿上…

晚安~

(30 gadget day 1) MYO get started

MYO

MYO是一款类似Leap motion的新型人机交互HCI设备。它被戴在人的前臂,从而可以感知人的肌肉电流,进而识别出人的各种手势动作,比如向左向右挥手。

图片描述

官方给出的MYO的几个用途是

  • 做展示。挥挥手就能换页,或者将Prezi的控制变成它应有的样子。
  • 控制手机。比如跑步的时候挥挥手就能切换歌曲,玩1024之类的。
  • 智能家居。打个响指就能让电视开机之类的。
  • 控制那些会跑的。现在支持了Sphero和Parrot Drone。

另一个我觉得很酷的例子是Armin Van Buuren在一次演出里使用MYO来辅助增强现场表演效果。特别有未来实时大规模交互演出的感觉。那些具体的表演视频就大家自己去搜吧。

avb-myo-home.jpg

我买了两个MYO腕带,下面三天我们就来想想能用它来玩点什么~(那上面的标志是在亮的,真的挺酷)

图片描述

MYO的结构

myo-overview.png

整个MYO中间靠近皮肤的部分都布满了各种金属触点,所以戴起来的时候完全不在乎什么角度。充电用的是标准的Micro USB。

图片描述

开发者视角

跟Leap motion类似,MYO提供两类输入数据:空间数据(Spatial data),手势数据(Gestural data)和唯一一种反馈接口,震动(vibration command)。

空间数据包括两个维度:方向(orientation),三维的加速度向量(acceleration vector)。
手势数据包括几种特定的手势,比如握拳等。

iOS sample

当然,MYO提供了基本所有平台的SDK(当然Windows phone除外)。开发起来最方便的还是Mac啦,windows要装一堆驱动啥的。如果只是开发应用的话,基本之用跟Android/iOS的SDK打交道就好啦。如果需要底层数据,MYO也提供C lib API。另外,还有一种用Lua写的Myo Scripts

sdk-stack.png

跟各种Sensor的使用类似,MYO的数据是以回调传递事件的方式来提供。MYO提供三类事件,如前面所说所空间事件,手势事件,以及一些辅助类的事件(如连接,断开设备等)。

开发MYO应用的最好方式就是先运行sample程序。iOS的SDK里面包括一个Doc和叫HelloMyo的Sample程序。打开Sample,运行,玩玩就好了。(MYO SDK开发速度很快,所以如果发现Sample程序告知版本太低,则需要连上USB和蓝牙发射器进行一次升级)。

看看代码吧。

- (void)viewDidLoad {
    [super viewDidLoad];

    // Data notifications are received through NSNotificationCenter.
    // Posted whenever a TLMMyo connects
    [[NSNotificationCenter defaultCenter] addObserver:self
                                          selector:@selector(didConnectDevice:)
                                          name:TLMHubDidConnectDeviceNotification
                                          object:nil];
    // Posted whenever a TLMMyo disconnects.
    [[NSNotificationCenter defaultCenter] addObserver:self
                                          selector:@selector(didDisconnectDevice:)
                                          name:TLMHubDidDisconnectDeviceNotification
                                          object:nil];
...
    // Posted when a new pose is available from a TLMMyo.
    [[NSNotificationCenter defaultCenter] addObserver:self
                                          selector:@selector(didReceivePoseChange:)
                                          name:TLMMyoDidReceivePoseChangedNotification
                                          object:nil];

}

首先是注册各种事件,包括连接断开连接,这里有个Sync Gesture,指的是一种比较奇怪的动作(不大好描述)。应该是MYO用来给手臂肌肉电流做一个基本的base line吧。

最有用的可能就是TLMMyoDidReceivePoseChangedNotification了。一旦有新的姿势检测到,这个函数就能收到一次callback。来看这个Callback的内容。

- (void)didReceivePoseChange:(NSNotification *)notification {
    // Retrieve the pose from the NSNotification's userInfo with the kTLMKeyPose key.
    TLMPose *pose = notification.userInfo[kTLMKeyPose];
    self.currentPose = pose;

    // Handle the cases of the TLMPoseType enumeration, and change the color of helloLabel based on the pose we receive.
    switch (pose.type) {
        case TLMPoseTypeUnknown:
        case TLMPoseTypeRest:
        case TLMPoseTypeDoubleTap:
            // Changes helloLabel's font to Helvetica Neue when the user is in a rest or unknown pose.
            self.helloLabel.text = @"Hello Myo";
            self.helloLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:50];
            self.helloLabel.textColor = [UIColor blackColor];
            break;
        case TLMPoseTypeFist:
            // Changes helloLabel's font to Noteworthy when the user is in a fist pose.
            self.helloLabel.text = @"Fist";
            self.helloLabel.font = [UIFont fontWithName:@"Noteworthy" size:50];
            self.helloLabel.textColor = [UIColor greenColor];
            break;
        case TLMPoseTypeWaveIn:
            // Changes helloLabel's font to Courier New when the user is in a wave in pose.
            self.helloLabel.text = @"Wave In";
            self.helloLabel.font = [UIFont fontWithName:@"Courier New" size:50];
            self.helloLabel.textColor = [UIColor greenColor];
            break;
        case TLMPoseTypeWaveOut:
            // Changes helloLabel's font to Snell Roundhand when the user is in a wave out pose.
            self.helloLabel.text = @"Wave Out";
            self.helloLabel.font = [UIFont fontWithName:@"Snell Roundhand" size:50];
            self.helloLabel.textColor = [UIColor greenColor];
            break;
        case TLMPoseTypeFingersSpread:
            // Changes helloLabel's font to Chalkduster when the user is in a fingers spread pose.
            self.helloLabel.text = @"Fingers Spread";
            self.helloLabel.font = [UIFont fontWithName:@"Chalkduster" size:50];
            self.helloLabel.textColor = [UIColor greenColor];
            break;
    }

    // Unlock the Myo whenever we receive a pose
    if (pose.type == TLMPoseTypeUnknown || pose.type == TLMPoseTypeRest) {
        // Causes the Myo to lock after a short period.
        [pose.myo unlockWithType:TLMUnlockTypeTimed];
    } else {
        // Keeps the Myo unlocked until specified.
        // This is required to keep Myo unlocked while holding a pose, but if a pose is not being held, use
        // TLMUnlockTypeTimed to restart the timer.
        [pose.myo unlockWithType:TLMUnlockTypeHold];
        // Indicates that a user action has been performed.
        [pose.myo indicateUserAction];
    }
}

内置的手势有这些:

TLMPoseTypeDoubleTap(拇指和中指连续点击两次)
TLMPoseTypeFist(握拳)
TLMPoseTypeWaveIn(向内挥手,戴在右手就是往左挥手)
TLMPoseTypeWaveOut(向外挥手)
TLMPoseTypeFingersSpread(按理来说是类似cross finger的意思,但似乎我没咋触发过这个pose)

基本就这么点儿代码。明天我们尝试把这个跟其他功能联系起来哈。

(30 hackdays ) 30个gadget day

Gadget days

30hackday帮助我验证了快速学习的可能性和方法。下面这30hackday我想集中在硬件Gadget的开发上,看能不能积累出一套适用于Gadget App开发的经验。

2015年2月20日开始,每天我会写一篇比较正式的博客文章(文章质量参考原作者,第二天早上2点前发出算数),内容都是关于这些硬件Gadget的应用开发。

非常希望借此机会认识对Gadget开发感兴趣的伙伴们。所以,如果在文章里发现了任何错误,请帮忙指出,我都很乐意请你喝咖啡(限北京…)~ contact: fxp007@gmail.com

开发设备如下,过程中可能略有变化,排名不分先后。MYO,Kinect for windows 2,SmartScopes,Estimote iBeacon,LittleBits,Tobii eyeX,Sphero,Philips hue,Mindstorm,ARDrone

进度

图片描述

在WordPress.com的博客.

向上 ↑