/*  ESP32_BME280.ino
    2019/02 Programmed by gijin77@gmail.com
*/
#include <WiFi.h>
#include <ACROBOTIC_SSD1306.h>
#include "SparkFunBME280.h"
#include <Wire.h>

#include "Ambient.h"
#include <ThingSpeak.h>

#define T05M 16 //5分間隔 送信間隔設定用ピン番号 
#define T10M 17 //10分間隔
#define T20M 5
#define T30M 18
#define T60M 19

#define LED 2
#define ON  HIGH
#define OFF LOW

const char* ssid = "...ssid...";
const char* password = "...password...";
 
const char *server   = "api.thingspeak.com" ;  // or "184.106.153.149"
 
// 作成した書き込み用チャネルの番号を以下に記述すること
unsigned long channelNumber = 1111111 ;
// 作成した書き込み用チャネルのAPI Keyを以下に記述すること
const char *apiKey = "AAAAAAAAAAAA" ;

unsigned int channelId =100; // AmbientのチャネルID
const char* writeKey = "...writeKey..."; // ライトキー
Ambient ambient;

BME280 Sensor;

WiFiClient client ;
 
char msg[50];
int wait_time=1;
 
void setup() {
  pinMode(LED, OUTPUT);
  pinMode(T05M, INPUT_PULLUP);
  pinMode(T10M, INPUT_PULLUP);
  pinMode(T20M, INPUT_PULLUP);
  pinMode(T30M, INPUT_PULLUP);
  pinMode(T60M, INPUT_PULLUP);
  
  Serial.begin(115200);
  Serial.println("Program Start");
  for (int i=0;i<5;i++) {
    digitalWrite(LED,ON);
    delay(200); 
    digitalWrite(LED,OFF);
    delay(200); 
  }
  //connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  
  Sensor.settings.commInterface = I2C_MODE; 
  Sensor.settings.I2CAddress = 0x76;
  Sensor.settings.runMode = 3; 
  Sensor.settings.tStandby = 0;
  Sensor.settings.filter = 0;
  Sensor.settings.tempOverSample = 1 ;
  Sensor.settings.pressOverSample = 1;
  Sensor.settings.humidOverSample = 1;
  delay(10);
  Sensor.begin();
  Serial.println("BME280Sensor Start");
 
  oled.init();                        // Initialze SSD1306 OLED display  
  // Clear the buffer.
  oled.clearDisplay(); 
  oled.setTextXY(0,0);oled.putString("WiFi connected.");

  ThingSpeak.begin(client) ;
  Serial.println("ThingSpeak Start");

  ambient.begin(channelId, writeKey, &client); // チャネルIDとライトキーを指定してAmbientの初期化
  Serial.println(" ambient Start");
}
 
void loop() {
  float temp; // 温度
  float humi;  // 湿度
  float pres; // 気圧
  float alti; // 高度
  float b;    // 露点計算用
  float c;
  double gammma;
  float dew ;  // 露点
  float ews ;  // 露点計算用
  
  char pa[]="%"; 
  
  // 気圧(hPa)、温度(摂氏)、湿度を取得
  temp=Sensor.readTempC();
  humi=Sensor.readFloatHumidity();
  pres=Sensor.readFloatPressure()/100;
  alti=Sensor.readFloatAltitudeMeters();

//  dew = bme.dew(true) ; // 露点(摂氏)を取得
  ews = humi * 0.01 * exp((17.502 * temp) / (240.9 + temp));
  dew = (240.9 * log(ews)) / (17.5 - log(ews));

//クラウドへUPする間隔読み込み
  if (digitalRead(T05M)==0) {
    wait_time=5;
  } else if (digitalRead(T10M)==0) {
    wait_time=10;
  } else if (digitalRead(T20M)==0) {
    wait_time=20;
  } else if (digitalRead(T30M)==0) {
    wait_time=30;
  } else if (digitalRead(T60M)==0) {
    wait_time=60;
  } else {
    wait_time=1;
  }
  // 測定値をOLEDディスプレイに表示
  oled.clearDisplay(); 
  oled.setTextXY(0,0);oled.putString("<BME280 Sensor>");
  sprintf(msg,"T=%2.2f 'C",temp);
  oled.setTextXY(2,0);oled.putString(msg);
  sprintf(msg,"H=%2.2f %s",humi,pa);
  oled.setTextXY(3,0);oled.putString(msg);
  sprintf(msg,"P=%4.2f hPa",pres);
  oled.setTextXY(4,0);oled.putString(msg);
  sprintf(msg,"A=%4.2f m",alti);
  oled.setTextXY(5,0);oled.putString(msg);
  sprintf(msg,"D=%4.2f 'C",dew);
  oled.setTextXY(6,0);oled.putString(msg); 
  sprintf(msg,"Wait=%d Min",wait_time);
  oled.setTextXY(7,0);oled.putString(msg); 
 

  // サーバーに送るデーターを設定
  ThingSpeak.setField(1, temp) ;
  ThingSpeak.setField(2, humi) ;
  ThingSpeak.setField(3, pres) ;
  ThingSpeak.setField(4, dew) ;
  // 設定されたデータをサーバーに送信
  ThingSpeak.writeFields(channelNumber, apiKey) ;  
  Serial.println("ThingSpeak writeFields"); 

  // 温度、湿度、気圧、露点の値をAmbientに送信する
  ambient.set(1, temp); // 温度をデータ1にセット
  ambient.set(2, humi); // 湿度をデータ2にセット
  ambient.set(3, pres); // 気圧をデータ3にセット
  ambient.set(4, dew); // 露点をデータ4にセット
  ambient.send();
  Serial.println("Ambient writeFields"); 
  
  delay(wait_time * 60 * 1000) ;  // 最低でも15秒間隔(ThingSpeakの制限)をあけること
}