『瀚思彼岸』» 智能家居技术论坛

 找回密码
 立即注册
楼主: zhenxiwen

热水循环泵制作安装简易方法(另一种思路)

  [复制链接]

69

主题

691

帖子

4242

积分

论坛元老

Rank: 8Rank: 8

积分
4242
金钱
3546
HASS币
80
 楼主| 发表于 2020-1-11 15:13:21 | 显示全部楼层
本帖最后由 zhenxiwen 于 2020-1-11 15:19 编辑
sinker1985 发表于 2020-1-11 14:32
最早的原帖应该使用的nodemcu lua脚本实现的。后面那个坛友是用的arduino写的,你刷报错的原因是和他使用 ...

我完全按照原贴下图将板子和电源连接好,并接到pt100上(继电器部分还没结,现在我关键想把水温检测部分搞好,能读取温度并接入ha)。只是我用开发板不同,他用ESP-07S(太小,很难接线),我用nodemcu lua v3,其他设备都是同样的。
195856a090vvpvn40oqziq.png     923861073.jpg


我也已经用esphome将esp8266接入了ha,mqtt也配置好了,但就是不知道怎么样才能将普读取pt100检测到的水温并接入到ha中。


我也试过用mqtt做了一个sensor,在configuration.yaml中配置如下:但没法读取到水温,ha中显示温度:未知,我不知道 state_topic应该怎么写。


sensor:
  - platform: mqtt
    name: "washroom_water_tem"
    state_topic: "wendu"
    value_template: '{{ value_json.Temperature }}'
    unit_of_measurement: '°C'

这些问题对懂得的人来说,应该是很简单的,但对我等马萌就是拦路虎呀,呵呵呵呵

回复

使用道具 举报

0

主题

24

帖子

76

积分

注册会员

Rank: 2

