Mục lục:

DuvelBot - Robot phục vụ bia ESP32-CAM: 4 bước (có hình ảnh)
DuvelBot - Robot phục vụ bia ESP32-CAM: 4 bước (có hình ảnh)

Video: DuvelBot - Robot phục vụ bia ESP32-CAM: 4 bước (có hình ảnh)

Video: DuvelBot - Robot phục vụ bia ESP32-CAM: 4 bước (có hình ảnh)
Video: Трактористы (комедия, реж. Иван Пырьев, 1939 г.) 2024, Tháng sáu
Anonim
DuvelBot - Robot phục vụ bia ESP32-CAM
DuvelBot - Robot phục vụ bia ESP32-CAM

Sau một ngày làm việc mệt mỏi, không gì bằng nhâm nhi ly bia yêu thích trên chiếc ghế dài. Trong trường hợp của tôi, đó là cậu bé tóc vàng Bỉ "Duvel". Tuy nhiên, sau tất cả, trừ việc sụp đổ, chúng tôi đang phải đối mặt với một vấn đề nghiêm trọng nhất: tủ lạnh chứa Duvel của tôi là một chiếc ghế dài 20 feet không thể kiểm soát được.

Trong khi một số hành động ép buộc nhẹ từ phía tôi có thể khiến một người nhặt rác tủ lạnh thiếu niên không thường xuyên tiêu hết tiền trợ cấp Duvel trong tuần của tôi, nhiệm vụ thực sự giao nó cho tổ tiên gần như kiệt quệ của nó rõ ràng là một bước quá xa.

Đã đến lúc bẻ sắt hàn và bàn phím…

DuvelBot là một webcam lái xe dựa trên AI-Thinker ESP32-CAM đơn giản mà bạn có thể điều khiển từ điện thoại thông minh, trình duyệt hoặc máy tính bảng của mình.

Thật dễ dàng để điều chỉnh hoặc mở rộng nền tảng này cho những người ít sử dụng rượu hơn (hãy nghĩ đến SpouseSpy, NeighbourWatch, KittyCam…).

Tôi chế tạo robot này chủ yếu để tìm hiểu một chút về toàn bộ lập trình web và công cụ IoT, mà tôi không biết gì về nó. Vì vậy, ở phần cuối của Tài liệu hướng dẫn này là một lời giải thích tỉ mỉ về cách hoạt động của nó.

Nhiều phần của Có thể hướng dẫn này dựa trên những lời giải thích tuyệt vời được tìm thấy trong Hướng dẫn ngẫu nhiên Nerd, vì vậy hãy ghé thăm chúng!

Quân nhu

Những gì bạn cần:

Danh sách các bộ phận không được chạm khắc trên đá và nhiều bộ phận có thể được lấy từ rất nhiều phiên bản khác nhau và từ nhiều nơi khác nhau. Tôi đã mua hầu hết từ Ali-Express. Giống như Machete đã nói: tùy cơ ứng biến.

Phần cứng:

  • Mô-đun AI Thinker ESP32-CAM. Nó có thể hoạt động với các mô-đun ESP32-CAM khác nhưng đó là những gì tôi đã sử dụng
  • Bảng điều khiển động cơ L298N,
  • Một nền tảng robot 4 bánh giá rẻ,
  • Vỏ có bề mặt phẳng lớn, chẳng hạn như Hammond Electronics 1599KGY,
  • Bộ chuyển đổi USB-to-3.3V-TTL để lập trình.
  • Đối với ánh sáng: 3 đèn LED trắng, BC327 hoặc bóng bán dẫn đa năng khác NPN (Ic = 500mA), điện trở 4k7k, 3 điện trở 82Ohm, bảng điều khiển, dây cáp (xem sơ đồ và hình ảnh).
  • Một công tắc bật / tắt và một nút bấm thường mở để lập trình.

Không bắt buộc:

  • Máy ảnh mắt cá có độ uốn cong dài hơn máy ảnh OV2460 tiêu chuẩn được cung cấp với mô-đun ESP32-CAM,
  • Ăng-ten Wi-Fi với cáp dài phù hợp và Đầu nối Coax Siêu thu nhỏ, như thế này. ESP32-CAM có một ăng-ten trên bo mạch và vỏ bằng nhựa, vì vậy, một ăng-ten không thực sự cần thiết, tuy nhiên tôi nghĩ nó trông rất ngầu, vì vậy…
  • Giấy nhãn có thể in phun cho thiết kế bìa trên.

Các công cụ phần cứng thông thường: mỏ hàn, máy khoan, tua vít, kìm…

Bước 1: Xây dựng Nền tảng Robot

Xây dựng nền tảng robot
Xây dựng nền tảng robot
Xây dựng nền tảng robot
Xây dựng nền tảng robot
Xây dựng nền tảng robot
Xây dựng nền tảng robot

Sơ đồ:

Sơ đồ không có gì đặc biệt. ESP32-cam điều khiển động cơ thông qua bảng điều khiển động cơ L298N, có hai kênh. Các động cơ của bên trái và bên phải được đặt song song và mỗi bên chiếm một kênh. Bốn tụ gốm 10..100nF nhỏ gần chân động cơ luôn được khuyến khích để chống nhiễu RF. Ngoài ra, một nắp điện phân lớn (2200… 4700uF) trên nguồn cung cấp của bảng động cơ như được hiển thị trong sơ đồ, trong khi không cần thiết, có thể hạn chế gợn sóng điện áp cung cấp một chút (nếu bạn muốn xem một bộ phim kinh dị, hãy thăm dò Vbat bằng máy hiện sóng khi động cơ đang hoạt động).

Lưu ý rằng cả hai chân ENABLE kênh động cơ được điều khiển bởi cùng một chân được điều chế độ rộng xung (PWM) của ESP32 (IO12). Điều này là do mô-đun ESP32-CAM không có nhiều GPIO (sơ đồ của mô-đun được bao gồm để tham khảo). Các đèn LED của rô bốt được điều khiển bởi IO4, điều này cũng điều khiển đèn LED flash trên bo mạch, vì vậy hãy loại bỏ Q1 để ngăn đèn LED flash sáng trong hộp kín.

Nút lập trình, công tắc bật / tắt, đầu nối sạc và đầu nối lập trình có thể truy cập bên dưới robot. Tôi lẽ ra có thể làm tốt hơn nhiều đối với đầu nối lập trình (giắc cắm 3,5 mm?), Nhưng bia không thể đợi thêm được nữa. Ngoài ra, cập nhật qua mạng (OTA) cũng sẽ rất tốt khi thiết lập.

Để đặt rô bốt ở chế độ lập trình, hãy nhấn nút lập trình (nút này kéo IO0 xuống thấp) rồi bật nó lên.

Quan trọng: để sạc pin NiMH của rô bốt, hãy sử dụng bộ nguồn trong phòng thí nghiệm (không tải) khoảng 14V và dòng điện giới hạn 250mA. Điện áp sẽ thích ứng với điện áp của pin. Ngắt kết nối nếu robot cảm thấy nóng hoặc điện áp pin đạt khoảng 12,5V. Một cải tiến rõ ràng ở đây sẽ là tích hợp một bộ sạc pin thích hợp, nhưng điều đó nằm ngoài phạm vi của Có thể hướng dẫn này.

Phần cứng:

Hãy cũng xem các ghi chú trong hình ảnh. Vỏ được gắn trên bệ robot bằng 4 bu lông M4 và đai ốc tự khóa. Lưu ý ống cao su được sử dụng như miếng đệm khoảng cách. Hy vọng rằng, điều này cũng cung cấp một số hệ thống treo cho Duvel, nếu chuyến đi chứng minh là gập ghềnh. Mô-đun ESP32-CAM và bảng động cơ L298N được gắn trong vỏ bằng cách sử dụng chân dính nhựa (không chắc đúng tên bằng tiếng Anh), để tránh phải khoan thêm lỗ. Ngoài ra, ESP32 được gắn trên bảng điều khiển của riêng nó và các đầu cắm có thể cắm được. Điều này giúp bạn dễ dàng hoán đổi ESP32.

Đừng quên: nếu bạn đang sử dụng ăng-ten WiFi bên ngoài thay vì ăng-ten tích hợp, thì bạn cũng hãy hàn dây nối chọn ăng-ten ở mặt dưới của bo mạch ESP32-CAM.

In logo trên cùng trong tệp DuvelBot.svg trên giấy nhãn dán in phun (hoặc thiết kế của riêng bạn) và bạn đã sẵn sàng!

Bước 2: Lập trình Robot

Lập trình Robot
Lập trình Robot

Bạn nên lập trình robot trước khi đóng nó, để đảm bảo mọi thứ hoạt động và không có khói ma thuật nào xuất hiện.

Bạn cần các công cụ phần mềm sau:

  • Arduino IDE,
  • Thư viện ESP32, SPIFFS (hệ thống tệp flash ngoại vi nối tiếp), thư viện Máy chủ trang web ESPAsync.

Phần sau có thể được cài đặt bằng cách làm theo hướng dẫn ngẫu nhiên này cho đến và bao gồm phần "tổ chức các tệp của bạn". Tôi thực sự không thể giải thích nó tốt hơn.

Mật mã:

Mã của tôi có thể được tìm thấy tại:

  • Một bản phác thảo Arduino DuvelBot.ino,
  • Một thư mục con dữ liệu chứa các tệp sẽ được tải lên ESP flash bằng SPIFFS. Thư mục này chứa trang web mà ESP sẽ phục vụ (index.html), hình ảnh biểu trưng là một phần của trang web (duvel.png) và tệp kiểu hoặc CSS xếp tầng (style.css).

Để lập trình robot:

  • Kết nối bộ chuyển đổi USB-TTL như được hiển thị trong sơ đồ,
  • Tệp -> Mở -> chuyển đến thư mục có DuvelBot.ino.
  • Thay đổi thông tin đăng nhập mạng của bạn trong bản phác thảo:

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

  • Công cụ -> Bảng -> "AI-Thinker ESP-32 CAM" và chọn cổng nối tiếp thích hợp cho máy tính của bạn (Công cụ -> Cổng -> một cái gì đó như / dev / ttyUSB0 hoặc COM4),
  • Mở màn hình nối tiếp trong Arduino IDE, Trong khi nhấn nút PROG (kéo IO0 xuống thấp), bật rô-bốt,
  • Kiểm tra trên màn hình nối tiếp xem ESP32 đã sẵn sàng để tải xuống chưa,
  • Đóng màn hình nối tiếp (nếu không quá trình tải lên SPIFFS không thành công),
  • Công cụ -> "Tải lên dữ liệu phác thảo ESP32" và đợi nó hoàn tất,
  • Tắt và bật lại, giữ nút PROG để quay lại chế độ lập trình,
  • Nhấn vào mũi tên "Tải lên" để lập trình bản phác thảo và đợi nó hoàn thành,
  • Mở màn hình nối tiếp và đặt lại ESP32 bằng cách tắt / bật,
  • Khi nó đã khởi động, hãy ghi lại địa chỉ ip (chẳng hạn như 192.168.0.121) và ngắt kết nối robot khỏi bộ chuyển đổi USB-TTL,
  • Mở trình duyệt tại địa chỉ ip này. Bạn sẽ thấy giao diện như trong hình.
  • Tùy chọn: đặt địa chỉ mac của ESP32 thành địa chỉ ip cố định trong bộ định tuyến của bạn (tùy thuộc vào cách thực hiện của bộ định tuyến).

Đó là nó! Đọc tiếp nếu bạn muốn biết nó hoạt động như thế nào…

Bước 3: Cách thức hoạt động

Bây giờ chúng ta đến với phần thú vị: tất cả hoạt động cùng nhau như thế nào?

Tôi sẽ cố gắng giải thích nó từng bước… từng… từng bước nhưng xin lưu ý Kajnjaps không phải là chuyên gia lập trình web. Trên thực tế, học một chút lập trình web là tiền đề để xây dựng DuvelBot. Nếu tôi mắc lỗi rõ ràng, xin vui lòng để lại bình luận!

Được rồi, sau khi ESP32 được bật, như thường lệ trong quá trình thiết lập, nó sẽ khởi tạo các GPIO, liên kết chúng với bộ định thời PWM để điều khiển động cơ và đèn LED. Xem ở đây để biết thêm về điều khiển động cơ, nó khá chuẩn.

Sau đó, máy ảnh được cấu hình. Tôi cố tình giữ độ phân giải khá thấp (VGA hoặc 640x480) để tránh phản ứng chậm chạp. Lưu ý rằng bo mạch AI-Thinker ESP32-CAM có một chip ram nối tiếp (PSRAM) mà nó sử dụng để lưu trữ các khung hình máy ảnh có độ phân giải lớn hơn:

if (psramFound ()) {Serial.println ("Đã tìm thấy PSRAM."); config.frame_size = FRAMESIZE_VGA; config.jpg_quality = 12; config.fb_count = 2; // số bộ đệm khung xem: https://github.com/espressif/esp32-camera} else {Serial.println ("không tìm thấy PSRAM."); config.frame_size = FRAMESIZE_QVGA; config.jpg_quality = 12; config.fb_count = 1; }

Sau đó, hệ thống tệp flash ngoại vi nối tiếp (SPIFFS) được khởi tạo:

// khởi tạo SPIFFS if (! SPIFFS.begin (true)) {Serial.println ("Đã xảy ra lỗi khi gắn SPIFFS!"); trở lại; }

SPIFFS hoạt động giống như một hệ thống tệp nhỏ trên ESP32. Ở đây, nó được sử dụng để lưu trữ ba tệp: chính trang web index.html, một tệp định kiểu xếp tầng style.css và một biểu trưng hình ảnh-p.webp

Tiếp theo, ESP32 kết nối với bộ định tuyến của bạn (đừng quên đặt thông tin đăng nhập của bạn trước khi tải lên):

// thay đổi thông tin đăng nhập của bộ định tuyến của bạn hereconst char * ssid = "yourNetworkSSIDHere"; const char * password = "yourPasswordHere"; … // kết nối với WiFi Serial.print ("Đang kết nối với WiFi"); WiFi.begin (ssid, mật khẩu); while (WiFi.status ()! = WL_CONNECTED) {Serial.print ('.'); chậm trễ (500); } // hiện đã kết nối với bộ định tuyến: ESP32 hiện có địa chỉ ip

Để thực sự làm điều gì đó hữu ích, chúng tôi bắt đầu một máy chủ web không đồng bộ:

// tạo một đối tượng AsyncWebServer trên máy chủ port 80AsyncWebServer (80); … Server.begin (); // bắt đầu lắng nghe các kết nối

Bây giờ, nếu bạn nhập địa chỉ ip đã được bộ định tuyến gán cho ESP32 vào thanh địa chỉ của trình duyệt, ESP32 sẽ nhận được một yêu cầu. Điều này có nghĩa là nó sẽ phản hồi với khách hàng (bạn hoặc trình duyệt của bạn) bằng cách cung cấp cho nó một cái gì đó, ví dụ như một trang web.

ESP32 biết cách phản hồi, vì trong quá trình thiết lập, các phản hồi cho tất cả các yêu cầu được phép có thể đã được đăng ký bằng cách sử dụng server.on (). Ví dụ: trang web chính hoặc chỉ mục (/) được xử lý như thế này:

server.on ("/", HTTP_GET, (AsyncWebServerRequest * request) {Serial.println ("/ request đã nhận được!"); request-> send (SPIFFS, "/index.html", String (), false, bộ xử lý);});

Vì vậy, nếu máy khách kết nối, ESP32 sẽ phản hồi bằng cách gửi tệp index.html từ hệ thống tệp SPIFFS. Bộ xử lý tham số là tên của một hàm xử lý trước html và thay thế bất kỳ thẻ đặc biệt nào:

// Thay thế các trình giữ chỗ trong html như% DATA% // bằng các biến bạn muốn hiển thị //

Dữ liệu:% DATA%

Bộ xử lý chuỗi (const String & var) {if (var == "DATA") {//Serial.println("in processor! "); return String (dutyCycleNow); } return String ();}

Bây giờ, hãy ngắt chính trang web index.html. Nói chung luôn có ba phần:

  1. mã html: những phần tử nào sẽ được hiển thị (nút / văn bản / thanh trượt / hình ảnh, v.v.),
  2. mã kiểu, trong một tệp.css riêng biệt hoặc trong một phần…: các phần tử sẽ trông như thế nào,
  3. javascript a… section: cách hoạt động của trang web.

Sau khi index.html tải vào trình duyệt (biết nó là html vì dòng DOCTYPE), nó sẽ chạy vào dòng này:

Đó là một yêu cầu cho một trang định kiểu css. Vị trí của trang tính này được đưa ra trong href = "…". Vì vậy, trình duyệt của bạn làm gì? Đúng vậy, nó khởi chạy một yêu cầu khác tới máy chủ, lần này là style.css. Máy chủ nắm bắt yêu cầu này, vì nó đã được đăng ký:

server.on ("/ style.css", HTTP_GET, (AsyncWebServerRequest * request) {Serial.println ("css request đã nhận"); request-> send (SPIFFS, "/style.css", "text / css ");});

Gọn gàng hả? Thật ngẫu nhiên, nó có thể là href = "/ some / file / on / the / other / side / of / the / moon", đối với tất cả những gì trình duyệt của bạn quan tâm. Nó sẽ đi lấy tệp đó một cách vui vẻ. Tôi sẽ không giải thích về bảng định kiểu vì nó chỉ kiểm soát sự xuất hiện nên nó không thực sự thú vị ở đây, nhưng nếu bạn muốn tìm hiểu thêm, hãy xem hướng dẫn này.

Logo DuvelBot xuất hiện như thế nào? Trong index.html, chúng tôi có:

mà ESP32 phản hồi với:

server.on ("/ duvel", HTTP_GET, (AsyncWebServerRequest * request) {Serial.println ("đã nhận được yêu cầu logo duvel!"); request-> send (SPIFFS, "/duvel.png", "image / png ");});

..một tệp SPIFFS khác, lần này là một hình ảnh hoàn chỉnh, như được chỉ ra bởi "image / png" trong phản hồi.

Bây giờ chúng ta đến với phần thực sự thú vị: mã cho các nút. Hãy tập trung vào nút FORWARD:

PHÍA TRƯỚC

Tên class = "…" chỉ là tên để liên kết nó với biểu định kiểu để tùy chỉnh kích thước, màu sắc, v.v. Các phần quan trọng là onmousedown = "toggleCheckbox ('forward')" và onmouseup = "toggleCheckbox ('stop') ". Những điều này tạo thành các hành động của nút (tương tự đối với ontouchstart / ontouchend nhưng đối với màn hình cảm ứng / điện thoại). Tại đây, hành động nút gọi một hàm toggleCheckbox (x) trong phần javascript:

function toggleCheckbox (x) {var xhr = new XMLHttpRequest (); xhr.open ("GET", "/" + x, true); xhr.send (); // cũng có thể làm điều gì đó với phản hồi khi đã sẵn sàng, nhưng chúng tôi thì không}

Vì vậy, nhấn nút chuyển tiếp, ngay lập tức kết quả là toggleCheckbox ('chuyển tiếp') được gọi. Sau đó, hàm này khởi chạy một XMLHttpRequest "GET", của vị trí "/ forward", hoạt động giống như khi bạn nhập 192.168.0.121/ionary vào thanh địa chỉ trình duyệt của mình. Khi yêu cầu này đến ESP32, nó sẽ được xử lý bởi:

server.on ("/ forward", HTTP_GET, (AsyncWebServerRequest * request) {Serial.println ("đã nhận / chuyển tiếp"); actionNow = FORWARD; yêu cầu-> gửi (200, "văn bản / đồng bằng", "OK chuyển tiếp. ");});

Bây giờ ESP32 chỉ trả lời bằng một văn bản "OK chuyển tiếp". Lưu ý rằng toggleCheckBox () không thực hiện bất kỳ điều gì với (hoặc chờ trên) phản hồi này, tuy nhiên, nó có thể như được hiển thị sau trong mã camera.

Bản thân trong quá trình phản hồi này, chương trình chỉ đặt một biến actionNow = FORWARD, làm phản hồi khi nhấn nút. Bây giờ trong mainloop của chương trình, biến này được theo dõi với mục tiêu tăng / giảm PWM của động cơ. Logic là: miễn là chúng ta có một hành động không DỪNG, hãy tăng tốc động cơ theo hướng đó cho đến khi đạt đến một số nhất định (dutyCycleMax). Sau đó, duy trì tốc độ đó, miễn là actionNow không thay đổi:

void loop () {currentMillis = millis (); if (currentMillis - beforeMillis> = dutyCycleStepDelay) {// lưu lần cuối cùng bạn thực hiện vòng lặp beforeMillis = currentMillis; // mainloop chịu trách nhiệm tăng / giảm động cơ if (actionNow! = beforeAction) {// dốc xuống, sau đó dừng, sau đó thay đổi hành động và tăng lên dutyCycleNow = dutyCycleNow-dutyCycleStep; if (dutyCycleNow <= 0) {// nếu sau khi dốc xuống dc là 0, đặt thành hướng mới, bắt đầu từ min dutycycle setDir (actionNow); beforeAction = actionNow; dutyCycleNow = dutyCycleMin; }} else // actionNow == beforeAction tăng tốc, ngoại trừ khi hướng là STOP {if (actionNow! = STOP) {dutyCycleNow = dutyCycleNow + dutyCycleStep; if (dutyCycleNow> dutyCycleMax) dutyCycleNow = dutyCycleMax; } else dutyCycleNow = 0; } ledcWrite (pwmChannel, dutyCycleNow); // điều chỉnh vòng tua động cơ}}

Điều này từ từ làm tăng tốc độ của động cơ, thay vì chỉ phóng hết tốc độ và làm đổ Duvel quý giá. Một cải tiến rõ ràng sẽ là chuyển mã này sang một quy trình ngắt hẹn giờ, nhưng nó vẫn hoạt động như vậy.

Bây giờ nếu chúng tôi nhả nút chuyển tiếp, trình duyệt của bạn sẽ gọi toggleCheckbox ('dừng'), dẫn đến yêu cầu GET / dừng. ESP32 đặt actionNow thành STOP (và phản hồi bằng "OK stop."), Điều này mở ra mainloop để quay động cơ.

Điều gì về đèn LED? Cơ chế tương tự, nhưng bây giờ chúng ta có một thanh trượt:

Trong javascript, cài đặt của thanh trượt được giám sát, sao cho mỗi lần thay đổi sẽ xảy ra lệnh gọi lấy "/ LED / xxx", trong đó xxx là giá trị độ sáng mà đèn LED phải được đặt tại:

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; }

Lưu ý rằng chúng tôi đã sử dụng document.getElementByID ('slide') để lấy chính đối tượng slider, được khai báo bằng và giá trị được xuất cho một phần tử văn bản với mỗi thay đổi.

Trình xử lý trong bản phác thảo bắt tất cả các yêu cầu về độ sáng bằng cách sử dụng "/ LED / *" trong đăng ký trình xử lý. Sau đó, phần cuối cùng (một số) được tách ra và chuyển thành int:

server.on ("/ LED / *", HTTP_GET, (AsyncWebServerRequest * request) {Serial.println ("đã nhận được yêu cầu đã dẫn!"); setLedBrightness ((request-> url ()). substring (5).toInt ()); request-> send (200, "text / pure", "OK Leds.");});

Tương tự như mô tả ở trên, các nút radio điều khiển các biến đặt giá trị mặc định của PWM, để DuvelBot có thể lái xe từ từ đến chỗ bạn với bia, cẩn thận để không làm đổ vàng lỏng đó và nhanh chóng quay trở lại bếp để lấy thêm một ít bia nữa.

… Vậy làm cách nào để hình ảnh máy ảnh được cập nhật mà bạn không cần phải làm mới trang? Để làm được điều đó, chúng tôi sử dụng một kỹ thuật được gọi là AJAX (JavaScript và XML không đồng bộ). Vấn đề là thông thường kết nối máy khách-máy chủ tuân theo một quy trình cố định: máy khách (trình duyệt) đưa ra yêu cầu, máy chủ (ESP32) phản hồi, trường hợp đóng. Xong. Không có gì xảy ra nữa. Giá như bằng cách nào đó, chúng tôi có thể lừa trình duyệt thường xuyên yêu cầu cập nhật từ ESP32… và đó chính xác là những gì chúng tôi sẽ làm với đoạn javascript này:

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) {// xem: 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); // tạo một đối tượng từ blob document.querySelector ("# camimage"). src = imageUrl; urlCreator.revokeObjectURL (imageurl)}}; xhttp.send ();}, 250);

setInterval lấy tham số là một hàm và thực thi nó thường xuyên (ở đây là một lần mỗi 250ms dẫn đến 4 khung hình / giây). Hàm được thực thi tạo một yêu cầu cho một "đốm màu" nhị phân tại địa chỉ / CAMERA. Điều này được xử lý bởi ESP32-CAM trong bản phác thảo như (từ Randomnerdtutorials):

server.on ("/ CAMERA", HTTP_GET, (AsyncWebServerRequest * request) {Serial.println ("đã nhận được yêu cầu camera!"); camera_fb_t * fb = NULL; // esp_err_t res = ESP_OK; size_t _jpg_buf_len = 0; uint8_t * _jpg_buf = NULL; // chụp khung fb = esp_camera_fb_get (); if (! fb) {Serial.println ("Không thể lấy khung đệm"); return;} if (fb-> format! = PIXFORMAT_JPEG) / / đã ở định dạng này từ config {bool jpeg_converted = frame2jpg (fb, 80, & _jpg_buf, & _jpg_buf_len); esp_camera_fb_return (fb); fb = NULL; if (! jpeg_converted) {Serial.println ("Không nén được JPEG"); return; }} else {_jpg_buf_len = fb-> len; _jpg_buf = fb-> buf;} //Serial.println(_jpg_buf_len); // gửi yêu cầu hình ảnh đã định dạng-> send_P (200, "image / jpg", _jpg_buf, _jpg_buf_len); // dọn dẹp if (fb) {esp_camera_fb_return (fb); fb = NULL; _jpg_buf = NULL;} else if (_jpg_buf) {free (_jpg_buf); _jpg_buf = NULL;}});

Các phần quan trọng là lấy khung fb = esp_camera_fb_get () chuyển nó thành-j.webp

Sau đó, hàm javascript sẽ đợi hình ảnh này đến. Sau đó, chỉ mất một chút công việc để chuyển đổi "blob" đã nhận thành một url có thể được sử dụng làm nguồn để cập nhật hình ảnh trong trang html.

phew, chúng tôi đã hoàn thành!

Bước 4: Ý tưởng & Thức ăn thừa

Ý tưởng & Đồ ăn thừa
Ý tưởng & Đồ ăn thừa

Mục tiêu của dự án này đối với tôi là học lập trình web vừa đủ để giao diện phần cứng với web. Có thể có một số phần mở rộng cho dự án này. Dưới đây là một vài ý tưởng:

  • Triển khai phát trực tuyến camera 'thực' như được giải thích ở đây và ở đây và di chuyển nó đến máy chủ thứ hai như được giải thích ở đây trên cùng một ESP32, nhưng trên lõi CPU khác, sau đó nhập dòng camera vào html được cung cấp bởi máy chủ thứ nhất bằng cách sử dụng…. Điều này sẽ dẫn đến việc cập nhật máy ảnh nhanh hơn.
  • Sử dụng chế độ điểm truy cập (AP) để rô bốt độc lập hơn như được giải thích ở đây.
  • Mở rộng với khả năng đo điện áp pin, khả năng ngủ sâu, v.v. Điều này hơi khó khăn vào lúc này vì AI-Thinker ESP32-CAM không có nhiều GPIO; cần mở rộng qua uart và ví dụ như một arduino nô lệ.
  • Chuyển đổi thành rô bốt tìm mèo thỉnh thoảng đuổi mèo ra bằng cách nhấn một nút lớn, truyền phát hàng tấn bức ảnh mèo đẹp trong ngày…

Hãy bình luận nếu bạn thích hoặc có câu hỏi và cảm ơn vì đã đọc!

Đề xuất: