エントリー

タグ「ESP8266」の検索結果は以下のとおりです。

ページ移動

  • ページ
  • 1
  • 2
  • 3

なんちゃって百葉箱を作ってみる

ESP8266と気象センサを使って,なんちゃって百葉箱を作ってみる

なんちゃってといっても実用レベルを目指すつもり

いろんな試行実験が必要なので完成までは時間が掛かる予定

はじめに

実のところデジタルセンサで百葉箱を作ろう計画はかなり前からあり研究準備していた

と,いうのも現在住んでる場所が山の側であり市街に設置されていたアメダスと気温が(-2℃位)異なるため自宅付近の気温をロギングしたかったためであった

それが2年前8月にアメダスが近く(300m位離れた場所)に引っ越してきたため作製の意欲が無くなり現在に至ることとなる

準備したパーツも勿体ないので重い腰を上げたって感じでもある

arduinoIDE

基盤はESP8266であり久々に使うことになるのだが,先ずアップデートされたarduinoIDE(ボードESP8266選択)で(かなり)嵌る

Setup.png

設定が増えていて「Crystal Freequency」を26MHzに設定しないと古いESP8266では問題が生じるようだ

例えばシリアル出力が指定bps通りに出力されず文字化けする

ESP8266でDHT11とLPS25Hを試す

IMG_20180909_102030659_BURST001.jpgIMG_20180909_135921606.jpg

Arduinoで試していたDHT11とLPS25HのスケッチがあるのでESP8266で動作させてみたところ,DHT11は(DHT22も)動作したがLPS25HはCPU依存コードもあってか動作不良となった

  • sizeof(int)の違い
  • ESP8266のバイトオーダーはLSBファースト

ほどなくスケッチの解決はしたが,LPS25HをESP8266とArduino(ATMega328P)で差し替えしながら計測値を比べていたところ情けない事に逆差しして破壊してしまう

IMG_20180915_210806939.jpg

大気圧センサとしてLPS25H,気温・湿度センサとしてSHT31を高精度なので利用しようと考えていたため残念なことに・・・既にLPS25Hは販売していないのでBME280に変更を余儀なくされた

BME280を使う

BME280からのデータ取得はややこしかったのでライブラリをこちらからいただくことにして入出力部をSPIからI2Cへとコンストラクタを修正

ESP8266のデフォルトのI2Cピンアサインは、SDA: IO04, SCL: IO05だが Wire.begin(SDA, SCL); で指定可能

BME280は省電力モードで使用

サーバ

データは自前のWebサーバで受けMySQLでDB化,閲覧には見栄えするグラフ化を予定

DBは以下のとおりテーブルを3個

CREATE TABLE IF NOT EXISTS `LOG` (
  `LOCATION`       char(2)         DEFAULT NULL COMMENT '計測場所(ID)'
, `DATETIME`       datetime        DEFAULT NULL COMMENT '適用日'
, `PRESSURE`       decimal(6,2)    DEFAULT NULL COMMENT '気圧'
, `TEMPERATURE`    decimal(4,2)    DEFAULT NULL COMMENT '気温'
, `HUMIDITY`       decimal(4,2)    DEFAULT NULL COMMENT '湿度'
, `BATTERY_VOLT`   decimal(4,2)    DEFAULT NULL COMMENT 'バッテリー電圧'
, `BATTERY_TEMP`   decimal(4,2)    DEFAULT NULL COMMENT 'バッテリー温度'
, PRIMARY KEY (`LOCATION`, `DATETIME`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='気象データログ'

CREATE TABLE IF NOT EXISTS `LOCATION` (
   `ID`             char(2)         DEFAULT NULL COMMENT '計測場所ID'
, `NAME`           varchar(32)     DEFAULT NULL COMMENT '計測場所名'
, `STATUS`         boolean         DEFAULT NULL COMMENT '計測有効'
, `PRES_ID`        char(2)         DEFAULT NULL COMMENT '気圧センサID'
, `TEMP_ID`        char(2)         DEFAULT NULL COMMENT '気温センサID'
, `HUMI_ID`        char(2)         DEFAULT NULL COMMENT '湿度センサID'
, PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='計測場所'

CREATE TABLE IF NOT EXISTS `SENSOR` (
  `ID`             char(2)         DEFAULT NULL COMMENT 'センサID'
, `NAME`           varchar(32)     DEFAULT NULL COMMENT '名称'
, `VENDOR`         varchar(32)     DEFAULT NULL COMMENT '売り手'
, PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='センサ'

受けはPHPでプログラミングして今回はPOSTを使用(GETは手動確認用で使う)

<?php

//自宅アメダス : 気象データ(気圧,気温,湿度)を登録
//
//コード:UTF-8N
// 行末:LF
//TAB:4

//インターフェイスチェック
if(php_sapi_name() == "cli") {
    //コマンドラインで実行
   exit(0);
}
//Web経由で実行

//登録データ取得
$inLoc  = empty($_POST['LOC'])? empty($_GET['LOC'])? "0":$_GET['LOC']: $_POST['LOC'];  //計測場所
$inPres = empty($_POST['PRES'])?empty($_GET['PRES'])? "":$_GET['PRES']:$_POST['PRES']; //気圧
$inTemp = empty($_POST['TEMP'])?empty($_GET['TEMP'])? "":$_GET['TEMP']:$_POST['TEMP']; //気温
$inHumi = empty($_POST['HUMI'])?empty($_GET['HUMI'])? "":$_GET['HUMI']:$_POST['HUMI']; //湿度

$inBVolt = empty($_POST['BVOLT'])?empty($_GET['BVOLT'])? "":$_GET['BVOLT']:$_POST['BVOLT']; //バッテリー電圧
$inBTemp = empty($_POST['BTEMP'])?empty($_GET['BTEMP'])? "":$_GET['BTEMP']:$_POST['BTEMP']; //バッテリー温度

if(empty($inLoc) || empty($inPres) && empty($inTemp) && empty($inHumi)) {
   //パラメタエラー
   $content .= "Error.\n";
} else {

    //DB接続
    $db = new mysqli("localhost", "tenki", "tenki", "tenki");
   $db->query("set names utf8");

    //登録
    $sql = "insert into LOG (LOCATION, DATETIME, PRESSURE, TEMPERATURE, HUMIDITY, BATTERY_VOLT, BATTERY_TEMP)";
   $sql .= " values (${inLoc}, now(), '${inPres}', '${inTemp}', '${inHumi}', '${inBVolt}', '${inBTemp}')";
    $db->query($sql);
    $db->close();
    $content .= "Ok.\n";
}

//コンテンツ出力
echo $content;

?>
消費電力

ESP8266とサーバ側のDB登録が出来ているので消費電力の確認を行った

IMG_20180924_200700705.jpg

(Waitで1分毎にデータをDB登録)

IMG_20180924_210738254.jpg

1時間で累積42mAhとなる

(ディープスリープ使用で10分毎にデータをDB登録)

IMG_20180927_060539865.jpg

12時間で8mAhとなった

これは先人様が計測されているのと変わりないようである

また(WiFi有効の)起動時には300mA,通信時には約70mA程流れるらしい

ロギング装置の作製(ESP8266版)

開発ボードでSD版が完成したので基板に載せた

ログ

(写真のようにESP-WROOM-02を置いたが上下逆に付けるようにすればコンパクトになるなと完成した後に気が付く)

正式なマイクロSDカードスロットはブレッドボートで開発用にとして利用したいのでマイクロSDカードアダプタにピンを付けて(余り物を)利用してみた

SDカード裏SDカード表

両端は未使用なので7ピンのみ取付,なかなか良い感じ

ピンの接続情報を記録しておく(上がスロット,下がアダプタの場合)

SD-PIN

放電器と高さを合わせ(合体)接続できるようにしたが,放電器の電源アダプタが左側で電源が接続できなくなり取り外して付け替えるのも大変なので電源アダプタを右側にも付け,ついでに入力が直5Vなので安全のため5.1Vのツェナーダイオードを追加

合体

テスト実施のログ出力(SDカード)

;Constant voltage : 1000mV
;End current : 100mA
0, 991, 325, 0
1, 1003, 311, 5
2, 1002, 310, 10
3, 997, 314, 15
4, 997, 314, 20
5, 996, 316, 26
6, 995, 318, 31
7, 995, 322, 36
8, 997, 323, 42
9, 1000, 326, 47
10, 1000, 332, 53
11, 1004, 334, 58
12, 1000, 344, 64
(略)
291, 999, 84, 1595
292, 998, 83, 1596
293, 997, 82, 1597

グラフ化すると

青線:放電流値(mA)

赤線:累積電力(mAh)

上記の試験サンプルは劣化している充電池のため大きな電流を流せていない

今後の展開

このボードではIoT化しないと効果を発揮しないのでWebとの連携仕様を考える

基本仕様として当初はロギング装置を汎用化と考えていたが,別物を作製することも早々無いしその都度プログラムを変えるのも趣味の世界はありなので,放電器専用のロギング装置として構築することにする

ログの数値表とグラフを表示する位までは構築していこうと思う(気長に・・・)

ESP8266開発ボードを作る

次回に「ESP-WROOM-02」を使おうとした時に,また回路図など探してブレッドボードに展開するのが面倒なので,偉そうなものではないが開発ボードを作っておくことにした

必要な仕様
  • プログラム書込みボタンとリセットボタン
  • 3.3V電源(USB電源から降圧させる)
  • 3.3ロジックのUSBシリアル変換
  • ESP-WROOM-02は取り外し可能(こうしないと意味がない)
  • LEDをIO15に接続(動作確認用)
準備

USBシリアル変換はaitendoのUSB-TTL変換キットを使う(既に制作済の物)

USB

このUSB-TTL変換キットは5Vロジックなので3.3Vロジックにする

CH340Gの仕様などを参照して3.3VをVCCに入れれば3.3Vとして動作するのを確認

パターンを見てみるとVCCに入るUSB5Vの部分をカットして3.3Vの3端子レギュレーターを経由しVCCに入れれば良さそう

パターン

他にカットできそうな場所が無かったのでココにしたが,削ったパターンのカスがUSBコネクタとの間に入り+-がショートするといった問題が起きて嵌った

パターンカット

入念に掃除して解決

ボードに実装

今回はブレッドボード基板を使ってみた

基板1

ミニブレッドボードを載せるためのスペースを作るため両端の空きに寄せて配置

基板

黒:リセットボタン

白:プログラム書込みボタン(押しながらリセットするとプログラム書込みモードとなる)

SWやLEDを配置するためパターンのカットも行った

基板裏

3端子レギュレーター(NJM2845DL1-33 3.3V800mA)は裏に配置

開発中

SDカードスロットを取り付けてプログラム開発中(AVR用のプログラムはCSの変更のみで動作した)

開発中

NTPで日時を取得できるのでタイムスタンプが使えそうだ

ロギング装置の作製とESP8266のセットアップ

ロギング装置の構想は前々からあるのだがロギングするようなシステム作ってないので着手しなかった

ところが今回作製した放電器はロギングの必要性が高いと感じログ装置を作製することにする

どう実現するか,基本スタンドアロンでのロギングするとして,装置毎(例えば放電器)にSDカード等を実装して保存する内蔵型か,UART通信などを経由してので外付け型となる

外付け型ならSDカード保存の他にフラッシュメモリー保存や無線通信にてクラウド保存も可能だし融通がききそう

そこで楽しめそうな外付け型でSDカードへのロギングをやってみることにした

SDログ

この装置は前にも似たような物を作製したことあるのでさくっと実験版は完成

SDカードは3.3Vロジックのため3.3V版Arduino(AVR)を利用したほうが回路が楽になる

外付けなのでプロトコルが必要となるが通信は無手順,ログの記録として開始と終了のみ決めた

 開始:@Begin

 終了:@End

ログ装置側のプログラム(簡単すぎだけど公開)

//    Serial Logging To SD Card
//
//    シリアル出力のロギングをSDカードに書き込む
//    シリアル:9600bps
//    SD:ファイル名は連番(Ex.log.1xxxx.txt)
//    プロトコル
//        @Begin. - @End.間をSDに書き込む
//    Ex.
//        @Begin.
//        ;Constant current : 500mA
//        ;End voltage : 1000mV
//        0, 1237, 0, 0
//        1, 1237, 499, 8
//        2, 1226, 501, 16
//        131, 1051, 499, 1088
//        @End.
//
#include <EEPROM.h>
#include <SPI.h>
#include <SD.h>

// SD card attached to SPI bus as follows:
// * MOSI - pin 11
// * MISO - pin 12
// * CLK  - pin 13
// * CS   - pin 10
// ※CS pinは使用しているシールドで変更する必要がある
//        イーサーネットシールドは 4
//        Adafruit のSDシールドは 10
//        Sparkfun のSDシールドは 8
//
//#define DEBUG        1

#define CSPIN        10                  //チップセレクト
#define LEDPIN        8                  //状態表示LED
#define BLINKTIME    1000                //点滅間隔

static char strBegin[] = { '@', 'B', 'e', 'g', 'i', 'n', '.', '\r', '\n', '\0' };
static char strEnd[] = { '@', 'E', 'n', 'd', '.', '\r', '\n', '\0' };

static uint16_t year = 2017;
static uint8_t month = 1, day = 1, hour = 19, minute = 0, second = 0;

static char fileName[16];                //ログファイル名

static boolean sd = false;               //SD書込み開始フラグ
static boolean light;                    //LED点灯フラグ
static int timer;                        //LED点滅時間カウンタ

static int getByte() {
    for(;;) {
        timer++;
        if(Serial.available()) {
            return(Serial.read());
        }
        delay(1);
        if(timer > BLINKTIME) {
            timer = 0;
            if(sd) {
                if(light) {
                    digitalWrite(LEDPIN, LOW);
                    light = false;
                } else {
                    digitalWrite(LEDPIN, HIGH);
                    light = true;
                }
            }
        }
    }
}

void dateTime(uint16_t *date, uint16_t *time) {
    // FAT_DATEマクロでフィールドを埋めて日付を返す
    *date = FAT_DATE(year, month, day);
    // FAT_TIMEマクロでフィールドを埋めて時間を返す
    *time = FAT_TIME(hour, minute, second);
}

static void makeFileName() {
    int fileNum = (EEPROM.read(0)<<8) + EEPROM.read(1);
    if(fileNum < 10000) fileNum = 10001;
    sprintf(fileName, "log%5d.txt", fileNum);
    //次のファイル番号
    fileNum++;
    EEPROM.write(0, fileNum>>8);
    EEPROM.write(1, fileNum&0xff);
}

void setup() {
    Serial.begin(9600);                    // 9600bpsでポートを開く
#ifdef DEBUG
//    Serial.println("Start");
#endif
    //SSピンは使用しない場合でも出力にしないとSDライブラリが動作しない
    //pinMode(SS, OUTPUT);
   
    //SDライブラリの初期化
    if(!SD.begin(CSPIN)) {
        Serial.println("SD Card failed");
        for(;;);
    }   
    //日付と時刻を返す関数を登録
    //登録することでファイルの作成日時や変更日時が記録できる
    SdFile::dateTimeCallback(&dateTime);

    //初期化正常で開始
    pinMode(LEDPIN, OUTPUT);
    digitalWrite(LEDPIN, HIGH);            //点灯
    light = true;
    sd = false;
    timer = 0;
}

void loop() {
    char c, buf[128];
    int n = 0;
    File dataFile;

    for(;;) {
        c = getByte();
        buf[n++] = c;
        if(c == '\n') {
            buf[n] = '\0';
            n = 0;
#ifdef DEBUG
//            Serial.print(buf);
#endif
            if(!sd) {
                if(!strcmp(buf, strBegin)) {
                    //sd write start
                    makeFileName();
                    if(dataFile = SD.open(fileName, FILE_WRITE)) {
                        sd = true;
#ifdef DEBUG
                        Serial.println("logging start");
#endif
                    } else {
                        //ファイルが開けなかったらエラーを出力
                        Serial.print("can not open ");
                        Serial.println(fileName);
                    }
                }
#ifdef DEBUG
                else {
                    //ignore string
                    Serial.print("ignore : ");
                    Serial.print(buf);
                }
#endif
            } else {
                if(!strcmp(buf, strEnd)) {
                    //sd write done
                    dataFile.close();
                    sd = false;
#ifdef DEBUG
                    Serial.println("logging done");
#endif
                } else {
                    //sd writting
                    dataFile.print(buf);
#ifdef DEBUG
                    Serial.print("sd wrt : ");
                    Serial.print(buf);
#endif
                }
            }
        }
    }
}

ログ装置側が動作してるかどうか判るようにLEDで通知(点灯:Reday,点滅:Logging)するようにした

・・・

さてボードに組み込もうかと思ったところで,どうせならってことで・・・

ESP-WROOM-02

いつか使おうと思いながら購入して置きっぱなしだった「ESP-WROOM-02」を取り出す(世間では「ESP-WROOM-32」が旬みたいだけど・・・)

いつもお世話になってるこちらを参考にしてブレッドボードに展開

ブレッドボード

ATコマンドで動作確認して(115200bps8N1,行末:CR+LF)

AT1

AT2

開発環境を整え(参考

IDE

プログラムを書き込み動作させることができた

注意点や嵌った事など

デフォルトでは「softAP」モードになっていて先ずは「station」モードに変更しないとWiFiが使えない(AT+CWMODE=1)

cc版でないとESPは扱えないのでダウンロードしてarduino.1.8.1を設定(和解統合されてIDEはorg版オンリーになったようだが),拙者はcc版だと何故か問題があったためorgを使っていたので,これまでのローカル設定が全部使えてない

尚,分裂時のorg版とは共存できるようなので良かった

ボード選択設定(追加)

ボード Generic ESP8266 Module
Flash Mode QIO
Flash Frequency 40MHz
CPU Frequency 80MHz
Flash Size 4M(3M SPIFFS)
Debug port Disabled
Debug Level なし
Reset Method 手動SWなら「ck」,自動の場合(スイッチサイエンスの開発ボードなら)「nodemcu」
Upload Speed 115200
シリアルポート シリアルポート番号

ページ移動

  • ページ
  • 1
  • 2
  • 3

ユーティリティ

検索

エントリー検索フォーム
キーワード

過去ログ

Feed