Πίνακας περιεχομένων:

Θερμοκρασία και υγρασία χρησιμοποιώντας ESP32-DHT22-MQTT-MySQL-PHP: 7 βήματα
Θερμοκρασία και υγρασία χρησιμοποιώντας ESP32-DHT22-MQTT-MySQL-PHP: 7 βήματα

Βίντεο: Θερμοκρασία και υγρασία χρησιμοποιώντας ESP32-DHT22-MQTT-MySQL-PHP: 7 βήματα

Βίντεο: Θερμοκρασία και υγρασία χρησιμοποιώντας ESP32-DHT22-MQTT-MySQL-PHP: 7 βήματα
Βίντεο: Καταγραφικό θερμοκρασίας & υγρασίας SUPCO SL300TH | ΡΟΜΠΟΓΙΑΝΝΑΚΗΣ ΑΝΔΕΑΣ & ΣΙΑ Ο.Ε. 2024, Νοέμβριος
Anonim
Θερμοκρασία και υγρασία χρησιμοποιώντας ESP32-DHT22-MQTT-MySQL-PHP
Θερμοκρασία και υγρασία χρησιμοποιώντας ESP32-DHT22-MQTT-MySQL-PHP

Η φίλη μου ήθελε ένα θερμοκήπιο, οπότε της έκανα ένα. Αλλά ήθελα έναν αισθητήρα θερμοκρασίας και υγρασίας μέσα στο θερμοκήπιο. Έτσι, έψαξα στο Google για παραδείγματα και άρχισα να πειραματίζομαι.

Το συμπέρασμά μου ήταν ότι όλα τα παραδείγματα που βρήκα δεν ήταν ακριβώς αυτά που ήθελα να φτιάξω. Πήρα πολλά μικρά κομμάτια κώδικα και τα συνδύασα. Μου πήρε πολύ χρόνο για να τελειώσω την πρώτη μου κατασκευή, επειδή η τεκμηρίωση των περισσότερων παραδειγμάτων ήταν πολύ δύσκολη για μένα ή θεωρούσαν μέρος που έπρεπε να γνωρίζω; Αλλά δεν ήξερα τίποτα (ακόμα)

Αυτός είναι ο λόγος για τον οποίο κατασκευάζω αυτό το διδακτικό. Ένα σεμινάριο "από την αρχή μέχρι το τέλος" για να το καταλάβουν όλοι κυριολεκτικά. (Τουλάχιστον ελπίζω;)

Πως δουλεύει …

Το τελικό προϊόν είναι ένα ESP32-CAM με έναν αισθητήρα DHT22 προσαρτημένο σε αυτόν, ο οποίος παίρνει την ισχύ του από μια μπαταρία 18650. Κάθε τρία λεπτά διαβάζει τη θερμοκρασία και την υγρασία και το στέλνει μέσω WiFi σε εξωτερικό διακομιστή MQTT και στη συνέχεια κοιμάται (για τρία λεπτά) για να χρησιμοποιήσει όσο λιγότερη μπαταρία χρειάζεται

Σε διακομιστή Debian, (ο οποίος θα μπορούσε επίσης να είναι ένα raspberry 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%…

  • Συγκολλητικό σίδερο
  • 3D εκτυπωτής (απαιτείται μόνο για θήκη περιβλήματος)

Βήμα 1: Ανεβάστε τον κωδικό Arduino στο ESP32-CAM

Ανεβάστε τον κωδικό Arduino στο ESP32-CAM
Ανεβάστε τον κωδικό Arduino στο ESP32-CAM

Ας ξεκινήσουμε λοιπόν!

Για να ανεβάσετε τον κωδικό Arduino στο ESP32-CAM, πρέπει να συνδέσετε τη σύνδεση USBtoTTL στο ESP32 χρησιμοποιώντας τα παραπάνω σχήματα.

Ο κώδικας Arduino είναι:

/*Ένα μικρό πρόγραμμα για την ανάγνωση της θερμοκρασίας και της υγρασίας από έναν αισθητήρα DHT22 και

μεταδώστε το στο MQTT. B. Duijnhouwer, 8 Ιουνίου 2020*/#include #include #include #define wifi_ssid "*** WIFI_SSID ***" // wifi ssid #define wifi_password "*** WIFI_PASSWORD ***" // wifi password #define mqtt_server "*** SERVER_NAME ***" // όνομα διακομιστή ή IP #define mqtt_user "*** MQTT_USER ***" // όνομα χρήστη #define mqtt_password "*** MQTT_PASSWORD ***" // password #define topic "glasshouse /dhtreadings "#define debug_topic" glasshouse /debug "// Θέμα για εντοπισμό σφαλμάτων /* ορισμοί για βαθύ ύπνο* /#define uS_TO_S_FACTOR 1000000 /* Συντελεστής μετατροπής για δευτερόλεπτα σε δευτερόλεπτα* /#define TIME_TO_SLEEP 180 /* Χρόνος ESP32 θα πάει για ύπνο για 5 λεπτά (σε δευτερόλεπτα) */ bool debug = true; // Εμφάνιση μηνύματος καταγραφής εάν True #define DHT22_PIN 14 dht DHT; WiFiClient espClient; Πελάτης PubSubClient (espClient). δεδομένα char [80]; void setup () {Serial.begin (115200); setup_wifi (); // Συνδεθείτε στο πρόγραμμα -πελάτη δικτύου Wifi.setServer (mqtt_server, 1883); // Διαμόρφωση σύνδεσης MQTT, αλλαγή θύρας εάν χρειάζεται. if (! client.connected ()) {επανασύνδεση (); } // ΔΙΑΒΑΣΤΕ ΔΕΔΟΜΕΝΑ int chk = DHT.read22 (DHT22_PIN); float t = DHT.temperature; float h = DHT. υγρασία; String dhtReadings = "{" θερμοκρασία / ": \" " + String (t) +" / ", \" υγρασία / ": \" " + String (h) +" / "}"; dhtReadings.toCharArray (δεδομένα, (dhtReadings.length () + 1)); if (εντοπισμός σφαλμάτων) {Serial.print ("Θερμοκρασία:"); Serial.print (t); Serial.print ("| Υγρασία:"); Serial.println (h); } // Δημοσίευση τιμών σε θέματα MQTT client.publish (θέμα, δεδομένα); // Δημοσιεύστε αναγνώσεις σχετικά με το θέμα (glasshouse/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 void setup_wifi () {καθυστέρηση (20); Serial.println (); Serial.print ("Σύνδεση σε"); Serial.println (wifi_ssid); WiFi.begin (wifi_ssid, wifi_password); while (WiFi.status ()! = WL_CONNECTED) {καθυστέρηση (100); Serial.print ("."); } Serial.println (""); Serial.println ("Το WiFi είναι εντάξει"); Serial.print ("=> ESP32 νέα διεύθυνση IP είναι:"); Serial.print (WiFi.localIP ()); Serial.println (""); } // Επανασύνδεση στο wifi εάν η σύνδεση χαθεί άκυρη επανασύνδεση () {ενώ (! Client.connected ()) {Serial.print ("Σύνδεση σε μεσίτη MQTT …"); if (client.connect ("ESP32Client", mqtt_user, mqtt_password)) {Serial.println ("OK"); } else {Serial.print ("[Σφάλμα] Δεν είναι συνδεδεμένο:"); Serial.print (client.state ()); Serial.println ("Περιμένετε 5 δευτερόλεπτα πριν προσπαθήσετε ξανά."); καθυστέρηση (5000)? }}} void loop () {}

Και πάλι, μην ξεχάσετε να αντικαταστήσετε τα διαπιστευτήρια με τα δικά σας διαπιστευτήρια

Βήμα 2: Συνδεθείτε

Wire Up!
Wire Up!

Για την τροφοδοσία, χρησιμοποίησα ένα παλιό καλώδιο USB από το οποίο έκοψα τη σύνδεση USB-A. Υπάρχουν τέσσερα καλώδια στο καλώδιο USB, χρειαζόμαστε μόνο το μαύρο και το κόκκινο.

Έτσι, συνδέστε τα πάντα σύμφωνα με το παραπάνω πρόγραμμα.

Βήμα 3: Σενάριο Python3

Το σενάριο Python3 πηγαίνει σε ένα μέρος όπου είναι προσβάσιμο από τον βασικό χρήστη.

Χρησιμοποίησα /root/scripts/glasshouse/glasshouse.py για αυτό το σενάριο. Το περιεχόμενο του σεναρίου python είναι:

# Python3 δέσμη ενεργειών για σύνδεση με MQTT, ανάγνωση τιμών και εγγραφή τους στο MySQL

# # B. Duijnhouwer # Ιούνιος, 8η 2020 # # έκδοση: 1.0 # # import paho.mqtt.client as mqtt import json import pymysql pymysql.install_as_MySQLdb () import MySQLdb from datetime import datetime db = MySQLdb.connect (" "glasshouse", "*** MYSQL_USERNAME ***", "*** MYSQL_PASSWORD ***") cursor = db.cursor () broker_address = "localhost" #Broker address port = 1883 #Χρήστης θύρας μεσίτη = "** *MQTT_USERNAME *** "#Connection username password =" *** MQTT_PASSWORD *** "#Connection password def on_connect (client, datadata, flags, rc): #Η επανάκληση όταν ο πελάτης συνδέεται στην εκτύπωση μεσίτη (" Συνδέθηκε με κωδικό αποτελέσματος {0} ". format (str (rc))) # Εκτύπωση αποτελέσματος απόπειρας σύνδεσης client.subscribe (" glasshouse/dhtreadings/ # ") def on_message (client, userdata, msg): # The callback for when a ΔΗΜΟΣΙΕΥΣΗ μήνυμα λαμβάνεται από το διακομιστή. cursor.execute ("select * from sensordata") numrows = int (cursor.rowcount) newrow = numrows + 1 now = datetime.now () formatatted_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 (ωφέλιμο φορτίο ["υγρασία"]) εκτύπωση ("Θερμοκρασία:"+str (θερμοκρασία)) εκτύπωση ("Υγρασία:"+str (υγρασία)) εκτύπωση ("DateTime:"+str (μορφοποιημένη_ημερομηνία)) εάν ((θερμοκρασία > -20) και (θερμοκρασία = 0) και (υγρασία <= 100)): cur = db.cursor () cur.execute ("INSERT INTO glasshouse.sensordata (idx, θερμοκρασία, υγρασία, χρονική σήμανση) ΤΙΜΕΣ ("+str. (newrow)+","+str (θερμοκρασία)+","+str (υγρασία)+", %s)", (μορφοποιημένη_ημερομηνία)) db.commit () εκτύπωση ("δεδομένα που λαμβάνονται και εισάγονται στο MySQL") άλλο: print ("τα δεδομένα ξεπέρασαν τα όρια και ΔΕΝ εισάγονται στο MySQL") client = mqtt. Client ("duijnhouwer-com-glasshouse-script") client.username_pw_set (user, password = password) client.on_connect = on_connect # Ορισμός λειτουργίας επανάκλησης Για πετυχημένη σύνδεση client.on_message = on_message # Ορισμός λειτουργίας επανάκλησης για λήψη μηνύματος client.connect (broker_address, port = port) #connect to broker client.loop_forever () # Start networking daemon

Μην ξεχάσετε να αντικαταστήσετε το όνομα χρήστη και τον κωδικό πρόσβασης MySQL και το όνομα χρήστη και τον κωδικό πρόσβασης MQTT στα δικά σας διαπιστευτήρια

Μπορείτε να κάνετε το σενάριο να εκτελείται ως υπηρεσία δημιουργώντας δύο αρχεία.

Το πρώτο είναι "/etc/init/glasshouse.conf" με το ακόλουθο περιεχόμενο:

εκκίνηση σε επίπεδο εκτέλεσης [2345]

στάση στο runlevel [! 2345] exec /root/scripts/glasshouse/glasshouse.py

Το δεύτερο είναι «/etc/systemd/system/multi-user.target.wants/glasshouse.service» με τα ακόλουθα περιεχόμενα:

[Μονάδα]

Περιγραφή = Υπηρεσία παρακολούθησης θερμοκηπίου Μετά = multi-user.target [Service] Τύπος = απλή Επανεκκίνηση = πάντα RestartSec = 1 ExecStart =/usr/bin/python3 /root/scripts/glasshouse/glasshouse.py [Install] WantedBy = multi-user.στόχος

Μπορείτε να το εκτελέσετε ως υπηρεσία χρησιμοποιώντας την ακόλουθη εντολή:

systemctl ενεργοποιεί θερμοκήπιο

και ξεκινήστε χρησιμοποιώντας:

systemctl start glasshouse

Βήμα 4: MySQL Server

Πρέπει να δημιουργήσετε μια νέα βάση δεδομένων MySQL με μόνο έναν πίνακα.

Ο κώδικας για τη δημιουργία του πίνακα είναι:

ΔΗΜΙΟΥΡΓΙΑ ΠΙΝΑΚΑ `sensordata` (`idx` int (11) DEFAULT NULL,` `temperature 'float DEFAULT NULL,` humidity' float DEFAULT NULL, `timestamp` datetime DEFAULT NULL) ENGINE = InnoDB DEFAULT 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 ('τρέχον', {'πακέτα': ['corechart']}); google.charts.setOnLoadCallback (drawChart); συνάρτηση drawChart () {var data = google.visualization.arrayToDataTable ([// [«Χρονική σήμανση», «Θερμοκρασία», «Υγρασία», «Δείκτης θερμότητας»], [«Χρονική σήμανση», «Θερμοκρασία», «Υγρασία»], ερώτημα ($ sql); # Αυτή τη στιγμή - μορφές βρόχου και βάλτε όλα τα δεδομένα που ανακτήθηκαν στον τρόπο ['χρονική σήμανση', 'θερμοκρασία', 'υγρασία']. ενώ ($ row = $ result-> fetch_assoc ()) {$ timestamp_rest = substr ($ row ["timestamp"], 10, 6); echo "['". $ timestamp_rest. "',". $ row ['temperature']. ",". $ row ['υγρασία']. "],"; // echo "['". $ timestamp_rest. "',". $ row ['θερμοκρασία']. ",". $ row ['υγρασία']. ",". $ row ['heatindex ']. "],";}?>]); // Curved line var options = {title: 'Temperature and humidity', curveType: 'function', legend: {position: 'bottom'}, hAxis: {slantedText: true, slantedTextAngle: 45}}; // Καμπύλο γράφημα var chart = new google.visualization. LineChart (document.getElementById ('curve_chart')); chart.draw (δεδομένα, επιλογές). } // Τέλος αγκύλης από το drawChart //

Βήμα 6: Περίβλημα με 3D εκτύπωση

Για το περίβλημα, χρησιμοποίησα δύο ξεχωριστά περιβλήματα, ένα για το ESP32-CAM και το DHT22 μαζί και ένα για την ασπίδα μπαταρίας 18650.

Βήμα 7: Το τελικό αποτέλεσμα

Το Τελικό Αποτέλεσμα!
Το Τελικό Αποτέλεσμα!
Το Τελικό Αποτέλεσμα!
Το Τελικό Αποτέλεσμα!
Το Τελικό Αποτέλεσμα!
Το Τελικό Αποτέλεσμα!
Το Τελικό Αποτέλεσμα!
Το Τελικό Αποτέλεσμα!

Το τελικό αποτέλεσμα φαίνεται επίσης στις παραπάνω εικόνες.

Και όποτε η μπαταρία είναι άδεια, μπορείτε να τη φορτίσετε με ένα καλώδιο μίνι USB.

Συνιστάται: