今回はArduinoとEthernet Shieldを使い、自作したぼかし肥料の発酵熱をリアルタイムでモニタリングしてみる。
使用する部品は以下。
参考サイト
(こちらのサイトでは、Sparkfun Pachube製のガイガーカウンターモジュールSEN-09848を使用してPachubeにアップロードするための詳細な情報あり。
大変参考にさせていただきました。Sketchの一部分使わせていただいております。)
参考リンク先にはArduinoとPachubeを接続するためのたいていの事が書いてあるので、ここでは割愛する。
Pachubeにユーザ登録してフィードとデータストリームを設置した後、回路図とArduino、Ethernet Sheild、Ethernetケーブルをルータにつなげて
以下のスケッチをアップ。
CompostsFermentationTemp2Pachube ▼
/*
* sketch name : CompostsFermentationTemp2Pachube
* summary : ぼかし肥の発酵温度を4種類のフィードでオンラインモニタリングする
*/
// init setting //////////////////////////////////
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetDHCP.h>
#include <Sensirion.h>
// 設定ファイル読み込み
#include "PrivateSettings.h"
// Arduino 基準電圧
#define ARDUINO_VCC 5
// Pachube データストリームID
unsigned int datastream_ids[] = {0, 1, 2, 3, 4, 5, 6};
// 温度センサ type / 0:LM35DZ 1:LM60BIZ 2:LM61CIZ
unsigned int temperature_pins[] = {0, 1, 2, 3}; // アナログピン0,1,2,3
unsigned int temperature_sensor_type[] = {0, 0, 0, 0}; // 使用センサタイプ(temperature_pins の値に対応)
float temperature_gain[] = {5, 5, 5, 5}; // Op-amp ゲイン(temperature_pins の値に対応)
#define CNT_TEMPERATURE_PINS sizeof(temperature_pins) / sizeof(temperature_pins[0])
float temp_data[CNT_TEMPERATURE_PINS]; // 温度データ格納
// 気温・湿度・露点 type / SHT71
#define SHT_CLOCK_PIN 7 // CLOCK(デジタルピン)
#define SHT_DATA_PIN 8 // DATA(デジタルピン)
#define CNT_SHT 3
float sht_data[CNT_SHT]; // SHTデータ格納
// センシングデータ総数
#define SENSOR_CNT CNT_TEMPERATURE_PINS + CNT_SHT
// api.pachube.com IPアドレス
byte server_ip_address[] = {
173, 203, 98, 29
};
// TCP client
Client client(server_ip_address, 80);
// TCP client
Client log_client(log_server_ip_address, 80);
// 更新インターバル(minutes)
const unsigned int update_interval = 5;
// 次にフィードを更新する時刻
unsigned long next_execute_millis = 0;
// 更新データ
String csv_data = ""; // Pachube
float log_data[SENSOR_CNT]; // ログサーバ
// SHT-71
Sensirion obj_sht = Sensirion(SHT_DATA_PIN, SHT_CLOCK_PIN);
// function //////////////////////////////////
/*
* func name : calcTemperature
* processing : 温度センサの種類別計算処理
* param : arduino_vcc Arduino基準電圧
* sensor_type 0:LM35DZ / 1:LM60BIZ / 2:LM61CIZ
* analog_val Analog値(0-1023)
* gain Op-amp ゲイン
* return : 計測温度(℃)
*/
float calcTemperature(float arduino_vcc, int sensor_type, int analog_val, float gain)
{
float dc_offset; // DCオフセット電圧(V)
float factor; // 温度係数(V/1℃)
switch (sensor_type) {
case 0: // LM35DZ
dc_offset = 0; // DC offset;0V
factor = 0.01; // +10mV/℃
break;
case 1: // LM60BIZ
dc_offset = 0.424; // DC offset 424mV
factor = 0.00625; // +6.25mV/℃
break;
case 2: // LM61CIZ
dc_offset = 0.6; // DC offset 600mV
factor = 0.01; // +10mV/℃
break;
default:
return 0;
break;
}
return (((arduino_vcc * analog_val) / 1023) - (dc_offset * gain)) / (factor * gain);
}
/*
* func name : appendFloatValueAsString
* processing : Float型の値をString型に整形
* param : outString 文字列格納
* value 値格納
* return : 整形後の文字列
*/
void appendFloatValueAsString(String& outString, float value) {
int integerPortion = (int)value;
int fractionalPortion = (value - integerPortion + 0.0005) * 1000;
outString += integerPortion;
outString += ".";
if (fractionalPortion < 10) {
// e.g. 9 > "00" + "9" = "009"
outString += "00";
}
else if (fractionalPortion < 100) {
// e.g. 99 > "0" + "99" = "099"
outString += "0";
}
outString += fractionalPortion;
}
/*
* func name : updateDataStream2Pachube
* processing : Pachubeに値をアップデート
* param : environment_id 環境ID
* api_key APIキー
* value 更新値文字列(CSV形式)
* return : なし
*/
void updateDataStream2Pachube(int environment_id, char *api_key, String value) {
Serial.println(environment_id);
Serial.println(api_key);
Serial.println(value);
Serial.println(value.length());
// Try to connect to the server
Serial.println();
Serial.print("Connecting to Pachube...");
if (client.connect()) {
Serial.println("connected");
} else {
Serial.println("failed");
return;
}
// サーバにアクセスして指定したデータストリームを更新
client.print("PUT /v2/feeds/");
client.print(environment_id);
client.println(" HTTP/1.1");
client.println("User-Agent: Arduino");
client.println("Host: api.pachube.com");
client.print("X-PachubeApiKey: ");
client.println(api_key);
client.print("Content-Length: ");
client.println(value.length());
client.println("Content-Type: text/csv");
client.println();
client.println(value);
}
/*
* func name : updateDataLog
* processing : ログサーバにデータをアップロード
* param : value 更新値配列
* cnt 更新値総数
* return : なし
*/
void updateDataLog(float *value, unsigned int cnt) {
// Try to connect to the server
Serial.println();
Serial.print("Connecting to Log Server...");
if (log_client.connect()) {
Serial.println("connected");
} else {
Serial.println("failed");
return;
}
// 指定のwebサーバのPHPスクリプトにGET送信
log_client.write("GET ");
log_client.write(LOG_DIR);
for (int i = 0; i < cnt; i++) {
Serial.print("val");
Serial.print(i);
Serial.print(":");
Serial.println(value[i]);
if (i==0) {
log_client.write("?");
} else {
log_client.write("&");
}
log_client.write("val");
log_client.print(i, DEC);
log_client.write("=");
log_client.print(value[i], DEC);
}
log_client.write(" HTTP/1.1");
// log_client.write("HOST: ");
// log_client.write(LOG_DOMAIN);
// log_client.write("\n\n");
}
// setup //////////////////////////////////
void setup() {
Serial.begin(9600);
// DHCPセッション開始
EthernetDHCP.begin(mac_address);
}
// loop //////////////////////////////////
void loop() {
// DHCPによるIPアドレスのリースを維持
EthernetDHCP.maintain();
// 発酵温度(CSV形式で送信値を整形)
csv_data = "";
for (int i = 0; i < CNT_TEMPERATURE_PINS; i++) {
// Pachube
temp_data[i] = calcTemperature(ARDUINO_VCC, temperature_sensor_type[i], analogRead(temperature_pins[i]), temperature_gain[i]);
csv_data += datastream_ids[i];
csv_data += ",";
appendFloatValueAsString(csv_data, temp_data[i]);
csv_data += "\n";
// ログサーバ
log_data[i] = temp_data[i];
}
// 気温 & 湿度 & 露点
obj_sht.measure(&sht_data[0], &sht_data[1], &sht_data[2]);
int j = 0;
for (int k = CNT_TEMPERATURE_PINS; k < SENSOR_CNT; k++) {
// Pachube
csv_data += datastream_ids[k];
csv_data += ",";
appendFloatValueAsString(csv_data, sht_data[j]);
csv_data += "\n";
// ログサーバ
log_data[k] = sht_data[j];
j++;
}
/* Pachube */
// ホストからの応答を表示
if (client.available()) {
char c = client.read();
Serial.print(c);
}
if (client.connected()) {
Serial.println("Disconnecting.");
client.stop();
}
Serial.println();
Serial.println("Updating...");
// Pachubeにアップ
updateDataStream2Pachube(environment_id, API_KEY, csv_data);
/* ログサーバ */
// ホストからの応答を表示
if (log_client.available()) {
char c = client.read();
Serial.print(c);
}
if (log_client.connected()) {
Serial.println("Log Client Disconnecting.");
log_client.stop();
}
Serial.println();
Serial.println("Log Updating...");
// 別サーバにログを記録
updateDataLog(log_data, SENSOR_CNT);
delay((update_interval * 60) * 1000UL);
}
PrivateSetting.h ▼
/*
* sketch name : CompostsFermentationTemp2Pachube(PrivateSetting.h)
* summary : ぼかし肥の発酵温度を4種類のフィードでオンラインモニタリングする
*/
/* Pachube */
const int environment_id = 24902;
// APIキー
#define API_KEY "○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○"
// MACアドレス
byte mac_address[] = {
○○○○, ○○○○, ○○○○, ○○○○, ○○○○, ○○○○
};
/* ログサーバ */
// IPアドレス
byte log_server_ip_address[] = {
○○○, ○○○, ○○○, ○○○
};
// ホスト名
#define LOG_DOMAIN "○○○○○○○○○○○○"
// 保存処理ファイルパス
#define LOG_DIR "○○○○○○○○○○○○○○○○"
|
0 コメント:
コメントを投稿