ふろ水ポンプをWiFi無線通信で遠隔操作する

ふろ水ポンプと洗濯機が離れており15mのコードリールにて延して運転していたが、これをWiFiで接続して遠隔制御を行ったので紹介する。

ふろの残り水を洗濯機に送るふろ水ポンプは、洗濯機から出ている電源(DC12V)に接続して運転するようになっている。ところが、風呂場と洗濯機との距離が10m以上もあるので、延長コードを用意する必要があった。

この作業は洗濯の都度、ほぼ毎日行う必要があり、また雨の時など、扉を開けたままにする必要もあり大変面倒だった。

今回これを改善するため、ESP-Wroom-02マイコン2台を用い、WiFi通信で無線制御を行うシステムを製作した。

システム設計

水中ポンプ遠隔起動システムの概要設計

このシステムは、距離的に約10m離れた風呂場と洗濯室の2拠点間をWiFi通信で接続し、洗濯機から出力される起動信号を風呂場に設置した水中ポンプに伝え、風呂の残り水を洗濯機に送水するものである。

洗濯機専用ふろ水ポンプを変更

もともと、シャープのふろ水ポンプはDC12V×14Wの水中ポンプで、最大揚程1.4m×揚水量6L/minであり4mほどのホース接続に用いられるもので、今回のような10m離れて送水するには無理があった。

このため、3年前、AC100Vの35W水中ポンプ(最大揚程2m×揚水量36.7L/min)を購入して使用していた。

システム構成図

システム構成図を下記に示す。

風呂場には、サーバー側マイコン(以下サーバー)を、また洗濯室には、クライアント側マイコン
(以下 クライアント)を設置して、WiFi通信を行う。

サーバーには、AC100V(35W)の水中ポンプを運転するためリレー出力回路が接続されている。

一方、クライアントには、洗濯機からの「ふろ水ポンプ電源」を起動信号として入力するため、フォトカプラ入力回路が接続されている。

洗濯機からの要求で「ふろ水ポンプ電源」がONとなると、クライアントは起動信号をサーバーに送りサーバーがこの信号で水中ポンプを起動する。

同様に「ふろ水ポンプ電源」がOFFになると、クライアントは停止信号をサーバーに送りサーバーがリレーをOFFにして水中ポンプを停止する。

マイクロコントローラー

マイクロコントローラーは、ESP-Wroom-02を使用した。ESP-Wroom-02については、これまでもシステム開発に使用して来た実績があり下記記事に紹介している。

また、Wroom-02を使った各システム開発については、下記記事に紹介している。

ESP-WROOM-02 | リタイア後の人生は毎日が楽しい!
「ESP-WROOM-02」の記事一覧です。

ふろ水ポンプ起動信号入力インタフェース回路

クライアントでは、洗濯機の「ふろ水ポンプ」の運転用電源を起動信号としてフォトカプラにて入力する。

この電源は、元々シャープ指定のふろ水ポンプ用に設計されており、DC12V全波整流された信号となる。

この信号のままフォトカプラ入力すると出力側トランジスターが120HzでON/OFFを繰り返すので信号として整形する必要がある。

そのため、リップル率を5%以下になるよう、100μFの平滑コンデンサを入れた。

水中ポンプ起動出力インタフェース回路

サーバーでは、クライアントから送られたふろ水ポンプ起動信号にてリレーを駆動して、水中ポンプを起動する。

リレーは1a接点を使用して、AC100V電源をON/OFFするようにした。

ソフトウェア設計・製作

WiFi通信のプロトコルとフェールセーフ

今回、Wroom-02を使用したWiFi通信において、TCPIPかUDPのいずれを使うかを実際にテストをして見た。その結果、TCPIPよりUDPが向いていると判断した。

TCPIPでは通信のやり取りが面倒で、通信エラー発生時には再送したりする手間があるが、UDPでは一方的な通信となるので、エラーが起きても無視されるので、次の通信で正常化され、あたかも有線接続のように使用出来る。

ただ、クライアントが送信できない状態となった場合を考慮して、サーバー側でタイマーを設け一定時間更新されない時はフェールセーフとなるようにしなければならない。

今回は、このタイマーを3秒と設定して、もしクライアントからの送信が途切れても3秒後に水中ポンプを停止するようにした。

参考になったWiFi通信のサイトは下記のふたつである。

サーバー側ソフトウェア

サーバー側はESP-Wroom-02をアクセスポイントモードに設定する。

サーバーには、運転動作表示用LEDがあり、ポンプ運転信号がONになると5Hzでの点滅を、停止信号で0.5Hzの点滅となる。

サーバー側プログラムリストを下記に示す。

#define PROG_NAME "(BathWaterReuse_SVR000)"

#include <Ticker.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h> 
#include <WiFiUDP.h>

// Variable setting
char WiFibuff[4];


// UDP setting
WiFiUDP UDP;

// WiFi setting
IPAddress myIP(192, 168, 4, 1);
Ticker ticker1;

//led
#define LED_BLINK 13 
#define RelayOutPin 4 


const char* ssid = "WROOM-02MICOM";
const char* password = "password";

//const int ledPin = 16;
//const int led1 = 4;
const int led2 = 5;
const int led3 = 12;
const int led4 = 2;

static int count_sec = 0;  // 1 sec counter
static int sub_counter=10;  // 100 msec counter
static bool flg_NoPacket=false;
static int cnt_NoPacket=0;

void setup() {
  Serial.begin(115200);
  
  pinMode(LED_BLINK, OUTPUT);
  pinMode(RelayOutPin, OUTPUT);
  digitalWrite(RelayOutPin, LOW);
  
  ticker1.attach_ms(100, count_down);
  
  WiFi.mode(WIFI_AP);
  WiFi.softAP(ssid, password);
  WiFi.config(myIP, WiFi.gatewayIP(), WiFi.subnetMask());
  UDP.begin(893);


//  digitalWrite(ledPin, HIGH);
  Serial.println("UDP.begin!");

}

void rcvWiFi() {
  UDP.read(WiFibuff, 4);
  Serial.println(WiFibuff);
  UDP.flush();
}

void count_down() { // 100msec 毎にカウント
  sub_counter--;
  if(sub_counter <= 0){
    sub_counter = 10;
    count_sec--;
  }
  if(digitalRead(RelayOutPin)==1){
    digitalWrite(LED_BLINK, sub_counter%2);
  }else{
    digitalWrite(LED_BLINK, count_sec%2);
  }
  if(flg_NoPacket){
    cnt_NoPacket++;
  }
}

void loop() {

  if (UDP.parsePacket() > 0) {
     Serial.println("parsePacket OK!");
    rcvWiFi();
    flg_NoPacket = false; //  false: 正常、true:受診データなし
    cnt_NoPacket = 0;
    if(WiFibuff[0] == '0') { digitalWrite(RelayOutPin, HIGH); } else { digitalWrite(RelayOutPin, LOW); }
    if(WiFibuff[1] == '0') { digitalWrite(led2, HIGH); } else { digitalWrite(led2, LOW); }
    if(WiFibuff[2] == '0') { digitalWrite(led3, HIGH); } else { digitalWrite(led3, LOW); }
    if(WiFibuff[3] == '0') { digitalWrite(led4, HIGH); } else { digitalWrite(led4, LOW); }
  }else{
//  Serial.print("parsePacket NG!");
//   Serial.println(cnt_NoPacket );
    flg_NoPacket = true;
    if(cnt_NoPacket >= 30){ // 通信が不通になって3秒後に全てOFFにする
      digitalWrite(RelayOutPin, LOW);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
  ESP.restart();
    }
  }
}

クライアント側ソフトウェア

クライアント側はESP-Wroom-02をステーションモードに設定する。

クライアント側には、運転動作表示用LEDは2つあり、ひとつは、サーバー未接続時5Hzの点滅、接続すると0.5Hzの点滅表示する。もうひとつは、洗濯機からのふろ水ポンプ電源で、ONになると点灯、OFFで消灯となる。

クライアント側プログラムリストを下記に示す。

#define PROG_NAME "(BathWaterReuse_CLT000)"

#include <Ticker.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h> 
#include <WiFiUDP.h>


//led
#define LED_BLINK 13 
#define PumpOnInputPin 4 


// UDP setting
WiFiUDP UDP;

Ticker ticker1;


// WiFi setting
IPAddress HOSTIP (192, 168, 4, 1);
IPAddress myIP(192, 168, 4, 2);

const char* ssid = "WROOM-02MICOM";
const char* password = "password";


// const int btn1 = 4;
const int btn2 = 5;
const int btn3 = 12;
const int btn4 = 2;

// const int ledPin = 13;
static int wifiStatus = 1;

// Variable setting
static char WiFibuff[4];


static int count_sec = 0;  // 1 sec counter
static int sub_counter=10;  // 100 msec counter



void connectWiFi() {
  WiFi.begin(ssid, password);
  WiFi.config(myIP, WiFi.gatewayIP(), WiFi.subnetMask());

  Serial.println("start_connect");
  while (WiFi.status() != WL_CONNECTED) {
    delay(200); // 500
    Serial.print(".");
  }
  Serial.println("CONNECTED!");
  wifiStatus = 0;
//  digitalWrite(wifiStatusPin, HIGH);
}

void count_down() {
  sub_counter--;
   if(sub_counter <= 0){
    sub_counter = 10;
    count_sec--;
    digitalWrite(LED_BLINK, count_sec%2);
   }
  if(wifiStatus == 1){
    digitalWrite(LED_BLINK, sub_counter%2);
  }
}


void setup() {
  Serial.begin(115200);
  
  pinMode(LED_BLINK, OUTPUT);
//  pinMode(PumpOnInputPin, INPUT);
//  pinMode(ledPin, OUTPUT);
//  pinMode(wifiStatusPin, OUTPUT);
  
  pinMode(PumpOnInputPin, INPUT_PULLUP);
  pinMode(btn2, INPUT_PULLUP);
  pinMode(btn3, INPUT_PULLUP);
  pinMode(btn4, INPUT_PULLUP);

   delay(500);
  wifiStatus = 1;
// digitalWrite(ledPin, HIGH); 
  ticker1.attach_ms(100, count_down);

  Serial.println("-");
  Serial.println("start");
  WiFi.mode(WIFI_STA);//重要!
  UDP.begin(893);
  connectWiFi();
}
  
void sendWiFi(char byteData[]) {
  if (UDP.beginPacket(HOSTIP, 893)) {
    UDP.write(byteData);
    UDP.endPacket();
    Serial.println(byteData);
  }
}


void loop() {
  char  b[4];
  
  b[0] = digitalRead(PumpOnInputPin) ? '1' : '0';
  b[1] = (digitalRead(btn2)) ? '1' : '0';
  b[2] = (digitalRead(btn3)) ? '1' : '0';
  b[3] = (digitalRead(btn4)) ? '1' : '0';
  Serial.println(b);

  sendWiFi(b);
  
  delay(50); //17
  end_loop();
}
void end_loop(){
  if (WiFi.status() != WL_CONNECTED) {
    WiFi.disconnect();
    wifiStatus = 1;
//    digitalWrite(wifiStatusPin, LOW);
    Serial.println("disconnect!");
    connectWiFi();
  }
}

筐体を3Dプリンターで製作する

サーバー、クライアント回路の各基板のケースを3Dプリントして製作した。

Fusion360でモデリング

まず、Fusion360でモデリングを行った。

3Dプリンターで印刷

モデリングで完成したstlファイルをcuraに取込み、Gコードを生成し、Ender-3にて印刷を行った。

組立て・運転

サーバー、クライアントそれぞれを、洗濯室に置き、電源および信号、ポンプを接続して運転に入った。

サーバー

サーバー回路をハンダ付けにて基板に構成し、ケースに収納して完成。

風呂場に設置したサーバーをAC100V電源に接続し、ポンプをリレー出力ソケットに接続して準備完了。

クライアント回路をハンダ付けにて基板に構成し、同様にケースに収納して完成。

洗濯室に設置したクライアントの電源をAC100Vに接続し、洗濯機のふろ水ポンプ接続ソケットに信号入力プラグを差込み準備完了。

写真上のコネクターが洗濯機から出ているふろ水ポンプ接続用プラグである。

水中ポンプ運転

洗濯機をふろ水利用に設定し、運転すると、ふろ水ポンプの電源がONとなり、クライアントからサーバーに運転指令が送られる。

これにともない、サーバーにてリレー出力がONとなり、AC100V水中ポンプが起動される。

その後、ふろ水ポンプの電源がOFFになると、サーバー側のリレー出力もOFFとなり、水中ポンプが停止する。

まとめ

以上がWiFiを使った、水中ポンプ遠隔制御システムである。

コスト的にもESP-WROOM-2マイコンが400円/枚、直流電源、その他の部品を含めて合計1,500円未満で出来あがった。

参考までに、既設の水中ポンプは約2,500円で2018年に購入したもので、配管材料(ホースとVP13)などを入れて総合計約5,000円で出来上がる。

タイトルとURLをコピーしました