1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ESP8266とBME280で温度・湿度・気圧を測定、Ambientで表示

Last updated at Posted at 2019-10-19

測定データをAmbientで公開しています。
https://ambidata.io/ch/channel.html?id=10090

image.png

過去に書いた記事ではプログラムについて書いていなかったのでこちらに書いておこうと思います。

##参照
プログラムについてはAmbientサイトの以下を参考にさせていただきました。
「Arduino ESP8266で温度・湿度を測定し、Ambientに送ってグラフ化する」
https://ambidata.io/docs/esp8266/

ハードウェアについては以下をご参照下さい。
「ESP8266にBME280 をつないで温度、湿度、気圧測定」
https://qiita.com/UchiwaFuujinn/items/c4369460d181dfe10ab8

Arduino IDEを使った開発環境については以下をご参照下さい。
「ESP8266 Arduino 開発環境」
https://qiita.com/UchiwaFuujinn/items/96ce018777a3ffe78353

##準備
Ambient のサービスをESP8266から使うには、ライブラリを追加する必要があります。GithubからAmbient_ESP8266_libをZip形式でダウンロードし、Arduino IDEのライブラリに追加しておきます。

##アルゴリズム
測定装置は電池駆動です。なるべく電池を長持ちさせたかったので、Deep Sleep ModeとRTCメモリーを使っています。(単四電池4本で40日間運用できました。)Deep Sleep Modeは、ESP8266の省電力モードで一定時間間隔でリセットをかけるようになっています。RTCメモリーは、スリープ中もデータを保持しているメモリーです。

「ESP8266 RTCMemory」
https://qiita.com/UchiwaFuujinn/items/c8db045c48dc3ebd0b24

「ESP8266 RTC memoryを使う」
https://qiita.com/UchiwaFuujinn/items/9eda65654e5587c6377a

本プログラムでは、ESP8266は10分に1回立ち上がり、BME280の測定が実行されます。Ambientへデータをアップするのは1時間に1回としています。

Setupではまず、RTCメモリを読み込みます。RTCメモリには何回立ち上がったかを示すカウンター(Count)、温度、湿度、気圧を平均するためのレジスタ(temp_sum,hum_sum,press_sum)が保存されています。RTCメモリがintegerのレジスタですので、測定値を100倍して保存しています。

次の、BME280から温度、湿度、気圧の現在値(temp_act,hum_act,press_act)を読み込みます。読み込んだ値は、平均するためのレジスタに加算されます。

Count を Decrements し、もしゼロならAmbientへデータを転送します。判定はゼロ以下で行っています。一番最初に立ち上がった時、RTCメモリーの状態が不定だとまずいと思ってこのようになっています。Ambientへの転送後、Countとレジスタをクリアします。

最後にレジスタをRTCメモリに保存し、Deep Sleep Modeへ移行します。

image.png

プログラム

プログラムはGithubに置いておきます。
https://github.com/UchiwaFuujinn/ESP8266

bme280_ambient.ino
#include <ESP8266WiFi.h>
#include "Ambient.h"

/* ---------------------------------------- */
/* for RTC Memory */
/* ---------------------------------------- */
extern "C"{
    #include "user_interface.h"
}

typedef struct{
  int data1;
  int data2;
} rtcStore;

rtcStore rtcMem;
#define RTCMEMORYSTART  64
#define RTCMEMORYLEN    128
int rtcBuffer[RTCMEMORYLEN]={0};

/* ---------------------------------------- */
/* for BME280 */
/* ---------------------------------------- */
#define BME280_ADDRESS 0x76
#define SENDCOUNT 6
double temp_act = 0.0, press_act = 0.0,hum_act=0.0;
extern void initBME280();
extern void readBME280(double *temp_act, double *press_act, double *hum_act);

/* ---------------------------------------- */
/* Wifi */
/* ---------------------------------------- */
const char *ssid = "XXXXXXX-X-XXXX";
const char *password = "YYYYYYYYYYYY";
WiFiClient client;

/* ---------------------------------------- */
/* Ambient */
/* ---------------------------------------- */
unsigned int channelId = 99999;
const char* writeKey = "12345678901234567890";
Ambient ambient;

/* ---------------------------------------- */
/* Setup */
/* ---------------------------------------- */
void setup()
{
    /* ---------------------------------------- */
    /* RTC Read */
    readRTCdata();
    int count = rtcBuffer[0];
    int sendfrag=0;
    double temp_sum =(double)rtcBuffer[1]/100.;
    double press_sum=(double)rtcBuffer[2]/100.;
    double hum_sum  =(double)rtcBuffer[3]/100.;

    /* ---------------------------------------- */
    /* Read Data from BME280 */
    readBME280(&temp_act, &press_act, &hum_act);
    temp_sum  = temp_sum  + temp_act;
    press_sum = press_sum + press_act;
    hum_sum   = hum_sum   + hum_act;

    /* ---------------------------------------- */
    /* send Data to Ambient */
    count=count-1;
    if(count<=0){
       sendfrag = 1;
    }

    if(sendfrag){
      openWifi();
      openAmbient();
      temp_act  =temp_sum/SENDCOUNT;
      press_act =press_sum/SENDCOUNT;
      hum_act   =hum_sum/SENDCOUNT;
      sendBME280();
      count = SENDCOUNT;
      temp_sum  = 0.;
      press_sum = 0.;
      hum_sum   = 0.;
    }

    /* ---------------------------------------- */
    /* RTC Write */
    rtcBuffer[0] = count;
    rtcBuffer[1] = (int)(temp_sum*100.);
    rtcBuffer[2] = (int)(press_sum*100.);
    rtcBuffer[3] = (int)(hum_sum*100.);

    readRTCdata();

    /* ---------------------------------------- */
    /* RTC Sleep */
    ESP.deepSleep(10*60e6);   //10minitus
    delay(100);
}

void loop()
{
}

void openWifi()
{
  /* ---------------------------------------- */
  /* Wifi */
  int i = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    if(i>100){ 
    ESP.deepSleep(10*60e6);   //10minitus
    delay(100);
    }
  }
}

void openAmbient()
{
  /* ---------------------------------------- */
  /* Ambient */
  int irtn =false;
  int i=0;

  while(irtn!=true){
    irtn = ambient.begin(channelId, writeKey, &client);
    delay(100);
    i++;
    if(i>100){ 
      ESP.deepSleep(10*60e6);   //10minitus
      delay(100);
    }
  }  
}

void sendBME280()
{
  ambient.set(1, temp_act);
  ambient.set(2, hum_act);
  ambient.set(3, press_act);
  ambient.send();
}  

void writeRTCdata()
{
  int buckets = sizeof(rtcStore)/sizeof(int);
  int i, rtcPos;
  for(i=0; i<RTCMEMORYLEN/buckets; i++){
    rtcPos = RTCMEMORYSTART+i*buckets;
    rtcMem.data1 = rtcBuffer[i*buckets];
    rtcMem.data2 = rtcBuffer[i*buckets+1];
    system_rtc_mem_write(rtcPos,&rtcMem,buckets*4);
  }
}

void readRTCdata()
{
  int buckets = sizeof(rtcStore)/sizeof(int);
  int i, rtcPos;
  for(i=0; i<RTCMEMORYLEN/buckets; i++){
    rtcPos = RTCMEMORYSTART+i*buckets;
    system_rtc_mem_write(rtcPos,&rtcMem,sizeof(rtcStore));
    rtcBuffer[i*buckets] = rtcMem.data1;
    rtcBuffer[i*buckets+1] = rtcMem.data2;
  }    
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?