M5StickCPlusで完全自動水やり機を作ってみよう！

# はじめに

この記事を作成した経緯は、今年の6月に設立した団体 [PCN渋谷](https://pcn.livspect.com/) にてワークショップを開催する際、小学生に親しみやすいユニットを探していたことがきっかけです。その際、[M5Stack公式ページ](https://m5stack.com/) を確認したところ、興味深い [**Watering-Unit**](https://docs.m5stack.com/en/unit/watering)を見つけました。

このユニットは、小学生にも理解しやすく、実際に使うことで学習に繋がるプロジェクトを提供できると考えました。今回の記事では、M5Stackのユニットを活用したプロジェクトやその実装について詳しく紹介していきます。また、コードにつきましては、ワークショップに来ていただいたお子様にわかりやすいよう細かく分けてあります。

# 実際の動作画像、動画

![IMG_2276.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3814349/e360fafc-e1b8-d10f-7c11-1578bbca5fcb.png)

https://www.instagram.com/p/C-1yJkAu-fp/




# 開発環境
- **VSCode** (エディター)
- **PlatformIO** (組み込み開発に特化したVSCode拡張機能)
- **M5StickCPlus2** (今回使用するBoard名)
- **Watering-Unit** (M5用水やり機Unit)

※開発環境構築方法は[こちら](https://qiita.com/koyochan/items/a8abfb97c000fb233b27)です。

# 使用言語
- **C++**

# Githubリポジトリー

- [URL](https://github.com/koyochan/Watering-Unit)

# 実行Flow

1\. ~/Document/PlatformIO ディレクトリに
```git clone https://github.com/koyochan/Watering-Unit```する

2\. **PIO Home**の**Open Project**から、先ほどクローンしてきたディレクトリを開く

3\. プロジェクのルートディレクトリで```pio run --target upload && pio device monitor```を実行する

以上のステップをM5StickCPlus2が接続されているデバイスで行うと実行できます。

# 動作解説

### Watering Unit

このユニットは、土壌の水分量を測定するために、土に刺すセンサーが内蔵されています。センサーが土の中の電気抵抗を計測することで、土の乾燥具合や湿り具合を判断します。水分が多いほど電気が流れやすく、水分が少ないと電気の流れが悪くなるため、この原理を使って土壌の水分量を把握します。


### **src/measure_and_display_moisture.cpp**

このコードでは、analogRead関数を使い、帰ってきた電圧を測定したのちにmoisture(水分量)、vol(電圧)へ変換して表示しています。

```
#include "../lib/watering_unit.h"

void	measureAndDisplayMoisture(float &vol, float &moisture)
{
	float	adc;

	adc = analogRead(INPUT_PIN);
	vol = (adc + 1) * 3.3 / (4095 + 1);
	moisture = 100 * (1.65 - vol) / (1.65 - 1.2);
	Serial.printf("電圧: %2.2fV  土壌水分量: %0.2f%%\r\n", vol, moisture);
	M5.Lcd.setCursor(0, 0);
	M5.Lcd.setTextColor(WHITE);
	M5.Lcd.printf("Voltage: %2.2fV\n", vol);
	M5.Lcd.printf("Moisture: %0.2f%%\n", moisture);
	delay(1000);
}
```

### **src/control_pump.cpp**

このコードでは、measureAndDisplayMoistureによって求めた水分量を使い、ポンプをオンにするかオフにするかの条件分岐を行なっています。判定はTHRESHOLD_MOISTUREという閾値によって制御されています。(THRESHOLD_MOISTUREはsrc/main.cppで定義されています。)
```
#include "../lib/enable.h"
#include "../lib/watering_unit.h"

void controlPump(float moisture, int &number) {
    static bool pumpOn = false;

    if (moisture <= THRESHOLD_MOISTURE) {
        if (!pumpOn) {
            number++;
            pumpOn = true;
            digitalWrite(PUMP_PIN, HIGH);
            Serial.println("ポンプオン");
            M5.Lcd.fillScreen(RED);
            M5.Lcd.setTextColor(WHITE, RED);
            M5.Lcd.drawString("Pump On", 40, 50);
            
            #if ENABLE_SOUND_ALERT
                playTone();
            #endif
            
            #if ENABLE_VISUAL_EFFECT
                drawImage(40, 70, image_data, 135, 240);
            #endif
        }
    } else {
        if (pumpOn) {
            pumpOn = false;
            digitalWrite(PUMP_PIN, LOW);
            Serial.println("ポンプオフ");
            M5.Lcd.fillScreen(BLACK);
            M5.Lcd.setTextColor(WHITE, BLACK);
            M5.Lcd.drawString("Pump Off", 40, 50);
        }
    }
} 
```

# まとめ

今回は、Watering-UnitをM5StickCPlusを使って動かして見ました！PCN渋谷では、このようにプログラミングとハードウェアを組み合わせたワークショップを開催しております。


# 参考
https://github.com/m5stack/M5Stack/tree/master/examples/Unit/WATERING