見出し画像

【SALZmini2022作製日誌】装置作製の峠を越えました。

はじめに

前回記事

緊急事態が発生しまして、こちらの記事を書きましたが、最近はところてん式に記事を書くことが多くなっています。次に取り掛かりたいテーマが見えてくると、今やっていることを取りまとめ記事にします。

今回、取り掛かりたいテーマとして気になったのは「M5Stack用はかりキット(重さユニット付き)」が発売されたためです。

ただ、こちらのデバイスを追加するうえで、今までの経験上思い当たる課題として、
・はたして「M5Stack用はかりキット(重さユニット付き)」が使えるのか?
・戻り値を意味ある値に変換できるか?
・温度などほかの影響を受けないか?
・水分計と同時に使えないか?
等が挙げられます。

こうして考えていくと、だんだんとモチベーションがなくなってきました。
今目の前にある課題から目を背けて、新しい課題に取り組んでも大変になるだけだ。と思うようになってきました。

もう一度、現在の問題点に目を向けます。

・履歴データを受信し視覚化する。

という課題です。
まずは、現在の状況をきちんと把握することから始めました。

試しにNotify信号に現在のカウント(millis)を追加をしてみましたが、正しくデータが通信できません。

適当に組んでいたのが原因です。
気になることがいくつかありました。

・BLEのパケットにすべての情報が乗っているのか?
・エンディアンの確認

これらをひとつずつ見てみました。

BLEのパケットにすべての情報が乗っているのか?

typedef struct {
  SALZData sd;
  uint8_t iHd;
  uint8_t nHd;
  HistoryData hd;
  uint32_t nowMillis;
} SALZNotifyData;

の代わりに

typedef struct {
  uint8_t a[28];
} SNDDecoy;

を使い、

  SNDDecoy sd;
  for (int i = 0; i < 28; i++)
    sd.a[i] = i;
  pCharacteristic->setValue((uint8_t*)&sd, sizeof(SNDDecoy));

を行いました。
SALZNotifyDataのサイズが28バイトなので、28バイトの構造体を作り、通信してみました。
AruduinoIDEで構造体を作った際に既に、バイトアライメントが入っていたようでした。

BOWL側では、1バイトずつ読むようにデバッグ情報を表示できるようにしました。

        // デバッグ用
        document.getElementById("dumpL").innerHTML = "data length:" + data.byteLength;
        document.getElementById("dump1").innerHTML = "00:"
                + data.getUint8(0).toString(16).padStart(2, '0') + "."
                + data.getUint8(1).toString(16).padStart(2, '0') + "."
                + data.getUint8(2).toString(16).padStart(2, '0') + "."
                + data.getUint8(3).toString(16).padStart(2, '0') + "."
                + data.getUint8(4).toString(16).padStart(2, '0') + "."
                + data.getUint8(5).toString(16).padStart(2, '0') + "."
                + data.getUint8(6).toString(16).padStart(2, '0') + "."
                + data.getUint8(7).toString(16).padStart(2, '0') + "...."
                + data.getUint8(8).toString(16).padStart(2, '0') + "."
                + data.getUint8(9).toString(16).padStart(2, '0') + "."
                + data.getUint8(10).toString(16).padStart(2, '0') + "."
                + data.getUint8(11).toString(16).padStart(2, '0') + "."
                + data.getUint8(12).toString(16).padStart(2, '0') + "."
                + data.getUint8(13).toString(16).padStart(2, '0') + "."
                + data.getUint8(14).toString(16).padStart(2, '0') + "."
                + data.getUint8(15).toString(16).padStart(2, '0');
        document.getElementById("dump2").innerHTML = "10:"
                + data.getUint8(16).toString(16).padStart(2, '0') + "."
                + data.getUint8(17).toString(16).padStart(2, '0') + "."
                + data.getUint8(18).toString(16).padStart(2, '0') + "."
                + data.getUint8(19).toString(16).padStart(2, '0') + "."
                + data.getUint8(20).toString(16).padStart(2, '0') + "."
                + data.getUint8(21).toString(16).padStart(2, '0') + "."
                + data.getUint8(22).toString(16).padStart(2, '0') + "."
                + data.getUint8(23).toString(16).padStart(2, '0') + "...."
                + data.getUint8(24).toString(16).padStart(2, '0') + "."
                + data.getUint8(25).toString(16).padStart(2, '0') + "."
                + data.getUint8(26).toString(16).padStart(2, '0') + "."
                + data.getUint8(27).toString(16).padStart(2, '0');

正常にデータ通信できています。
すこし解説をいたしますと、

data.getUint8(4).toString(16).padStart(2, '0')

ble.onRead = function (data, uuid) {

で得られる data(0x0F0E0D0C0B...) から

.getUint8(4)

5バイト目から始まる 8ビット unsigned int 値(11)を取り出し、

.toString(16)

16進数文字列(b)を作り、

.padStart(2, '0')

前0を付けて2文字の文字列(0b)を作る。
という意味になります。

デバッグ出力をするため、1バイトデータの16進数表示が必要だったのですが、このように書くことをネットで知り、オブジェクト指向プログラミングのエレガントさに触れました。古いプログラマなので動作や効率のコストが気になりますが、振返って、自分の書いたコードがどこまでエレガントかと言われると全く自信がなく、特に今やっている部分に関してはなかなかの泥臭さっぷりです。

エンディアンの確認

2バイト以上のデータを読み取る際、アドレスの読み取り方向が上からか下からか2方向あります。

前回の記事ではエンディアンが混在していましたが、確認した所、全てtrueでした。
ということは、今まではたまたま読めていたということになります!

かなり泥臭い方法で実装と確認を行いました。
今の所は、これで進みたいと思います。また気が向けば、この部分に手を入れようと思います。

次は、いよいよ視覚化です。

Smoothi.jsライブラリがオフラインで使えなかったので、別の方法を試してみたいと思います。
HTMLでグラフを書かせる方法を調べてみました。

・Smoothi.jsなどのライブラリを利用する。
・canvasの機能を使う。
・SVGの機能を使う。

等の方法があります。
SVGはほとんど認識していませんでした。
SVGという大文字3文字の名前から連想される少し古めの技術感から、注目していませんでした。
CSSはそれほど感じないのですが、不思議なものです。

こちらのサンプルでSVGを用いてグラフを描画されていました。

参考のため、取りこんでみました。
bodyタグの中で

<div id="conta" width="480" height="350"></div>

を宣言し、対応するCSSを書きます。
scriptタグの中で SVGline()関数を定義(コピペ)します。
最後に、window.onload()関数内で、SVGline()関数を呼び出せば、上記の結果が得られました。

HTMLやJavaScriptの世界が少しずつ分かってきたような気がします。
Python同様にコピペでとりあえず動くものが作れる、このあたりの可搬性は抜群ですね。

ただ、CSSのコントロールはとても難しく思った通りのレイアウトになかなかできません。
今回は、margin: auto; でハマりました。
上下左右に均等のマージンを付け真ん中に配置したいと思ったのですが、なかなか思うようになりません。
ネットで検索し下記の情報を得て、ようやく真ん中に揃えることができました。

display: flex; を追加することで真ん中になりました。

さあ、道具は揃いました。あとは作るのみ。

サンプルプログラムをどんどん書き換えていきます。

まずは思いつくまま組んでみます。

ソースを自分なりに整形しながら理解していきます。
そして、プログラムを修正しながら、少しずつ自分のやりたかったものに近づけていきます。

パラメータを調整していき、グラフデータの本体 xys にたどり着きました。この xys を履歴データにしてみました。

テストモードのSALZmini2022と接続し、確認しています。

これで技術的な峠は越えました。

あと残っていることは、
・BOWLの総仕上げ
・画面サイズによって、表示を変えたい。
・ネットでアクセスできるようにして、使えるようにしたい。
・iPhone、iPadでも使えるか確認したい。
・SALZmini2022の稼働テスト
・しばらく動作させてみる。

このようなことが考えられます。

さいごに

今回はこの辺でまとめようと思います。
待望のMaker Faire Tokyo 2022が来週となり、盆栽系メイカーとして、このイベントに注目しています。

また、今年も M5Stack Japan Creativity Contest 2022 があります。

こちらも何とか間に合いそうです。

#自動潅水装置 #盆栽 #園芸 #電子工作 #BLE #M5StampC3 #SALZmini2022 #SVG #HTML #夏の自由研究

この記事が気に入ったらサポートをしてみませんか?