积分
76
金钱
52
HASS币
0
发表于 2020-1-11 18:36:34 | 显示全部楼层
zhenxiwen 发表于 2020-1-11 15:13
我完全按照原贴下图将板子和电源连接好,并接到pt100上(继电器部分还没结,现在我关键想把水温检测部分搞 ...

我正在帮你改后面那位坛友的arduino 程序,已经在我的esp8266上跑起来了,温度部分我没有你一样的RTD接口板无法测试,其他设置服务器,连接hass工作挺正常的, 我帮你改成HASS MQTT自动发现, 启动后不需要在Hass中更改yaml配置文件,直接在lovelace中添加实体即可。。坛友这个用了很多的第三方库,需要在在库管理器中手动下载,其中一个还需要arduinoJson还需要5.X老版本的。等我改好了发给你测试一下。
回复

使用道具 举报

69

主题

691

帖子

4242

积分

论坛元老

Rank: 8Rank: 8

积分
4242
金钱
3546
HASS币
80
 楼主| 发表于 2020-1-11 20:53:17 | 显示全部楼层
tshadow 发表于 2020-1-10 12:40
淘宝搜:温度检测器 MAX31865铂电阻温度测量模块,不用刷,直接用

模块的作用只是把PT100数据转换成数字 ...

我也已经用esphome将esp8266接入了ha,mqtt也配置好了,但就是不知道怎么样才能将普读取pt100检测到的水温并接入到ha中。

我也试过用mqtt做了一个sensor,在configuration.yaml中配置如下:但没法读取到水温,ha中显示温度:未知,我不知道 state_topic应该怎么写。

你的这个是怎么配置的,topic是根据什么写的呢
回复

使用道具 举报

0

主题

24

帖子

76

积分

注册会员

Rank: 2

积分
76
金钱
52
HASS币
0
发表于 2020-1-12 10:33:06 | 显示全部楼层
本帖最后由 sinker1985 于 2020-1-12 10:41 编辑
sinker1985 发表于 2020-1-11 18:36
我正在帮你改后面那位坛友的arduino 程序,已经在我的esp8266上跑起来了,温度部分我没有你一样的RTD接口 ...

已经改好了,除了max31865因为手头没有硬件无法测试外,其他功能都测试了,max31865 部分是复制的adafruit库里面的官方例程,只要接线正确的话应该没有问题。一些需要的库什么的我都给你打包在文件夹中了,你就不用下载了,对于如何更改某些设置,也写了一个简要的说明附上。我这里网络不行,上不了百度网盘,你PM个邮箱什么的,我发给你测试一下。
代码是基于 https://bbs.hassbian.com/thread-5522-1-1.html 修改的,
让HASS 自动发现MQTT设备,无需添加yaml。
更改温度传感器为max31865,
去除了水流传感器检测,好像你没有该传感器。

引脚根据你的板子改了一下。
加了一句wifi断线重连。

//#include <Arduino.h> //platformio

/* Board type: nodeMCU1.0;
 * Hass entity name:
 *  sensor.water_temperature
 *  switch.warm_water
 * 
 * 
 */

//  below libraries included in folder
// 1. WiFimmnager by tzapu
//2. ArduinoJson version 5.13.5
//3.Pubsubclient , changed MQTT_MAX_PACKET_SIZE from 128 to 256 in Pubsubclient.h
//4.SimpleTimer
#include <FS.h>
#include "Adafruit_MAX31865.h"
#include <ArduinoOTA.h>
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include "WiFiManager.h" //WiFimmnager by tzapu
#include "ArduinoJson.h"  // version 5.13.5
#include "PubSubClient.h"// Pubsubclient
//for LED status
#include <Ticker.h>
Ticker ticker;
#include "SimpleTimer.h"//  SimpleTimer library, included in the folder

SimpleTimer timer; // Create a Timer object called "timer"!
#define MQTT_VERSION MQTT_VERSION_3_1_1

//define your default values here, if there are different values in config.json, they are overwritten.
// MQTT: ID, server IP, port, username and password
char mqtt_server[40] = "192.168.99.7";
char mqtt_port[6] = "1883";
char mqtt_user[40] = "yourMqttUserName";
char mqtt_password[40] = "yourMQTTpass";

// Pin allocation 
#define BTN_RESET D1
#define STATUS_LED D4
#define RADIO_TUBE_PIN D0 // solenoid valve?
#define WATER_PUMP_PIN D2
#define BEEP_PIN D3


const float tempThreshold = 35.0;// pump stop temperature 
const unsigned long MAX_RUNNING_TIME_MS = 5 * 60000; // pump max running time, 5 min 

const PROGMEM char *MQTT_CLIENT_ID = "warm_water";
// MQTT: topics
const char *MQTT_SENSOR_CONFIG_TOPIC = "homeassistant/sensor/RTDsensor/config";
const char *MQTT_PUMP_CONFIG_TOPIC = "homeassistant/switch/pump/config";
const char *MQTT_PUMP_STATE_TOPIC = "home/pump/status";
const char *MQTT_PUMP_COMMAND_TOPIC = "home/pump/switch";
const  char* MQTT_PUMP_SENSOR_TOPIC = "home/pump/sensor";
// MQTT : hass auto discovery
const char* PUMP_CONFIG_MSG = 
"{"name": "Warm Water", "command_topic": "home/pump/switch", "state_topic": "home/pump/status"}";
const char* SENSOR_CONFIG_MSG = 
"{"device_class": "temperature", "name": "Water Temperature", "state_topic": "home/pump/sensor", "unit_of_measurement": "°C", "value_template": "{{ value_json.watertemp}}" }";
// payloads by default (on/off)
const char *PUMP_ON = "ON";
const char *PUMP_OFF = "OFF";

//flag for saving data
bool shouldSaveConfig = false;

const PROGMEM char *HOST_NAME = "Cold-Water-Recycle";
float tempC =0.0;
int delayTime = 1000;
//int sensorPin = A0;
//int sensorValue = 0;
bool isRecycling = false;

// for mqtt connection retry logic
long retryTimes = 2;
long baseRetryTime = 0 ;
boolean giveUpRetryMqtt = false;

long buttonTimer = 0;
unsigned long longPressTime = 6000;
long recycleStartTime = 0;

boolean buttonActive = false;
boolean longPressActive = false;

// max31865 RTD
// Use software SPI: CS, DI, DO, CLK
Adafruit_MAX31865 thermo = Adafruit_MAX31865(D8, D7, D6, D5);
// use hardware SPI, just pass in the CS pin
//Adafruit_MAX31865 thermo = Adafruit_MAX31865(D8);

// The value of the Rref resistor. Use 430.0 for PT100 and 4300.0 for PT1000
#define RREF      430.0
// The 'nominal' 0-degrees-C resistance of the sensor
// 100.0 for PT100, 1000.0 for PT1000
#define RNOMINAL  100.0



//==========MQTT BEGIN===========
boolean m_pump_state = false;
WiFiClient wifiClient;
PubSubClient client(wifiClient);
bool isWIFIConnected();
void readTempC();
void startRecycleWater();
void stopRecycle();
void flowTriggerListener();
void checkLongRunException();

void publishPumpState()
{
  if (m_pump_state)
  {
    client.publish(MQTT_PUMP_STATE_TOPIC, PUMP_ON, true);
  }
  else
  {
    client.publish(MQTT_PUMP_STATE_TOPIC, PUMP_OFF, true);
  }
}
////////todo
void setPumpState()
{
  if (m_pump_state)
  {
    //    digitalWrite(LED_PIN, HIGH);
    readTempC();
    if (tempC > tempThreshold) {
      m_pump_state = false;
    }
    Serial.println("MQTT INFO: Turn pump on...");
    startRecycleWater();
  }
  else
  {
    //    digitalWrite(LED_PIN, LOW);
    m_pump_state = false;
    Serial.println("MQTT INFO: Turn pump off...");
    stopRecycle();
  }
}


// function called when a MQTT message arrived
void callback(char *p_topic, byte *p_payload, unsigned int p_length)
{
  // concat the payload into a string
  String payload;
  for (uint8_t i = 0; i < p_length; i++)
  {
    payload.concat((char)p_payload[i]);
  }

  // handle message topic
  if (String(MQTT_PUMP_COMMAND_TOPIC).equals(p_topic))
  {
    // test if the payload is equal to "ON" or "OFF"
    if (payload.equals(String(PUMP_ON)))
    {
      if (m_pump_state != true)
      {
        m_pump_state = true;
        setPumpState();
        publishPumpState();
      }
    }
    else if (payload.equals(String(PUMP_OFF)))
    {
      if (m_pump_state != false)
      {
        m_pump_state = false;
        setPumpState();
        publishPumpState();
      }
    }
  }
}

void reconnect()
{
  //Serial.println("current millins:" + String(millis()));
  //Serial.println("previous millins:" + String(baseRetryTime));
  long timespan = millis() - baseRetryTime;
  //Serial.println("compare:" + String(timespan) + " with " + String(5000 * retryTimes));
  if (!client.connected() && !giveUpRetryMqtt ) {
    if (retryTimes == 2 || timespan > 5000 * retryTimes) {

      Serial.print("INFO: Attempting MQTT connection...");
      // Attempt to connect
      if (client.connect(MQTT_CLIENT_ID, mqtt_user, mqtt_password))
      {
        Serial.println("INFO: connected");
        // Once connected, publish an announcement...
        publishPumpState();
        // ... and resubscribe
        client.subscribe(MQTT_PUMP_COMMAND_TOPIC);
        // publish config data to hass
        client.publish(MQTT_PUMP_CONFIG_TOPIC,PUMP_CONFIG_MSG,true);
        client.publish(MQTT_SENSOR_CONFIG_TOPIC,SENSOR_CONFIG_MSG,true);
        Serial.println("published config data");

      }
      else
      {
        Serial.print("ERROR: failed, rc=");
        Serial.print(client.state());

        // debug
        //retryTimes = sq(retryTimes);
        baseRetryTime = millis();
        retryTimes = retryTimes + 1;
        Serial.println("retryTimes" + String(retryTimes));
        if (retryTimes > 1024) {
          giveUpRetryMqtt = true;
        }
        Serial.println("failed to connect mqtt, will retry after " + String(5 * retryTimes) + " seconds");

      }
    }

  }
  else {
    Serial.println("reset retry time");
    retryTimes = 2;
    baseRetryTime = millis();
  }

  //  }
}
void mqttloop() {
  if (isWIFIConnected()) {
    if (!client.connected())
    {
      reconnect();
    }
    client.loop();
    //publishSensorData();
    //publishPumpState();
  }
  else{
    WiFi.reconnect();
    }
}

void publishSensorData() {
  readTempC();
  if (client.connected() && tempC != 85.0 && tempC != (-127.0)) {
    StaticJsonBuffer<200> jsonBuffer;
    JsonObject& root = jsonBuffer.createObject();
    root["watertemp"] = (String)tempC;
    root.prettyPrintTo(Serial);
    char data[200];
    root.printTo(data, root.measureLength() + 1);
    client.publish(MQTT_PUMP_SENSOR_TOPIC, data);
  }
}
void publishData(){
  publishSensorData();
  publishPumpState();
}
//==========MQTT END===========

void tick()
{
  //toggle state
  int state = digitalRead(LED_BUILTIN); // get the current state of GPIO1 pin
  digitalWrite(LED_BUILTIN, !state);    // set pin to the opposite state
}

void beep(int msBeep, int msSpace, int times)
{
  for (int i = 0; i < times; i++)
  {
    digitalWrite(BEEP_PIN, HIGH);
    delay(msBeep);
    digitalWrite(BEEP_PIN, LOW);
    delay(msSpace);
  }
}

//gets called when WiFiManager enters configuration mode
void configModeCallback(WiFiManager *myWiFiManager)
{
  Serial.println("Entered config mode");
  Serial.println(WiFi.softAPIP());
  //if you used auto generated SSID, print it
  Serial.println(myWiFiManager->getConfigPortalSSID());
  //entered config mode, make led toggle faster
  ticker.attach(0.2, tick);
}

//callback notifying us of the need to save config
void saveConfigCallback()
{
  Serial.println("Should save config");
  shouldSaveConfig = true;
}

void mountFS() {

  //clean FS, for testing
  //SPIFFS.format();

  //read configuration from FS json
  Serial.println("mounting FS...");

  if (SPIFFS.begin())
  {
    Serial.println("mounted file system");
    if (SPIFFS.exists("/config.json"))
    {
      //file exists, reading and loading
      Serial.println("reading config file");
      File configFile = SPIFFS.open("/config.json", "r");
      if (configFile)
      {
        Serial.println("opened config file");
        size_t size = configFile.size();
        // Allocate a buffer to store contents of the file.
        std::unique_ptr<char[]> buf(new char[size]);

        configFile.readBytes(buf.get(), size);
        DynamicJsonBuffer jsonBuffer;
        JsonObject &json = jsonBuffer.parseObject(buf.get());
        json.printTo(Serial);
        if (json.success())
        {
          Serial.println("\nparsed json");

          strcpy(mqtt_server, json["mqtt_server"]);
          strcpy(mqtt_port, json["mqtt_port"]);
          strcpy(mqtt_user, json["mqtt_user"]);
          strcpy(mqtt_password, json["mqtt_password"]);
        }
        else
        {
          Serial.println("failed to load json config");
        }
        configFile.close();
      }
    }
  }
  else
  {
    Serial.println("failed to mount FS");
  }
  //end read
}

// initailize for SPIFFS and wifi config manager
void configPortal()
{
  // put your setup code here, to run once:

  // start ticker with 0.5 because we start in AP mode and try to connect
  ticker.attach(0.6, tick);

  mountFS();
  // The extra parameters to be configured (can be either global or just in the setup)
  // After connecting, parameter.getValue() will get you the configured value
  // id/name placeholder/prompt default length
  WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);
  WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqtt_port, 6);
  WiFiManagerParameter custom_mqtt_user("user", "mqtt user", mqtt_user, 40);
  WiFiManagerParameter custom_mqtt_password("password", "mqtt password", mqtt_password, 40);

  //WiFiManager
  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;

  //set config save notify callback
  wifiManager.setSaveConfigCallback(saveConfigCallback);

  //set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
  wifiManager.setAPCallback(configModeCallback);

  //add all your parameters here
  wifiManager.addParameter(&custom_mqtt_server);
  wifiManager.addParameter(&custom_mqtt_port);
  wifiManager.addParameter(&custom_mqtt_user);
  wifiManager.addParameter(&custom_mqtt_password);

  //reset settings - for testing
  //wifiManager.resetSettings();

  //set minimu quality of signal so it ignores AP's under that quality
  //defaults to 8%
  //wifiManager.setMinimumSignalQuality();

  //sets timeout until configuration portal gets turned off
  //useful to make it all retry or go to sleep
  //in seconds
  //wifiManager.setTimeout(120);

  //fetches ssid and pass and tries to connect
  //if it does not connect it starts an access point with the specified name
  //here  "AutoConnectAP"
  //and goes into a blocking loop awaiting configuration
  if (!wifiManager.autoConnect("cold_water_recycle_system"))
  {
    Serial.println("failed to connect and hit timeout");
    delay(3000);
    //reset and try again, or maybe put it to deep sleep
    ESP.reset();
    delay(5000);
  }

  //if you get here you have connected to the WiFi
  Serial.println("connected...yeey :)");
  ticker.detach();
  beep(200, 200, 2);
  //keep LED on
  digitalWrite(LED_BUILTIN, LOW);

  //read updated parameters
  strcpy(mqtt_server, custom_mqtt_server.getValue());
  strcpy(mqtt_port, custom_mqtt_port.getValue());
  strcpy(mqtt_user, custom_mqtt_user.getValue());
  strcpy(mqtt_password, custom_mqtt_password.getValue());

  //save the custom parameters to FS
  if (shouldSaveConfig)
  {
    Serial.println("saving config");
    DynamicJsonBuffer jsonBuffer;
    JsonObject &json = jsonBuffer.createObject();
    json["mqtt_server"] = mqtt_server;
    json["mqtt_port"] = mqtt_port;
    json["mqtt_user"] = mqtt_user;
    json["mqtt_password"] = mqtt_password;

    File configFile = SPIFFS.open("/config.json", "w");
    if (!configFile)
    {
      Serial.println("failed to open config file for writing");
    }

    json.printTo(Serial);
    json.printTo(configFile);
    configFile.close();
    //end save
  }

  Serial.println("local ip");
  Serial.println(WiFi.localIP());
}

