สารบัญ:

อุณหภูมิและความชื้นโดยใช้ ESP32-DHT22-MQTT-MySQL-PHP: 7 ขั้นตอน
อุณหภูมิและความชื้นโดยใช้ ESP32-DHT22-MQTT-MySQL-PHP: 7 ขั้นตอน

วีดีโอ: อุณหภูมิและความชื้นโดยใช้ ESP32-DHT22-MQTT-MySQL-PHP: 7 ขั้นตอน

วีดีโอ: อุณหภูมิและความชื้นโดยใช้ ESP32-DHT22-MQTT-MySQL-PHP: 7 ขั้นตอน
วีดีโอ: EP.25 Arduino Esp8266 รับส่งข้อมูลระหว่าง server กับ client : Server-Client Communication 2024, กรกฎาคม
Anonim
อุณหภูมิและความชื้นโดยใช้ ESP32-DHT22-MQTT-MySQL-PHP
อุณหภูมิและความชื้นโดยใช้ ESP32-DHT22-MQTT-MySQL-PHP

แฟนของฉันต้องการเรือนกระจก ฉันก็เลยสร้างให้เธอ แต่ฉันต้องการเซ็นเซอร์อุณหภูมิและความชื้นภายในเรือนกระจก ดังนั้นฉันจึงลองค้นหาตัวอย่างและเริ่มทดลอง

ข้อสรุปของฉันคือตัวอย่างทั้งหมดที่ฉันพบไม่ใช่สิ่งที่ฉันต้องการสร้าง ฉันคว้าส่วนเล็ก ๆ ของรหัสและรวมเข้าด้วยกัน ฉันใช้เวลาค่อนข้างนานในการสร้างงานสร้างครั้งแรกให้เสร็จ เนื่องจากเอกสารประกอบของตัวอย่างส่วนใหญ่ยากเกินไปสำหรับฉันที่จะเข้าใจ หรือพวกเขาสันนิษฐานว่าเป็นส่วนหนึ่งที่ฉันควรรู้ แต่ไม่รู้อะไรเลย (ยัง) ☹

นั่นเป็นเหตุผลที่ฉันสร้างคำสั่งนี้ บทช่วยสอน "ต้นจนจบ" สำหรับทุกคนที่จะเข้าใจอย่างแท้จริง (อย่างน้อยฉันก็หวัง ?)

มันทำงานอย่างไร …

ผลิตภัณฑ์ขั้นสุดท้ายคือ ESP32-CAM ที่มีเซ็นเซอร์ DHT22 ติดอยู่ซึ่งใช้พลังงานจากแบตเตอรี่ 18650 เครื่องจะอ่านอุณหภูมิและความชื้นทุก ๆ สามนาที และส่งข้อมูลนี้ผ่าน WiFi ไปยังเซิร์ฟเวอร์ MQTT ภายนอก จากนั้นเข้าสู่โหมดสลีป (เป็นเวลาสามนาที) เพื่อใช้แบตเตอรี่น้อยลงตามต้องการ

บนเซิร์ฟเวอร์ Debian (ซึ่งอาจเป็นราสเบอร์รี่ pi ฉันเดา) ฉันมี python3, เซิร์ฟเวอร์ MQTT, เซิร์ฟเวอร์ MySQL และเว็บเซิร์ฟเวอร์

สคริปต์ python3 ทำงานเป็นบริการ และเมื่อใดก็ตามที่ได้รับข้อความ MQTT สคริปต์จะนับจำนวนรายการก่อนหน้า (หมายเลขดัชนี) และเพิ่มขึ้นทีละรายการ จากนั้นจะอ่านค่าอุณหภูมิและความชื้นจากข้อความ MQTT จะตรวจสอบค่าเท็จและเมื่อใดก็ตามที่ค่าถูกต้อง จะส่งค่าพร้อมกับหมายเลขดัชนีใหม่และวันที่และเวลาปัจจุบันไปยังเซิร์ฟเวอร์ MySQL

เว็บเซิร์ฟเวอร์มีสคริปต์ PHP ซึ่งอ่านค่าจากเซิร์ฟเวอร์ MySQL และสร้างกราฟที่ดีโดยใช้ Google Charts (ตัวอย่าง)

เสบียง

ส่วนที่ฉันใช้มีดังนี้:

  • ESP32-CAM (เหตุผลที่ฉันใช้เวอร์ชันลูกเบี้ยวเพราะมีขั้วต่อเสาอากาศภายนอกอยู่ อาจมี ESP32 อื่นๆ ที่คุณสามารถใช้ได้ด้วย)
  • เสาอากาศภายนอก
  • เซ็นเซอร์ AM2302 DHT22 (อันนี้มีตัวต้านทานในตัว คุณจึงต้องใช้เพียงสามสาย)

    https://www.amazon.de/gp/product/B07CM2VLBK/ref=p…

  • ตัวป้องกันแบตเตอรี่ 18650 v3
  • แบตเตอรี่ 18650 (NCR18650B)
  • สาย micro USB แบบเก่า (สำหรับเชื่อมต่อ ESP32 กับตัวป้องกันแบตเตอรี่)
  • สายจัมเปอร์สั้นบางสาย

จำเป็นเพิ่มเติม:

  • ขั้วต่อ USB เป็น TTL (ภาพ)

    https://www.amazon.de/FT232RL-Seriell-Unterst%C3%…

  • หัวแร้ง
  • เครื่องพิมพ์ 3 มิติ (จำเป็นสำหรับเคสเท่านั้น)

ขั้นตอนที่ 1: อัปโหลดรหัส Arduino ไปยัง ESP32-CAM

อัปโหลดรหัส Arduino ไปยัง ESP32-CAM
อัปโหลดรหัส Arduino ไปยัง ESP32-CAM

เริ่มกันเลย!

ในการอัปโหลดโค้ด Arduino ไปยัง ESP32-CAM คุณต้องเชื่อมต่อตัวเชื่อมต่อ USBtoTTL กับ ESP32 โดยใช้แผนผังด้านบน

รหัส Arduino คือ:

/*โปรแกรมเล็กๆ อ่านอุณหภูมิและความชื้นจากเซ็นเซอร์ DHT22 และ

ส่งต่อให้ MQTT B. Duijnhouwer มิถุนายน 8th 2020 */ #include #include #include #define wifi_ssid "***WIFI_SSID***" //wifi ssid #define wifi_password "***WIFI_PASSWORD***" // รหัสผ่าน wifi #define mqtt_server "***SERVER_NAME***" // ชื่อเซิร์ฟเวอร์หรือ IP #define mqtt_user "***MQTT_USER***" // username #define mqtt_password "***MQTT_PASSWORD***" // รหัสผ่าน #define topic "glasshouse /dhtreadings" #define debug_topic "glasshouse/debug" //Topic for debugging /* definitions for deepsleep */ #define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */ #define TIME_TO_SLEEP 180 /* Time ESP32 will go to sleep เป็นเวลา 5 นาที (เป็นวินาที) */ bool debug = true; //แสดงข้อความบันทึกถ้า True #define DHT22_PIN 14 dht DHT; WiFiClient espClient; ไคลเอนต์ PubSubClient (espClient); ข้อมูลถ่าน[80]; การตั้งค่าเป็นโมฆะ () { Serial.begin (115200); setup_wifi(); //เชื่อมต่อกับเครือข่าย Wifi client.setServer(mqtt_server, 1883); // กำหนดค่าการเชื่อมต่อ MQTT เปลี่ยนพอร์ตหากจำเป็น if (!client.connected()) { เชื่อมต่อใหม่ (); } // อ่านข้อมูล int chk = DHT.read22(DHT22_PIN); float t = DHT อุณหภูมิ; float h = DHT.ความชื้น; String dhtReadings = "{"temperature\":\"" + String(t) + "\", \"humidity\":\"" + String(h) + "\"}"; dhtReadings.toCharArray(ข้อมูล, (dhtReadings.length() + 1)); ถ้า (ดีบัก) { Serial.print ("อุณหภูมิ: "); Serial.print(t); Serial.print(" | ความชื้น: "); Serial.println(ซ); } // เผยแพร่ค่าไปยังหัวข้อ MQTT client.publish(หัวข้อ, ข้อมูล); // เผยแพร่การอ่านในหัวข้อ (เรือนกระจก/dhtreadings) ถ้า (ดีบัก) { Serial.println ("การอ่านส่งไปยัง MQTT"); } esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); //ไปที่โหมดสลีป Serial.println("ตั้งค่า ESP32 ให้เข้าสู่โหมดสลีปสำหรับทุก ๆ " + สตริง (TIME_TO_SLEEP) + " วินาที"); Serial.println("เข้าสู่โหมดสลีปตามปกติแล้ว"); esp_deep_sleep_start(); } // ตั้งค่าการเชื่อมต่อกับ wifi เป็นโมฆะ setup_wifi () { ล่าช้า (20); Serial.println(); Serial.print("กำลังเชื่อมต่อกับ "); Serial.println(wifi_ssid); WiFi.begin(wifi_ssid, wifi_password); ในขณะที่ (WiFi.status () != WL_CONNECTED) { ล่าช้า (100); Serial.print("."); } Serial.println(""); Serial.println("WiFi ใช้ได้"); Serial.print("=>ที่อยู่ IP ใหม่ ESP32 คือ: "); Serial.print(WiFi.localIP()); Serial.println(""); } // เชื่อมต่อกับ wifi อีกครั้งหากการเชื่อมต่อขาดหาย การเชื่อมต่อใหม่เป็นโมฆะ () { ในขณะที่ (!client.connected ()) { Serial.print ("กำลังเชื่อมต่อกับนายหน้า MQTT …"); ถ้า (client.connect("ESP32Client", mqtt_user, mqtt_password)) { Serial.println ("OK"); } อื่น { Serial.print ("[ข้อผิดพลาด] ไม่ได้เชื่อมต่อ: "); Serial.print(client.state()); Serial.println("รอ 5 วินาทีแล้วลองใหม่"); ล่าช้า (5000); } } } วงเป็นโมฆะ () { }

และอีกครั้ง อย่าลืมเปลี่ยนข้อมูลประจำตัวด้วยข้อมูลประจำตัวของคุณเอง

ขั้นตอนที่ 2: วางสาย

สายขึ้น!
สายขึ้น!

สำหรับพลังงาน ฉันใช้สาย USB แบบเก่าซึ่งฉันตัดขั้วต่อ USB-A สาย USB มีสี่สาย เราต้องการสายสีดำและสีแดงเท่านั้น

ดังนั้น เชื่อมต่อทุกอย่างตามกำหนดการด้านบน

ขั้นตอนที่ 3: สคริปต์ Python3

สคริปต์ Python3 จะเข้าไปในที่ที่ผู้ใช้รูทสามารถเข้าถึงได้

ฉันใช้ /root/scripts/glasshouse/glasshouse.py สำหรับสคริปต์นี้ เนื้อหาของสคริปต์หลามคือ:

# สคริปต์ Python3 เพื่อเชื่อมต่อกับ MQTT อ่านค่าและเขียนลงใน MySQL

# # B. Duijnhouwer # มิถุนายน 8th 2020 # # รุ่น: 1.0 # # นำเข้า paho.mqtt.client เป็น mqtt นำเข้า json นำเข้า pymysql pymysql.install_as_MySQLdb () นำเข้า MySQLdb จากวันที่และเวลานำเข้า datetime db = MySQLdb.connect ("localhost", "เรือนกระจก", "***MYSQL_USERNAME***", "***MYSQL_PASSWORD***") cursor=db.cursor() Broker_address= "localhost" #Broker address port = 1883 #Broker port user = "** *MQTT_USERNAME***" #Connection username password = "***MQTT_PASSWORD***" #Connection password def on_connect(client, userdata, flags, rc): # การเรียกกลับเมื่อไคลเอ็นต์เชื่อมต่อกับนายหน้าพิมพ์ ("เชื่อมต่อแล้ว ด้วยรหัสผลลัพธ์ {0}".format(str(rc))) # พิมพ์ผลลัพธ์ของความพยายามในการเชื่อมต่อ client.subscribe("glasshouse/dhtreadings/#") def on_message(client, userdata, msg): # การเรียกกลับเมื่อ ได้รับข้อความ PUBLISH จากเซิร์ฟเวอร์ cursor.execute ("เลือก * จาก sensordata") numrows = int (cursor.rowcount) newrow = numrows + 1 now = datetime.now() formatted_date = now.strftime('%Y-%m-%d %H:% M:%S') payload = json.loads(msg.payload.decode('utf-8')) print("New row: "+str(newrow)) temperature = float(payload["temperature"]) ความชื้น = float(payload["humidity"]) print("Temperature: "+str(temperature)) print("Humidity: "+str(humidity)) print("DateTime:"+str(formatted_date)) if ((อุณหภูมิ) > -20) และ (อุณหภูมิ = 0) และ (ความชื้น <= 100)): cur = db.cursor() cur.execute("INSERT INTO glasshouse.sensordata (idx, อุณหภูมิ, ความชื้น, การประทับเวลา) VALUES ("+str (newrow)+", "+str(temperature)+", "+str(humidity)+", %s)", (formatted_date)) db.commit() print("ข้อมูลที่ได้รับและนำเข้าใน MySQL") อื่น: print("ข้อมูลเกินขีดจำกัดและไม่ได้นำเข้าใน MySQL") client = mqtt. Client("duijnhouwer-com-glasshouse-script") client.username_pw_set(user, password=password) client.on_connect = on_connect # Define callback function สำหรับ ประสบความสำเร็จในการเชื่อมต่อ client.on_message = on_message # กำหนดฟังก์ชันการโทรกลับเพื่อรับข้อความ

อย่าลืมแทนที่ชื่อผู้ใช้และรหัสผ่าน MySQL และชื่อผู้ใช้และรหัสผ่าน MQTT เป็นข้อมูลประจำตัวของคุณเอง

คุณสามารถทำให้สคริปต์ทำงานเป็นบริการได้โดยการสร้างสองไฟล์

