土壌水分のリモート測定装置を作ろうとしていましたが、センサーの部分について少々問題があり挫折中。 で、取りあえずESP8266のADCを利用してデータを取得、基板上のLCDに表示して、更にデータをWiFi経由でサーバーに送る部分は使えるレベルのようなので公開することにします。
ESP8266のADCで0~1Vを1024の分解能で計測する事が出来ます。 ルーターのアドレス、パスワードやホストのURL等を後から変更できるようにSDカードで管理できるようにしてみました(セキュリティ上の問題がありますので、注意する必要があります) 。
ユニバーサル基板上に組んでいますが、専用の基板を起こせば、この半分くらいのサイズには出来ると思います。
疑問点;
ESP8266のDeep Sleep modeで最大1時間程度のインターバルが出来るはずなのですが、うまく行きませんでした。 30分位が限界のようですが、何故?
SD cardは最近の容量の大きいものは使用できません。大容量のSDカードに対応した(ファイル形式の異なる)スケッチが見つかりませんでした。 もっとも、この場合、大容量は要らないので、問題ではありませんが。
/* Sketch */
/*
*
*
*/
#include
extern "C" {
#include "user_interface.h"
}
#include
#include
#include
#include
Sd2Card card;
ST7032 lcd;
const int chipSelect = 2;
// router情報、接続情報などのdefault値 port番号が固定(80)にしてあるので注意
char ssid[30] = "?????";
char password[30] = "**********";
char Id[13] = "********";
char host[20] = "192.168.1.3";
const int httpPort = 80;
boolean WiFiFlag = false;
// ESPのADCの生データを取得 データ変換は後で、、、
uint tout_get(){
uint ADC_Value = 0.0;
count = 5; // 5回計測して平均値を返す
uint temp = 0;
for(int i = 0; i < count; i++ ){
ADC_Value = system_adc_read();
Serial.println("===> " + String(ADC_Value));
temp = temp+ADC_Value;
delay(30);
}
temp = temp/count;
// Serial.println("ADC_Value = " + String(temp));
return temp;
}
// SSIDの指定されたファイル名のファイルの内容(文字列)を返す
char *read_sd(char* file) {
// open the file for reading:
File myFile = SD.open(file, FILE_READ);
char *s0, *s1;
s0 = s1;
if (myFile) {
// read from the file until there's nothing else in it:
while (myFile.available()) {
*s1++ = myFile.read();
}
*s1 = '\0';
// close the file:
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening " + file);
}
return *s0;
}
void setup() {
Serial.begin(115200);
delay(10);
#if 0
// 自分のMAC addressの取得と表示
byte mac_addr[6];
WiFi.macAddress(mac_addr);
char buff[20];
Serial.print("Mac address: ");
sprintf(buff, "%02X:%02X:%02X:%02X:%02X:%02X",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.println(buff);
#endfi
// SDカード読み取りの初期化(設定)
Serial.print("Initializing SD card...");
if (!SD.begin(chipSelect)) {
Serial.println("initialization failed!");
// SD card無しでdefaultで動かすのなら、ここのコメントを取る
// return;
}
Serial.println("initialization done.");
Serial.println("");
Serial.println("Started");
// SDカードの情報の読み込み
ssid = read_sd("ssid.txt"); // WiFiルーターの名前
password = read_sd("pass.txt"); // WiFi接続のためのpassword
Id = read_sd("Id.txt"); // 本情報の識別のための任意の名前文字列
host = read_sd("host.txt"); // HostのIPアドレス或いはURL
delay(500); //Why?, but need this, otherwise WiFi cannot connect to
// SSIDから取得した情報でWiFiと接続
char *s = ssid;
if(*s != '?' ){
WiFi.begin(ssid, password);
Serial.println("connecting to " + String(ssid) + " pass: " + String(password) );
int i=0;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
i++;
}
WiFiFlag = true; // When connection being made, then transmit data to WiFi, otherwise only to LCD.
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
} else {
WiFiFlag = false;
}
// LCDの初期化
lcd.begin(8,2);
lcd.setContrast(25);
delay(40);
}
void loop() {
String s1;
int xx;
// データ計測
xx = tout_get();
s1 = String(xx) + " C"; //仮に温度だとして
// LCDへの表示
lcd.clear();
lcd.setCursor(2,0);
lcd.print(s1);
Serial.println(" ==== Temp = " + s1 );
// WiFiでHostに接続してデータ送出
if (WiFiFlag){
// Use WiFiClient class to create TCP connections
Serial.print("connecting to ");
Serial.println(host);
WiFiClient client;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
}
// URIを生成 Host側がIdentifier,data1,data2,data3,data4,data5,data6を受け取るようにしているので使っていなくても数だけ""を入れる
String url = "/data/data_logger.php";
url += "?Identifier=" + String(Id);
url += "&data1="+String(xx);
url += "&data2=" +String("");
url += "&data3=" +String("");
url += "&data4="+String("");
url += "&data5=" +String("");
url += "&data6=" +String("");
// Serial.print("Requesting URL: ");
// Serial.println("GET "+url);
// Hostにデータを送出
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
delay(50);
// Hostからの応答を読み込み、serialに表示
while(client.available()){
String line = client.readStringUntil('\r');
Serial.print(line);
}
Serial.println();
Serial.println("closing connection");
}
//DEEP SLEEPモード突入命令
Serial.println("DEEP SLEEP START!!");
//1:μ秒での復帰までのタイマー時間設定 2:復帰するきっかけの設定(モード設定)
//ESP.deepSleep( (30*1000*1000), WAKE_RF_DEFAULT); // 1 min
ESP.deepSleep( (60*1000*1000) * 30, WAKE_RF_DEFAULT); // uint32 = 4294967296micro sec, 4295 sec, 1.1 hour. でも30分位が限界?
//deepsleepモード移行までのダミー命令
delay(1000);
}
ESP8266のADCで0~1Vを1024の分解能で計測する事が出来ます。 ルーターのアドレス、パスワードやホストのURL等を後から変更できるようにSDカードで管理できるようにしてみました(セキュリティ上の問題がありますので、注意する必要があります) 。
ユニバーサル基板上に組んでいますが、専用の基板を起こせば、この半分くらいのサイズには出来ると思います。
疑問点;
ESP8266のDeep Sleep modeで最大1時間程度のインターバルが出来るはずなのですが、うまく行きませんでした。 30分位が限界のようですが、何故?
SD cardは最近の容量の大きいものは使用できません。大容量のSDカードに対応した(ファイル形式の異なる)スケッチが見つかりませんでした。 もっとも、この場合、大容量は要らないので、問題ではありませんが。
/* Sketch */
/*
*
*
*/
#include
extern "C" {
#include "user_interface.h"
}
#include
#include
#include
#include
Sd2Card card;
ST7032 lcd;
const int chipSelect = 2;
// router情報、接続情報などのdefault値 port番号が固定(80)にしてあるので注意
char ssid[30] = "?????";
char password[30] = "**********";
char Id[13] = "********";
char host[20] = "192.168.1.3";
const int httpPort = 80;
boolean WiFiFlag = false;
// ESPのADCの生データを取得 データ変換は後で、、、
uint tout_get(){
uint ADC_Value = 0.0;
count = 5; // 5回計測して平均値を返す
uint temp = 0;
for(int i = 0; i < count; i++ ){
ADC_Value = system_adc_read();
Serial.println("===> " + String(ADC_Value));
temp = temp+ADC_Value;
delay(30);
}
temp = temp/count;
// Serial.println("ADC_Value = " + String(temp));
return temp;
}
// SSIDの指定されたファイル名のファイルの内容(文字列)を返す
char *read_sd(char* file) {
// open the file for reading:
File myFile = SD.open(file, FILE_READ);
char *s0, *s1;
s0 = s1;
if (myFile) {
// read from the file until there's nothing else in it:
while (myFile.available()) {
*s1++ = myFile.read();
}
*s1 = '\0';
// close the file:
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening " + file);
}
return *s0;
}
void setup() {
Serial.begin(115200);
delay(10);
#if 0
// 自分のMAC addressの取得と表示
byte mac_addr[6];
WiFi.macAddress(mac_addr);
char buff[20];
Serial.print("Mac address: ");
sprintf(buff, "%02X:%02X:%02X:%02X:%02X:%02X",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.println(buff);
#endfi
// SDカード読み取りの初期化(設定)
Serial.print("Initializing SD card...");
if (!SD.begin(chipSelect)) {
Serial.println("initialization failed!");
// SD card無しでdefaultで動かすのなら、ここのコメントを取る
// return;
}
Serial.println("initialization done.");
Serial.println("");
Serial.println("Started");
// SDカードの情報の読み込み
ssid = read_sd("ssid.txt"); // WiFiルーターの名前
password = read_sd("pass.txt"); // WiFi接続のためのpassword
Id = read_sd("Id.txt"); // 本情報の識別のための任意の名前文字列
host = read_sd("host.txt"); // HostのIPアドレス或いはURL
delay(500); //Why?, but need this, otherwise WiFi cannot connect to
// SSIDから取得した情報でWiFiと接続
char *s = ssid;
if(*s != '?' ){
WiFi.begin(ssid, password);
Serial.println("connecting to " + String(ssid) + " pass: " + String(password) );
int i=0;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
i++;
}
WiFiFlag = true; // When connection being made, then transmit data to WiFi, otherwise only to LCD.
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
} else {
WiFiFlag = false;
}
// LCDの初期化
lcd.begin(8,2);
lcd.setContrast(25);
delay(40);
}
void loop() {
String s1;
int xx;
// データ計測
xx = tout_get();
s1 = String(xx) + " C"; //仮に温度だとして
// LCDへの表示
lcd.clear();
lcd.setCursor(2,0);
lcd.print(s1);
Serial.println(" ==== Temp = " + s1 );
// WiFiでHostに接続してデータ送出
if (WiFiFlag){
// Use WiFiClient class to create TCP connections
Serial.print("connecting to ");
Serial.println(host);
WiFiClient client;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
}
// URIを生成 Host側がIdentifier,data1,data2,data3,data4,data5,data6を受け取るようにしているので使っていなくても数だけ""を入れる
String url = "/data/data_logger.php";
url += "?Identifier=" + String(Id);
url += "&data1="+String(xx);
url += "&data2=" +String("");
url += "&data3=" +String("");
url += "&data4="+String("");
url += "&data5=" +String("");
url += "&data6=" +String("");
// Serial.print("Requesting URL: ");
// Serial.println("GET "+url);
// Hostにデータを送出
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
delay(50);
// Hostからの応答を読み込み、serialに表示
while(client.available()){
String line = client.readStringUntil('\r');
Serial.print(line);
}
Serial.println();
Serial.println("closing connection");
}
//DEEP SLEEPモード突入命令
Serial.println("DEEP SLEEP START!!");
//1:μ秒での復帰までのタイマー時間設定 2:復帰するきっかけの設定(モード設定)
//ESP.deepSleep( (30*1000*1000), WAKE_RF_DEFAULT); // 1 min
ESP.deepSleep( (60*1000*1000) * 30, WAKE_RF_DEFAULT); // uint32 = 4294967296micro sec, 4295 sec, 1.1 hour. でも30分位が限界?
//deepsleepモード移行までのダミー命令
delay(1000);
}
0 件のコメント:
コメントを投稿