1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

オリジナル土壌センサーの作成(ソフトウェア編)

1
Posted at

はじめに

前回の記事では、BLE対応オリジナル土壌センサーのハードウェア構成について紹介した。

今回はArduino IDEを用いて、ESP32C3上で動作するソフトウェアについて紹介する。

今回実装する機能は次のとおりである。

  • BLE通信
  • 土壌温度の取得(DS18B20)
  • 土壌水分量の取得(ADS1115)
  • Deep Sleepによる低消費電力化

開発環境

開発環境は以下のとおり。

項目 内容
IDE Arduino IDE
CPU Seeed Studio XIAO ESP32C3
ライブラリ DallasTemperature
ライブラリ OneWire
ライブラリ Adafruit ADS1X15
ライブラリ NimBLE-Arduino

Arudino IDEでのESP32C3 の開発について

QiitaにはESP32C3 についての記事がたくさん投稿されている。
Arduino IDEでの開発についてはそちらの参照をお願いします。

ソースコード

ソースコード全体はGitHubに以下のURLで公開している。

ソースコードは各センサーとのアクセス部分を要点のみ解説する。

プログラム全体の流れ

センサーは常時動作するのではなく、一定時間ごとに起床し、測定が終われば再びDeep Sleepへ入る。

Deep Sleep
    │
    ▼
起床
    │
    ▼
DS18B20測定
    │
    ▼
水分センサーON
    │
    ▼
ADS1115測定
    │
    ▼
BLE送信
    │
    ▼
水分センサーOFF
    │
    ▼
Deep Sleep

起床している時間は数百ms程度しかないため、電池寿命を長くすることができる。


使用ライブラリ

今回使用したライブラリは次の4つだけである。

#include <OneWire.h>
#include <DallasTemperature.h>
#include <Adafruit_ADS1X15.h>
#include <NimBLEDevice.h>

それぞれの役割は、

ライブラリ 用途
OneWire DS18B20通信
DallasTemperature 温度取得
Adafruit ADS1X15 ADS1115からA/D値をISPで取得する
NimBLE BLE通信

である。


DS18B20で温度を取得する

まずは土壌温度を取得する。

初期化は非常に簡単で、

OneWire oneWire(PIN_TEMP);
DallasTemperature sensors(&oneWire);

void setup()
{
    sensors.begin();
}

温度取得も数行で済む。

sensors.requestTemperatures();

float temp0 = sensors.getTempCByIndex(0);
float temp1 = sensors.getTempCByIndex(1);

今回は2本接続しているため、

  • センサー0
  • センサー1

を取得している。

ADS1115で土壌水分を取得する

次は土壌水分である。

まずADS1115を初期化する。

Adafruit_ADS1115 ads;

void setup()
{
    ads.begin();
}

測定前だけGPIOからセンサーへ電源を供給する。

digitalWrite(PIN_SENSOR_POWER,HIGH);

delay(50);

int moisture0 = ads.readADC_SingleEnded(0);
int moisture1 = ads.readADC_SingleEnded(1);

digitalWrite(PIN_SENSOR_POWER,LOW);

このようにすることで、

  • 電極の腐食防止
  • 消費電力削減

を同時に実現している。


BLE通信

取得したデータはBLE Advertisementへ載せて送信している。

今回は接続型(GATT)ではなく、

Advertisementのみ

を利用した。

その理由は

  • 消費電力が少ない
  • Python側が受信しやすい
  • 接続処理が不要

だからである。

送信データは以下の形式としている。

データ サイズ
Battery 2Byte
Temperature0 2Byte
Temperature1 2Byte
Moisture0 2Byte
Moisture1 2Byte

送信処理は以下のようになる。

まず、データ配列に各センサーの値をセットする。

  uint8_t txData[12];

  txData[0] = DEVICE_NO;
  txData[1] = status;

  txData[2] = battery & 0xFF;
  txData[3] = battery >> 8;

  // 水分量
  txData[4] = moisture_ch0 & 0xFF;
  txData[5] = moisture_ch0 >> 8;

  txData[6] = moisture_ch1 & 0xFF;
  txData[7] = moisture_ch1 >> 8;

  // 温度

  txData[8] = temp_ch0 & 0xFF;
  txData[9] = temp_ch0 >> 8;

  txData[10] = temp_ch1 & 0xFF;
  txData[11] = temp_ch1 >> 8;

Advertising用のデータ構造に先ほどのデータ構造をセットする。
COMPANY_ID は、本センサーを識別するための適当な値。

  // Advertisingデータ作成
  NimBLEAdvertisementData advData;

  advData.setFlags(BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP);

  // Company ID = 0xFFFF(テスト用)
  std::string mfg;
  mfg.push_back(COMPANY_ID&0xff);   // Company ID LSB
  mfg.push_back((COMPANY_ID&0xff00)>>8);   // Company ID MSB
  mfg.append((char*)txData, sizeof(txData));

  advData.setManufacturerData(mfg);

AdvertisingでBLE通信を開始する。

  // Advertising開始
  NimBLEAdvertising *adv = NimBLEDevice::getAdvertising();
  adv->setAdvertisementData(advData);
  adv->start();

Deep Sleep

測定が終わればESP32をDeep Sleepへ移行させる。

esp_sleep_enable_timer_wakeup(60ULL * 1000000ULL);

esp_deep_sleep_start();

今回は60秒ごとに起床している。

Deep Sleepを利用することで、待機中の消費電流を大幅に削減できる。

まとめ

今回はESP32C3を用いて、

  • DS18B20
  • ADS1115
  • BLE
  • Deep Sleep

を組み合わせた土壌センサーを作成した。

Arduinoライブラリが充実しているため、100行程度のコードで実現できた。

次回はPython側でBLEを受信するプログラムについて紹介する。

リンク

こちらは生成AIのちーちゃん(GPT5)にアドバイスをもらいながらAI/IoTを活用して家庭菜園にいそしんでいるブログです。よかったらこちらも見てやってください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?