/*bool isWaterFlow()
{
  sensorValue = analogRead(sensorPin);
  Serial.println("water flow is:");
  Serial.println(sensorValue);
  return sensorValue > 1000;
}*/

void readTempC()
{
  /*do
  {
    //sensors.requestTemperatures(); // Send the command to get temperatures
    //tempC = sensors.getTempCByIndex(0);
    Serial.println("the tempreture is:");
    Serial.println(tempC);
  } while (tempC == 85.0 || tempC == (-127.0));*/ 
  uint16_t rtd = thermo.readRTD();
  Serial.print("RTD value: "); Serial.println(rtd);
  float ratio = rtd;
  ratio /= 32768;
  Serial.print("Ratio = "); Serial.println(ratio,8);
  Serial.print("Resistance = "); Serial.println(RREF*ratio,8);
  tempC = thermo.temperature(RNOMINAL, RREF);
  Serial.print("Temperature = "); Serial.println(thermo.temperature(RNOMINAL, RREF));

  // Check and print any faults
  uint8_t fault = thermo.readFault();
  if (fault) {
    tempC = 0.0;
    Serial.print("Fault 0x"); Serial.println(fault, HEX);
    if (fault & MAX31865_FAULT_HIGHTHRESH) {
      Serial.println("RTD High Threshold"); 
    }
    if (fault & MAX31865_FAULT_LOWTHRESH) {
      Serial.println("RTD Low Threshold"); 
    }
    if (fault & MAX31865_FAULT_REFINLOW) {
      Serial.println("REFIN- > 0.85 x Bias"); 
    }
    if (fault & MAX31865_FAULT_REFINHIGH) {
      Serial.println("REFIN- < 0.85 x Bias - FORCE- open"); 
    }
    if (fault & MAX31865_FAULT_RTDINLOW) {
      Serial.println("RTDIN- < 0.85 x Bias - FORCE- open"); 
    }
    if (fault & MAX31865_FAULT_OVUV) {
      Serial.println("Under/Over voltage"); 
    }
    thermo.clearFault();
  }
  Serial.println();
  //delay(1000);

}

void startRecycle()
{
  beep(200, 0, 1);
  digitalWrite(RADIO_TUBE_PIN, LOW);
  //  delay(1500);
  digitalWrite(WATER_PUMP_PIN, LOW);
  isRecycling = true;
  Serial.println("start recycling!");
  if (client.connected()) {
    publishPumpState();
  }
}

void stopRecycle()
{
  if (isRecycling) {
    beep(200, 200, 2);
    digitalWrite(WATER_PUMP_PIN, HIGH);
    //  delay(1500);
    digitalWrite(RADIO_TUBE_PIN, HIGH);
    isRecycling = false;
    Serial.println("stop recycle!");

  }
  //if (client.connected()) {
    publishPumpState();
  //}
}



void otaConfig()
{
  //=====================OTA start====================================
  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH)
      type = "sketch";
    else // U_SPIFFS
      type = "filesystem";

    // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
    Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR)
      Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR)
      Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR)
      Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR)
      Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR)
      Serial.println("End Failed");
  });
  ArduinoOTA.begin();
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  //=====================OTA end====================================
}

void startRecycleWater()
{
  readTempC();
  if (tempC < tempThreshold)
  {
    Serial.println("start recycle cold water...");

    if (!isRecycling)
    {
      m_pump_state = true;
      startRecycle();
    }
  }
  else
  {
    // if tempreture is good, set the flag to false
    m_pump_state = false;
    if (isRecycling)
    {
      stopRecycle();
    }
    Serial.println("the tempreture is good enough! will not start recycle.");
  }

  //if (client.connected()) {
  //  publishPumpState();
  //}
}

void manualButtonListener() {

  if (digitalRead(BTN_RESET) == LOW)
  {

    if (buttonActive == false)
    {
      buttonActive = true;
      buttonTimer = millis();
    }
    if ((millis() - buttonTimer > longPressTime) && (longPressActive == false))
    {
      longPressActive = true;

      WiFiManager wifiManager;
      wifiManager.resetSettings();
      Serial.println("reseting to factory...0");
      beep(400, 400, 3);
      //      ESP.reset();
      configPortal();
    }
  }
  else
  {
    if (buttonActive == true)
    {
      if (longPressActive == true)
      {
        longPressActive = false;
      }
      else
      {
        Serial.println("trigger manually");

        if (m_pump_state == false) {
          m_pump_state = true;
          startRecycleWater();
        }
        else {
          m_pump_state = false;
          stopRecycle();
        }

        buttonActive = false;
      }
    }
  }
}
void startMain() {

  Serial.println("m_pump_state:" + String(m_pump_state));
  Serial.println("isRecycling:" + String(isRecycling));

  //flowTriggerListener();

  mqttloop();

  if(isRecycling){
    publishSensorData();
  }
  
  if (tempC > tempThreshold && isRecycling) {
    Serial.println("water stoped");
    m_pump_state = false;
    stopRecycle();
  }

  checkLongRunException();

  //set signal led status
  if (isWIFIConnected() && client.connected())
  {
    digitalWrite(LED_BUILTIN, LOW);
    ticker.detach();
  }
}

/*void flowTriggerListener() {
  if (isWaterFlow())
  {
    delay(300);
    if (isWaterFlow()) {
      Serial.println("water flowing...");
      m_pump_state = true;
      startRecycleWater();
    }
  }
}*/
bool isWIFIConnected() {
  //WiFi.status() == WL_CONNECTED not work
  return WiFi.status() == WL_CONNECTED;//(WiFi.localIP().toString() != "0.0.0.0");
}

void checkLongRunException(){
  if(isRecycling){
    if(recycleStartTime<1){
      recycleStartTime = millis();
    }
    else{
      // if keep running more than 5 minites, stop recycle
      if(millis() - recycleStartTime > (MAX_RUNNING_TIME_MS)){
        Serial.println("Warning! keep running to long time to stop the recycle!!");
        m_pump_state = false;
        stopRecycle();
      }
    }
    
  }
  else{
    recycleStartTime = 0;
  }
}

void setup(void)
{
  // start serial port
  Serial.begin(115200);
  thermo.begin(MAX31865_3WIRE);

  //set led pin as output
  pinMode(STATUS_LED, OUTPUT);

  otaConfig();

  mountFS();

  Serial.println("####### Cold Water Recycle System #######");
  pinMode(RADIO_TUBE_PIN, OUTPUT);
  digitalWrite(RADIO_TUBE_PIN, HIGH);
  pinMode(WATER_PUMP_PIN, OUTPUT);
  digitalWrite(WATER_PUMP_PIN, HIGH);
  pinMode(BEEP_PIN, OUTPUT);
  pinMode(BTN_RESET, INPUT_PULLUP);

  // Start up the library
  //sensors.begin();
  // system start signal
  beep(600, 0, 1);

  m_pump_state = false;

  // init the MQTT connection
  // TODO: parameterlize the port
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  ticker.attach(1, tick);

  timer.setInterval(1000L, startMain);
  timer.setInterval(100L, manualButtonListener);
  timer.setInterval(120000L, publishData);//2 mins
  // publish pump switch and temp sensor config to HASS
  
}

