エンジニア風味 (Engineer-taste)

電子系エンジニアのメモ帳

ESP-WROOM-02で無線LANチャイムをつくる

今まで315MHz帯の無線チャイムを使っていたのですが、意外に電波が届かなくて、鳴ったり鳴らなかったりという状況で、無線LAN経由でチャイムを鳴らすガジェットを作りました。
今回は送信器編です。

回路については、Expansiffのユーザマニュアルにある回路を、ほとんどそのまま使っています。
ESP-WROOM-02秋月電子のピッチ変換基板に載っているものを使いました。

回路図は、下のようになります。

f:id:engineer-paju:20190414181053p:plain
チャイム送信器の回路図

CN1, CN2は、プログラミングのときしか使わないので、ジャンパーピンを挿せばショートされるようにしてあり、スイッチは使いませんでした。また、CN3にはUSBシリアルコンバータが接続されます。

f:id:engineer-paju:20190414181404j:plain
ケースに収めたところ

80x50x20mmのケースが手元にあったので、使いました。たぶんaitendoのものだと思います。
ケースの中はこのようになっています。

f:id:engineer-paju:20190414181554p:plain
内蔵基板の図

電源はUSBから取ることにしました。

f:id:engineer-paju:20190414181732j:plain
基板の裏側
ハンダ付けで配線してあります。

プログラムは、こちらを参考にさせていただきました
www.autumn-color.com

ただ、動かしてみると、ボタンを長押ししないと(つまり、ボタンを押している間に、プログラムが状態を拾いに来ないと)ボタンが押されたという情報が出て行かないことがわかりました。
それで、Arduinoの割り込み処理を調べて、プログラムは下記のようになりました。

#include <ESP8266WiFi.h>
#include <WebSocketsClient.h> //https://github.com/Links2004/arduinoWebSockets
#include <Ticker.h>

#define btn1 4 //スイッチ1のGPIO

//LED
#define led1 13 //LED1のGPIO

//ServerIP
const char* ServerIp("192.168.xx.xx"); //サーバーに割り当てるアドレス
int ServerPort = 8000;

//Ssid, pass
const char* Ssid = "xxxx"; //ルータのID
const char* Password = "xxxx"; //ルータのpassword

int b; //ボタン状態


WebSocketsClient webSocket;

//タイマ初期化
Ticker ticker;

//Connected Flag 接続されるとtrue
bool ConnectFlag = false;

//Timer callback
void doBlockingIO() {
    Serial.println(b);
    if(ConnectFlag){
       if(b){
        webSocket.sendTXT("1"); //Send Message
        b=0;
        digitalWrite(led1, HIGH);
        delay(500);
        digitalWrite(led1, LOW);
        delay(500);
        digitalWrite(led1, HIGH);
        delay(500);
        digitalWrite(led1, LOW);
       }
       else{
        webSocket.sendTXT("0"); //Send Message
       }
    }
}

void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) {

    switch(type) {
        case WStype_DISCONNECTED:
            Serial.printf("[WSc] Disconnected!\n");
            ConnectFlag = false;
            break;

        case WStype_CONNECTED:
            {
                Serial.printf("[WSc] Connected to url: %s\n",  payload);
                ConnectFlag = true;
            }
            break;

        case WStype_TEXT:
           Serial.printf("[WSc]Recv: %s\n", payload);

            // send data to back to Server
            //webSocket.sendTXT(payload, lenght);
            break;

        case WStype_BIN:
            Serial.printf("[WSc] get binary lenght: %u\n", lenght);
            hexdump(payload, lenght);

            // echo data back to Server
            webSocket.sendBIN(payload, lenght);
            break;

        case WStype_ERROR:
            Serial.printf("We received an error \n");
            break;

        default:
            break;
    }
}


void setup() {
    pinMode(led1, OUTPUT);
    Serial.begin(115200);
    Serial.print("\nStart\n");

    pinMode(btn1, INPUT_PULLUP); //btn1は入力でプルアップされている
    attachInterrupt(btn1,intFunc,FALLING); //btn1がHigh→Lowで割り込みルーチンへ

    WiFi.begin(Ssid, Password);
    while(WiFi.status() != WL_CONNECTED) {
        Serial.print('.');
        delay(500);
        }

    Serial.println();
    Serial.printf("Connected, IP address: ");
    Serial.println(WiFi.localIP());

    //server ip
    webSocket.begin(ServerIp, ServerPort);
    webSocket.onEvent(webSocketEvent);
    Serial.println("Client started\n");
    digitalWrite(led1, HIGH);
    delay(500);
    digitalWrite(led1, LOW);
    delay(500);
    digitalWrite(led1, HIGH);
    delay(500);
    digitalWrite(led1, LOW);
    delay(500);
    digitalWrite(led1, HIGH);
    delay(500);
    digitalWrite(led1, LOW);

    //set timer
    ticker.attach(2, doBlockingIO); //2sec
}


void loop() {
    webSocket.loop();
}

void intFunc(){
  b=1; //ボタンが押されたステータス発行
}

これで、ボタンを押したという情報が確実に送信されるようになりました。

続きは後ほど。

※esp8266 by ESP8266 Communityのバージョンにより、うまく動作しないという問題が出ることがわかりました。
 その場合は、こちら
www.engineer-taste.com
を試していただければと思います。