未分類

esp32

#include <BluetoothSerial.h>
BluetoothSerial SerialBT; 

//馬達及入水閥電源relay01,使用低壓觸發
int relay01 = 25;

//控制沖洗開關relay02,只沖洗8秒,使用低壓觸發
int relay02 = 33;

//控制前段水排出不飲用relay03,前段水30秒不取用
int relay03 = 32;

//用來計數已製水多少秒
int playRoTime = 0;
int playRoTimeOver = 60 * 20;

//製水開關
int playRO = 0;

//水源偵測器,短路表示有水
int Sensor_RoWater = 21;

//低水位偵測器
int Sensor_lowLine = 22;
//高水位偵測器
int Sensor_highLine = 23;

//水塔抽水偵測器
int Sensor_PumpWater = 18;

//蜂鳴器
int buzzer = 19;




//-------------------------  TDS START  -------------------------
#define TdsSensorPin 35
#define VREF 3.3              // analog reference voltage(Volt) of the ADC
#define SCOUNT  1            // sum of sample point

int analogBuffer[SCOUNT];     // store the analog value in the array, read from ADC
int analogBufferTemp[SCOUNT];
int analogBufferIndex = 0;
int copyIndex = 0;

float averageVoltage = 0;
float tdsValue = 0;
float tdsValueMax = 0;
float tdsValueAvg = 0;
float tdsValueMin = 0;
String tdsValueStr = "";
float temperature = 25;       // current temperature for compensation

// median filtering algorithm
int getMedianNum(int bArray[], int iFilterLen){
  int bTab[iFilterLen];
  for (byte i = 0; i<iFilterLen; i++)
  bTab[i] = bArray[i];
  int i, j, bTemp;
  for (j = 0; j < iFilterLen - 1; j++) {
    for (i = 0; i < iFilterLen - j - 1; i++) {
      if (bTab[i] > bTab[i + 1]) {
        bTemp = bTab[i];
        bTab[i] = bTab[i + 1];
        bTab[i + 1] = bTemp;
      }
    }
  }
  if ((iFilterLen & 1) > 0){
    bTemp = bTab[(iFilterLen - 1) / 2];
  }
  else {
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
  }
  return bTemp;
}
void getTDS()
{
  static unsigned long analogSampleTimepoint = millis();
  if(millis()-analogSampleTimepoint > 40U){     //every 40 milliseconds,read the analog value from the ADC
    analogSampleTimepoint = millis();
    analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin);    //read the analog value and store into the buffer
    analogBufferIndex++;
    if(analogBufferIndex == SCOUNT){ 
      analogBufferIndex = 0;
    }
  }   
  
  static unsigned long printTimepoint = millis();
  if(millis()-printTimepoint > 800U){
    printTimepoint = millis();
    for(copyIndex=0; copyIndex<SCOUNT; copyIndex++){
      analogBufferTemp[copyIndex] = analogBuffer[copyIndex];
      
      // read the analog value more stable by the median filtering algorithm, and convert to voltage value
      averageVoltage = getMedianNum(analogBufferTemp,SCOUNT) * (float)VREF / 4096.0;
      
      //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0)); 
      float compensationCoefficient = 1.0+0.02*(temperature-25.0);
      //temperature compensation
      float compensationVoltage=averageVoltage/compensationCoefficient;
      
      //convert voltage value to tds value
      tdsValue=(133.42*compensationVoltage*compensationVoltage*compensationVoltage - 255.86*compensationVoltage*compensationVoltage + 857.39*compensationVoltage)*0.5;
      
      Serial.print("voltage:");
      Serial.print(averageVoltage,2);
      Serial.print("V   ");

      Serial.print("TDS Value:");
      Serial.print(tdsValue,0);
      Serial.println("ppm");

    }
  }
}
//-------------------------  TDS END  -------------------------

//-------------------------  LINE START  -------------------------
#include <WiFi.h>
#include <WiFiClientSecure.h>

WiFiClientSecure client;

void sendLine(String msg, String line_token) {
  
  //debug
  line_token = "mOhPIFK2NBPZaxIHn8CXwAb2auU8hYGsqbLkeL2UG1c";

  client.setInsecure();
  if (client.connect("notify-api.line.me",443)) {
    String data = "message="+msg;
    client.println("POST /api/notify HTTP/1.1");
    client.println("Host: notify-api.line.me");
    client.println("Authorization: Bearer " + line_token);
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.print("Content-Length: ");
    client.println(data.length());
    client.println();
    client.println(data);
  }
  client.stop();
  
  Serial.println("send line:" + msg);
  Serial.println("token:"+line_token);
}
//-------------------------  LINE END  -------------------------


//-------------------------  水塔抽水偵測 START  -------------------------
//用來計數已抽水多少秒
int startPumpTime = 0;
//運時超過20分line+警告3短音,且後續每5分line警告
int startPumpTimeOver = 60 * 20;

void check_PumpWater() {

  Serial.print("Sensor_PumpWater:");
  Serial.println(digitalRead(Sensor_PumpWater));

  //1=馬達沒有在抽水
  if ( digitalRead(Sensor_PumpWater) == 1)
  {

    //如果startPumpTime不等於0,那表示剛製水完成,發送通知
    if (startPumpTime != 0)
    {
      String l_msg = "完成 "+TimeFormate(startPumpTime);
      String l_line_token = "5oF8K44hd45iw8dLBw789YBpgMU3DHOqi2LDiGwjm0C";
      sendLine( l_msg, l_line_token);
    }
    startPumpTime = 0;
    return;
  }

  startPumpTime++;
  String l_msg = "startPumpTime:" + String(startPumpTime) + "/" + String(startPumpTimeOver);
  Serial.println(l_msg);

  //抽水超時警告
  if( startPumpTime >= startPumpTimeOver)
  {
    //每超過5分鐘發line通知警告一次
    if( startPumpTime % 300 == 0 )
    {
      String l_msg = "超時 "+TimeFormate(startPumpTime);
      String l_line_token = "5oF8K44hd45iw8dLBw789YBpgMU3DHOqi2LDiGwjm0C";
      sendLine( l_msg, l_line_token);
    }
    bb(3);
  }
}
//-------------------------  水塔抽水偵測 END  -------------------------

//-------------------------  RO水源偵測 START  -------------------------
//用來計數已停水多少秒
int RoWaterMissTime = 0;
//超過30分鐘沒有水源,警告
int RoWaterMissTimeOver = 60 * 30;

bool ckeck_RoWaterMiss() {

  //水源開關:當水源缺水時=1進入停止
  if ( digitalRead(Sensor_RoWater) == 1)
  {
    RoWaterMissTime++;

    String l_msg = "RoWaterMissTime:" + String(RoWaterMissTime) + "/" + String(RoWaterMissTimeOver);
    Serial.println(l_msg);

    //停水超時警告
    if( RoWaterMissTime >= RoWaterMissTimeOver)
    {
      if( RoWaterMissTime % RoWaterMissTimeOver == 0 )
      {
        String l_msg = "無水源 "+TimeFormate(RoWaterMissTime);
        String l_line_token = "i82ej11WC8Z12j77tmxtRGC6H45NWaE7e7gkuMjjglw";
        sendLine( l_msg, l_line_token);
      }
      bb(1);
    }
    
    return true;
  }
  //不缺水歸0
  RoWaterMissTime = 0;
  return false;
}
//-------------------------  RO水源偵測 START  -------------------------

//-------------------------  SerialBT START   -------------------------

int sendSerialBT_resend_Time = 0;
void sendSerialBT()
{
  sendSerialBT_resend_Time++;
  if( sendSerialBT_resend_Time >= 5 )
  {
    SerialBT.println("---------------------------------------");

    SerialBT.print("抽水馬達(黃):");
    if( startPumpTime > 0)
    {
      SerialBT.print("運作中--> " + String(startPumpTime) + "/" + String(startPumpTimeOver) );
      if( startPumpTime >= startPumpTimeOver)
      {
        SerialBT.println("❌");
      }
      else
      {
        SerialBT.println("⚡");
      }
    }
    else
    {
      SerialBT.println("停止✔️");
    }



    SerialBT.print("RO水源(綠):");
    if( digitalRead(Sensor_RoWater) == 1 )
    {
      SerialBT.print("無水--> " + String(RoWaterMissTime) + "/" + String(RoWaterMissTimeOver) );
      SerialBT.println("❌");
    }
    else
    {
      SerialBT.println("有水💧");
    }

    SerialBT.print("上水位(紫):");
    if( digitalRead(Sensor_highLine) == 1 )
    {
      if( digitalRead(Sensor_lowLine) == 1 )
      {
        SerialBT.println("尚有水💧");
      }
      else
      {
        SerialBT.println("缺水❌");
      }
    }
    else
    {
      SerialBT.println("滿水💦");
      if( playRoTime > 0)
      {
        SerialBT.println("滿水還在製水❌");
      }
      if( digitalRead(Sensor_lowLine) == 0 )
      {
        SerialBT.println("上水位滿水,下水位缺水⚠️⚠️⚠️");
      }
    }
    
    SerialBT.print("下水位(藍):");
    if( digitalRead(Sensor_lowLine) == 1 )
    {
      SerialBT.println("有水💧");
    }
    else
    {
      SerialBT.println("無水❌");
    }

    SerialBT.print("TDS: " + String(tdsValue,0) + " PPM");
    if( tdsValue > 30 )
    {
      SerialBT.println("❌");
    }
    else
    {
      SerialBT.println("✔️");
    }

    if( playRoTime > 0 )
    {
      SerialBT.print("RO製水中--> " + String(playRoTime) + "/" + String(playRoTimeOver) );
      if( playRoTime >= playRoTimeOver)
      {
        SerialBT.println("❌");
      }
      else
      {
        SerialBT.println("⚡");
      }
      if( playRoTime > 10)
      {
        SerialBT.print(tdsValueStr);
        if( tdsValueAvg > 30 )
        {
          SerialBT.println("❌");
        }
        else
        {
          SerialBT.println("✔️");
        }
      }

    }

    sendSerialBT_resend_Time = 0;
  }

}

//-------------------------  SerialBT END   -------------------------




void setup() {

  Serial.begin(115200);
  SerialBT.begin("RO121");

  //TDS偵測器
  pinMode(TdsSensorPin,INPUT);

  WiFi.begin("AP", "PASS");

  while(WiFi.status() != WL_CONNECTED)
  {
    delay(1000);
    Serial.print(F("."));
  }
  Serial.println();
  Serial.println(F("WiFi connected"));

  // Print the IP address
  Serial.println(WiFi.localIP());

  //馬達及入水閥電源relay01,使用低壓觸發
  pinMode( relay01, OUTPUT);
  digitalWrite( relay01, HIGH);//通電時預設關閉

  //控制沖洗開關relay02,只沖洗8秒,使用低壓觸發
  pinMode( relay02, OUTPUT);
  digitalWrite( relay02, HIGH);//通電時預設關閉

  //控制前段水排出不飲用relay03,前段水30秒不取用
  pinMode( relay03, OUTPUT);
  digitalWrite( relay03, HIGH);//通電時預設關閉

  //水源開關
  pinMode( Sensor_RoWater, INPUT_PULLUP);

  //飲水機高水位偵測
  pinMode( Sensor_highLine, INPUT_PULLUP);

  //飲水機低水位偵測
  pinMode( Sensor_lowLine,  INPUT_PULLUP);

  //水塔抽水偵測器
  pinMode( Sensor_PumpWater, INPUT_PULLUP);

  //蜂鳴器 - 開機取得網路後嗶一聲
  pinMode( buzzer, OUTPUT);
  digitalWrite( buzzer, HIGH);
  delay(100);
  digitalWrite( buzzer, LOW);

}


void loop() {

  //1秒執行一次
  delay(1000);
  sendSerialBT();
  Serial.println("**********************************");


  check_PumpWater();

  Serial.print("Sensor_RoWater:");
  Serial.print(digitalRead(Sensor_RoWater));

  Serial.print(", Sensor_lowLine:");
  Serial.print(digitalRead(Sensor_lowLine));

  Serial.print(", Sensor_highLine:");
  Serial.println(digitalRead(Sensor_highLine));

  //取得TDS
  getTDS();

  //低水位偵測器,0=缺水,可開始製水
  if ( digitalRead(Sensor_lowLine) == 0) playRO = 1;

  //高水位偵測器,0=滿水,需立即停止
  if ( digitalRead(Sensor_highLine) == 0) playRO = 0;

  //如果RO水源缺水就必須立即停止
  if( ckeck_RoWaterMiss() ) playRO = 0;


  //playRO=0,表示尚有水
  if ( playRO == 0)
  {

    digitalWrite( relay01, HIGH);
    digitalWrite( relay02, HIGH);
    digitalWrite( relay03, HIGH);

    //如果playRoTime不等於0,那表示剛製水完成,發送通知
    if (playRoTime != 0)
    {
      String l_msg = "完成 "+TimeFormate(playRoTime);
      l_msg += "\n";
      l_msg += tdsValueStr;
      String l_line_token = "i82ej11WC8Z12j77tmxtRGC6H45NWaE7e7gkuMjjglw";
      sendLine( l_msg, l_line_token);
    }

    playRoTime = 0;
    return;
  }

  //製水計時器
  playRoTime++;

  //製水超時警告,強制停止
  if( playRoTime >= playRoTimeOver)
  {

    digitalWrite( relay01, HIGH);
    digitalWrite( relay02, HIGH);
    digitalWrite( relay03, HIGH);

    if( playRoTime == playRoTimeOver )
    {
      String l_msg = "超時警告 "+TimeFormate(playRoTime);
      l_msg += "\n";
      l_msg += tdsValueStr;
      String l_line_token = "i82ej11WC8Z12j77tmxtRGC6H45NWaE7e7gkuMjjglw";
      sendLine( l_msg, l_line_token);
    }
    bb(4);

    return;
  }

  //check tds
  //10秒後洗牌tda
  if( playRoTime == 10 )
  {
    tdsValueMax = tdsValue;
    tdsValueAvg = tdsValue;
    tdsValueMin = tdsValue;
  }else if( playRoTime > 10 )
  {
    if( tdsValue > tdsValueMax ) tdsValueMax = tdsValue;
    tdsValueAvg = (tdsValueAvg+tdsValue) / 2;
    if( tdsValue < tdsValueMin ) tdsValueMin = tdsValue;
    tdsValueStr = "tds:"+String(tdsValueMin,0)+"/"+String(tdsValueAvg,0)+"/"+String(tdsValueMax,0);
    Serial.println(tdsValueStr);
  }


  //馬達及入水閥電源
  digitalWrite( relay01, LOW);

  //控制前段水排出不飲用
  if(playRoTime < 120)
  {
    digitalWrite( relay02, LOW);
  }
  else
  {
    digitalWrite( relay02, HIGH);
  }

  //控制沖洗開關10(s)
  if(playRoTime < 10)
  {
    digitalWrite( relay03, LOW);
  }
  else
  {
    digitalWrite( relay03, HIGH);
  }

    String l_msg = "playRoTime:" + String(playRoTime) + "/" + String(playRoTimeOver);
    Serial.println(l_msg);
}

void bb(int ct)
{
  //不影響主線程,10秒來一次
  if( (playRoTime+RoWaterMissTime+startPumpTime) % 10 == 0 )
  {
    //1短聲:缺水
    //2短聲:啟動太久
    for(int i=0;i<ct;i++)
    {
      digitalWrite( buzzer, HIGH);
      delay(100);
      digitalWrite( buzzer, LOW);
      delay(100);
    }
  }
}

String TimeFormate(int seconds)
{
  unsigned int minutes = seconds / 60;
  unsigned int hours = minutes / 60;
  unsigned int days = hours / 24;
  seconds %= 60;
  minutes %= 60;
  hours %= 24;

  String l_time = "";

  if( days > 0 ) l_time = String(days)+"D ";

  if (hours > 0)
  {
    if (hours < 10)
    {
      l_time += "0";
    }
    l_time += String(hours) + ":";
  }

  if (minutes < 10)
  {
    l_time += "0";
  }
  l_time += String(minutes) + ":";

  if (seconds < 10)
  {
    l_time += "0";
  }
  l_time += String(seconds);

  return l_time;

}

http版

#include <WebServer.h>

//GET WIFI IP
String g_ip = "";

//run time
unsigned long g_runTime = 0;

//馬達及入水閥電源relay01,使用低壓觸發
int relay01 = 25;

//控制沖洗開關relay02,只沖洗8秒,使用低壓觸發
int relay02 = 33;

//控制前段水排出不飲用relay03,前段水30秒不取用
int relay03 = 32;

//用來計數已製水多少秒
int playRoTime = 0;
int playRoTimeOver = 60 * 30;

//製水開關
int playRO = 0;

//水源偵測器,短路表示有水
int Sensor_RoWater = 21;

//低水位偵測器
int Sensor_lowLine = 22;
//高水位偵測器
int Sensor_highLine = 23;

//水塔抽水偵測器
int Sensor_PumpWater = 18;

//蜂鳴器
int buzzer = 19;




//-------------------------  TDS START  -------------------------
#define TdsSensorPin 35
#define VREF 3.3              // analog reference voltage(Volt) of the ADC
#define SCOUNT  1            // sum of sample point

int analogBuffer[SCOUNT];     // store the analog value in the array, read from ADC
int analogBufferTemp[SCOUNT];
int analogBufferIndex = 0;
int copyIndex = 0;

float averageVoltage = 0;
float tdsValue = 0;
float tdsValueMax = 0;
float tdsValueAvg = 0;
float tdsValueMin = 0;
String tdsValueStr = "";
float temperature = 20;       // current temperature for compensation

// median filtering algorithm
int getMedianNum(int bArray[], int iFilterLen){
  int bTab[iFilterLen];
  for (byte i = 0; i<iFilterLen; i++)
  bTab[i] = bArray[i];
  int i, j, bTemp;
  for (j = 0; j < iFilterLen - 1; j++) {
    for (i = 0; i < iFilterLen - j - 1; i++) {
      if (bTab[i] > bTab[i + 1]) {
        bTemp = bTab[i];
        bTab[i] = bTab[i + 1];
        bTab[i + 1] = bTemp;
      }
    }
  }
  if ((iFilterLen & 1) > 0){
    bTemp = bTab[(iFilterLen - 1) / 2];
  }
  else {
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
  }
  return bTemp;
}
void getTDS()
{
  static unsigned long analogSampleTimepoint = millis();
  if(millis()-analogSampleTimepoint > 40U){     //every 40 milliseconds,read the analog value from the ADC
    analogSampleTimepoint = millis();
    analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin);    //read the analog value and store into the buffer
    analogBufferIndex++;
    if(analogBufferIndex == SCOUNT){ 
      analogBufferIndex = 0;
    }
  }   
  
  static unsigned long printTimepoint = millis();
  if(millis()-printTimepoint > 800U){
    printTimepoint = millis();
    for(copyIndex=0; copyIndex<SCOUNT; copyIndex++){
      analogBufferTemp[copyIndex] = analogBuffer[copyIndex];
      
      // read the analog value more stable by the median filtering algorithm, and convert to voltage value
      averageVoltage = getMedianNum(analogBufferTemp,SCOUNT) * (float)VREF / 4096.0;
      
      //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0)); 
      float compensationCoefficient = 1.0+0.02*(temperature-25.0);
      //temperature compensation
      float compensationVoltage=averageVoltage/compensationCoefficient;
      
      //convert voltage value to tds value
      tdsValue=(133.42*compensationVoltage*compensationVoltage*compensationVoltage - 255.86*compensationVoltage*compensationVoltage + 857.39*compensationVoltage)*0.5;
      
      Serial.print("voltage:");
      Serial.print(averageVoltage,2);
      Serial.print("V   ");

      Serial.print("TDS Value:");
      Serial.print(tdsValue,0);
      Serial.println("ppm");

    }
  }
}
//-------------------------  TDS END  -------------------------

//-------------------------  LINE START  -------------------------
#include <WiFi.h>
#include <WiFiClientSecure.h>

WiFiClientSecure client;

void sendLine(String msg, String line_token) {
  
  //debug
  //line_token = "mOhPIFK2NBPZaxIHn8CXwAb2auU8hYGsqbLkeL2UG1c";

  msg += "\nhttp://";
  msg += g_ip;

  client.setInsecure();
  if (client.connect("notify-api.line.me",443)) {
    String data = "message="+msg;
    client.println("POST /api/notify HTTP/1.1");
    client.println("Host: notify-api.line.me");
    client.println("Authorization: Bearer " + line_token);
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.print("Content-Length: ");
    client.println(data.length());
    client.println();
    client.println(data);
  }
  client.stop();
  
  Serial.println("send line:" + msg);
  Serial.println("token:"+line_token);
}
//-------------------------  LINE END  -------------------------


//-------------------------  水塔抽水偵測 START  -------------------------
//用來計數已抽水多少秒
int startPumpTime = 0;
//運時超過20分line+警告3短音,且後續每5分line警告
int startPumpTimeOver = 60 * 20;

void check_PumpWater() {

  Serial.print("Sensor_PumpWater:");
  Serial.println(digitalRead(Sensor_PumpWater));

  //1=馬達沒有在抽水
  if ( digitalRead(Sensor_PumpWater) == 1)
  {

    //如果startPumpTime不等於0,那表示剛製水完成,發送通知
    if (startPumpTime != 0)
    {
      String l_msg = "完成 "+TimeFormate(startPumpTime);
      String l_line_token = "5oF8K44hd45iw8dLBw789YBpgMU3DHOqi2LDiGwjm0C";
      sendLine( l_msg, l_line_token);
    }
    startPumpTime = 0;
    return;
  }

  startPumpTime++;
  String l_msg = "startPumpTime:" + String(startPumpTime) + "/" + String(startPumpTimeOver);
  Serial.println(l_msg);

  //抽水超時警告
  if( startPumpTime >= startPumpTimeOver)
  {
    //每超過5分鐘發line通知警告一次
    if( startPumpTime % 300 == 0 )
    {
      String l_msg = "超時 "+TimeFormate(startPumpTime);
      String l_line_token = "5oF8K44hd45iw8dLBw789YBpgMU3DHOqi2LDiGwjm0C";
      sendLine( l_msg, l_line_token);
    }
    bb(3);
  }
}
//-------------------------  水塔抽水偵測 END  -------------------------

//-------------------------  RO水源偵測 START  -------------------------
//用來計數已停水多少秒
int RoWaterMissTime = 0;
//超過30分鐘沒有水源,警告
int RoWaterMissTimeOver = 60 * 30;

bool ckeck_RoWaterMiss() {

  //水源開關:當水源缺水時=1進入停止
  if ( digitalRead(Sensor_RoWater) == 1)
  {
    RoWaterMissTime++;

    String l_msg = "RoWaterMissTime:" + String(RoWaterMissTime) + "/" + String(RoWaterMissTimeOver);
    Serial.println(l_msg);

    //停水超時警告
    if( RoWaterMissTime >= RoWaterMissTimeOver)
    {
      if( RoWaterMissTime % RoWaterMissTimeOver == 0 )
      {
        String l_msg = "無水源 "+TimeFormate(RoWaterMissTime);
        String l_line_token = "i82ej11WC8Z12j77tmxtRGC6H45NWaE7e7gkuMjjglw";
        sendLine( l_msg, l_line_token);
      }
      bb(1);
    }
    
    return true;
  }
  //不缺水歸0
  RoWaterMissTime = 0;
  return false;
}

//-------------------------  WiFiServer END   -------------------------

WebServer server(80);

void setup() {

  Serial.begin(115200);


  //TDS偵測器
  pinMode(TdsSensorPin,INPUT);

  WiFi.begin("AP168", "n0911661293");

  while(WiFi.status() != WL_CONNECTED)
  {
    delay(1000);
    Serial.print(F("."));
  }
  Serial.println();
  Serial.println(F("WiFi connected"));

  // Print the IP address
  g_ip = WiFi.localIP().toString();
  Serial.println(g_ip);

  //馬達及入水閥電源relay01,使用低壓觸發
  pinMode( relay01, OUTPUT);
  digitalWrite( relay01, HIGH);//通電時預設關閉

  //控制沖洗開關relay02,只沖洗8秒,使用低壓觸發
  pinMode( relay02, OUTPUT);
  digitalWrite( relay02, HIGH);//通電時預設關閉

  //控制前段水排出不飲用relay03,前段水30秒不取用
  pinMode( relay03, OUTPUT);
  digitalWrite( relay03, HIGH);//通電時預設關閉

  //水源開關
  pinMode( Sensor_RoWater, INPUT_PULLUP);

  //飲水機高水位偵測
  pinMode( Sensor_highLine, INPUT_PULLUP);

  //飲水機低水位偵測
  pinMode( Sensor_lowLine,  INPUT_PULLUP);

  //水塔抽水偵測器
  pinMode( Sensor_PumpWater, INPUT_PULLUP);

  //蜂鳴器 - 開機取得網路後嗶一聲
  pinMode( buzzer, OUTPUT);
  digitalWrite( buzzer, HIGH);
  delay(100);
  digitalWrite( buzzer, LOW);

  createWebServer();
  server.begin();
}