อันแรกคือ “/etc/init/glasshouse.conf” โดยมีเนื้อหาดังต่อไปนี้:

เริ่มต้นในระดับรัน [2345]

หยุดที่ runlevel [!2345] exec /root/scripts/glasshouse/glasshouse.py

อันที่สองคือ “/etc/systemd/system/multi-user.target.wans/glasshouse.service” โดยมีเนื้อหาดังต่อไปนี้:

[หน่วย]

Description=Glasshouse Monitoring Service After=multi-user.target [Service] Type=simple Restart=always RestartSec=1 ExecStart=/usr/bin/python3 /root/scripts/glasshouse/glasshouse.py [Install] WantedBy=multi-user.เป้า

คุณสามารถทำให้การทำงานนี้เป็นบริการโดยใช้คำสั่งต่อไปนี้:

systemctl เปิดใช้งานเรือนกระจก

และเริ่มต้นโดยใช้:

systemctl เริ่มต้นเรือนกระจก

ขั้นตอนที่ 4: เซิร์ฟเวอร์ MySQL

คุณต้องสร้างฐานข้อมูล MySQL ใหม่โดยมีเพียงตารางเดียวในนั้น

รหัสสำหรับสร้างตารางคือ:

สร้างตาราง `ข้อมูลเซ็นเซอร์' (`idx` int(11) ค่าเริ่มต้น NULL, `อุณหภูมิ' float ค่าเริ่มต้น NULL, `ความชื้น' float ค่าเริ่มต้น NULL, `การประทับเวลา' วันที่และเวลาเริ่มต้น NULL) ENGINE = InnoDB ค่าเริ่มต้น CHARSET = utf8;

ขั้นตอนที่ 5: เว็บเซิร์ฟเวอร์

เว็บเซิร์ฟเวอร์มีสองไฟล์ ได้แก่ ไฟล์ index.php และไฟล์ config.ini หนึ่งไฟล์

เนื้อหาของไฟล์ config.ini คือ:

[ฐานข้อมูล]

db_host = "localhost" db_name = "glasshouse" db_table = "sensordata" db_user = "***DATABASE_USER***" db_password = "***DATABASE_PASSWORD***"

นอกหลักสูตรที่คุณแทนที่ ***DATABASE_USER*** และ ***DATABASE_PASSWORD*** ด้วยข้อมูลประจำตัวของคุณเอง

google.charts.load('current', {'packages':['corechart']}); google.charts.setOnLoadCallback(drawChart); ฟังก์ชัน drawChart () { ข้อมูล var = google.visualization.arrayToDataTable ([// ['Timestamp', 'Temperature', 'Humidity', 'Heat Index'], ['Timestamp', 'Temperature', 'Humidity'], query($sql); # This while - วนรอบรูปแบบและใส่ข้อมูลที่ดึงมาทั้งหมดลงในวิธี ['timestamp', 'temperature', 'humidity'] ขณะที่ ($row = $result->fetch_assoc()) { $timestamp_rest = substr($row["timestamp"], 10, 6); echo "['".$timestamp_rest."', ".$row['temperature'].", ".$row['humidity']. "], "; // echo "['".$timestamp_rest."', ".$row['temperature'].", ".$row['humidity'].", ".$row['heatindex" ']."], "; } ?>]); // ตัวเลือกเส้นโค้งเส้นโค้ง = { ชื่อ: 'อุณหภูมิและความชื้น', ประเภทเส้นโค้ง: 'ฟังก์ชัน', ตำนาน: { ตำแหน่ง: 'ด้านล่าง' }, hAxis: { ข้อความเอียง: จริง, ข้อความเอียง: 45 } }; // แผนภูมิโค้ง var chart = ใหม่ google.visualization. LineChart(document.getElementById('curve_chart')); chart.draw(ข้อมูล, ตัวเลือก); } // จบวงเล็บเหลี่ยมจาก drawChart //

ขั้นตอนที่ 6: ตัวเรือนพิมพ์ 3 มิติ

สำหรับตัวเรือน ฉันใช้ตัวเรือนแยกกันสองตัว ตัวหนึ่งสำหรับ ESP32-CAM และ DHT22 ร่วมกัน และอีกอันสำหรับตัวป้องกันแบตเตอรี่ 18650

ขั้นตอนที่ 7: ผลลัพธ์สุดท้าย

ผลสุดท้าย!
ผลสุดท้าย!
ผลสุดท้าย!
ผลสุดท้าย!
ผลสุดท้าย!
ผลสุดท้าย!
ผลสุดท้าย!
ผลสุดท้าย!

ผลลัพธ์สุดท้ายยังแสดงในรูปภาพด้านบน

และเมื่อใดก็ตามที่แบตเตอรี่หมด คุณสามารถชาร์จด้วยสาย mini USB ได้

แนะนำ: