Hana道場【師範】のブログ

IchigoJamの徹底解説ブログ

【IchigoJam × Ambient】センサーの値、ゲームのスコアをグラフ化!IchigoJamでIoT入門【NT鯖江2020】

f:id:hanadojo_sihan:20201004204657j:plain

IchigoJamをインターネットにつなげて川下りゲームのスコアをグラフ化!

 

NT鯖江2020にHana道場として出展しました!(10/3-4)

※NTとは「なにか・つくろう」の略

Hana道場ブースはIchigoJamとドローンのみ置いてあるだけだったので、SNT(その場で・なにか・つくろう)しました。出展中でもなにかつくる!

<今回SNTしたもの>

  1. GPS付きIoTプロダクト基板づくり
  2. 距離センサーで店番ドローン
  3. インターネットにつながった川下りゲーム

 

3の川下りゲームのスコアがグラフ化されるプログラムを解説していきます!

川下りゲーム自体の解説は、こちらでしています↓↓

hanadojo-sihan.hatenablog.com

 

【目次】

 

1.必要なもの

Ambientはマイコンから送信されたデータを蓄積・グラフ化するIoT可視化サービスです。アカウントとチャネルは無料で作れるので、IchigoJamとMixJuice(+WiFi環境)があればお金は掛かりません!(2020年10月現在)

 

2.プログラム概要

ファイル0番:川下りゲーム本体

ファイル1番:スコア送信

※1つのファイルにまとめてもらってもOK

※値送信→グラフ化のテストだけしたい方はファイル1番のみでOK

 

【ファイル0番:川下りゲーム本体】

5 CLS:VIDEO3:WAIT60
6 K=INKEY():IF K!=10 LC 0,5:?"エンター デ スタート":?"ハイスコア";PEEK(#FFF):CONT
10 CLS:CLT:VIDEO1:X=15
15 S=TICK()/60
20 LC X,5:?"🐱"
30 LC RND(32),23:?S
40 WAIT 4
50 X=X-BTN(28)+BTN(29)
60 X=X&31
70 IF SCR(X,5)=0 GOTO15
80 IF S>PEEK(#FFF) GSB@HS ELSE ?"スコア:";S
90 WAIT120
100 LRUN 1
200 @HS
210 VIDEO6
220 ?"ハイスコア!":?S:WAIT180
230 POKE #FFF,S
240 SAVE FILE()
250 RTN
0番にセーブしましょう。
グレーの部分はハイスコア保存部分です。不要な方は入れなくてOK!
NT鯖江の間での最高記録は117秒!ぜひ挑戦してみてください。
 

【ファイル1番:値送信プログラム】

IchigoJam + MixJuiceで製作するIoTセンサを参考に作成しました。

10 CLS:P=#C00:UART1

20 ?"MJ PCT application/json"

30 ?"MJ POST START ambidata.io/api/v2/channels/チャネルID/data"

35 GSB@TX

40 '{"writeKey":"ライトキー","d1":"#"}

50 ?"MJ POST END"

100 LRUN 0

500 @TX

510 IF PEEK(P)!=ASC("'") P=P+1:CONT

520 P=P+1:IF PEEK(P)=ASC("#") ?S;:CONT

530 IF PEEK(P)!=0 ?CHR$(PEEK(P));:GOTO520

540 ?:RTN

Ambientの「チャネル一覧」からグラフ化したいチャネルのIDとライトキーをプログラムに追記すればプログラム完成です!1番に保存しましょう。

f:id:hanadojo_sihan:20201004223202p:plainそもそもMixJuiceの使い方(接続方法、ネットワークにつなぎ方など)が分からない方は下記サイトからご確認ください。

 

3.Ambientの使い方

川下りゲームのスコアをグラフ化するために、Ambientで設定をしていきましょう。

  1. 「チャネル一覧」からチャネルを選択(クリック)
  2. 画面上部の「グラフ+」のアイコンをクリックし「チャネル/データ設定」をクリック
  3. 「チャート設定」から下記画像のように入力

f:id:hanadojo_sihan:20201004230317p:plain

参考:Ambientを使ってみる – Ambient

 
公開チャネルに設定すると誰でもグラフを見ることができるようになります。 
「チャネル一覧」→「設定変更」→「公開チャネル」にチェック
※チャネルを公開するにはユーザー名を設定する必要があるようです。
 
これで完成!!(プログラムの仕組みが気になる方は4へ)
IchigoJamから送信してからグラフに反映されるのに15秒ほど掛かります。
 
CSV形式でダウンロードもできます!
「チャネル一覧」→「ダウンロード」
センサーと組み合わせて、気温や湿度などのグラフ化にも挑戦してみてください!
 
人感センサー(超音波センサー)と組み合わせた例↓↓

 

4.プログラム解説

【ファイル0番:川下りゲーム本体】

5 CLS:VIDEO3:WAIT60 ビデオ画面を2倍サイズにして1秒まつ
6 K=INKEY():IF K!=10 LC 0,5:?"エンター デ スタート":?"ハイスコア";PEEK(#FFF):CONT
エンターを押すまで待機。ハイスコア(メモリ#FFFに保存してある値)を表示
10 CLS:CLT:VIDEO1:X=15 ビデオ画面を通常サイズにする
15 S=TICK()/60 経過時間(スコア)を秒にして変数Sに保存
20 LC X,5:?"🐱" X,5の位置に、ネコを表示
30 LC RND(32),23:?S
0-31の中でランダム,23の位置に、経過時間を表示
40 WAIT 4 スピード
50 X=X-BTN(28)+BTN(29) ←→キー操作 
60 X=X&31 変数Xが0より小さくなったら31に、31より大きくなったら0にする
70 IF SCR(X,5)=0 GOTO15 ネコが経過時間に当たるまでゲーム続行
80 IF S>PEEK(#FFF) GSB@HS ELSE ?"スコア:";S
スコアがハイスコア(メモリ#FFFに保存してある値)より大きかったらサブルーチン@HSを呼び出す。大きくなかったらスコアを表示
90 WAIT120
100 LRUN 1 ファイル1番のプログラムをLOADしてRUN
200 @HS 200行目以降HSというハイスコア更新時のサブルーチン
210 VIDEO6 白黒反転の画面サイズ4倍にする
220 ?"ハイスコア!":?S:WAIT180
230 POKE #FFF,S メモリ#FFFに変数Sの値を書き込む
240 SAVE FILE() 現在のファイル番号にSAVE
250 RTN サブルーチン呼び出し元(GSB)へもどる

ハイスコアの保存以外は普通の川下りゲームとほとんど変わりませんが、敵が経過時間です!

 

ハイスコアの保存プログラムを入れると、電源を切ったとしてもハイスコアごと保存されます(メモリのプログラム領域#FFFに保存しているため)。再びLOADすればハイスコアが残っていることが分かります。

参考:メモリマップ - イチゴジャム レシピ

 

【ファイル1番:値送信プログラム】

ⅰ) MixJuiceで値を送信するプログラム

10 CLS:P=#C00:UART1 変数Pはプログラム領域のメモリアドレス

20 ?"MJ PCT application/json通信のタイプを設定

30 ?"MJ POST START ambidata.io/api/v2/channels/チャネルID/data"

POST通信開始(START以降のURLに通信する)

35 GSB@TX サブルーチンTXを呼び出す

40 '{"writeKey":"ライトキー","d1":"#"}

JSON形式で、キー名はd1、値はスコア(変数S)をAmbientへ送信する。#は目印のようなもの

50 ?"MJ POST END"  POST通信を終了

30行目:START以降のURLは大文字・小文字を間違えずに打ちましょう。エラーコードが返ってきた場合は打ち間違いの可能性大です。

40行目JSON形式でデータを送ります。{キー名:値,キー名:値,…}のようにキー名と値をセットで記述します。

キー名d1の値(=スコア)が#になっている理由と`を使っている理由は(ⅲ)で書きます。

参考:JSONの形式を完全理解して読み書きできるようになるための記事 | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト

ⅱ) ファイル移行

100 LRUN 0 0番のプログラムをLOADしてRUN

Ambientへ送信が終了したら川下りゲームのスタート画面にもどるようにします。

ⅲ) 40行目のプログラムをPRINT出力するプログラム

500 @TX 40行目をPRINT出力するためのサブルーチンTX

510 IF PEEK(P)!=ASC("'") P=P+1:CONT ' を見つけるまで変数Pを更新し続ける

520 P=P+1:IF PEEK(P)=ASC("#") ?S;:CONT #を見つけたら#の代わりに変数SをPRINT出力

530 IF PEEK(P)!=0 ?CHR$(PEEK(P));:GOTO520 終了コード0を見つけるまでPRINT出力

540 ?:RTN 改行して、呼び出し元にもどる

MixJuiceのMJコマンドはPRINT出力することで実行されます。

 例:?"MJ APL"

20,30,50行目のプログラムは、PRINT(?)出力でMJコマンドを実行しています。

 

<なぜ40行目だけ処理が難しい(違う)のか>

 

【理由】

?" "の中でさらに"が使われているため

 

40行目を20,30,50行目と同じように、?で書くとこのようになります。

40 ? "{"writeKey":"ライトキー","d1":"#"}"

JSON形式では、キー名と値(文字列の場合)は""で囲む必要があるので、

?命令の""の中にさらに"を書くことになります。

?"""
Syntax error 

(例1 errorの原因は、?""で完結しているのにその後ろにさらに"があるから)

40 ? "{"writeKey":"ライトキー","d1":"#"}"
{Syntax error in 40

(例2 errorの原因は、?"{"で完結しているのにその後ろにwriteKEY...と文字列が続いているため) 

Syntax errorを防ぐため、500行目以降の処理でPRINT出力をしています。

 

<500行目以降のTXサブルーチン解説>

510行目:'を見つけるまで変数P(メモリのアドレス)を更新し続ける。

520、530行目:行の最後のメモリの値は終了コードといって、0が保存されています。変数Pの値が0のときは、行の最後までPRINT出力が完了したことになります。

次の文字が#の場合のみ、520行目で(#の代わりに)変数Sを出力しています。

つまり{d1:S}となり変数Sの値をキー名d1としてAmbientへ送ることができるという訳です。

 

【結論】

MixJuiceでJSON形式で送るには、”の問題で500行目以降のようにプログラムのメモリ領域から読み込んでPRINT出力をする必要がある。

 

5.まとめ

4.プログラム解説をちゃんと理解しようと思うと、IchigoJamのメモリマップやMixJuiceでの通信(GET,POST)やデータ形式JSON)の知識も必要になります。IchigoJamのステップアップ、IoT入門として良い教材かも!?

 

<やってみよう>

  1. d1だけでなくd2,d3の値も送信してみよう!
  2. センサーと組み合わせてIoTを作ってみよう!

 

質問やご指摘はTwitterからお願いします。

CC BY shoichi1031da / @shoichi1031da

twitter.com

<参考リンク>

IchigoJam + MixJuiceで製作するIoTセンサ

Ambientを使ってみる – Ambient

準備・使い方 - イチゴジャム レシピ

メモリマップ - イチゴジャム レシピ

JSONの形式を完全理解して読み書きできるようになるための記事 | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト