สารบัญ:

DuvelBot - หุ่นยนต์เสิร์ฟเบียร์ ESP32-CAM: 4 ขั้นตอน (พร้อมรูปภาพ)
DuvelBot - หุ่นยนต์เสิร์ฟเบียร์ ESP32-CAM: 4 ขั้นตอน (พร้อมรูปภาพ)

วีดีโอ: DuvelBot - หุ่นยนต์เสิร์ฟเบียร์ ESP32-CAM: 4 ขั้นตอน (พร้อมรูปภาพ)

วีดีโอ: DuvelBot - หุ่นยนต์เสิร์ฟเบียร์ ESP32-CAM: 4 ขั้นตอน (พร้อมรูปภาพ)
วีดีโอ: Очередной рейс (1958) фильм 2024, มิถุนายน
Anonim
DuvelBot - หุ่นยนต์เสิร์ฟเบียร์ ESP32-CAM
DuvelBot - หุ่นยนต์เสิร์ฟเบียร์ ESP32-CAM

หลังจากวันอันเหน็ดเหนื่อย ไม่มีอะไรจะเทียบได้กับการจิบเบียร์ที่คุณโปรดปรานบนโซฟา ในกรณีของฉัน นั่นคือเบียร์สีบลอนด์เบลเยียม "Duvel" อย่างไรก็ตาม หลังจากที่ทั้งหมดแต่พังทลายลง เราต้องเผชิญกับปัญหาร้ายแรงที่สุด: ตู้เย็นที่มี Duvel ของฉันนั้นถูกถอดออกจากโซฟาดังกล่าวโดยไม่สามารถต่อสะพานได้ 20 ฟุต

ในขณะที่การบีบบังคับเล็กน้อยจากด้านข้างของฉันอาจทำให้คนเก็บขยะในตู้เย็นวัยรุ่นเป็นครั้งคราวเพื่อเทค่าเผื่อสัปดาห์ของฉันของ Duvel ภารกิจในการส่งมันไปยังบรรพบุรุษที่เกือบจะหมดแรงก็เห็นได้ชัดว่าขั้นตอนเดียวเกินไป

ถึงเวลาแยกหัวแร้งและคีย์บอร์ดออก…

DuvelBot เป็นเว็บแคมสำหรับการขับขี่ที่ใช้ AI-Thinker ESP32-CAM ที่ใช้งานง่าย ซึ่งคุณสามารถควบคุมได้จากสมาร์ทโฟน เบราว์เซอร์ หรือแท็บเล็ตของคุณ

ง่ายต่อการปรับเปลี่ยนหรือขยายแพลตฟอร์มนี้ให้มีการใช้แอลกอฮอล์น้อยลง (ลองนึกถึง SpouseSpy, NeighbourWatch, KittyCam…)

ฉันสร้างหุ่นยนต์ตัวนี้ขึ้นมาเพื่อเรียนรู้เล็กน้อยเกี่ยวกับการเขียนโปรแกรมเว็บทั้งหมดและเรื่อง IoT ซึ่งฉันไม่รู้อะไรเลย ดังนั้นในตอนท้ายของคำแนะนำนี้คือคำอธิบายอย่างละเอียดเกี่ยวกับวิธีการทำงาน

หลายส่วนของคำแนะนำนี้อิงตามคำอธิบายที่ยอดเยี่ยมที่พบใน Random Nerd Tutorials ดังนั้นโปรดไปเยี่ยมชมพวกเขา!

เสบียง

สิ่งที่คุณต้องการ:

รายการชิ้นส่วนไม่ได้ถูกแกะสลักด้วยหิน และชิ้นส่วนจำนวนมากสามารถหาได้จากรุ่นต่างๆ มากมายและจากที่ต่างๆ มากมาย ฉันซื้อจาก Ali-Express มากที่สุด เหมือนมาเชเต้พูดว่า: ด้นสด

ฮาร์ดแวร์:

  • โมดูล AI Thinker ESP32-CAM มันอาจจะทำงานกับโมดูล ESP32-CAM อื่นๆ ได้ แต่นั่นคือสิ่งที่ฉันใช้
  • บอร์ดควบคุมมอเตอร์ L298N,
  • แพลตฟอร์มหุ่นยนต์ 4 ล้อราคาถูก
  • ตัวเรือนที่มีพื้นผิวเรียบขนาดใหญ่ เช่น Hammond Electronics 1599KGY,
  • ตัวแปลง USB เป็น 3.3V-TTL สำหรับการเขียนโปรแกรม
  • สำหรับไฟส่องสว่าง: ไฟ LED สีขาว 3 ดวง, BC327 หรือทรานซิสเตอร์ทั่วไปอื่นๆ NPN (Ic=500mA), ตัวต้านทาน 4k7k, ตัวต้านทาน 82Ohm 3 ตัว, บอร์ดต่อสายไฟ, สายเคเบิล (ดูแผนผังและรูปภาพ)
  • สวิตช์เปิด/ปิดและปุ่มกดเปิดตามปกติสำหรับการตั้งโปรแกรม

ไม่จำเป็น:

  • กล้องฟิชอายที่โค้งงอได้นานกว่ากล้อง OV2460 มาตรฐานที่มาพร้อมกับโมดูล ESP32-CAM
  • เสาอากาศ WiFi พร้อมสายยาวพอสมควร และ Ultra Miniature Coax Connector แบบนี้ ESP32-CAM มีเสาอากาศออนบอร์ดและตัวเรือนเป็นพลาสติก ดังนั้นจึงไม่จำเป็นต้องใช้เสาอากาศ แต่ฉันคิดว่ามันดูดี ดังนั้น…
  • กระดาษสติกเกอร์พิมพ์อิงค์เจ็ทสำหรับการออกแบบฝาครอบด้านบน

เครื่องมือฮาร์ดแวร์ทั่วไป: หัวแร้ง สว่าน ไขควง คีม…

ขั้นตอนที่ 1: สร้างแพลตฟอร์มหุ่นยนต์

การสร้างแพลตฟอร์มหุ่นยนต์
การสร้างแพลตฟอร์มหุ่นยนต์
การสร้างแพลตฟอร์มหุ่นยนต์
การสร้างแพลตฟอร์มหุ่นยนต์
การสร้างแพลตฟอร์มหุ่นยนต์
การสร้างแพลตฟอร์มหุ่นยนต์

แผนผัง:

แผนผังไม่มีอะไรพิเศษ ESP32-cam ควบคุมมอเตอร์ผ่านบอร์ดไดรเวอร์มอเตอร์ L298N ซึ่งมีสองช่องสัญญาณ มอเตอร์ด้านซ้ายและขวาวางขนานกันและแต่ละด้านใช้ช่องเดียว ขอแนะนำให้ใช้ตัวเก็บประจุเซรามิก 10..100nF เซรามิกขนาดเล็กสี่ตัวใกล้กับหมุดของมอเตอร์เพื่อตอบโต้สัญญาณรบกวน RF นอกจากนี้ ฝาครอบอิเล็กโทรไลต์ขนาดใหญ่ (2200…4700uF) บนแหล่งจ่ายของมอเตอร์บอร์ดตามที่แสดงในแผนผัง ในขณะที่ไม่จำเป็นอย่างยิ่ง สามารถจำกัดการกระเพื่อมของแรงดันไฟจ่ายได้เล็กน้อย (ถ้าคุณต้องการดูหนังสยองขวัญ ให้ตรวจสอบ Vbat ด้วยออสซิลโลสโคปในขณะที่มอเตอร์ทำงาน)

โปรดทราบว่าหมุดเปิดใช้งานช่องสัญญาณมอเตอร์ทั้งสองช่องนั้นขับเคลื่อนด้วยพินแบบปรับความกว้างพัลส์ (PWM) เดียวกันของ ESP32 (IO12) เนื่องจากโมดูล ESP32-CAM ไม่มี GPIO จำนวนมาก (มีแผนผังของโมดูลสำหรับการอ้างอิง) LED ของหุ่นยนต์ขับเคลื่อนโดย IO4 ซึ่งขับเคลื่อน LED แฟลชออนบอร์ดด้วย ดังนั้นให้ถอด Q1 ออกเพื่อป้องกันไม่ให้ LED แฟลชติดสว่างในเคสแบบปิด

ปุ่มตั้งโปรแกรม สวิตช์เปิด/ปิด ขั้วต่อการชาร์จ และขั้วต่อการเขียนโปรแกรมสามารถเข้าถึงได้ใต้หุ่นยนต์ ฉันทำได้ดีกว่านี้มากสำหรับขั้วต่อการเขียนโปรแกรม (แจ็ค 3.5 มม.) แต่เบียร์รอไม่ไหวแล้ว นอกจากนี้ การอัปเดตแบบ over-the-air-update (OTA) ก็น่าจะดีสำหรับการติดตั้ง

ในการทำให้หุ่นยนต์เข้าสู่โหมดการเขียนโปรแกรม ให้กดปุ่มตั้งโปรแกรม (ซึ่งจะดึง IO0 ให้ต่ำ) แล้วจึงเปิดเครื่อง

สำคัญ: ในการชาร์จแบตเตอรี่ NiMH ของหุ่นยนต์ ให้ใช้ชุดจ่ายไฟสำหรับห้องปฏิบัติการ (ไม่ได้บรรจุ) ไว้ที่ประมาณ 14V และกระแสไฟจำกัดที่ 250mA แรงดันไฟฟ้าจะปรับให้เข้ากับแรงดันไฟฟ้าของแบตเตอรี่ ตัดการเชื่อมต่อหากหุ่นยนต์รู้สึกร้อนหรือแรงดันแบตเตอรี่ถึงประมาณ 12.5V การปรับปรุงที่ชัดเจนในที่นี้คือการรวมเครื่องชาร์จแบตเตอรี่ที่เหมาะสมเข้าด้วยกัน แต่นั่นอยู่นอกเหนือขอบเขตของคำแนะนำนี้

ฮาร์ดแวร์:

โปรดดูหมายเหตุในภาพด้วย ตัวเรือนติดตั้งบนฐานหุ่นยนต์โดยใช้สลักเกลียว M4 4 ตัวและน็อตล็อคตัวเอง สังเกตท่อยางที่ใช้เป็นตัวเว้นระยะ หวังว่าสิ่งนี้จะทำให้ Duvel ระงับการนั่งได้หากพบว่าเป็นหลุมเป็นบ่อ โมดูล ESP32-CAM และแผงมอเตอร์ L298N ติดตั้งอยู่ในตัวเครื่องโดยใช้หมุดพลาสติกแบบเหนียว (ภาษาอังกฤษไม่แน่ใจในชื่อที่ถูกต้อง) เพื่อป้องกันไม่ให้ต้องเจาะรูเพิ่มเติม นอกจากนี้ ESP32 ยังติดตั้งอยู่บนบอร์ดแบบ perfboard และพินเฮดเดอร์แบบเสียบได้ ทำให้ง่ายต่อการเปลี่ยน ESP32

อย่าลืม: หากคุณกำลังใช้เสาอากาศ WiFi ภายนอกแทนเสาอากาศในตัว ให้บัดกรีจัมเปอร์สำหรับเลือกเสาอากาศที่ด้านล่างของบอร์ด ESP32-CAM ด้วย

พิมพ์โลโก้ด้านบนในไฟล์ DuvelBot.svg บนกระดาษสติกเกอร์อิงค์เจ็ท (หรือออกแบบของคุณเอง) เท่านี้คุณก็พร้อมแล้ว!

ขั้นตอนที่ 2: ตั้งโปรแกรมหุ่นยนต์

โปรแกรมหุ่นยนต์
โปรแกรมหุ่นยนต์

ขอแนะนำให้ตั้งโปรแกรมหุ่นยนต์ก่อนปิดเพื่อให้แน่ใจว่าทุกอย่างทำงานได้และไม่มีควันวิเศษปรากฏขึ้น

คุณต้องมีเครื่องมือซอฟต์แวร์ต่อไปนี้:

  • Arduino IDE,
  • ไลบรารี ESP32, SPIFFS (ระบบไฟล์แฟลชต่อพ่วงแบบอนุกรม), ไลบรารีเว็บเซิร์ฟเวอร์ ESPAsync

หลังสามารถติดตั้งได้โดยทำตาม randomnerdtutorial นี้จนถึงและรวมถึงส่วน "การจัดระเบียบไฟล์ของคุณ" ฉันไม่สามารถอธิบายได้ดีกว่านี้

รหัส:

รหัสของฉันสามารถพบได้ที่:

  • ภาพร่าง Arduino DuvelBot.ino
  • โฟลเดอร์ย่อยข้อมูลที่เก็บไฟล์ที่จะอัปโหลดไปยังแฟลช ESP โดยใช้ 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 จะเริ่มต้น GPIO เชื่อมโยงกับตัวจับเวลา PWM สำหรับการควบคุมมอเตอร์และ LED ดูที่นี่สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการควบคุมมอเตอร์ ซึ่งเป็นมาตรฐานที่ค่อนข้างดี

จากนั้นกำหนดค่ากล้อง ฉันตั้งใจเก็บความละเอียดไว้ค่อนข้างต่ำ (VGA หรือ 640x480) เพื่อหลีกเลี่ยงการตอบสนองที่เฉื่อย โปรดทราบว่าบอร์ด AI-Thinker ESP32-CAM มีชิป Serial ram (PSRAM) ที่ใช้เก็บเฟรมของกล้องที่มีความละเอียดสูงกว่า:

ถ้า (psramFound ()) { Serial.println ("พบ PSRAM"); config.frame_size = FRAMESIZE_VGA; config.jpg_quality = 12; config.fb_count = 2; //จำนวนเฟรมบัฟเฟอร์ ดู: https://github.com/espressif/esp32-camera } else { Serial.println("ไม่พบ PSRAM"); config.frame_size = FRAMESIZE_QVGA; config.jpg_quality = 12; config.fb_count = 1; }

จากนั้นระบบไฟล์แฟลชต่อพ่วงซีเรียล (SPIFFS) จะเริ่มต้น:

// เริ่มต้น SPIFFS ถ้า (!SPIFFS.begin (จริง)) { Serial.println ("เกิดข้อผิดพลาดขณะติดตั้ง SPIFFS!"); กลับ; }

SPIFFS ทำหน้าที่เหมือนระบบไฟล์เล็กๆ บน ESP32 ในที่นี้ใช้เพื่อเก็บไฟล์สามไฟล์: หน้าเว็บเอง index.html, stylesheet ไฟล์แบบเรียงซ้อน style.css และโลโก้รูปภาพ-p.webp

ถัดไป ESP32 จะเชื่อมต่อกับเราเตอร์ของคุณ (อย่าลืมตั้งค่าข้อมูลรับรองของคุณก่อนอัปโหลด):

//เปลี่ยนข้อมูลประจำตัวของเราเตอร์ของคุณที่นี่const char* ssid = "yourNetworkSSIDHere";const char* password = "yourPasswordHere"; … //เชื่อมต่อกับ WiFi Serial.print("กำลังเชื่อมต่อกับ WiFi"); WiFi.begin(ssid, รหัสผ่าน); ในขณะที่ (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 *request){ Serial.println(" / request received!"); request->send(SPIFFS, "/index.html", String(), false, โปรเซสเซอร์); });

ดังนั้นหากไคลเอ็นต์เชื่อมต่อ ESP32 จะตอบกลับโดยส่งไฟล์ index.html จากระบบไฟล์ SPIFFS ตัวประมวลผลพารามิเตอร์คือชื่อของฟังก์ชันที่ประมวลผล html ล่วงหน้าและแทนที่แท็กพิเศษใดๆ:

// แทนที่ตัวยึดตำแหน่งใน html เช่น %DATA%// ด้วยตัวแปรที่คุณต้องการแสดง//

ข้อมูล: %DATA%

ตัวประมวลผลสตริง (const String& var){ if(var == "DATA"){ //Serial.println("ในโปรเซสเซอร์!"); ส่งคืนสตริง (dutyCycleNow); } return String();}

ตอนนี้ ให้แยกหน้าเว็บ index.html เอง โดยทั่วไปมีสามส่วนเสมอ:

  1. โค้ด html: องค์ประกอบที่ควรแสดง (ปุ่ม/ข้อความ/ตัวเลื่อน/รูปภาพ ฯลฯ)
  2. โค้ดสไตล์ ไม่ว่าจะในไฟล์.css แยกต่างหากหรือในส่วน … องค์ประกอบควรมีลักษณะอย่างไร
  3. javascript a … ส่วน: วิธีการทำงานของหน้าเว็บ

เมื่อ index.html โหลดเข้าสู่เบราว์เซอร์ (ซึ่งรู้ว่าเป็น html เนื่องจากเป็นบรรทัด DOCTYPE) มันจะทำงานในบรรทัดนี้:

นั่นคือคำขอสำหรับสไตล์ชีต css ตำแหน่งของแผ่นงานนี้อยู่ใน href="…" เบราว์เซอร์ของคุณทำอะไรได้บ้าง? ใช่ มันเปิดตัวคำขออื่นไปยังเซิร์ฟเวอร์ คราวนี้สำหรับ style.css เซิร์ฟเวอร์รวบรวมคำขอนี้ เนื่องจากได้ลงทะเบียนแล้ว:

server.on("/style.css", HTTP_GET, (AsyncWebServerRequest *request){ Serial.println(" css request received"); request->send(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 *request){ Serial.println("duvel logo request gets!"); request->send(SPIFFS, "/duvel.png", "image/png) คำขอ->ส่ง "); });

..ไฟล์ SPIFFS อีกไฟล์ คราวนี้เป็นภาพที่สมบูรณ์ ตามที่ระบุโดย "image/png" ในการตอบกลับ

ตอนนี้เรามาถึงส่วนที่น่าสนใจจริงๆ: โค้ดสำหรับปุ่มต่างๆ มาเน้นที่ปุ่ม FORWARD:

ซึ่งไปข้างหน้า

ชื่อ เป็นเพียงชื่อสำหรับลิงก์ไปยังสไตล์ชีตเพื่อกำหนดขนาด สี ฯลฯ ส่วนที่สำคัญคือ onmousedown="toggleCheckbox('forward')" และ onmouseup="toggleCheckbox('stop') ". สิ่งเหล่านี้ประกอบขึ้นจากการทำงานของปุ่ม (เหมือนกันสำหรับ ontouchstart/ontouchend แต่สำหรับหน้าจอสัมผัส/โทรศัพท์) ที่นี่ การทำงานของปุ่มจะเรียกใช้ฟังก์ชัน toggleCheckbox(x) ในส่วนจาวาสคริปต์:

ฟังก์ชัน toggleCheckbox(x){ var xhr = ใหม่ XMLHttpRequest(); xhr.open("GET", "/" + x, จริง); xhr.send(); //สามารถทำอะไรกับการตอบสนองได้เช่นกันเมื่อพร้อม แต่เราไม่ }

ดังนั้นการกดปุ่มไปข้างหน้าจะส่งผลให้มีการเรียก toggleCheckbox('forward') ทันที ฟังก์ชันนี้จะเปิด XMLHttpRequest "GET" ของตำแหน่ง "/forward" ซึ่งทำหน้าที่เหมือนกับว่าคุณจะพิมพ์ 192.168.0.121/forward ในแถบที่อยู่ของเบราว์เซอร์ เมื่อคำขอนี้มาถึงที่ ESP32 จะได้รับการจัดการโดย:

server.on("/forward", HTTP_GET, (AsyncWebServerRequest *request){ Serial.println("received /forward"); actionNow = FORWARD; request->send(200, "text/plain", "ตกลงไปข้างหน้า."); });

ตอนนี้ ESP32 ตอบกลับด้วยข้อความว่า "ตกลงไปข้างหน้า" หมายเหตุ toggleCheckBox() ไม่ได้ดำเนินการใดๆ กับ (หรือรอ) การตอบสนองนี้ อย่างไรก็ตาม อาจเป็นดังที่แสดงในรหัสกล้องในภายหลัง

ในตัวเองระหว่างการตอบสนองนี้ โปรแกรมจะตั้งค่าตัวแปร actionNow = FORWARD เป็นการตอบสนองต่อการกดปุ่มเท่านั้น ขณะนี้อยู่ใน mainloop ของโปรแกรม ตัวแปรนี้ได้รับการตรวจสอบโดยมีเป้าหมายเพื่อเพิ่ม/ลด PWM ของมอเตอร์ ตรรกะคือ: ตราบใดที่เรามีการกระทำที่ไม่ใช่ STOP ให้เพิ่มมอเตอร์ในทิศทางนั้นจนกว่าจะถึงจำนวนที่กำหนด (dutyCycleMax) จากนั้นรักษาความเร็วนั้นไว้ ตราบใดที่ actionNow ไม่เปลี่ยนแปลง:

วงเป็นโมฆะ () { currentMillis = มิลลิวินาที (); if (currentMillis - PreviousMillis >= dutyCycleStepDelay) { // บันทึกครั้งสุดท้ายที่คุณดำเนินการวนรอบ PreviousMillis = currentMillis; //mainloop มีหน้าที่เพิ่ม/ลดมอเตอร์ ถ้า (actionNow != PreviousAction) { // ลงแล้วหยุด จากนั้นเปลี่ยนการกระทำและเพิ่ม dutyCycleNow = dutyCycleNow-dutyCycleStep; if (dutyCycleNow <= 0) {// ถ้าหลังจากลดความเร็วลง dc เป็น 0 ให้ตั้งค่าเป็นทิศทางใหม่ให้เริ่มที่ min dutycycle setDir (actionNow); PreviousAction = actionNow; dutyCycleNow = dutyCycleMin; } } else //actionNow == PreviousAction เพิ่มขึ้น ยกเว้นเมื่อทิศทางคือ STOP { if (actionNow != STOP) { dutyCycleNow = dutyCycleNow+dutyCycleStep; ถ้า (dutyCycleNow > dutyCycleMax) dutyCycleNow = dutyCycleMax; } อื่น ๆ dutyCycleNow = 0; } ledcWrite(pwmChannel, dutyCycleNow); //ปรับรอบมอเตอร์ }}

สิ่งนี้จะเพิ่มความเร็วของมอเตอร์อย่างช้าๆ แทนที่จะเปิดตัวด้วยความเร็วเต็มที่แล้วปล่อย Duvel อันล้ำค่าอันล้ำค่าออกไป การปรับปรุงที่ชัดเจนคือการย้ายรหัสนี้ไปยังรูทีนขัดจังหวะตัวจับเวลา แต่ทำงานได้ตามที่เป็นอยู่

ตอนนี้ หากเราปล่อยปุ่มไปข้างหน้า เบราว์เซอร์ของคุณจะเรียก toggleCheckbox('stop') ส่งผลให้มีการร้องขอให้ GET /stop ESP32 ตั้งค่า actionNow เป็น STOP (และตอบสนองด้วย "OK stop") ซึ่งจะนำ mainloop ไปหมุนมอเตอร์

แล้ว LED ล่ะ? กลไกเดียวกัน แต่ตอนนี้เรามีตัวเลื่อน:

ในจาวาสคริปต์ การตั้งค่าของแถบเลื่อนจะถูกตรวจสอบ ดังนั้นทุกครั้งที่มีการเปลี่ยนแปลงการโทรเพื่อรับ "/LED/xxx" จะเกิดขึ้น โดยที่ xxx คือค่าความสว่างที่ควรตั้งค่า LED ไว้ที่:

var slide = document.getElementById('slide'), sliderDiv = document.getElementById("sliderAmount"); slide.onchange = ฟังก์ชั่น () { var xhr = ใหม่ XMLHttpRequest (); xhr.open("GET", "/LED/" + this.value, จริง); xhr.send(); sliderDiv.innerHTML = this.value; }

โปรดทราบว่าเราใช้ document.getElementByID('slide') เพื่อรับตัวเลื่อนวัตถุ ซึ่งถูกประกาศด้วย และค่าจะถูกส่งออกไปยังองค์ประกอบข้อความที่มีการเปลี่ยนแปลงทุกครั้ง

ตัวจัดการในภาพร่างจับคำขอความสว่างทั้งหมดโดยใช้ "/LED/*" ในการลงทะเบียนตัวจัดการ จากนั้นส่วนสุดท้าย (ตัวเลข) จะถูกแยกออกเป็น int:

server.on("/LED/*", HTTP_GET, (AsyncWebServerRequest *request){ Serial.println("led request gets!"); setLedBrightness((request->url()).substring(5).toInt ("/LED/*", HTTP_GET, (AsyncWebServerRequest *request){ Serial.println("led request gets!"); ()); request->send(200, "text/plain", "OK Leds."); });

คล้ายกับที่อธิบายไว้ข้างต้น ปุ่มเรดิโอปุ่มควบคุมตัวแปรที่ตั้งค่าเริ่มต้นของ PWM เพื่อให้ DuvelBot สามารถขับเบียร์มาหาคุณอย่างช้าๆ ระวังอย่าให้ทองคำเหลวหก และรีบกลับไปที่ห้องครัวเพื่อหยิบขึ้นมา

…แล้วภาพของกล้องจะอัปเดตได้อย่างไรโดยที่คุณไม่ต้องรีเฟรชหน้า เพื่อที่เราใช้เทคนิคที่เรียกว่า AJAX (Asynchronous JavaScript และ XML) ปัญหาคือโดยปกติการเชื่อมต่อระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์จะทำตามขั้นตอนคงที่: ไคลเอ็นต์ (เบราว์เซอร์) ส่งคำขอ เซิร์ฟเวอร์ (ESP32) ตอบสนอง ปิดตัวพิมพ์ใหญ่ เสร็จแล้ว. ไม่มีอะไรเกิดขึ้นอีกแล้ว หากเพียงแต่เราสามารถหลอกให้เบราว์เซอร์ร้องขอการอัปเดตจาก ESP32 เป็นประจำ…และนั่นคือสิ่งที่เราจะทำกับจาวาสคริปต์ชิ้นนี้:

setInterval(function(){ var xhttp = new XMLHttpRequest(); xhttp.open("GET", "/CAMERA", true); xhttp.responseType = "blob"; xhttp.timeout = 500; xhttp.ontimeout = function()){}; xhttp.onload = function(e){ if (this.readyState == 4 && this.status == 200) { //see: 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 *request){ Serial.println("camera request gets!"); camera_fb_t * fb = NULL; //esp_err_t res = ESP_OK; size_t _jpg_buf_len = 0; uint8_t * _jpg_buf = NULL; //จับภาพเฟรม fb = esp_camera_fb_get(); if (!fb) {Serial.println("Frame buffer ไม่สามารถรับได้");return;} if(fb->format != PIXFORMAT_JPEG)/ / อยู่ในรูปแบบนี้จาก config แล้ว { bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len); esp_camera_fb_return(fb); fb = NULL; if(!jpeg_converted){Serial.println("JPEG compression failed");return; } } else{ _jpg_buf_len = fb->len; _jpg_buf = fb->buf; } //Serial.println(_jpg_buf_len); // ส่งคำขอรูปภาพที่จัดรูปแบบ->send_P(200, "image/jpg", _jpg_buf, _jpg_buf_len); //ล้างข้อมูล if(fb){ esp_camera_fb_return(fb); fb = NULL; _jpg_buf = NULL; } else if (_jpg_buf){ ฟรี (_jpg_buf); _jpg_buf = NULL; } });

ส่วนสำคัญคือรับเฟรม fb = esp_camera_fb_get() แปลงเป็น-j.webp

ฟังก์ชันจาวาสคริปต์จะรอจนกว่าภาพนี้จะมาถึง จากนั้นจะใช้เวลาเล็กน้อยในการแปลง "blob" ที่ได้รับเป็น url ที่สามารถใช้เป็นแหล่งที่มาเพื่ออัปเดตรูปภาพด้วยในหน้า html

วุ้ย เสร็จแล้ว!

ขั้นตอนที่ 4: ไอเดียและของเหลือ

ไอเดียและของเหลือ
ไอเดียและของเหลือ

เป้าหมายของโครงงานนี้สำหรับฉันคือการเรียนรู้การเขียนโปรแกรมเว็บให้เพียงพอเพื่อเชื่อมต่อฮาร์ดแวร์กับเว็บ สามารถขยายโครงการนี้ได้หลายแบบ นี่คือแนวคิดบางประการ:

  • ใช้การสตรีมกล้อง 'ของจริง' ตามที่อธิบายไว้ที่นี่และที่นี่ และย้ายไปยังเซิร์ฟเวอร์ที่ 2 ตามที่อธิบายไว้ที่นี่ใน ESP32 เดียวกัน แต่ในคอร์ CPU อื่น จากนั้นนำเข้าสตรีมกล้องไปยัง html ที่ให้บริการโดยเซิร์ฟเวอร์ที่ 1 โดยใช้ …. ซึ่งจะทำให้การอัปเดตกล้องเร็วขึ้น
  • ใช้โหมดจุดเข้าใช้งาน (AP) เพื่อให้หุ่นยนต์เป็นแบบสแตนด์อโลนมากขึ้นตามที่อธิบายไว้ที่นี่
  • ขยายด้วยการวัดแรงดันแบตเตอรี่ ความสามารถในการหลับลึก ฯลฯ ซึ่งค่อนข้างยากในขณะนี้เนื่องจาก AI-Thinker ESP32-CAM ไม่มี GPIO จำนวนมาก ต้องการการขยายผ่าน uart และตัวอย่างเช่น arduino ทาส
  • แปลงร่างเป็นหุ่นยนต์หาแมวที่ปล่อยขนมแมวออกมาเป็นครั้งคราวด้วยการกดปุ่มขนาดใหญ่ สตรีมรูปแมวสวย ๆ มากมายในระหว่างวัน…

กรุณาแสดงความคิดเห็นหากคุณชอบหรือมีคำถามและขอขอบคุณที่อ่าน!

แนะนำ: