見出し画像

【SALZmini2022作製日誌】リリースを終えて

はじめに

自動水やり装置【SALZmini2022】は夏休みの自由研究のようになんとか発表までこぎつけることができました。

それから、そのまま稼働テストに入っています。
また、所属している盆栽会などの会合で見て頂いています。

ここまでの問題点をご報告いたします。
・水やりが偏っている?
・通信トラブルが解消されていない?
・BOWLで気になること。
・水やり方法はこれでよいのか?

など、思ったよりも問題点は少ないですが、それでも課題は残っています。

水やりが偏っている?

昨年までの水やり方法では、ゴムホースに穴をあける方法でうまく散水できていたのですが、今年のSALZminiではなぜか詰まってしまっていました。穴あけの仕方が甘かったのでしょうか?

それで、少し悩んで4分岐栓を使いました。

これで確かに詰まらなくなりましたが、これでも少し不安です。

ホースを持ち上げてテストすると、手前の水栓のみ放水されて、奥まで水が届かない状態になっていました。

でも、土の中に埋めると、全体から放水されるみたいです。

500円近くするパーツなので、できれば使わずに済ませたいところです。

あれこれどうしたものか考えていました。細い真鍮管を差し込もうか?とか、その真鍮管をカットすると、へしゃげて開口部の確保が難しくなるんじゃないか?とか。

今度は盆栽趣味者にとって身近な針金を使うとどうだろうかと考えました。丸い針金をそのまま使うと穴をきれいに塞いでしまうし、ダメかと思いましたが、針金を折り曲げねじって突っ込むことで、針であけた穴に隙間を確保できそうだと思いました。

併せて、地表部でホースを固定することにも効果がありそうです。
一度チャレンジしてみます。

通信トラブルが解消されていない?

こちらも、途中から発生していた問題点です。SALZmini2022を稼働させているとBLEアドバタイズ信号が途絶し、見えなくなってしまう現象が発生しています。

およそ2~3日経ったときにその問題が発生しています。

何度か原因を突き止めようと調査したのですが、結局突き止められず、装置が安定し始めたのでうやむやにしておりました。
ただ、現象が発生してしまうと楽しみにしていた履歴データが見れなくなってしまうので残念です。

途方に暮れて、ネットで相談してみることにしました。
相談に乗ってくれる方は貴重な時間を割いて一緒に問題解決をしてくださるので、事前準備はとても大切です。
念入りにやったつもりですが、それでも漏れがあります。

何度かやり取りした後、報告のためにデバッグ文字列を再点検しているときに問題点が見つかりました。

デバッグ出力を取るため、PCと接続した状態で装置を組んでテストを開始しました。

毎日、nRF Connectアプリを使って動作チェックをしていましたが4日経っても問題は発生せず、現象が発生しなくなったと思い困っておりましたが、ある時BOWLで接続したのち、nRF Connectアプリを使うと、表示されなくなっていることに気づきました。

現象が再現したので、正常時と異常時のデバッグ出力を比較しましたが、まったく違いがありませんでした。つまり、M5Stamp3Cでの動作は何も変わりませんでした。

ただ、少し気になることがあり、デバッグを進めたところ、下記のことがわかりました。

・給水モードのときに、BLEのコネクトをすると、ディスコネクトできなくなり、以降、アドバタイズ信号が発信されなくなる。
・M5StampC3単体で現象が発生する。
・BOWLを使わなくても、nRF Connectアプリで再現する。

必ず不具合を出す手順が分かりましたので、更にデバッグ出力を精査して調べていくうちに、コネクト、ディスコネクトが切り換わる時に必ず実行されるべき処理が行われていないことが分かりました。

GetInput関数の中で、入力情報を作っているのですが、そこの条件文の書き方に不備があり、優先順位を誤っていたようです。コールバック関数でセットされた変数の処理はまず先に処理すべきところを後回しにしていたため、そこに到達する前に他の条件に合致していました。

int
GetInput(void) {
  int input = IN_NOOP;

  if (TimeDiff(millis(), waitTimeMillis) > SECONDS(salzData.waitTime)) {
    Serial.print("w");
    input = IN_WLGT;
  }
  else if (TimeDiff(millis(), advartiseTimeMillis) > ADVARTISE_TIME) {
    Serial.print("A");
    input = IN_ADDS;
  }
  else if (TimeDiff(millis(), historyTimeMillis) > HISTORY_TIME) {
    Serial.print("h");
    input = IN_HDAD;
  }
  else if (deviceConnected == true && TimeDiff(millis(), notifyTimeMillis) > NOTIFY_TIME) {
    Serial.print("N");
    input = IN_NTDS;
  }
  else if (prevDeviceConnected == false && deviceConnected == true) {
    Serial.print("C");
    prevDeviceConnected = deviceConnected;
    input = IN_CNCT;
  }
  else if (prevDeviceConnected == true && deviceConnected == false) {
    Serial.print("D");
    delay(500); // give the bluetooth stack the chance to get things ready
    pServer->startAdvertising(); // restart advertising
    prevDeviceConnected = deviceConnected;
    input = IN_DCNT;
  }
  else if (bForceWater || salzData.currentWaterLevel < salzData.wateringLevel) {
    Serial.print("W");
    bForceWater = false;
    input = IN_WTNW;
  }
  else if (bPump && TimeDiff(millis(), pumpTimeMillis) > SECONDS(salzData.pumpTime)) {
    Serial.print("P");
    input = IN_POFF;
  }
  else {
    //Serial.print("n");
    input = IN_NOOP;
  }

  // その他の処理
  if (salzData.currentWaterLevel < salzData.yellowLevel) {
    salzData.status = stWaitRed;
  }
  else if (salzData.currentWaterLevel < salzData.blueLevel) {
    salzData.status = stWaitYellow;
  }
  else {
    salzData.status = stWaitBlue;
  }

  return input;
}

その結果、コネクト、ディスコネクトのイベントが全く無視され、ディスコネクト後の

pServer->startAdvertising(); // restart advertising

が実行されず、その結果、アドバタイジング信号の発信が再開されない状態となっておりました。

int
GetInput(void) {
  int input = IN_NOOP;

  if (prevDeviceConnected == false && deviceConnected == true) {
    Serial.print("C");
    prevDeviceConnected = deviceConnected;
    input = IN_CNCT;
  }
  else if (prevDeviceConnected == true && deviceConnected == false) {
    Serial.print("D");
    delay(500); // give the bluetooth stack the chance to get things ready
    pServer->startAdvertising(); // restart advertising
    prevDeviceConnected = deviceConnected;
    input = IN_DCNT;
  }
  else if (TimeDiff(millis(), waitTimeMillis) > SECONDS(salzData.waitTime)) {
    Serial.print("w");
    input = IN_WLGT;
  }
  else if (TimeDiff(millis(), advartiseTimeMillis) > ADVARTISE_TIME) {
    Serial.print("A");
    input = IN_ADDS;
  }
  else if (TimeDiff(millis(), historyTimeMillis) > HISTORY_TIME) {
    Serial.print("h");
    input = IN_HDAD;
  }
  else if (deviceConnected == true && TimeDiff(millis(), notifyTimeMillis) > NOTIFY_TIME) {
    Serial.print("N");
    input = IN_NTDS;
  }
  else if (bForceWater || salzData.currentWaterLevel < salzData.wateringLevel) {
    Serial.print("W");
    bForceWater = false;
    input = IN_WTNW;
  }
  else if (bPump && TimeDiff(millis(), pumpTimeMillis) > SECONDS(salzData.pumpTime)) {
    Serial.print("P");
    input = IN_POFF;
  }
  else {
    //Serial.print("n");
    input = IN_NOOP;
  }

  // その他の処理
  if (salzData.currentWaterLevel < salzData.yellowLevel) {
    salzData.status = stWaitRed;
  }
  else if (salzData.currentWaterLevel < salzData.blueLevel) {
    salzData.status = stWaitYellow;
  }
  else {
    salzData.status = stWaitBlue;
  }

  return input;
}

その後、しばらく使っておりますが、以前ほどではないまでも、BOWLとの接続切断を繰り返しているうちに、電波が飛ばなくなる状態はまだ発生します。

今後、しばらく使いながら、検証方法を探っていきたいと思います。

BOWLで気になること。

これで安心してBOWLを使って表示、設定を行うことができるようになりました。

HTMLで書かれたBOWL。もっともっと手を入れたいところはたくさんあるのですが、なんとか動かしている状態で壊してしまうのが怖くてあまり手を入れていません。
ただどうしても手を入れたい部分が出てきました。

グラフの表示について、横軸についてもう少しわかりやすくしたいということです。

せっかく時間の記録ができているので、昼か夜かで色分けをしてみたいと思います。

水やり方法はこれでよいのか?

今回作成した自動水やり装置は持ち運びが便利なので、盆栽教室などで先生や盆栽仲間に見ていただいています。

そこでいろんなご感想、ご意見をいただきました。

今回の水やり装置では点滴方式で用土を湿らせる方法を取っていますが、盆栽園などではスプリンクラー方式の水やり装置も多く使われているようです。今後、スプリンクラー方式の水やり装置も考えてみたいと思います。

さいごに

自動水やり装置【SALZmini2022】をリリースしてから約1ヶ月たちました。

クールダウンしながら、現時点での課題をあぶり出しました。

これからも、SALZmini2022を実際に使用しながら装置を磨き上げていきたいと思います。

最後までお読みいただき誠にありがとうございます。

#自動水やり装置 #電子工作 #BLE #SALZmini2022


いいなと思ったら応援しよう!