/*  ESP32_powermonitor.ino
    2019/02 Programmed by gijin77@gmail.com
*/
#include <WiFi.h>
#include "esp_sleep.h"
#include <Ticker.h>
#include <SPI.h>
#include "Ambient.h"

#define _DEBUG 1

#if _DEBUG
#define DBG(...) { Serial.print(__VA_ARGS__); }
#define ERR(...) { Serial.print(__VA_ARGS__); }
#else
#define DBG(...)
#define ERR(...)
#endif /* _DBG */

// 電流センサ係数(巻き数 / (R * 係数))
#define kCT  (3000.0 / (100.0 * 0.998))
#define ZERO_PIN 36
#define CH0_PIN 34
#define CH1_PIN 35
#define NOISE_OFFSET 0.4
#define ACV 100.0

const char* ssid = "...ssid...";
const char* password = "...password...";

WiFiClient client;

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

Ticker t1, t2;
volatile int t1flag, t2flag;

#define LED 2

#define PERIOD 30           // 送信間隔(秒)
#define SAMPLE_PERIOD 1     // サンプリング間隔(ミリ秒)
#define SAMPLE_SIZE 100     // 1ms x 100 = 100ms


void t1callback() {
  t1flag = 1;
}

void t2callback() {
  t2flag = 1;
}


float ampRead(int ch) {
  int vt;
//  float vt;
  float amp, ampsum;
  t2flag = 0;
  ampsum = 0;
  
  t2.attach_ms(SAMPLE_PERIOD, t2callback);
  
  for (int i = 0; i < SAMPLE_SIZE; i++) {
    while (t2flag == 0) {        // 測定開始の割込み待ち
      yield();
    }
    t2flag = 0;
    
      vt = analogRead(ch)-analogRead(ZERO_PIN);
//    amp = (float)vt * 3.3 / 1023.0 * 3000.0 / 100.0; //atmega328
//    amp = (float)vt * 3.3 / 4095.0 * 3000.0 / 100.0; //esp32
      amp = (float)vt * 3.3 / 4095.0 * kCT; //esp32 電流に換算kCT=(3000.0 / (100.0 * 0.998))

/*  
    float d1= 3.3 / 4095.0; //  4095=3.3V     
    float v1= vt * d1; // 電圧に変換
    amp= (v1/0.3) * 10.0;   // 0.3V = 10A 電流に変換
*/
    ampsum += amp * amp;
  }

  t2.detach();
  return ((float)sqrt((double)(ampsum / SAMPLE_SIZE))); //内部関数使用
}

void setup() {
int waiting=0;  
#if _DEBUG
  Serial.begin(115200);
#endif
  delay(80);
  DBG("\nPower Monitor\n");

  pinMode(LED, OUTPUT);
  WiFi.begin(ssid,password); 
  while(WiFi.status() != WL_CONNECTED){     // 接続に成功するまで待つ
        delay(100);                          // 待ち時間処理
        waiting++;                           // 待ち時間カウンタを1加算する
        digitalWrite(LED,waiting%2);         // LED(EN信号)の点滅
        if(waiting%10==0)Serial.print('.'); // 進捗表示
        if(waiting > 300) sleep(100);        // 300回(30秒)を過ぎたらスリープ
  }
  digitalWrite(LED,0);    
  DBG("WiFi connected\r\nIP address: ");
  DBG(WiFi.localIP());
  DBG("\r\n");
    
  ambient.begin(channelId, writeKey, &client);

  t1flag = 0;
  t1.attach(PERIOD, t1callback);
}

void loop() {
  float amp0, amp1,w0,w1;
  char buf0[12], buf1[12],buf2[12], buf3[12];
  
  while (t1flag == 0) {
    yield();
  }
  t1flag = 0;

  amp0 = ampRead(CH0_PIN) - NOISE_OFFSET;
  amp1 = ampRead(CH1_PIN) - NOISE_OFFSET ;
  if (amp0 < 0.0) amp0=0.0;
  if (amp1 < 0.0) amp1=0.0;
   
  dtostrf(amp0, 3, 1, buf0);
  ambient.set(1, buf0);
  DBG("amp0: ");  DBG(buf0); DBG("A "); 

  dtostrf(amp1, 3, 1, buf1);
  ambient.set(2, buf1);
  DBG(", amp1: ");  DBG(buf1);; DBG("A ");
  
  w0=ACV * amp0;
  dtostrf(w0, 6, 1, buf2);
  ambient.set(3, buf2);
  DBG(", W0: ");  DBG(buf2);; DBG("W ");

  w1=ACV * amp1;
  dtostrf(w1, 6, 1, buf3);
  ambient.set(4, buf3);
  DBG(", W1: ");  DBG(buf3);; DBG("W "); DBG("\r\n");

  
  digitalWrite(LED, HIGH);
  ambient.send();
  digitalWrite(LED, LOW);

 }