知的好奇心 for IoT

IoT関連の知的好奇心を探求するブログです

高精度温湿度センサーSHT31が付属しているスゴイCO2センサーSCD30を見つけたのでESP8266のDeep Sleepで使えるようにした

前回はベランダの温湿度センサーをSHT31に変更してリニューアルした記事を書きました。

それから間を開けずにスゴイセンサーを千石電商で見つけてしましました。

このセンサー、高精度非分散型赤外線(NDIR)ベースのCO2センサーで左下の赤枠部分にSHT31が付随しています。I2Cに対応しているので、これ一つで温度・湿度・CO2を簡単に計測することができるスゴ物です。値段もスゴイですが...。

f:id:IntellectualCuriosity:20190827194611j:plain

ただ、このセンサー、大きい(と言っても縦35mm)のと上部の窓が2秒に1回オレンジ色に光って赤外線を放出しているためか結構電力を消費するんです。平均で19mA、最大で75mAも流れます!

そのため、SHT31と同じようにGPIOから電力を供給しても動きません。しかし、電源に繋いでしまうとESP8266のDeep Sleep中でも電力を消費してしまいます。

そこで、ちょっと回路を工夫してみました。

f:id:IntellectualCuriosity:20190827202506p:plain

※2019年11月3日追加

3.3kΩの抵抗を1kΩぐらいにしないとボードの個体差により動作しない場合があるようです。AE-ESP-WROOM02-DEVで現象を確認しました。

2SC1815のベースに1mAぐらい流せばコレクタに100mA以上流せるようになるのでセンサーを動かすことができます。

実際の写真はこんな感じです。

f:id:IntellectualCuriosity:20190827204940j:plain

配線がWeMos D1 miniとSCD30に隠れてしまっているので、それを外した写真も載せておきます。

f:id:IntellectualCuriosity:20190827205410j:plain

 

スケッチ

SCD30のスケッチはSHT31スケッチとほぼ同じなのですが、一応載せておきます。

気を付ける点は、SCD30のCO2センサーは正常な値を出力するのに時間がかかるため、8秒待ってから計測するようにしていることぐらいです。

/*
 * SCD30 sensor using ESP8266 and Blynk with Deep Sleep.
 * August 27, 2019
 * By Hiroyuki ITO
 * http://intellectualcuriosity.hatenablog.com/  
 * MIT Licensed.
 */

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <TimeLib.h>
#include "SparkFun_SCD30_Arduino_Library.h" 

// Blynk Auth Token and WiFi credentials.
#define AUTH_TOKEN  "YourAuthToken"
#define WIFI_SSID   "YourNetworkName"
#define WIFI_PASS   "YourPassword"

// NTP
#define NTP_SERVER  "ntp.nict.jp" // National Institute of Information and Communications Technology
#define TIME_OFFSET 9*60*60       // UTC+9h (JST)

#define VCC_PIN     13            // Sensor VCC Pin (WeMos D1 mini D7)
#define DS_INTERVAL 60            // Deep Sleep Interval Time (minutes)

// Global Objects
ADC_MODE(ADC_VCC);                // A-D Converter mode (Voltage)
SCD30 airSensor;

/*
 * Get Time as String
 */
void getDateTime(char *dateTime) {
  sprintf(dateTime, "%04d/%02d/%02d %02d:%02d", year(), month(), day(), hour(), minute());
}

/*
 * Get and Send Sensor Data to Blynk
 */
void sendSensor() {
  // Get and Send SCD30 Data
  digitalWrite(VCC_PIN, HIGH); // Sensor Power ON
  airSensor.begin();           // Initialize SCD30
  BLYNK_LOG("Wait 8 seconds for sensor initialization");
  delay(8000);
  while (!airSensor.dataAvailable()) {
    BLYNK_LOG("NO DATA");
    delay(500);
  }
  float t = airSensor.getTemperature();
  float h = airSensor.getHumidity();
  float c = airSensor.getCO2();
  Blynk.virtualWrite(V1, t);
  Blynk.virtualWrite(V2, h);
  Blynk.virtualWrite(V3, c);
  BLYNK_LOG2("Temp    : ", t);
  BLYNK_LOG2("Humidity: ", h);
  BLYNK_LOG2("CO2     : ", c);
  digitalWrite(VCC_PIN, LOW); // Sensor Power OFF

  // Get and Send Voltage
  float vcc = ESP.getVcc() / 1024.0;
  Blynk.virtualWrite(V4, vcc);
  BLYNK_LOG2("Voltage : ", vcc);
  WidgetLCD lcd(V5);
  char dateTime[17];
  getDateTime(dateTime);
  lcd.clear();
  lcd.print(0, 0, dateTime);
  BLYNK_LOG2("Time    : ", dateTime);

  delay(1000);
}

void setup() {
  Serial.begin(74880);

  // Setup Sensor Power Pin
  pinMode(VCC_PIN, OUTPUT);      
 
  // Setup Blynk
  Blynk.begin(AUTH_TOKEN, WIFI_SSID, WIFI_PASS);

  // Setup NTP
  WiFiUDP ntpUDP;
  NTPClient timeClient(ntpUDP, NTP_SERVER, TIME_OFFSET);
  timeClient.begin();
  while (!timeClient.update()) {
    delay(500);
  }
  setTime(timeClient.getEpochTime());
  BLYNK_LOG("Got time from ntp.");
}

void loop() {
  int min = DS_INTERVAL - minute() % DS_INTERVAL; // Time to wake up
  double sleep = (double)(min * 60 - second() + 10) * 1000 * 1000; // Sleep time (microsecond)

  // Double sleep confirmation
  if (min != DS_INTERVAL) {
    BLYNK_LOG("It's early. Go to sleep for %d minutes.", min);
    ESP.deepSleep(sleep, WAKE_RF_DEFAULT);
  }

  // Get and Send Sensor Data to Blynk
  sendSensor();

  // Sleep until wake up time
  BLYNK_LOG("Go to sleep for %d minutes.", min);
  ESP.deepSleep(sleep, WAKE_RF_DEFAULT);
}

使ったセンサーのライブラリはこれです!

f:id:IntellectualCuriosity:20190828232420p:plain


Blynkの設定などは以前のSHT31の記事を参考にしてみてください。

ぼくはこんな感じにしました。

f:id:IntellectualCuriosity:20190827213112p:plain

 

おしましい。