【Aruduino】環境測定システム
・温度湿度をセンサーで取得
・Wifi経由でインターネットに接続
・Googleスプレットシートに自動入力
#include <Time.h> //時刻取得
#include <TimeLib.h>//時刻取得
#include <NTP.h> //時刻取得
#include <ESP8266WiFi.h> //WIFI
#include <WiFiClient.h> //WIFI
#include <SPI.h> //SPI通信
#define SS 15 //SPI通信出力ピン15番
//待ち時間(ウエイト10秒=10000//2分-110000/3分-170000で設定)+関数内delayで5秒
#define Latency 50000 //1分-50000
//#define Latency 110000 //2分-110000
//#define Latency 170000 //3分-170000
//#define Latency 170000 //4分-230000
//グローバル変数の宣言*********************************************************************
char ssid[] = "**********";
char password[] = "************";
char host[] = "**********com";
char url[] = "/trigger/test/with/key/*************"; //送信1
char url2[] = "/trigger/No.1/with/key/***********"; //送信2
int port = 80;
//[setup関数]*********************************************************************
void setup() {
Serial.begin(115200); //シリアル通信
Serial.println("");
SPI.begin(); //SPI通信開始
SPI.setDataMode(SPI_MODE0); //SPIモード0 デフォルトはモード0
SPI.setBitOrder(MSBFIRST); //MSBから送信 デフォルトはMSBFIRST
pinMode(SS, OUTPUT); //SS(15)を出力に設定
//SPI.setClockDivider(SPI_CLOCK_DIV2); //8MHz クロック分周設定(未使用)
ntp_begin(2390); //NTP設定(ポート設定)
//setTimeServer("ntp.ring.gr.jp"); //NTPサーバを変更 (デフォルト: ntp.nict.jp)
}
//[●Loop関数]*********************************************************************
void loop() {
//wifi環境設定
connectWifi();
//時刻取得 [●Loop関数]
time_t n = now();
time_t t;
char str_day[20]; //日付格納
char str_time[20]; //時間格納
const char* format1 = "%04d-%02d-%02d"; //雛形(2016-10-31)
const char* format2 = "%02d:%02d:%02d"; //雛形(00:00:00)
t = localtime(n, 9);// JST
sprintf(str_day, format1, year(t), month(t), day(t));//日付をstr_day変数に代入(文字列)
sprintf(str_time, format2, hour(t), minute(t), second(t));//時間をstr_time変数に代入(文字列)
Serial.print("str_day = ");
Serial.println(str_day);
Serial.print("str_time = ");
Serial.println(str_time);
delay(1000); //ウエイト10秒=10000
//ADC値を代入[●Loop関数]
double adc_ch0 = 0; //ADC値格納(CH0温度)
double adc_ch1 = 0; //ADC値格納(CH1湿度)
double adc_ch2 = 0; //ADC値格納(CH2照度)
double adc_ch3 = 0; //ADC値格納(CH3土壌水分)
double adc_ch4 = 0; //ADC値格納(CH4風速)
double adc_ch5 = 0; //ADC値格納(CH5風向)
double adc_ch6 = 0; //ADC値格納(CH6雨量)
double adc_ch7 = 0; //ADC値格納(CH7****)
/*
adc_ch0 = value0(); //CH0温度(value0関数の値を代入)
delay(200); //ウエイト10秒=10000
adc_ch1 = value1(); //CH1湿度(value1関数の値を代入)
delay(200); //ウエイト10秒=10000
adc_ch2 = value2(); //CH2照度(value2関数の値を代入)
delay(200); //ウエイト10秒=10000
adc_ch3 = value3(); //CH3土壌(value3関数の値を代入)
delay(200); //ウエイト10秒=10000
*/
adc_ch0 = value0(); //CH0温度(value0関数の値を代入)
delay(200); //ウエイト0.2秒
adc_ch1 = value1(); //CH1湿度(value1関数の値を代入)
delay(200); //ウエイト0.2秒
adc_ch2 = value2(); //CH2照度(value2関数の値を代入)
delay(200); //ウエイト0.2秒
adc_ch3 = value3(); //CH3土壌(value3関数の値を代入)
delay(200); //ウエイト0.2秒
adc_ch4 = value4(); //CH4風速(value4関数の値を代入)
delay(200); //ウエイト0.2秒
adc_ch5 = value5(); //CH5風向(value5関数の値を代入)
delay(200); //ウエイト0.2秒
adc_ch6 = value6(); //CH6雨量(value6関数の値を代入)
delay(200); //ウエイト0.2秒
adc_ch7 = value7(); //CH7****(value7関数の値を代入)
delay(200); //ウエイト0.2秒
//ADC値格納変数の初期化[●Loop関数]
double analog0 = 0; //CH0温度
double analog1 = 0; //CH1湿度
double analog2 = 0; //CH2照度
double analog3 = 0; //CH3土壌水分
double analog4 = 0; //CH4風速
double analog5 = 0; //CH5風向
double analog6 = 0; //CH6雨量
double analog7 = 0; //CH7****
double analog8 = 0; //その他1
double analog9 = 0; //その他2
double analog10 = 0; //その他3
//CH0を温度(℃)に変換[●Loop関数]
adc_ch0 = adc_ch0 + 9;
analog0 = ((adc_ch0)*3300/1024-600)/10; //LM61-5v
//CH1を湿度(%)に変換[●Loop関数]
analog1 = ((adc_ch1)*3300/1024)/10;
//CH2を照度(lux)に変換[●Loop関数]
double v_lux = 0;
double vref = 5;//電圧
double r_lux = 1000;//抵抗値(10k=10000)
v_lux = adc_ch2*vref/1024;
analog2 = 2*(v_lux/r_lux)*1000000;
//CH3を土壌(水分量)に変換[●Loop関数]
analog3 = ((adc_ch3)*3300/1024-600)/10; //LM61-5v
//analog3 = adc_ch3;
delay(1000); //ウエイト1秒
//CH4を風速()に変換[●Loop関数]
adc_ch4 = 4;//test
analog4 = adc_ch4;
delay(1000); //ウエイト1秒
//CH5を風向()に変換[●Loop関数]
adc_ch5 = 5;//test
analog5 = adc_ch5;
delay(1000); //ウエイト1秒
//CH6を雨量()に変換[●Loop関数]
adc_ch6 = 6;//test
analog6 = adc_ch6;
delay(1000); //ウエイト1秒
//CH7を***()に変換[●Loop関数]
adc_ch7 = 7;//test
analog7 = adc_ch7;
delay(1000); //ウエイト1秒
//コメント
analog8 = 8;//その他1
analog9 = 9;//その他2
analog10 = 10;//その他3
//送信データを文字列にする(doubule→char型へ変換)[●Loop関数]
char str0[10]="1";//スプレッドシートQuery関数対策用
char str1[30]={0};//温度
char str2[30]={0};//湿度
char str3[30]={0};//照度
char str4[30]={0};//土壌水分
char str5[30]={0};//風速
char str6[30]={0};//風向
char str7[30]={0};//雨量
char str8[30]={0};//****
char str9[30]={0};//****
char str10[30]={0};//****
char str11[30]={0};//****
//char str12[30]={0};//
//char str13[30]={0};//
//char str14[30]={0};//
//char str15[30]={0};//
//http://garretlab.web.fc2.com/arduino/reverse_lookup/index.html#string-float_to_string
dtostrf(analog0, 6, 1, str1);//温度
dtostrf(analog1, 6, 1, str2);//湿度
dtostrf(analog2, 6, 1, str3);//照度
dtostrf(analog3, 6, 1, str4);//土壌水分
dtostrf(analog4, 6, 1, str5);//風速
dtostrf(analog5, 6, 1, str6);//風向
dtostrf(analog6, 6, 1, str7);//雨量
dtostrf(analog7, 6, 1, str8);//****
//コメント
dtostrf(analog8, 6, 1, str9);//****
dtostrf(analog9, 6, 1, str10);//****
dtostrf(analog10, 6, 1, str11);//****
delay(1000); //ウエイト1秒
//送信データ文字列を結合する[●Loop関数]
char sosin[99] = {0};//文字数60
sprintf(sosin, "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", str0,str_day,str_time,str1,str2,str3,str4,str5,str6,str7,str8,str9,str10,str11);
//sprintf(sosin, "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", str0,str_day,str_time,str1,str2,str3,str4,str5,str6,str7,str8,str9,str10,str11);
delay(1000); //ウエイト1秒
//送信[●Loop関数]
httpPostJson(sosin);//test1
//送信2[●Loop関数]
//httpPostJson2(sosin);//No.1
//シリアルモニタ用表示[●Loop関数]
Serial.print("analog0(C ) = ");
Serial.print(analog0);
Serial.print("/");
Serial.println(adc_ch0);
Serial.print("analog1(% ) = ");
Serial.print(analog1);
Serial.print("/");
Serial.println(adc_ch1);
Serial.print("analog2(lx) = ");
Serial.print(analog2);
Serial.print("/");
Serial.println(adc_ch2);
Serial.print("analog3(D%) = ");
Serial.print(analog3);
Serial.print("/");
Serial.println(adc_ch3);
Serial.print("analog4() = ");
Serial.print(analog4);
Serial.print("/");
Serial.println(adc_ch4);
Serial.print("analog5() = ");
Serial.print(analog5);
Serial.print("/");
Serial.println(adc_ch5);
/*
Serial.print("analog6() = ");
Serial.print(analog6);
Serial.print("/");
Serial.println(adc_ch6);
Serial.print("analog7() = ");
Serial.print(analog7);
Serial.print("/");
Serial.println(adc_ch7);
*/
Serial.print("sosin = ");
Serial.println(sosin);
//●次の送信まで待つ時間[●Loop関数]
delay(Latency); //#define
Serial.println("LOOP END-------------------------------------------");
}
//関数の定義******************************************************************************
//▼▼▼value0関数の定義(温度アナログ値の取得)
double value0(void){
double sum = 0; //戻り値
int ans = 0; //SPI関数の戻り値格納
ans=get_adc(0); //CH0
sum=ans; //double型←int型
return sum;
}
//▼▼▼value1関数の定義(湿度アナログ値の取得)
double value1(void){
double sum = 0; //戻り値
int ans = 0; //SPI関数の戻り値格納
ans=get_adc(1); //CH1
sum=ans; //double型←int型
return sum;
}
//▼▼▼value2関数の定義(照度アナログ値の取得)
double value2(void){
double sum = 0; //戻り値
int ans = 0; //SPI関数の戻り値格納
ans=get_adc(2); //CH2
sum=ans; //double型←int型
return sum;
}
//▼▼▼value3関数の定義(土壌水分アナログ値の取得)
double value3(void){
double sum = 0; //戻り値
int ans = 0; //SPI関数の戻り値格納
ans=get_adc(3); //CH3
sum=ans; //double型←int型
return sum;
}
//▼▼▼value4関数の定義()
double value4(void){
double sum = 0; //戻り値
int ans = 0; //SPI関数の戻り値格納
ans=get_adc(4); //CH4
sum=ans; //double型←int型
return sum;
}
//▼▼▼value5関数の定義()
double value5(void){
double sum = 0; //戻り値
int ans = 0; //SPI関数の戻り値格納
ans=get_adc(5); //CH5
sum=ans; //double型←int型
return sum;
}
//▼▼▼value6関数の定義()
double value6(void){
double sum = 0; //戻り値
int ans = 0; //SPI関数の戻り値格納
ans=get_adc(6); //CH5
sum=ans; //double型←int型
return sum;
}
//▼▼▼value7関数の定義()
double value7(void){
double sum = 0; //戻り値
int ans = 0; //SPI関数の戻り値格納
ans=get_adc(7); //CH5
sum=ans; //double型←int型
return sum;
}
/*
double value(int x){
double sum = 0; //戻り値
int ans = 0; //SPI関数の戻り値格納
ans=get_adc(x); //CH0
sum=ans; //double型←int型
return sum;
}
*/
//関数の定義******************************************************************************
//▼▼▼connectWifi関数の定義------------------
void connectWifi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("connected!");
}
//▼▼▼httpPostJson関数の定義 送信1()------------------
void httpPostJson(char *data1) {
WiFiClient wifiClient;
String json = "{\"value1\":\""+String(data1)+"\"}";
//String json = "{\"value1\":\""+String(data1)+"\", \"value2\":\""+String(data2)+"\", \"value3\":\""+String(data3)+"\"}";
if (!wifiClient.connect(host, port)) {
Serial.println("connection failed");
return;
}
Serial.println("http POST--test");
wifiClient.println(String("POST ") + url + " HTTP/1.1");
wifiClient.println(String("Host: ") + host);
wifiClient.println("Cache-Control: no-cache");
wifiClient.println("Content-Type: application/JSON");
wifiClient.print("Content-Length: ");
wifiClient.println(json.length());
wifiClient.println();
wifiClient.println(json);
}
//▼▼▼httpPostJson2関数の定義 送信2()------------------
void httpPostJson2(char *data1) {
WiFiClient wifiClient;
String json = "{\"value1\":\""+String(data1)+"\"}";
//String json = "{\"value1\":\""+String(data1)+"\", \"value2\":\""+String(data2)+"\", \"value3\":\""+String(data3)+"\"}";
if (!wifiClient.connect(host, port)) {
Serial.println("connection failed");
return;
}
Serial.println("http POST--No.1");
wifiClient.println(String("POST ") + url2 + " HTTP/1.1");
wifiClient.println(String("Host: ") + host);
wifiClient.println("Cache-Control: no-cache");
wifiClient.println("Content-Type: application/JSON");
wifiClient.print("Content-Length: ");
wifiClient.println(json.length());
wifiClient.println();
wifiClient.println(json);
}
//関数の定義******************************************************************************
//▼▼▼get_adc関数の定義------------------
int get_adc(byte ch){
byte data[2] = {0,0};//SPI通信用変数/配列初期化
int analog_data = 0;//AD変換値(10bit)用変数
//①SPI開始時にSSをLOWにする
digitalWrite(SS, LOW);
//②1回目の送受信は捨てる
SPI.transfer(0x01);//スタートビット送信(転送するバイト1(0x01)/戻り値(受信したバイト)
//③2回目の送受信は値の上位8ビット。
data[0] = SPI.transfer((ch << 4) | 0x80);//Single-ended チャンネル選択 bit9 bit8取得
//④3回目(値が下位8ビット
data[1] = SPI.transfer(0); //bit7 ~ bit0取得
//⑤data1とdata2の計算と代入
analog_data = ((data[0] & 0x03) << 8) | data[1]; //data1には16bitが入っている
//&は両方1
//⑥SPI終了時にCSをHIGHにする
digitalWrite(SS, HIGH);//SS HIGH
return analog_data;//戻り値
}
/*
//●異常感知検出(送信3を使用Maker→IFスマホへ)
int num1,num2,num3,num4,num5;
double sum5; //異常感知検出
if( sum1 > 29 ){ //CH0温度
delay(10000); //ウエイト10秒(10000)1万
num1 = 110;
httpPostJson3( num1 );
}
Serial.println("1***************************************");
if( sum2 > 80 ){
delay(10000); //ウエイト10秒(10000)1万
num2 = 120;
httpPostJson3( num2 ); //CH1湿度
}
Serial.println("2***************************************");
if( sum2 < 30 ){
delay(10000); //ウエイト10秒(10000)1万
num3 = 121;
httpPostJson3( num3 ); //CH1湿度
}
Serial.println("3***************************************");
if( sum4 > 600 ){
delay(10000); //ウエイト10秒(10000)1万
num4 = 140;
httpPostJson3( num4 ); //CH3土壌
}
Serial.println("4***************************************");
if( sum4 < 300 ){
delay(5000); //ウエイト10秒(10000)1万
num5 = 141;
httpPostJson3( num5 ); //CH3土壌
}
Serial.println(num1);
Serial.println(num2);
Serial.println(num3);
Serial.println(num4);
Serial.println(num5);
delay(1000); //ウエイト10秒=10000
*/