2016-07-26 9 views
0

광산의 홈 자동화 프로젝트에 문제가 있습니다. 나는 블라인드를 제어하고 싶은 aliexpress에서 nodeMCU v3를 샀다.nodeMCU와 함께 반복되는 브로커 메시지

이것은 내가 사용하고있는 코드입니다. 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를 컨트롤러로 사용하는 라즈베리 파이가 있어야했습니다. 나는 mosquitto와 openHAB을 설치하기 위해 몇 가지 가이드를 사용했으며 항상 같은 결과를 얻는다.

따라서 : nodeMCU가 내 Wi-Fi에 연결되어 비와 사진 값을 게시합니다. openHAB GUI에서 문제없이 읽을 수 있습니다.

openHAB의 활성화 버튼을 눌러 BLINDSUP 또는 BLINDSDOWN을 게시하면 메시지가 아무런 문제없이 도착하고 내 모스펫 터미널에서 메시지를 볼 수 있습니다. 예상치 못한 결과가 일어나기 시작한 때입니다. 동일한 메시지가 모스 킷토 터미널에 나타나지 않으면 노드 MCU에 여러 번 전달됩니다.

는 나는 이런 식으로 행동 할 이유를 찾기 위해 노력하고 난 라인 때문입니다 생각 :

if (!client.connected()) { 

이 거짓과 nodeMCU가 다시 연결하고 어떻게 든 동일한 메시지를 가져옵니다. 그러나 항상 첫 번째 메시지입니다. BLINDSUP을 보낸 다음 BLINDSDOWN을 보내면 BLINDSUP 만 영원히 등록됩니다.

저는이 문제를 해결하는 방법이 정말 부족하고 도움을 주셔서 감사합니다. nodeMCU에

URL 즉 어쨌든 도움이된다면 : nodeMCU

답변

0

깨끗한 세션 MQTT 브로커에 연결하십시오. 아마도 retain 플래그가 true로 설정된 주제를 발행했을 것입니다.

이렇게하는 경우 nodeMCU가 브로커에 연결하고 유지 된 주제에 가입하면 브로커는 마지막으로 보관 된 메시지를 전달합니다.