Điều khiển ESP8266 qua Raspberry Pi thông qua MQTT


9

Tôi đang làm việc trên một dự án tự động hóa nhà. Mục tiêu cơ bản của dự án của tôi là kiểm soát rơle và các cảm biến khác được đặt tại các vị trí khác nhau. Tôi đã thiết lập Raspberry Pi của mình với tư cách là nhà môi giới MQTT. Mosquitto đang chạy tốt. Hiện tại, những gì tôi đang cố gắng làm là kích hoạt một rơle nối dây với Esp8266 (GPIO2). Đây là mã máy chủ web Python của tôi:

import paho.mqtt.client as mqtt
from flask import Flask, render_template, request
app = Flask(__name__)

mqttc=mqtt.Client()
mqttc.connect("localhost",1883,60)
mqttc.loop_start()

# Create a dictionary called pins to store the pin number, name, and pin state:
pins = {
   2 : {'name' : 'GPIO 2', 'board' : 'esp8266', 'topic' : 'esp8266/2', 'state' : 'False'}
}

# Put the pin dictionary into the template data dictionary:
templateData = {
'pins' : pins
}

@app.route("/")
def main():
# Pass the template data into the template main.html and return it to the user
return render_template('main.html', **templateData)

# The function below is executed when someone requests a URL with the pin number and action in it:
@app.route("/<board>/<changePin>/<action>")

def action(board, changePin, action):
# Convert the pin from the URL into an integer:
changePin = int(changePin)
# Get the device name for the pin being changed:
devicePin = pins[changePin]['name']
# If the action part of the URL is "on," execute the code indented below:
  if action == "1" and board == 'esp8266':
  mqttc.publish(pins[changePin]['topic'],"1")
  pins[changePin]['state'] = 'True'

if action == "0" and board == 'esp8266':
  mqttc.publish(pins[changePin]['topic'],"0")
  pins[changePin]['state'] = 'False'

# Along with the pin dictionary, put the message into the template data dictionary:
templateData = {
  'pins' : pins
}

return render_template('main.html', **templateData)

if __name__ == "__main__":
app.run(host='0.0.0.0', port=8181, debug=True)

Đây là mã HTML của tôi:

<!DOCTYPE html>
<head>
   <title>RPi Web Server</title>
   <!-- Latest compiled and minified CSS -->
   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
   <!-- Optional theme -->
   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">
   <!-- Latest compiled and minified JavaScript -->
   <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
   <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
   <h1>RPi Web Server - ESP8266 MQTT</h1>
   {% for pin in pins %}
   <h2>{{ pins[pin].name }}
   {% if pins[pin].state == 'True' %}
  is currently <strong>on</strong></h2><div class="row"><div class="col-md-2">
  <a href="/esp8266/{{pin}}/0" class="btn btn-block btn-lg btn-default" role="button">Turn off</a></div></div>
   {% else %}
  is currently <strong>off</strong></h2><div class="row"><div class="col-md-2">
  <a href="/esp8266/{{pin}}/1" class="btn btn-block btn-lg btn-primary" role="button">Turn on</a></div></div>
   {% endif %}
   {% endfor %}
</body>
</html>

Đây là mã ESP8266 của tôi:

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

const char* ssid = "Godfather";
const char* password = "idontknow";

const char* mqtt_server = "192.168.137.100";

WiFiClient espClient;
PubSubClient client(espClient);

const int ledGPIO2 = 2;

void setup_wifi() {
  delay(10);

  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi connected - ESP IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(String topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;

  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  if(topic=="esp8266/2"){
      Serial.print("Changing GPIO 2 to ");
      if(messageTemp == "1"){
        digitalWrite(ledGPIO2, HIGH);
        Serial.print("On");
      }
      else if(messageTemp == "0"){
        digitalWrite(ledGPIO4, LOW);
        Serial.print("Off");
      }
  }
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ESP8266Client")) {
      Serial.println("connected");  

      client.subscribe("esp8266/2");

    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
  // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  pinMode(ledGPIO2, OUTPUT);

  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);    
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  if(!client.loop())
    client.connect("ESP8266Client");
}

Kết quả: mọi thứ dường như đang hoạt động tốt nhưng vẫn chuyển tiếp không được kích hoạt khi tôi nhấn nút tại máy chủ web. Tôi tin rằng ESP không được đăng ký đúng cách. Khi tôi chạy tập lệnh Python trên thiết bị đầu cuối, với lần nhấp đầu tiên, tôi nhận được HTTP / 1.1 "404 tại thiết bị đầu cuối và trên mỗi lần nhấp khác, tôi nhận được HTTP / 1.1" 200

Pi của tôi đang làm việc trên IP động ngay bây giờ. Nhưng tôi đã chắc chắn rằng ESP8266 được cấu hình với địa chỉ IP Pi hiện tại.


1
Chuỗi bình luận này đang trở nên khá dài bây giờ; cuộc trò chuyện này đã được chuyển sang trò chuyện . Bạn có thể tiếp tục cuộc thảo luận của mình ở đó trong một môi trường thân thiện hơn với các cuộc hội thoại mở rộng. Đồng thời xem xét chỉnh sửa câu hỏi của bạn bằng các bản cập nhật hoặc đặt câu hỏi mới nếu bạn gặp phải vấn đề mà bạn không thể giải quyết.
Aurora0001

1
Tôi nên thêm gì vào mã của mình nếu tôi có nhiều khách hàng?
Rohit Mathur

Câu trả lời:


3

Tôi đề nghị bạn phân tích vấn đề.

Hãy thử kiểm tra chuyển tiếp bằng cách xuất bản tin nhắn trực tiếp đến nhà môi giới MQTT (tức là sử dụng ứng dụng khách muỗi_pub).

Hãy thử kiểm tra xem ứng dụng web có xuất bản đúng chủ đề và tin nhắn cho nhà môi giới hay không (tức là sử dụng ứng dụng muỗi_sub).

Bạn cũng có thể theo dõi hành vi thiết bị của mình bằng cách đăng ký chủ đề SYS (tức là tổng số khách hàng được đăng ký hoặc đăng ký).


1
Và thêm một ping (xuất bản) từ ESP8266 để bạn có thể xác nhận rằng nó đang hoạt động và có thể truy cập máy chủ MQTT.
MatsK
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.