メインコンテンツ

このページは機械翻訳を使用して翻訳されました。最新版の英語を参照するには、ここをクリックします。

チャネルへのHTTP POST要求を使用した水分センサー

この例では、ディープ スリープから復帰したデバイスから ThingSpeak ™チャネルに複数のデータ フィールドを投稿する方法を示します。土壌水分センサーを読み取り、その値を ThingSpeakチャネルに投稿します。HTTP POST要求は、別のライブラリを使用せずに通信クライアントに書き込むことによって実行されます。HTTP要求をワイヤレス ネットワーク クライアントに直接書き込むと、ThingSpeak 通信ライブラリよりも柔軟性と速度が向上します。

サポートされているハードウェア

  • ESP8266-12

  • ノードMCU ESP8266-12

  • イーサネットまたはワイヤレス接続を備えた Arduino®(コードを少し調整)

この例では、オンボード ADC が水分センサーを読み取り、その値と経過時間を ThingSpeakチャネルの 2 つのフィールドにポストします。POST を変更して、最大 8 つのフィールドにデータを入力できます。

この画像は、NodeMCU ESP8266-12 に接続された湿度センサーを備えたオフィスの植物を示しています。NodeMCU はワイヤレス ネットワーク接続を提供します。湿度センサーはボード上のデータピンによって電源が供給され、センサーの電源がオンになっている時間が制限されます。この設計により、電力が削減され、センサーの寿命が延びます。測定の合間には、電力を節約するためにデバイス全体がディープスリープ モードになります。データがチャネルに投稿されると、そのデータに対する反応を設定できます。たとえば、水分レベルが低いことを通知するように React アプリを設定できます。

前提条件

1) 新しいチャネルでデータを収集するに示すように、ThingSpeakチャネルを作成します。

2) チャネル設定 タブで、フィールド1を有効にします。Moisture Value のようなわかりやすいフィールド名を指定できます。

3) API キー タブから書き込み API キーをメモします。デバイスのプログラミングに使用するコードではこの値が必要です。詳細については、 「チャネル構成」 および 「チャネルのプロパティ」 を参照してください。

必要なハードウェア

  • ESP8266 ベースのボードまたはインターネット接続を備えた Arduino ボード (このデモでは NodeMCU ESP8266-12E を使用)

  • 土壌水分センサー(例:Sparkfun 水分センサー

  • ジャンパー線(少なくとも4本)

  • USBケーブル

回路図と接続

1) 水分センサーの VCC を NodeMCU のピン D7 に接続します。

2) センサーの Gnd を NodeMCU のグランドに接続します。

3) センサーの Sig ピンを NodeMCU のピン A0 に接続します。

4) NodeMCU Rst ピンを NodeMCU ピン D0 に接続して、ディープ スリープからのウェイクアップを有効にします。

デバイスをプログラムする

1) 最新の Arduino IDE をダウンロードします。

2) ESP8266 ボード パッケージを追加します。

a) [File]> [Preferences][Additional Board Manager URLs] に「https://arduino.esp8266.com/stable/package_esp8266com_index.json」と入力します。

b) [Tools] > [Boards] > [Board Manager] を選択します。検索バーでESP8266を検索し、パッケージをインストールします。

3) Arduino IDE で適切なポートとボードを選択します。この例を生成するために使用されたハードウェアは、Node MCU 1.0 (ESP 8266–12E) オプションを使用しました。

4) アプリケーションを作成します。Arduino IDE で新しいウィンドウを開き、ファイルを保存します。コードセクションで提供されているコードを追加します。コード内のワイヤレス ネットワーク情報と API キーを必ず編集してください。

5) プログラムのアップロードが正常に完了したら、シリアル モニターまたはチャネルビュー ページを使用して出力を監視できます。

コード

1) ESP8266WiFi ライブラリをインクルードし、ハードウェアとデータ収集用の変数を初期化します。ネットワーク情報を編集し、コードに API キーを書き込みます。

#include <ESP8266WiFi.h>

// Network information.
#define WIFI_NAME "YOUR_WIFI_NAME"
#define PASSWORD "WIFI_PASSWORD"

// Hardware information.
#define SENSOR_POWER 13                            // Connect the power for the soil sensor here.
#define SOIL_PIN A0                                // Connect the sensor output pin here.
#define TIMEOUT  5000                              // Timeout for server response.
#define SLEEP_TIME_SECONDS 1800

// ThingSpeak information.
#define NUM_FIELDS 2                               // To update more fields, increase this number and add a field label below.
#define SOIL_MOISTURE_FIELD 1                      // ThingSpeak field for soil moisture measurement.
#define ELAPSED_TIME_FIELD 2                       // ThingSpeak field for elapsed time from startup.
#define THING_SPEAK_ADDRESS "api.thingspeak.com"
String writeAPIKey="XXXXXXXXXXXXXXXX";             // Change this to the write API key for your channel.

// Global variables. 
int numMeasure = 5;                                // Number of measurements to average.
int ADCValue = 0;                                  // Moisture sensor reading.
                         
WiFiClient client;

2) setup 関数で、シリアル モニターを起動し、ワイヤレス ネットワークに接続し、使用するデバイス ピンを初期化します。

// Put your setup code here, to run once:
void setup()
{
    Serial.begin( 115200 );   // You may need to adjust the speed depending on your hardware.
    connectWifi();
    pinMode( SENSOR_POWER , OUTPUT );
    digitalWrite( SENSOR_POWER , LOW );   // Set to LOW so no power is flowing through the sensor.
}

3) メイン ループで、土壌モニターを読み取り、それを data 配列に保存します。データを ThingSpeak に POST し、デバイスを低電力モードにします。

// Put your main code here, to run repeatedly:
void loop()
{
    // Write to successive fields in your channel by filling fieldData with up to 8 values.
    String fieldData[ NUM_FIELDS ];  

    // You can write to multiple fields by storing data in the fieldData[] array, and changing numFields.        
    // Write the moisture data to field 1.
    fieldData[ SOIL_MOISTURE_FIELD ] = String( readSoil( numMeasure ) ); 
    Serial.print( "Soil Moisture = " );
    Serial.println( fieldData[ SOIL_MOISTURE_FIELD ] );
    
    // Write the elapsed time from startup to Field 2.
    fieldData[ ELAPSED_TIME_FIELD ] = String( millis() ); 
    
    HTTPPost( NUM_FIELDS , fieldData );
    
    delay( 1000 );
    Serial.print( "Goodnight for "+String( SLEEP_TIME_SECONDS ) + " Seconds" );
    ESP.deepSleep( SLEEP_TIME_SECONDS * 1000000 );
    // If you disable sleep mode, add delay so you don't post to ThingSpeak too often.
    // delay( 20000 );
}

4) readSoil 関数を使用してセンサーに電力を供給し、ADC を使用して出力の電圧を読み取ります。測定後は電源を切ってください。

// This function reads the soil moisture sensor numAve times and returns the average.
long readSoil(int numAve)
{
  long ADCValue = 0;
  
  for ( int i = 0; i < numAve; i++ ) {
    digitalWrite( SENSOR_POWER, HIGH );  // Turn power to device on.
    delay(10);    // Wait 10 milliseconds for sensor to settle.
    ADCValue += analogRead( SOIL_PIN );     // Read the value from sensor.
    digitalWrite( SENSOR_POWER, LOW );   // Turn power to device off.
  }
  
  ADCValue = ADCValue / numAve;
  return ADCValue;                    // Return the moisture value.
}

5) connectWiFi 機能を使用してデバイスをワイヤレス ネットワークに接続します。

// Connect to the local Wi-Fi network
int connectWifi()
{
    
    while (WiFi.status() != WL_CONNECTED) {
        WiFi.begin( WIFI_NAME , PASSWORD );
        Serial.println( "Connecting to Wi-Fi" );
        delay( 2500 );
    }
    Serial.println( "Connected" );  // Inform the serial monitor.
}

6)チャネルに投稿するデータ文字列を構築します。ThingSpeak に接続し、Wi-Fi® クライアントを使用して HTTP POST を完了します。

// This function builds the data string for posting to ThingSpeak
    // and provides the correct format for the wifi client to communicate with ThingSpeak.
    // It posts numFields worth of data entries, and takes the
    // data from the fieldData parameter passed to it. 
  
int HTTPPost( int numFields , String fieldData[] ){
  
    if (client.connect( THING_SPEAK_ADDRESS , 80 )){

       // Build the postData string.  
       // If you have multiple fields, make sure the sting does not exceed 1440 characters.
       String postData= "api_key=" + writeAPIKey ;
       for ( int fieldNumber = 1; fieldNumber < numFields+1; fieldNumber++ ){
            String fieldName = "field" + String( fieldNumber );
            postData += "&" + fieldName + "=" + fieldData[ fieldNumber ];
            
            }

        // POST data via HTTP.
        Serial.println( "Connecting to ThingSpeak for update..." );
        Serial.println();
        
        client.println( "POST /update HTTP/1.1" );
        client.println( "Host: api.thingspeak.com" );
        client.println( "Connection: close" );
        client.println( "Content-Type: application/x-www-form-urlencoded" );
        client.println( "Content-Length: " + String( postData.length() ) );
        client.println();
        client.println( postData );
        
        Serial.println( postData );
        
        String answer=getResponse();
        Serial.println( answer );
    }
    else
    {
      Serial.println ( "Connection Failed" );
    }
    
}

7) getResponse を使用してサーバーからの応答を待機して受信します。

// Wait for a response from the server indicating availability,
// and then collect the response and build it into a string.

String getResponse(){
  String response;
  long startTime = millis();

  delay( 200 );
  while ( client.available() < 1 && (( millis() - startTime ) < TIMEOUT ) ){
        delay( 5 );
  }
  
  if( client.available() > 0 ){ // Get response from server.
     char charIn;
     do {
         charIn = client.read(); // Read a char from the buffer.
         response += charIn;     // Append the char to the string response.
        } while ( client.available() > 0 );
    }
  client.stop();
        
  return response;
}

チャネルの湿潤サイクルと乾燥サイクルを監視することで、有効な値の範囲を決定できます。ADC によって読み取られ、チャネルに投稿される数値は電圧に比例し、したがって土壌の水分にも比例します。値は温度、湿度、土壌の種類によって異なります。乾燥した土壌の値がわかれば、React アプリを使用して、植物に水をやる時期が来たことを通知することができます。React の設定の詳細については、React アプリ を参照してください。

参考

外部の Web サイト