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

DuvelBot - ESP32 -CAM Ρομπότ σερβιρίσματος μπύρας: 4 βήματα (με εικόνες)
DuvelBot - ESP32 -CAM Ρομπότ σερβιρίσματος μπύρας: 4 βήματα (με εικόνες)

Βίντεο: DuvelBot - ESP32 -CAM Ρομπότ σερβιρίσματος μπύρας: 4 βήματα (με εικόνες)

Βίντεο: DuvelBot - ESP32 -CAM Ρομπότ σερβιρίσματος μπύρας: 4 βήματα (με εικόνες)
Βίντεο: Update: $15 LIDAR laser distance scanner connected to Arduino ESP32 and ROS2 #arduino #ros2 #esp32 2024, Ιούνιος
Anonim
DuvelBot - Ρομπότ σερβιρίσματος μπύρας ESP32 -CAM
DuvelBot - Ρομπότ σερβιρίσματος μπύρας ESP32 -CAM

Μετά από μια δύσκολη μέρα, τίποτα δεν πλησιάζει το να πιείτε την αγαπημένη σας μπύρα στον καναπέ. Στην περίπτωσή μου, αυτή είναι η βελγική ξανθιά μπύρα "Duvel". Ωστόσο, αφού καταρρεύσουμε, βρισκόμαστε αντιμέτωποι με ένα σοβαρότερο πρόβλημα: το ψυγείο που περιέχει το Duvel μου είναι μη γεφύσιμο 20 πόδια αφαιρεμένο από τον εν λόγω καναπέ.

Ενώ κάποιος ελαφρύς εξαναγκασμός από την πλευρά μου μπορεί να οδηγήσει έναν περιστασιακό έφηβο καθαριστή ψυγείων να ξεφορτωθεί το επίδομα της εβδομάδας μου για το Duvel, το έργο να το παραδώσω στον σχεδόν εξαντλημένο πρόγονο του είναι προφανώς ένα βήμα πολύ μακριά.

Timeρα να σπάσουμε το κολλητήρι και το πληκτρολόγιο…

Το DuvelBot είναι μια διαδικτυακή κάμερα οδήγησης βασισμένη σε AI-Thinker ESP32-CAM, την οποία μπορείτε να ελέγχετε από το smartphone, το πρόγραμμα περιήγησης ή το tablet σας.

Είναι εύκολο να προσαρμόσετε ή να επεκτείνετε αυτήν την πλατφόρμα σε λιγότερο αλκοολικές χρήσεις (σκεφτείτε SpouseSpy, NeighbourWatch, KittyCam…).

Δημιούργησα αυτό το ρομπότ κυρίως για να μάθω λίγα λόγια για ολόκληρο τον προγραμματισμό ιστού και πράγματα IoT, για τα οποία δεν ήξερα τίποτα. Στο τέλος αυτού του Instructable υπάρχει μια περίτεχνη εξήγηση για το πώς λειτουργεί.

Πολλά μέρη αυτού του Instructable βασίζονται στις εξαιρετικές εξηγήσεις που βρίσκονται στα Random Nerd Tutorials, οπότε πηγαίνετε να τους επισκεφθείτε!

Προμήθειες

Ο, τι χρειάζεσαι:

Ο κατάλογος μερών δεν είναι σκαλισμένος σε πέτρα και πολλά μέρη μπορούν να ληφθούν σε έναν τόνο διαφορετικών εκδόσεων και από πολλά διαφορετικά μέρη. Προμηθεύτηκα τα περισσότερα από την Ali-Express. Όπως είπε ο Machete: αυτοσχεδιάστε.

Σκεύη, εξαρτήματα:

  • Μονάδα AI Thinker ESP32-CAM. Πιθανότατα θα μπορούσε να λειτουργήσει με άλλες μονάδες ESP32-CAM αλλά αυτό χρησιμοποίησα
  • L298N πίνακας οδηγού κινητήρα,
  • Μια φθηνή πλατφόρμα ρομποτικής 4 τροχών,
  • Ένα περίβλημα με μεγάλη επίπεδη επιφάνεια όπως το Hammond Electronics 1599KGY,
  • Μετατροπέας USB-σε-3.3V-TTL για προγραμματισμό.
  • Για τον φωτισμό: 3 λευκές λυχνίες LED, BC327 ή άλλο τρανζίστορ γενικής χρήσης NPN (Ic = 500mA), αντίσταση 4k7k, 3 αντιστάσεις 82Ω, διάτρητη επιφάνεια, καλώδια (βλέπε σχηματικό και εικόνες).
  • Διακόπτης ενεργοποίησης/απενεργοποίησης και κανονικά ανοιχτό πλήκτρο για προγραμματισμό.

