0

ホーム オートメーション プロジェクトで問題が発生しています。ブラインドを制御したい aliexpress から nodeMCU v3 を購入しました。

これは私が使用しているコードです。Arduino IDE を使用して、このコードを nodeMCU にプッシュします。

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <SimpleTimer.h>

// MQTT Server
const char* ssid = "****";
const char* password = "****";
const char* mqtt_server = "****";


char message_buff[100];
int photoValue = 0;
int rainValue = 0;
int photo = A0;
int rain = D6;
int relayUp = D7;
int relayDown= D8;
long interval = 10000;
long previousMillis = 0;

WiFiClient espClient;
PubSubClient client(espClient);

void setup_wifi() {
  delay(10);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
}

void setup() {

  pinMode(photo, INPUT);
  pinMode(rain, INPUT);
  pinMode(relayUp, OUTPUT);
  pinMode(relayDown, OUTPUT);

  digitalWrite(relayUp ,LOW);
  digitalWrite(relayDown, LOW);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    if (client.connect("ESP8266Client")) {
      client.subscribe("home/relayBlinds");
    } else {
      delay(5000);
    }
  }
}

void loop() {

  if (!client.connected())  {
    // Connect (or reconnect) to mqtt broker on the openhab server
    reconnect();
    }
// Read Photo- and Rain-sensors  
  photoValue = analogRead(photo);
  rainValue = analogRead(rain);

  // publish Temperature reading every 10 seconds
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis  > interval) {
    previousMillis = currentMillis; 

    // publish Photo
    String pubStringPhoto = String(photoValue);
    pubStringPhoto.toCharArray(message_buff, pubStringPhoto.length()+1);
    client.publish("home/photo", message_buff);

    // publish Rain
    String pubStringRain = String(rainValue);
    pubStringRain.toCharArray(message_buff, pubStringRain.length()+1);
    client.publish("home/rain", message_buff);
  }
  client.loop();
}


void callback(char* topic, byte* payload, unsigned int length) {
 // MQTT inbound Messaging 
int i = 0;

  // create character buffer with ending null terminator (string)
  for(i=0; i<length; i++) {
    message_buff[i] = payload[i];
  }
  message_buff[i] = '\0';

  String msgString = String(message_buff);

  if (msgString == "BLINDSUP") {
    digitalWrite(relayUp ,HIGH);
    delay(5000);
    digitalWrite(relayUp ,LOW);
  } else if (msgString == "BLINDSDOWN") {
    digitalWrite(relayDown ,HIGH);
   delay(5000);
    digitalWrite(relayDown ,LOW);
  } 
}

計画は、コントローラーとしてopenHABを備えたRaspberry Piを用意することでした。mosquitto と openHAB をセットアップするためにいくつかのガイドを使用しましたが、常に同じ結果が得られます。

nodeMCUが私の Wifi に接続し、雨と写真の値の両方を公開します。openHAB GUI で問題なく読み取ることができます。

openHAB のアクティブ化ボタンを押して BLINDSUP または BLINDSDOWN を発行すると、メッセージは問題なく届き、mosquitto 端末でメッセージを見ることができます。予期せぬ結果が起こり始めるのは今です。同じメッセージが、mosquitto ターミナルに表示されることなく、nodeMCU に複数回配信されます。

なぜこのように動作するのかを調べてみましたが、次の行が原因だと思います。

if (!client.connected())  {

false で、nodeMCU が再接続し、何らかの方法で同じメッセージを取得します。しかし、それは常に最初のメッセージです。BLINDSUP を送信してから BLINDSDOWN を送信すると、BLINDSUP のみが永久に登録されます。

これを修正する方法が本当にわからないので、助けていただければ幸いです。

とにかく役立つ場合は、nodeMCU への URL: nodeMCU

4

1 に答える 1

0

クリーン セッションで MQTT ブローカーに接続してみてください。おそらく、retain フラグを true に設定してトピックを公開しました。

これを行うと、nodeMCU がブローカーに接続し、保持されたトピックにサブスクライブするときに、ブローカーは最後に保持されたメッセージを配信します。

于 2016-09-08T10:29:12.120 に答える