void loop(void)
{
  timer.run(); // SimpleTimer is working

  ArduinoOTA.handle();
}
回复

使用道具 举报

0

主题

24

帖子

76

积分

注册会员

Rank: 2

积分
76
金钱
52
HASS币
0
发表于 2020-1-12 10:34:38 | 显示全部楼层
本帖最后由 sinker1985 于 2020-1-12 10:37 编辑

简要说明:

1.使用的开发板是nodemcu1.0。
2.硬件连接

Nodemcu         负载                     功能说明                            电位        备注        
D0         电磁阀继电器                                                  低电平有效               
D1        常开按钮        长按配网,短按启动循环泵        高电平输入有效        2K电阻接3.3V,        
D2        泵继电器                                                          低电平有效               
D3        蜂鸣器                              操作和状态提示        高电平有效               
D4        状态指示LED        慢闪:网络连接错误

                                        快闪:正在配网 常亮:正常状态                        
D5        Max31865,CLK                                                            代码中,RTD默认使用3 线接法,      
D6        Max31865,DO                                                            可根据实际情况改代码为2线或四线     
D7        Max31865,DI                                
D8        Max31865,CS                                

3.代码定制并下载
1)按上表连接硬件 或在代码中根据你的实际连接情况更改针脚定义。
2)代码中设置自动停泵水温, 默认是35.0
const float tempThreshold = 35.0;
3)代码中设置单次最长运转时间,防止意外情况下泵一直运转不停,默认 5分钟;
const unsigned long MAX_RUNNING_TIME_MS = 5 * 60000; // pump max running time, 5 min
此时可尝试编译下载到nodemcu中。

4.使用说明
下载完成后,板载led 和状态led D4 应该会慢闪, 长按D1 所连的按钮,直到 led开始快闪,用手机搜索热点cold_water_recycle, 选第一项进入,设置 你的wifi SSID, 密码, MQTT服务器的IP地址,端口,1883, 用户名和密码, 完成后提交,配网成功后,板载led会变为常亮。

打开arduino串口监视器,看看有没有MQTT服务器连接成功或失败的信息,顺便看看温度读取是否正常。

电脑上使用MQTT客户端,订阅所有主题,看看有没有收到配置消息。

如果一切正常,在HASS中打开lovelace编辑界面,添加entities card,连续添加sensor.water_temperature 和 switch.warm_waterr 两个实体。

评分

参与人数 1金钱 +10 收起 理由
zhenxiwen + 10 论坛有你更精彩!

查看全部评分

回复

使用道具 举报

69

主题

691

帖子

4242

积分

论坛元老

Rank: 8Rank: 8

积分
4242
金钱
3546
HASS币
80
 楼主| 发表于 2020-1-12 14:19:42 | 显示全部楼层
本帖最后由 zhenxiwen 于 2020-1-12 18:09 编辑
sinker1985 发表于 2020-1-12 10:34
简要说明:

1.使用的开发板是nodemcu1.0。

你真是太热心了,我向你致敬!
如果我们论坛中的大神都有你这种助人为乐的精神,这个论坛一定会是个学习和创新的乐园!论坛应该鼓励这种精神,赞同的加分吧!
总帅加分吧!

谢谢你!谢谢你!

其实,从使用上说,我原来的方案已经能够满足基本的需求,我是抱着学习的心态想把这个东西弄清楚,你花了很多时间帮我写了代码和使用说明,不仅对我有帮助,我想对其他有兴趣的朋友一定也是很大的帮助,我会认真学习试验的!

回复

使用道具 举报

0

主题

24

帖子

76

积分

注册会员

Rank: 2

积分
76
金钱
52
HASS币
0
发表于 2020-1-12 16:17:54 | 显示全部楼层
zhenxiwen 发表于 2020-1-12 14:19
你真是太热心了,我向你致敬!
如果我们论坛中的大神都有你这种助人为乐的精神,这个论坛一定会是个学习和 ...

太客气啦,我家里也是热水器离卫生间比较远,冬天很废水,所以对这个循环泵也很感兴趣。另外我也不是什么高手大神,十五六年学校的时候学过点C,C++, 程序我只是稍稍修改了一点点,原作者@yuwei526应该是花了很多心思的。包含所需库文件的程序我已经发到你邮箱了,有问题直接说就行啦。
回复

使用道具 举报

69

主题

691

帖子

4242

积分

论坛元老

Rank: 8Rank: 8

积分
4242
金钱
3546
HASS币
80
 楼主| 发表于 2020-1-12 17:59:35 | 显示全部楼层
本帖最后由 zhenxiwen 于 2020-1-12 18:14 编辑
sinker1985 发表于 2020-1-12 10:34
简要说明:

1.使用的开发板是nodemcu1.0。

热心助人的精神是永远应该崇尚的!!

1、不好意思,你发的文件是arduino的库文件吧,怎么使用呢。我的arduino已经根据报错,我自己下载了各种缺少是库,但是,我将你的代码复制保存为ino文件并刷机时,总是报错:
cold_water_recycle:305:11: error: DynamicJsonBuffer is a class from ArduinoJson 5. Please see arduinojson.org/upgrade to learn how to upgrade your program to ArduinoJson version 6

jason.JPG

我也已经下载了最新版的 ArduinoJson 6.x 库,但好像arduino无法加载这个v6的库,仍然重复上面的报错。

好像这是一个arduino的问题:https://arduinojson.org/v6/doc/upgrade/

2、我是要做个按钮吗,就是要用一个2k电阻串联一个微按钮,然后连接在板子的v3与D1上,做一个配置按钮,是吗。


回复

使用道具 举报

0

主题

24

帖子

76

积分

注册会员

Rank: 2

积分
76
金钱
52
HASS币
0
发表于 2020-1-12 20:48:11 来自手机 | 显示全部楼层
本帖最后由 sinker1985 于 2020-1-12 21:07 编辑


1. 我发到你邮箱里的zip文件,解压,不要改变文件夹名称和结构,里面有一个cold_water_recycle_Rev1.ino,双击打开,直接编译。考虑到你可能对下载库版本什么的不熟悉,我已经把需要的库文件放到目录里了,你看#include "ArduinoJson.h",这种带双引号的意思就是优先从本地目录寻找。
ArduinoJson 原作者用的是5.xx版本的。arduino库里面的 simpletimer 也不是作者用的那个,我从github下载了正确版本的放到本地目录了。


回复

使用道具 举报

0

主题

24

帖子

76

积分

注册会员

Rank: 2

积分
76
金钱
52
HASS币
0
发表于 2020-1-12 20:50:24 来自手机 | 显示全部楼层
2.是的,这个按钮长按用来配网,短按启动循环泵。原作者这么设计的,我也没有改动。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-11-25 08:28 , Processed in 1.361940 second(s), 35 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表