Προαιρετικός:

  • Μια κάμερα fisheye με μεγαλύτερη ευελιξία από την τυπική κάμερα OV2460 που παρέχεται με τη μονάδα ESP32-CAM,
  • Κεραία WiFi με κατάλληλο μακρύ καλώδιο και Ultra Miniature Coax Connector, όπως αυτό. Το ESP32-CAM έχει μια κεραία επί του σκάφους και το περίβλημα είναι πλαστικό, επομένως μια κεραία δεν χρειάζεται πραγματικά, ωστόσο νόμιζα ότι φαινόταν δροσερό, οπότε…
  • Αυτοκόλλητο με δυνατότητα εκτύπωσης Inkjet για το σχέδιο του πάνω καλύμματος.

Τα συνήθη εργαλεία υλικού: κολλητήρι, τρυπάνια, κατσαβίδια, πένσες…

Βήμα 1: Δημιουργία πλατφόρμας ρομπότ

Δημιουργία πλατφόρμας ρομπότ
Δημιουργία πλατφόρμας ρομπότ
Δημιουργία πλατφόρμας ρομπότ
Δημιουργία πλατφόρμας ρομπότ
Δημιουργία πλατφόρμας ρομπότ
Δημιουργία πλατφόρμας ρομπότ

Το σχηματικό:

Το σχηματικό δεν είναι τίποτα το ιδιαίτερο. Η κάμερα ESP32 ελέγχει τους κινητήρες μέσω της πλακέτας οδηγού μοτέρ L298N, η οποία διαθέτει δύο κανάλια. Οι κινητήρες της αριστερής και της δεξιάς πλευράς τοποθετούνται παράλληλα και κάθε πλευρά καταλαμβάνει ένα κανάλι. Τέσσερις μικροί κεραμικοί πυκνωτές 10..100nF κοντά στους πείρους του κινητήρα είναι πάντα σκόπιμο να αντισταθμίσουν τις παρεμβολές ραδιοσυχνοτήτων. Επίσης, ένα μεγάλο ηλεκτρολυτικό καπάκι (2200… 4700uF) στην τροφοδοσία της πλακέτας του μοτέρ, όπως φαίνεται στο σχήμα, ενώ δεν είναι απολύτως απαραίτητο, μπορεί να περιορίσει λίγο τον κυματισμό της τάσης τροφοδοσίας (αν θέλετε να δείτε μια ταινία τρόμου, τότε ελέγξτε το Vbat με παλμογράφο ενώ είναι ενεργά τα μοτέρ).

Σημειώστε ότι και οι δύο ακροδέκτες καναλιών κινητήρα ενεργοποιούνται από τον ίδιο πείρο διαμορφωμένου πλάτους παλμού (PWM) του ESP32 (IO12). Αυτό συμβαίνει επειδή η μονάδα ESP32-CAM δεν έχει έναν τόνο GPIO (το σχηματικό στοιχείο της ενότητας περιλαμβάνεται για αναφορά). Οι λυχνίες LED του ρομπότ κινούνται από IO4, το οποίο κινεί επίσης το ενσωματωμένο LED φλας, οπότε αφαιρέστε το Q1 για να μην ανάψει το φλας LED σε κλειστό περίβλημα.

Το κουμπί προγραμματισμού, ο διακόπτης ενεργοποίησης/απενεργοποίησης, η υποδοχή φόρτισης και η υποδοχή προγραμματισμού είναι προσβάσιμα κάτω από το ρομπότ. Θα μπορούσα να είχα κάνει πολύ καλύτερη δουλειά για το βύσμα προγραμματισμού (υποδοχή 3,5 χιλιοστών;), αλλά η μπύρα δεν μπορούσε να περιμένει άλλο. Επίσης, οι ενημερώσεις μέσω του αέρα (OTA) θα ήταν ωραίο να ρυθμιστούν.

Για να θέσετε το ρομπότ σε λειτουργία προγραμματισμού, πατήστε το κουμπί προγραμματισμού (αυτό μειώνει το IO0 χαμηλά) και, στη συνέχεια, ενεργοποιήστε το.

Σημαντικό: για να φορτίσετε τις μπαταρίες NiMH του ρομπότ, χρησιμοποιήστε ένα σετ τροφοδοσίας εργαστηρίου (χωρίς εκφόρτωση) σε περίπου 14V και ρεύμα περιορισμένο στα 250mA. Η τάση θα προσαρμοστεί στην τάση των μπαταριών. Αποσυνδέστε εάν το ρομπότ ζεσταθεί ή η τάση της μπαταρίας φτάσει περίπου τα 12,5V. Μια προφανής βελτίωση εδώ θα ήταν η ενσωμάτωση ενός κατάλληλου φορτιστή μπαταρίας, αλλά αυτό δεν εμπίπτει στο πεδίο αυτού του Instructable.

Το υλικό:

Παρακαλούμε δείτε επίσης τις σημειώσεις στις εικόνες. Το περίβλημα είναι τοποθετημένο στη βάση του ρομπότ χρησιμοποιώντας 4 μπουλόνια Μ4 και παξιμάδια με αυτόματο κλείδωμα. Σημειώστε την ελαστική σωλήνωση που χρησιμοποιείται ως αποστάτες αποστάσεων. Ας ελπίσουμε ότι αυτό δίνει επίσης κάποια ανάρτηση στο Duvel, εάν η διαδρομή αποδειχθεί ανώμαλη. Η μονάδα ESP32-CAM και ο πίνακας κινητήρα L298N είναι τοποθετημένοι στο περίβλημα χρησιμοποιώντας πλαστικά κολλώδη πόδια (δεν είστε σίγουροι για το σωστό όνομα στα Αγγλικά), για να αποφύγετε την ανάγκη να ανοίξετε επιπλέον τρύπες. Επίσης, το ESP32 είναι τοποθετημένο στο δικό του αλεξίπτωτο και συνδέσμους με καρφίτσες. Αυτό διευκολύνει την ανταλλαγή του ESP32.

Μην ξεχνάτε: εάν πρόκειται για εξωτερική κεραία WiFi αντί για ενσωματωμένη, τότε κολλήστε επίσης το βραχυκυκλωτήρα επιλογής κεραίας στην κάτω πλευρά της πλακέτας ESP32-CAM.

Εκτυπώστε το κορυφαίο λογότυπο στο αρχείο DuvelBot.svg σε αυτοκόλλητο χαρτί inkjet (ή σχεδιάστε το δικό σας) και είστε έτοιμοι!

Βήμα 2: Προγραμματίστε το ρομπότ

Προγραμματίστε το ρομπότ
Προγραμματίστε το ρομπότ

Συνιστάται να προγραμματίσετε το ρομπότ πριν το κλείσετε, για να βεβαιωθείτε ότι όλα λειτουργούν και δεν εμφανίζεται μαγικός καπνός.

Χρειάζεστε τα ακόλουθα εργαλεία λογισμικού:

  • Το Arduino IDE,
  • Οι βιβλιοθήκες ESP32, SPIFFS (σειριακό περιφερειακό σύστημα αρχείων flash), βιβλιοθήκη ESPAsync Webserver.

Το τελευταίο μπορεί να εγκατασταθεί ακολουθώντας αυτό το randomnerdtutorial μέχρι και συμπεριλαμβανομένης της ενότητας "οργάνωση των αρχείων σας". Πραγματικά δεν θα μπορούσα να το εξηγήσω καλύτερα.

Ο κώδικας:

Ο κωδικός μου μπορεί να βρεθεί στη διεύθυνση:

  • Ένα σκίτσο Arduino DuvelBot.ino,
  • Ένας υποφάκελος δεδομένων που περιέχει τα αρχεία που πρόκειται να μεταφορτωθούν στο ESP flash χρησιμοποιώντας SPIFFS. Αυτός ο φάκελος περιέχει την ιστοσελίδα που θα προβάλλει το ESP (index.html), μια εικόνα λογότυπου που αποτελεί μέρος της ιστοσελίδας (duvel.png) και ένα σελιδοποιημένο φύλλο στυλ ή αρχείο CSS (style.css).

Για να προγραμματίσετε το ρομπότ:

  • Συνδέστε τον μετατροπέα USB-TTL όπως φαίνεται στο σχήμα,
  • Αρχείο -> Άνοιγμα -> μεταβείτε στο φάκελο όπου βρίσκεται το DuvelBot.ino.
  • Αλλάξτε τα διαπιστευτήρια δικτύου στο σκίτσο:

const char* ssid = "yourNetworkSSIDHere"; const char* password = "yourPasswordHere";

  • Εργαλεία -> Πίνακας -> "AI -Thinker ESP -32 CAM" και επιλέξτε την κατάλληλη σειριακή θύρα για τον υπολογιστή σας (Εργαλεία -> Θύρα -> κάτι σαν /dev /ttyUSB0 ή COM4),
  • Ανοίξτε τη σειριακή οθόνη στο Arduino IDE, Ενώ πατάτε το κουμπί PROG (που τραβάει το IO0 χαμηλά), ενεργοποιήστε το ρομπότ,
  • Ελέγξτε στη σειριακή οθόνη ότι το ESP32 είναι έτοιμο για λήψη,
  • Κλείστε τη σειριακή οθόνη (διαφορετικά αποτυγχάνει η μεταφόρτωση SPIFFS),
  • Εργαλεία -> "ESP32 Sketch Data Upload" και περιμένετε να τελειώσει,
  • Απενεργοποιήστε και ενεργοποιήστε ξανά κρατώντας το κουμπί PROG για να επιστρέψετε στη λειτουργία προγραμματισμού,
  • Πατήστε το βέλος "Μεταφόρτωση" για να προγραμματίσετε το σκίτσο και περιμένετε να τελειώσει,
  • Ανοίξτε τη σειριακή οθόνη και επαναφέρετε το ESP32 απενεργοποιώντας/ενεργοποιώντας,
  • Μόλις ξεκινήσει, σημειώστε τη διεύθυνση IP (κάτι σαν 192.168.0.121) και αποσυνδέστε το ρομπότ από τον μετατροπέα USB-TTL,
  • Ανοίξτε ένα πρόγραμμα περιήγησης σε αυτήν τη διεύθυνση IP. Θα πρέπει να δείτε τη διεπαφή όπως στην εικόνα.
  • Προαιρετικά: ορίστε τη διεύθυνση mac του ESP32 σε μια σταθερή διεύθυνση IP στο δρομολογητή σας (εξαρτάται από το πώς να το κάνετε).

Αυτό είναι! Διαβάστε αν θέλετε να μάθετε πώς λειτουργεί…

Βήμα 3: Πώς λειτουργεί

Τώρα φτάνουμε στο ενδιαφέρον μέρος: πώς λειτουργούν όλα μαζί;

Θα προσπαθήσω να το εξηγήσω βήμα προς βήμα … αλλά λάβετε υπόψη ότι ο Kajnjaps δεν είναι ειδικός προγραμματισμού ιστού. Στην πραγματικότητα, η εκμάθηση λίγο προγραμματισμού ιστού ήταν η όλη προϋπόθεση για τη δημιουργία του DuvelBot. Εάν κάνω εμφανή λάθη, αφήστε ένα σχόλιο!

Εντάξει, μετά την ενεργοποίηση του ESP32, ως συνήθως στη ρύθμιση, αρχικοποιεί τα GPIO, τα συνδέει με χρονοδιακόπτες PWM για έλεγχο κινητήρα και LED. Δείτε εδώ για περισσότερα σχετικά με τον έλεγχο του κινητήρα, είναι αρκετά στάνταρ.

Στη συνέχεια, η κάμερα έχει ρυθμιστεί. Κράτησα σκόπιμα την ανάλυση αρκετά χαμηλή (VGA ή 640x480) για να αποφύγω την αργή απόκριση. Σημειώστε ότι η πλακέτα AI-Thinker ESP32-CAM διαθέτει σειριακό τσιπ RAM (PSRAM) που χρησιμοποιεί για την αποθήκευση καρέ κάμερας μεγαλύτερης ανάλυσης:

if (psramFound ()) {Serial.println ("βρέθηκε το PSRAM."); config.frame_size = FRAMESIZE_VGA; config.jpg_quality = 12; config.fb_count = 2; // αριθμός framebuffers δείτε: https://github.com/espressif/esp32-camera} else {Serial.println ("δεν βρέθηκε PSRAM."); config.frame_size = FRAMESIZE_QVGA; config.jpg_quality = 12; config.fb_count = 1; }

Στη συνέχεια, προετοιμάζεται το σειριακό περιφερειακό σύστημα αρχείων flash (SPIFFS):

// αρχικοποίηση SPIFFS εάν (! SPIFFS.begin (true)) {Serial.println ("Παρουσιάστηκε σφάλμα κατά την τοποθέτηση SPIFFS!"); ΕΠΙΣΤΡΟΦΗ; }

Το SPIFFS λειτουργεί σαν ένα μικρό σύστημα αρχείων στο ESP32. Εδώ χρησιμοποιείται για την αποθήκευση τριών αρχείων: την ίδια την ιστοσελίδα index.html, ένα σελιδοποιημένο στυλ αρχείου style.css και ένα λογότυπο εικόνας-p.webp

Στη συνέχεια, το ESP32 συνδέεται με το δρομολογητή σας (μην ξεχάσετε να ορίσετε τα διαπιστευτήριά σας πριν από τη μεταφόρτωση):

// αλλάξτε διαπιστευτήρια του δρομολογητή σας εδώ char* ssid = "yourNetworkSSIDHere"; const char* password = "yourPasswordHere"; … // σύνδεση στο WiFi Serial.print ("Σύνδεση σε WiFi"); WiFi.begin (ssid, κωδικός πρόσβασης); while (WiFi.status ()! = WL_CONNECTED) {Serial.print ('.'); καθυστέρηση (500)? } // τώρα συνδεδεμένος στο δρομολογητή: Το ESP32 έχει τώρα διεύθυνση IP

Για να κάνουμε πραγματικά κάτι χρήσιμο, ξεκινάμε έναν ασύγχρονο διακομιστή ιστού:

// δημιουργήστε ένα αντικείμενο AsyncWebServer στη θύρα διακομιστή 80AsyncWebServer (80). … Server.begin (); // ξεκινήστε να ακούτε τις συνδέσεις

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

Το ESP32 ξέρει πώς να απαντά, επειδή κατά τη ρύθμιση οι απαντήσεις σε όλα τα πιθανά επιτρεπόμενα αιτήματα έχουν καταχωρηθεί χρησιμοποιώντας το server.on (). Για παράδειγμα, η κύρια ιστοσελίδα ή το ευρετήριο (/) αντιμετωπίζεται με αυτόν τον τρόπο:

server.on ("/", HTTP_GET, (αίτημα AsyncWebServerRequest *) {Serial.println ("/request stand!"); request-> send (SPIFFS, "/index.html", String (), false, επεξεργαστής);});

Έτσι, εάν ο πελάτης συνδεθεί, το ESP32 απαντά στέλνοντας το αρχείο index.html από το σύστημα αρχείων SPIFFS. Ο επεξεργαστής παραμέτρων είναι το όνομα μιας συνάρτησης που προεπεξεργάζεται το html και αντικαθιστά τυχόν ειδικές ετικέτες:

// Αντικαθιστά τα σύμβολα κράτησης θέσης στο html όπως το %DATA %// με τις μεταβλητές που θέλετε να εμφανίσετε //

Δεδομένα: %DATA %

Επεξεργαστής συμβολοσειράς (const String & var) {if (var == "DATA") {//Serial.println("στο επεξεργαστή! "); επιστροφή συμβολοσειράς (dutyCycleNow); } επιστροφή συμβολοσειράς ();}

Τώρα, ας αποσυνδέσουμε την ίδια την ιστοσελίδα index.html. Σε γενικές γραμμές υπάρχουν πάντα τρία μέρη:

  1. κώδικας html: ποια στοιχεία πρέπει να εμφανίζονται (κουμπιά/κείμενο/ρυθμιστικά/εικόνες κ.λπ.),
  2. κώδικας στυλ, είτε σε ξεχωριστό αρχείο.css είτε σε… ενότητα: πώς πρέπει να μοιάζουν τα στοιχεία,
  3. javascript a… ενότητα: πώς πρέπει να λειτουργεί η ιστοσελίδα.

Μόλις το index.html φορτωθεί στο πρόγραμμα περιήγησης (το οποίο γνωρίζει ότι είναι html λόγω της γραμμής DOCTYPE), τρέχει σε αυτήν τη γραμμή:

Αυτό είναι ένα αίτημα για ένα φύλλο στυλ css. Η θέση αυτού του φύλλου δίνεται σε href = "…". Τι κάνει λοιπόν το πρόγραμμα περιήγησής σας; Δεξιά, εκκινεί ένα άλλο αίτημα στον διακομιστή, αυτή τη φορά για το style.css. Ο διακομιστής καταγράφει αυτό το αίτημα, επειδή καταχωρήθηκε:

server.on ("/style.css", HTTP_GET, (αίτημα AsyncWebServerRequest *) {Serial.println ("το αίτημα css ελήφθη"); αίτημα-> αποστολή (SPIFFS, "/style.css", "text/css ");});

Καθαρό ε; Παρεμπιπτόντως, θα μπορούσε να ήταν href = "/some/file/on/the/other/side/of/the/moon", για όλους τους περιηγητές σας. Θα πήγαινε να πάρει αυτό το αρχείο εξίσου ευτυχώς. Δεν θα εξηγήσω για το φύλλο στυλ, καθώς ελέγχει απλώς τις εμφανίσεις, οπότε δεν είναι πραγματικά ενδιαφέρον εδώ, αλλά αν θέλετε να μάθετε περισσότερα, ελέγξτε αυτό το σεμινάριο.

Πώς εμφανίζεται το λογότυπο του DuvelBot; Στο index.html έχουμε:

στο οποίο απαντά το ESP32 με:

server.on ("/duvel", HTTP_GET, (αίτημα AsyncWebServerRequest *) {Serial.println ("το αίτημα λογότυπου duvel ελήφθη!"); αίτημα-> αποστολή (SPIFFS, "/duvel.png", "image-p.webp

..ένα άλλο αρχείο SPIFFS, αυτή τη φορά μια πλήρης εικόνα, όπως υποδεικνύεται από το "image/png" στην απάντηση.

Τώρα φτάνουμε στο πραγματικά ενδιαφέρον μέρος: τον κωδικό για τα κουμπιά. Ας επικεντρωθούμε στο κουμπί FORWARD:

ΠΡΟΣ ΤΑ ΕΜΠΡΟΣ

Το όνομα class = "…" είναι μόνο ένα όνομα για να το συνδέσετε με το φύλλο στυλ για να προσαρμόσετε το μέγεθος, το χρώμα κ.λπ. ". Αυτές αποτελούν τις ενέργειες του κουμπιού (το ίδιο για το ontouchstart/ontouchend αλλά για τις οθόνες αφής/τηλέφωνα). Εδώ, η ενέργεια κουμπιού καλεί μια λειτουργία toggleCheckbox (x) στην ενότητα javascript:

συνάρτηση toggleCheckbox (x) {var xhr = new XMLHttpRequest (); xhr.open ("GET", "/" + x, true); xhr.send (); // θα μπορούσαμε να κάνουμε κάτι και με την απάντηση όταν είμαστε έτοιμοι, αλλά δεν το κάνουμε}

Πατώντας λοιπόν το κουμπί προώθησης, έχει άμεσο αποτέλεσμα την κλήση του toggleCheckbox ('εμπρός'). Στη συνέχεια, αυτή η λειτουργία εκκινεί ένα XMLHttpRequest "GET", της τοποθεσίας "/forward", το οποίο λειτουργεί ακριβώς όπως εάν θα είχατε πληκτρολογήσει 192.168.0.121/forward στη γραμμή διευθύνσεων του προγράμματος περιήγησής σας. Μόλις φτάσει αυτό το αίτημα στο ESP32, το χειρίζεται:

server.on ("/forward", HTTP_GET, (AsyncWebServerRequest *request) {Serial.println ("λαμβάνεται/προωθείται"); actionNow = FORWARD; request-> send (200, "text/plain", "OK forward. ");});

Τώρα το ESP32 απλώς απαντά με ένα κείμενο "OK εμπρός". Σημείωση Το toggleCheckBox () δεν κάνει τίποτα (ή περιμένετε) αυτήν την απάντηση, ωστόσο θα μπορούσε όπως φαίνεται αργότερα στον κώδικα της κάμερας.

Από μόνο του κατά τη διάρκεια αυτής της απόκρισης, το πρόγραμμα ορίζει μόνο μια μεταβλητή actionNow = FORWARD, ως απάντηση στο πάτημα του κουμπιού. Τώρα στο mainloop του προγράμματος, αυτή η μεταβλητή παρακολουθείται με στόχο να αυξήσει/κατεβάσει το PWM των κινητήρων. Η λογική είναι: όσο έχουμε μια ενέργεια που δεν είναι STOP, ανεβάζουμε τους κινητήρες προς αυτή την κατεύθυνση μέχρι να επιτευχθεί ένας ορισμένος αριθμός (dutyCycleMax). Στη συνέχεια, διατηρήστε αυτήν την ταχύτητα, εφόσον το actionNow δεν έχει αλλάξει:

void loop () {currentMillis = millis (); if (currentMillis - previousMillis> = dutyCycleStepDelay) {// αποθηκεύστε την τελευταία φορά που εκτελέσατε τον βρόχο previousMillis = currentMillis; // το mainloop είναι υπεύθυνο για την ανύψωση/κάμψη των κινητήρων εάν (actionNow! = previousAction) {// κατεβάστε κάτω, στη συνέχεια σταματήστε, μετά αλλάξτε δράση και ανεβάστε το dutyCycleNow = dutyCycleNow-dutyCycleStep; εάν (dutyCycleNow <= 0) {// εάν μετά την κατάρριψη του dc είναι 0, ορίστε στη νέα κατεύθυνση, ξεκινήστε από το ελάχιστο κύκλο εργασιών setDir (actionNow); previousAction = actionNow; dutyCycleNow = dutyCycleMin; }} else // actionNow == previousAmp ράμπα επάνω, εκτός όταν η κατεύθυνση είναι STOP {if (actionNow! = STOP) {dutyCycleNow = dutyCycleNow+dutyCycleStep; if (dutyCycleNow> dutyCycleMax) dutyCycleNow = dutyCycleMax; } else dutyCycleNow = 0; } ledcWrite (pwmChannel, dutyCycleNow); // ρυθμίστε τη μοτοσυκλέτα του κινητήρα}}

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

Τώρα, εάν αφήσουμε το κουμπί προώθησης, το πρόγραμμα περιήγησής σας καλεί το toggleCheckbox ("διακοπή"), με αποτέλεσμα ένα αίτημα GET /stop. Το ESP32 θέτει το actionNow στο STOP (και απαντά με "OK stop."), Το οποίο οδηγεί το mainloop να γυρίζει προς τα κάτω τους κινητήρες.

Τι γίνεται με τα LED; Ameδιος μηχανισμός, αλλά τώρα έχουμε ένα ρυθμιστικό:

Στο javascript, η ρύθμιση του ρυθμιστικού παρακολουθείται, έτσι ώστε σε κάθε αλλαγή να πραγματοποιείται μια κλήση για λήψη "/LED/xxx", όπου xxx είναι η τιμή φωτεινότητας που πρέπει να ρυθμιστούν τα LED:

var slide = document.getElementById ("slide"), sliderDiv = document.getElementById ("sliderAmount"); slide.onchange = function () {var xhr = new XMLHttpRequest (); xhr.open ("GET", "/LED/" + this.value, true); xhr.send (); sliderDiv.innerHTML = this.value; }

Σημειώστε ότι χρησιμοποιήσαμε το document.getElementByID («διαφάνεια») για να λάβουμε το ίδιο το αντικείμενο ρυθμιστικού, το οποίο δηλώθηκε με και ότι η τιμή εξάγεται σε ένα στοιχείο κειμένου με κάθε αλλαγή.

Ο χειριστής στο σκίτσο συλλαμβάνει όλα τα αιτήματα φωτεινότητας χρησιμοποιώντας "/LED/*" στην εγγραφή χειριστή. Στη συνέχεια, το τελευταίο μέρος (ένας αριθμός) διαχωρίζεται και μεταδίδεται σε ένα int:

server.on ("/LED/ *", HTTP_GET, (αίτημα AsyncWebServerRequest *) {Serial.println ("το αίτημα led λήφθηκε!"); setLedBrightness ((request-> url ()). substring (5).toInt ()); αίτημα-> αποστολή (200, "text/plain", "OK Leds.");});

Παρόμοια όπως περιγράφηκε παραπάνω, τα κουμπιά ασύρματου ελέγχου ελέγχουν τις μεταβλητές που ορίζουν τις προεπιλεγμένες ρυθμίσεις του PWM, έτσι ώστε το DuvelBot να μπορεί να σας οδηγήσει αργά με την μπύρα, προσέχοντας να μην χυθεί αυτός ο υγρός χρυσός και να επιστρέψει γρήγορα στην κουζίνα για να πάρει περισσότερα.

… Πώς λοιπόν ενημερώνεται η εικόνα της κάμερας χωρίς να χρειάζεται να ανανεώσετε τη σελίδα; Για αυτό χρησιμοποιούμε μια τεχνική που ονομάζεται AJAX (Asynchronous JavaScript and XML). Το πρόβλημα είναι ότι συνήθως μια σύνδεση πελάτη-διακομιστή ακολουθεί μια σταθερή διαδικασία: ο πελάτης (πρόγραμμα περιήγησης) υποβάλλει αίτημα, ο διακομιστής (ESP32) απαντά, η υπόθεση κλείνει. Εγινε. Τίποτα δεν συμβαίνει πια. Μόνο με κάποιο τρόπο θα μπορούσαμε να ξεγελάσουμε το πρόγραμμα περιήγησης να ζητά τακτικά ενημερώσεις από το ESP32… και αυτό ακριβώς θα κάνουμε με αυτό το κομμάτι της javascript:

setInterval (λειτουργία () {var xhttp = νέα XMLHttpRequest (); xhttp.open ("GET", "/CAMERA", true); xhttp.responseType = "blob"; xhttp.timeout = 500; xhttp.ontimeout = λειτουργία () {}; xhttp.onload = λειτουργία (ε) {if (this.readyState == 4 && this.status == 200) {// δείτε: https://stackoverflow.com/questions/7650587/using… // https://www.html5rocks.com/en/tutorials/file/xhr2/ var urlCreator = window. URL || window.webkitURL; var imageUrl = urlCreator.createObjectURL (this.response); // δημιουργήστε ένα αντικείμενο από την κηλίδα document.querySelector ("#camimage"). src = imageUrl; urlCreator.revokeObjectURL (imageurl)}}; xhttp.send ();},}, 250);

Το setInterval λαμβάνει ως παράμετρο μια συνάρτηση και την εκτελεί κάθε τόσο (εδώ μία φορά ανά 250ms με αποτέλεσμα 4 καρέ/δευτερόλεπτο). Η συνάρτηση που εκτελείται κάνει ένα αίτημα για ένα δυαδικό "blob" στη διεύθυνση /CAMERA. Αυτό χειρίζεται το ESP32-CAM στο σκίτσο ως (από Randomnerdtutorials):

server.on ("/CAMERA", HTTP_GET, (αίτημα AsyncWebServerRequest *) {Serial.println ("το αίτημα της κάμερας ελήφθη!"); camera_fb_t * fb = NULL; // esp_err_t res = ESP_OK; size_t _jpg_buf_len = 0; uint * _jpg_buf = NULL; // καταγραφή πλαισίου fb = esp_camera_fb_get (); if (! fb) {Serial.println ("Το πλαίσιο buffer δεν μπόρεσε να αποκτηθεί"); επιστροφή;} if (fb-> μορφή! = PIXFORMAT_JPEG)/ /ήδη σε αυτήν τη μορφή από config {bool jpeg_converted = frame-j.webp

Τα σημαντικά μέρη είναι η μετατροπή του πλαισίου fb = esp_camera_fb_get () σε-j.webp

Η συνάρτηση javascript περιμένει στη συνέχεια να φτάσει αυτή η εικόνα. Στη συνέχεια, χρειάζεται μόνο λίγη δουλειά για να μετατρέψετε το "blob" που λαμβάνετε σε url που μπορεί να χρησιμοποιηθεί ως πηγή για την ενημέρωση της εικόνας στη σελίδα html.

φευ, τελειώσαμε!

Βήμα 4: Ιδέες και υπολείμματα

Ιδέες & υπολείμματα
Ιδέες & υπολείμματα

Ο στόχος αυτού του έργου για μένα ήταν να μάθω αρκετά προγραμματισμό ιστού για διασύνδεση υλικού στον ιστό. Είναι δυνατές αρκετές επεκτάσεις σε αυτό το έργο. Ακολουθούν μερικές ιδέες:

  • Εφαρμόστε "πραγματική" ροή κάμερας όπως εξηγείται εδώ και εδώ και μετακινήστε την σε έναν 2ο διακομιστή όπως εξηγείται εδώ στο ίδιο ESP32, αλλά στον άλλο πυρήνα της CPU και, στη συνέχεια, εισαγάγετε το camerastream στο html που εξυπηρετεί ο 1ος διακομιστής χρησιμοποιώντας ένα…. Αυτό θα έχει ως αποτέλεσμα ταχύτερες ενημερώσεις της κάμερας.
  • Χρησιμοποιήστε τη λειτουργία σημείου πρόσβασης (AP) ώστε το ρομπότ να είναι πιο αυτόνομο όπως εξηγείται εδώ.
  • Επεκτείνετε με τη μέτρηση της τάσης της μπαταρίας, τις δυνατότητες ύπνου κλπ. Αυτό είναι λίγο δύσκολο αυτή τη στιγμή επειδή το AI-Thinker ESP32-CAM δεν έχει πολλούς GPIO. χρειάζεται επέκταση μέσω uart και για παράδειγμα slave arduino.
  • Μετατρέψτε σε ένα ρομπότ που ψάχνει γάτες που εκτοξεύει περιποιήσεις γάτας κατά διαστήματα με το πάτημα του ποδιού ενός μεγάλου κουμπιού, μεταδώστε τόνους ωραίων φωτογραφιών γάτας κατά τη διάρκεια της ημέρας…

Παρακαλώ σχολιάστε αν σας άρεσε ή έχετε ερωτήσεις και ευχαριστώ που διαβάσατε!

Συνιστάται: