酒と薔薇の日々(その2)

好きなことだけ求めて生きるアスペ気味のINTJ人

[ビオIOT化計画] M5Atom-lite のDeepSleep実験

2021年07月08日 21時53分27秒 | マイコン(ESP32・Arduino等)

■低消費電力で運用する方法
 あれこれ調べると、起動時には80mA、WiFiが30mA、ディープスリープ時にも13mA程度は食うようです。
 結局は電源を大きいものに変えるとかソーラーにするとか・・・

■大きな問題
 WiFi接続が途中でSleepするとモジュールが動き続けて勝手の意電力を消費する件

 

■まずは単純な寝るだけのプログラム

ポイントは、RTC領域にあるメモリはDeepSleep中も給電され値を保持し続ける。
何かを引き継ぐ場合はここに記録するかEEPROMに書き込むべし。
サンプルは、esp_deep_sleep(15*1000000); 命令で15秒間眠り
起き上がった時はsetup()から再開する。
※次のステップからではない点に注意

こちらのサイト様を参考にさせてもらいました。m(_ _)m

Atomは 13mA 程度を消費するようです。確かに1日になると結構大きいわ・・・

----単純に15秒ごとに起きるプログラム-------

#include "M5Atom.h"

RTC_DATA_ATTR int bootCount = 0; // RTCメモリ域に変数を確保
     :
(自作関数省略)
     :
void setup() {
    bootCount++;
    M5.begin(true, false, true);  // use LED
 }
void loop() {
  int i;
  for (i=0;i<bootCount;i++) {
    led_color('B');
    delay(500);
    led_color('E');
    delay(500);
  }
  esp_deep_sleep(15*1000000);  // 60=1分 30=30秒
}

■メダカに組み込む

動くのだがシステム側にBUGがあって、Sleep中でもLEDが消えなくなる。
ネットに記事があった。FastLED.hを直接使うしかないそうだ。

// Ambientへデータ送信
// data1,2,3 ... 温度 pin21(one wire read)
// data8 ....... 照度 pin33(analog read)
// (no) ........ 水位(High/Low) pin22(digital PullUp) 
//
//   2021/7/8 h.shin

#include "M5Atom.h"
#include "Ambient.h"
#include <OneWire.h>
#include <DallasTemperature.h>
// #include  DeepSleepでLEDが消えないためこちらを使うべき

#define ONE_WIRE_BUS 21    // Temp Pin No

WiFiClient client;
Ambient ambient;
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

const char* ssid       = "WAXXXXXXXXX";
const char* password   = "8FXXXXXXXXX";

unsigned int channelId = 38XXXXXXXXX; // AmbientのチャネルID  shimojima+ambient@gmail.com
const char* writeKey = "d3XXXXXXXXX"; // ライトキー

int CDS_PIN = 33;     // CDS sell Pin No 33
int FLOAT_Pin = 22; // float sensor

float tmp;
float tmp2;
float tmp3;
int fukai;
int blight;
RTC_DATA_ATTR int bootCount = 0; // RTCメモリ域に変数を確保

void setup() {
    bootCount++;
    M5.begin(true, false, true);  // use LED
    Serial.begin(115200);
    //---WiFi--
    WiFi.begin(ssid, password);
    Serial.print("WiFi conect ");
    while(WiFi.status()!=WL_CONNECTED) {
      Serial.print(".");
      M5.dis.drawpix(0, 0xf00000); // green
      delay(250);
      M5.dis.drawpix(0, 0x000000); // Erase
      delay(250);
    }  

//--- 青・緑 交互に点滅 -------
    if( bootCount % 2 == 0 ){
        M5.dis.drawpix(0, 0xf00000); // green
    } else {
        M5.dis.drawpix(0, 0x0000f0); // Blue
    }    

    //---- initilize -----
    pinMode(CDS_PIN,INPUT);
    pinMode(FLOAT_Pin,INPUT_PULLUP);

    //--- 温度 ch0..2 -------
    sensors.begin();                 // 温度計開始
    sensors.requestTemperatures();   // 温度取得 [0]
    tmp = sensors.getTempCByIndex(0);
    tmp2 = sensors.getTempCByIndex(1);
    tmp3 = sensors.getTempCByIndex(2);
    delay(100);

    //--- 不快指数 -------
    fukai = 0.72 * (tmp2 + tmp3) + 40.6;

    //--- 照度 -------
    blight = analogRead(CDS_PIN);    // blightness  

    //--- Ambient -------
    ambient.begin(channelId, writeKey, &client);  // Ambient環境初期化
    delay(50);
    ambient.set(1, tmp);       // 温度 set
    ambient.set(2, tmp2);      // 温度 set
    ambient.set(3, tmp3);      // 温度 set
    ambient.set(7, fukai);     // 照度 set
    ambient.set(8, blight);    // 不快指数 set
    ambient.send(); // send!        
    delay(50);

    Serial.printf("\nRestart M5Atom-lite %d\n",bootCount);
    Serial.print(" IP:");
    Serial.print(WiFi.localIP());
    Serial.print(" Temp:"); Serial.print(tmp);
    Serial.print(" ");      Serial.print(tmp2);
    Serial.print(" ");      Serial.print(tmp3);
    Serial.printf(" fukai: %d", fukai);
    Serial.printf(" Blight: %d", blight);
    //------ 水位 --------
    int water = digitalRead(FLOAT_Pin);
    if (water == HIGH){
       Serial.println("  water: HIGH");
    } else{
       Serial.println("  water: LOW");
       M5.dis.drawpix(0, 0x00f000); // LED RED
    }
        
    //------ Sleep --------
    WiFi.disconnect();
    Serial.println("Ambinient Send End.  good night!");
    delay(500);
    esp_deep_sleep(30*1000000);  // 60=1分 30=30秒
    // Atom.hにBUGがあってsleep時にLEDが消えなくなる。解決は直接FastLEDを叩くhttps://tomoto335.hatenablog.com/entry/m5atom-dont-use-library
}

void loop() {
  // do nothing
}


[ビオIOT化計画] 温度3センサ化、照度、フロートを検知

2021年07月08日 10時53分10秒 | マイコン(ESP32・Arduino等)

昨晩から結構な大雨で、今朝は三原、黒瀬川などで川が氾濫
己斐小学校は午前中は職員も登庁不要令
まだ今晩にかけて降水が予想される。

--------------

さて、DHT11は今回1-wireが2系統となって混乱するのも面倒なので繋がないことにした。

温度プローブを3本接続し3データを取得。通常は送信の度にLEDが緑と青に交互点灯している。
更にフロートセンサを取り付け、ピンをプルアップ設定とし抵抗外付けを省略、水位が下がると赤色LEDが点滅する設定
Ambient側ではグラフの高さを設定し、d1..3を同時に表示させるように設定
追加で不快指数を計算させてd7で送信

実験結果のグラフは、
1つのグラフに照度
2つ目のグラフに気温、湿った紙を巻きつけたセンサ、Atom-liteの表面温度の3種類を計測し同時表示
オマケで不快指数75%程度でフラフラ
させている。

シリアルでの値取得状況。
データは、温度3個、不快指数、照度1個、最後が水位判定

キリも無いのでここらで一旦プログラミングは中断

----------------------------
温度3センサ、不快指数、照度 => Ambient送信、水位検査(LED赤)
----------------------------

// Ambientへデータ送信
// data1,2,3 ... 温度 pin21(one wire read)
// data8 ....... 照度 pin33(analog read)
// (no) ........ 水位(High/Low) pin22(digital PullUp) 
//
//   2021/7/8 h.shin

#include "M5Atom.h"
#include "Ambient.h"
#include
#include

#define ONE_WIRE_BUS 21    // Temp Pin No

WiFiClient client;
Ambient ambient;
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

const char* ssid       = "WAXXXXX";
const char* password   = "8FXXXXX";

unsigned int channelId = XXXXX; // AmbientのチャネルID  shimojima+ambient@gmail.com
const char* writeKey = "d3XXXXX"; // ライトキー

int CDS_PIN = 33;     // CDS sell Pin No 33
int FLOAT_Pin = 22; // float sensor

float tmp;
float tmp2;
float tmp3;
int fukai;
int blight;

void setup() {
    M5.begin(true, false, true);  // use LED
    delay(50);
    M5.dis.drawpix(0, 0x00f000); // RED RED
    delay(50);
    
    Serial.begin(115200);
    Serial.print("start M5Atom-lite\n");

    WiFi.begin(ssid, password);
    Serial.print("WiFi start ");
    while(WiFi.status()!=WL_CONNECTED) {
      delay(500);
      Serial.print("x");
    }  
    Serial.print("\r\nWiFi connected\r\nIP address: ");
    Serial.println(WiFi.localIP());
    M5.dis.drawpix(0, 0xf00000); // green

    ambient.begin(channelId, writeKey, &client);  // Ambient環境初期化
    sensors.begin();    // 温度計開始

    pinMode(CDS_PIN,INPUT);
    pinMode(FLOAT_Pin,INPUT_PULLUP);

    while (1 == 1){                   // キーが押されるまで緑点滅で待機  
      M5.dis.drawpix(0, 0xf00000); // green
      delay(100);
      M5.update();    
      if (M5.Btn.wasPressed()) {
        M5.dis.drawpix(0, 0xf00000); // green
        break;
      }
      M5.dis.drawpix(0, 0x000000); // black
      delay(100);
    }
}

int  cnt = 0;

void loop() {
    cnt++;
    Serial.print("IP:");
    Serial.print(WiFi.localIP());
    Serial.print("  Loop cnt:");
    Serial.print(cnt);

    //--- 青・緑 交互に点滅 -------
    if( cnt % 2 == 0 ){
        M5.dis.drawpix(0, 0xf00000); // green
    } else {
        M5.dis.drawpix(0, 0x0000f0); // Blue
    }    

    //--- 温度 ch0..2 -------
    sensors.requestTemperatures();   // 温度取得 [0]
    Serial.print("  Tmp[0] ");
     tmp = sensors.getTempCByIndex(0);
     Serial.print(tmp);
    Serial.print("  Tmp[1] ");
     tmp2 = sensors.getTempCByIndex(1);
     Serial.print(tmp2);
    Serial.print("  Tmp[2] ");
     tmp3 = sensors.getTempCByIndex(2);
     Serial.print(tmp3);
    delay(50);

    //--- 不快指数 -------
    fukai = 0.72 * (tmp2 + tmp3) + 40.6;
    Serial.printf("  fukai = %d", fukai);
    delay(50);

    //--- 照度 -------
    blight = analogRead(CDS_PIN);    // blightness  
    Serial.printf("\tBlight = %d", blight);
    delay(50);

    //--- Ambient -------
    ambient.set(1, tmp);       // 温度 set
    ambient.set(2, tmp2);      // 温度 set
    ambient.set(3, tmp3);      // 温度 set
    ambient.set(7, fukai);     // 照度 set
    ambient.set(8, blight);    // 不快指数 set
    ambient.send(); // send!        
    delay(50);

    //------ 水位 --------
    int water = digitalRead(FLOAT_Pin);
    if (water == HIGH){
       Serial.println("  water: HIGH");
    } else{
       Serial.println("  water: LOW");
       M5.dis.drawpix(0, 0x00f000); // LED RED
    }    
    //------ delay --------
//    delay(1 * 60000);   // 1 min
    delay(10 * 1000);   // second
}


Atom-liteでキー入力は直前にM5.update();が読み込み実行で必須

2021年07月08日 01時23分31秒 | マイコン(ESP32・Arduino等)

キーの解説1サイト

ボタンが押されるまで待って、メイン処理を開始したかったが、if (M5.Btn.wasPressed()) だけを記述しても動かなかった。
どうもM5.update()を使わないとダメポイ
調べるとステータスを読み込む命令の本体がこれ update() らしい。
その後で得たデータを wasPressed() で参照するみたい。

思い違いしてましたw

ちなみに押されて300ms程度待ってもう一度読み込み+チェックすると、長押し判定が可能です。

#include "M5Atom.h"

void setup() {
    M5.begin(true, false, true);  // use LED
    delay(50);
    M5.dis.drawpix(0, 0x00f000); // RED RED
    delay(50);
    Serial.begin(115200);
    Serial.print("start M5Atom-lite\n");

    while (1 == 1){ 
      delay(100);
      Serial.print(".");
      M5.update();    
      if (M5.Btn.wasPressed()) {
        M5.dis.drawpix(0, 0xf00000); // green
        Serial.print("   Pushed!   ");
        break;
      }
    }
}

void loop() {
    delay(100);
    Serial.print("_");
}