String content;

void createWebServer()
{
  server.on("/", []() {

    content  = "<!DOCTYPE html>";
    content += "<html>";
    content += "<head>";
    content += "<title>ro status</title>";
    content += "<script>if (navigator.userAgent.indexOf(\"Line\") > -1) location.href  += \"?openExternalBrowser=1\";</script>";
    content += "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">";
    content += "<meta http-equiv=\"refresh\" content=\"5\">";
    content += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">";
    content += "</head>";
    content += "<body>";


    content += "<div>";
    content += "開機時間🕛 ";
    content += TimeFormate(g_runTime);
    content += "</div><br />";


    content += "<div>";
    content += "抽水馬達(黃):";
    if( startPumpTime > 0)
    {
      content += "運作中--> " + String(startPumpTime) + "/" + String(startPumpTimeOver);
      if( startPumpTime >= startPumpTimeOver)
      {
        content += "❌";
      }
      else
      {
        content += "⚡";
      }
    }
    else
    {
      content += "停止✔️";
    }
    content += "</div><br />";

    content += "<div>";
    content += "RO水源(綠):";
    if( digitalRead(Sensor_RoWater) == 1 )
    {
      content += "無水--> " + String(RoWaterMissTime) + "/" + String(RoWaterMissTimeOver);
      content += "❌";
    }
    else
    {
      content += "有水💧";
    }
    content += "</div>";

    content += "<div>";
    content += "上水位(紫):";
    if( digitalRead(Sensor_highLine) == 1 )
    {
      if( digitalRead(Sensor_lowLine) == 1 )
      {
        content += "尚有水💧";
      }
      else
      {
        content += "缺水❌";
      }
    }
    else
    {
      content += "滿水💦";
      if( playRoTime > 0)
      {
        content += "滿水還在製水❌";
      }
      if( digitalRead(Sensor_lowLine) == 0 )
      {
        content += "上水位滿水,下水位缺水⚠️⚠️⚠️";
      }
    }
    content += "</div>";
    
    content += "<div>";
    content += "下水位(藍):";
    if( digitalRead(Sensor_lowLine) == 1 )
    {
      content += "有水💧";
    }
    else
    {
      content += "無水❌";
    }
    content += "</div>";

    content += "<div>";
    content += "TDS: " + String(tdsValue,0) + " PPM (" + String(averageVoltage,2) + "V)";
    if( tdsValue > 30 )
    {
      content += "❌";
    }
    else
    {
      content += "✔️";
    }
    content += "</div>";


    if( playRoTime > 0 )
    {
      content += "<div>";
      content += "RO製水中--> " + String(playRoTime) + "/" + String(playRoTimeOver);
      if( playRoTime >= playRoTimeOver)
      {
        content += "❌";
      }
      else
      {
        content += "⚡";
      }
      content += "</div>";

      content += "<div>";
      if( playRoTime > 10)
      {
        content += tdsValueStr;
        if( tdsValueAvg > 30 )
        {
          content += "❌";
        }
        else
        {
          content += "✔️";
        }
      }
      content += "</div>";
    }

  content += "<div>";
  content += "RO馬達:";
  if( digitalRead(relay01)  == 0 )
  {
    content += "運作中:";
    content += "⚡";
  }
  else
  {
    content += "停止";
  }
  content += "</div>";


  content += "<div>";
  content += "前段水(100秒):";
  if( digitalRead(relay02)  == 0 )
  {
    content += "運作中:";
    content += "⚡";
  }
  else
  {
    content += "停止";
  }
  content += "</div>";


  content += "<div>";
  content += "沖洗(10秒):";
  if( digitalRead(relay03)  == 0 )
  {
    content += "運作中:";
    content += "⚡";
  }
  else
  {
    content += "停止";
  }
  content += "</div>";

    content += "</body>";
    content += "</html>";
    server.send(200, "text/html", content);
  });
}


void loop() {

  //1秒執行一次
  delay(1000);
  g_runTime++;
  server.handleClient();


  Serial.println("**********************************");


  check_PumpWater();

  Serial.print("Sensor_RoWater:");
  Serial.print(digitalRead(Sensor_RoWater));

  Serial.print(", Sensor_lowLine:");
  Serial.print(digitalRead(Sensor_lowLine));

  Serial.print(", Sensor_highLine:");
  Serial.println(digitalRead(Sensor_highLine));

  //取得TDS
  getTDS();

  //低水位偵測器,0=缺水,可開始製水
  if ( digitalRead(Sensor_lowLine) == 0) playRO = 1;

  //高水位偵測器,0=滿水,需立即停止
  if ( digitalRead(Sensor_highLine) == 0) playRO = 0;

  //如果RO水源缺水就必須立即停止
  if( ckeck_RoWaterMiss() ) playRO = 0;


  //playRO=0,表示尚有水
  if ( playRO == 0)
  {

    digitalWrite( relay01, HIGH);
    digitalWrite( relay02, HIGH);
    digitalWrite( relay03, HIGH);

    //如果playRoTime不等於0,那表示剛製水完成,發送通知
    if (playRoTime != 0)
    {
      String l_msg = "完成 "+TimeFormate(playRoTime);
      l_msg += "\n";
      l_msg += tdsValueStr;
      String l_line_token = "i82ej11WC8Z12j77tmxtRGC6H45NWaE7e7gkuMjjglw";
      sendLine( l_msg, l_line_token);
    }

    playRoTime = 0;
    return;
  }

  //製水計時器
  playRoTime++;

  //製水超時警告,強制停止
  if( playRoTime >= playRoTimeOver)
  {

    digitalWrite( relay01, HIGH);
    digitalWrite( relay02, HIGH);
    digitalWrite( relay03, HIGH);

    if( playRoTime == playRoTimeOver )
    {
      String l_msg = "超時警告 "+TimeFormate(playRoTime);
      l_msg += "\n";
      l_msg += tdsValueStr;
      String l_line_token = "i82ej11WC8Z12j77tmxtRGC6H45NWaE7e7gkuMjjglw";
      sendLine( l_msg, l_line_token);
    }
    bb(4);

    return;
  }

  //check tds
  //10秒後洗牌tda
  if( playRoTime == 10 )
  {
    tdsValueMax = tdsValue;
    tdsValueAvg = tdsValue;
    tdsValueMin = tdsValue;
  }else if( playRoTime > 10 )
  {
    if( tdsValue > tdsValueMax ) tdsValueMax = tdsValue;
    tdsValueAvg = (tdsValueAvg+tdsValue) / 2;
    if( tdsValue < tdsValueMin ) tdsValueMin = tdsValue;
    tdsValueStr = "tds:"+String(tdsValueMin,0)+"/"+String(tdsValueAvg,0)+"/"+String(tdsValueMax,0);
    Serial.println(tdsValueStr);
  }


  //馬達及入水閥電源
  digitalWrite( relay01, LOW);

  //控制前段水排出不飲用
  if(playRoTime < 100)
  {
    digitalWrite( relay02, LOW);
  }
  else
  {
    digitalWrite( relay02, HIGH);
  }

  //控制沖洗開關10(s)
  if(playRoTime < 10)
  {
    digitalWrite( relay03, LOW);
  }
  else
  {
    digitalWrite( relay03, HIGH);
  }

    String l_msg = "playRoTime:" + String(playRoTime) + "/" + String(playRoTimeOver);
    Serial.println(l_msg);
}

void bb(int ct)
{
  //不影響主線程,10秒來一次
  if( (playRoTime+RoWaterMissTime+startPumpTime) % 10 == 0 )
  {
    //1短聲:缺水
    //2短聲:啟動太久
    for(int i=0;i<ct;i++)
    {
      digitalWrite( buzzer, HIGH);
      delay(100);
      digitalWrite( buzzer, LOW);
      delay(100);
    }
  }
}

String TimeFormate(int seconds)
{
  unsigned int minutes = seconds / 60;
  unsigned int hours = minutes / 60;
  unsigned int days = hours / 24;
  seconds %= 60;
  minutes %= 60;
  hours %= 24;

  String l_time = "";

  if( days > 0 ) l_time = String(days)+"D ";

  if (hours > 0)
  {
    if (hours < 10)
    {
      l_time += "0";
    }
    l_time += String(hours) + ":";
  }

  if (minutes < 10)
  {
    l_time += "0";
  }
  l_time += String(minutes) + ":";

  if (seconds < 10)
  {
    l_time += "0";
  }
  l_time += String(seconds);

  return l_time;

}

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。