読者です 読者をやめる 読者になる 読者になる

SIN@SAPPOROWORKSの覚書

C#を中心に、夜な夜な試行錯誤したコードの記録です。

Wi-Fi付きのArduino互換機 Spark Core (その2) Spark Build と WebAPIによるアクセス


Wi-Fi付きのArduino互換機 Spark Core (その1) - SIN@SAPPOROWORKSの覚書

1 Spark Build とは

Spark Build とは、クラウド上に用意されたIDEであり、
https://www.spark.io/build
からログインします。
f:id:furuya02:20150212060525p:plain:w300
左のメニューは、それぞれ次のとおりです。

Flash: 現在のコードを、Core書き込み
Verify: 作成したプログラムが正しいかどうかのチェック
Save:プログラムをクラウド上に保存
Code:保存されているプログラムの一覧・追加・削除
Libraries:ライブラリの一覧(独自ライブラリの追加も可能)
Docs:ドキュメント表示
Cores:Coreの情報表示(Coreの追加・削除)
Settings:パスワード変更・Token確認

IDEがWebアプリで、プログラムの書き込みは、WiFi経由で行うとなると・・・
離れた場所からプログラム更新が可能だという事ですね。

2 WebAPI

Core(本体)との通信は、Sparkのクラウドサービスで用意されているWebAPIを使用して行うことができます。

https://api.spark.io/v1/devices/{デバイスID}/{ファンクション名}

で、本体にプログラムしたファンクションをコールできる仕組みです。
なお、このWebAPIは、POSTで呼び出して、コンテンツで「アクセストークン」と「ファンクションへのパラメータ」をセットします。
curlコマンドで表現すると、次のような感じです。

curl https://api.spark.io/v1/devices/{デバイスID}/{ファンクション名} \
    -d access_token={アクセストークン} \
    -d “パラメータ文字列”

ここで使用する「デバイスID」と「アクセストークン」は、それぞれ、「Core」及び「Settings」メニューから確認できます。
f:id:furuya02:20150212060556p:plain:w300f:id:furuya02:20150212060559p:plain:w300

本体側のファンクションは、戻り値がintで、1つのStringパラメータを受けるものでなければならないようです。

int func(String paramStr); //WebAPIの型宣言

3 Spark Coreのプログラム

Spark Buildで書くのは、ちょっと、C言語風の Android言語?
VisualStudioのように、リアルタイムでエラーが検出されないので、「Verify」ボタンを押して、コンパイルエラーが無いかを確かめる必要があります。
エラーが出なくなったら「Flash」でCoreへの書き込みを行います。本体のLEDがチカチカして、頑張っている感じ・・・数十秒かかります。

int func(String sw); //WebAPIの型宣言
#define pinNo 0

void setup(){
    Spark.function("func", func); //WebAPIの公開
    pinMode(pinNo, OUTPUT); // D0ピンを書き込み用にセット
}

//ループ処理は何もしない
void loop(){
    
}
//公開されたAPI
//パラメータに"ON"を送ると、デジタルピン(D0)はHIGHになる
int func(String sw){
    digitalWrite(pinNo,(sw=="ON")?1:0);
    return 1;
}

f:id:furuya02:20150212060627p:plain:w300

4 スマートフォンのプログラム

Xamarin.Formsで書きました。
画面に、スイッチを配置して、切り替え時にWebAPIを呼んでいるだけです。

namespace SparkSample001 {
    public class App : Application {
        public App() {
            MainPage = new MyPage();
        }

    // 省略・・・

    }

    public class MyPage : ContentPage {
        public MyPage() {
            //ラベル生成
            var label = new Label() { 
                Text = "set D0 in hegh or low",
                HorizontalOptions = LayoutOptions.Center,
            };
            //スイッチ生成
            var sw = new Switch() { 
                HorizontalOptions = LayoutOptions.Center,
            };
            //スイッチ切り替え時の動作
            sw.Toggled += async (s, a) => { 

                //スイッチがONの時、paramを"ON"にする
                var param = "OFF";
                if (sw.IsToggled) {
                    param = "ON";
                }

                var httpClient = new HttpClient();
                const string deviceId = "53ff6aXXXXXXXXXX0402567";//デバイスID
                const string accessToken = "50179a4005XXXXXXXXXXXXXXXXXXXX95413e";//アクセストークン
                const string funcName = "func";//WebAPIのファンクション名
                var data = new FormUrlEncodedContent(new Dictionary<string, string>{
                    {"access_token", accessToken},
                    {"params", param}
                });
                //URLはデバイスIDとファンクション名で決まる
                var url = string.Format("https://api.spark.io/v1/devices/{0}/{1}",deviceId,funcName);
                var response = await httpClient.PostAsync(url,data);
                await DisplayAlert("Result", response.ToString(), "OK");//戻り値をアラート表示

            };
            
            Content = new StackLayout {//スタックレイアウトで画面に配置する
                Padding = new Thickness(0, 100, 0, 0),
                Children = {label, sw}
            };

        }
    }
}

実行画面は、次のような感じ。
f:id:furuya02:20150212060640p:plain:w200f:id:furuya02:20150212060643p:plain:w200f:id:furuya02:20150212060648p:plain:w200

実機でも、動作確認しました。
f:id:furuya02:20150212060705p:plain