Dạo gần đây tôi nảy ra ý tưởng làm 1 project IoT Node.js: tạo 1 xe thám hiểm để nghịch ngợm bằng LEGO và Bluetooth. Do đó tôi đã làm 1 cái xe kỹ thuật nhỏ, rồi gắn thêm 1 cái camera và bắt đầu dựng sản phẩm cho ý tưởng của mình.

Sản phẩm sẽ là giải pháp để điều khiển phương tiện di chuyển từ trình duyệt

Trong bài viết này, tôi sẽ hướng dẫn bạn các bước để bạn có thể tự tay build sản phẩm của riêng bạn.

Tham khảo các khóa học lập trình online, onlab, và thực tập lập trình tại TechMaster

Cần những gì cho project này?

1. Một phương tiện di chuyển kỹ thuật bằng LEGO với pin và động cơ

Bạn có thể lựa chọn thoải mái. Tôi có 1 con Volvo L350F (42030), tuy nhiên hiện giờ tôi lại nghĩ cái ổn nhất lại là Tracked Racer (42065). Nếu bạn quyết định tự build 1 cái, hãy nhớ rằng bạn cần phải có hộp pin và ít nhất 2 động cơ để di chuyển và quay.

2. SBrick

SBrick sẽ thay thế cho hệ thống điều khiển từ xa bằng hồng ngoại với giao thức Bluetooth Low Energy để gia tăng phạm vi sử dụng và dùng được xuyên qua tường. Nó hoàn toàn tương thích với các động cơ LEGO kỹ thuật và hộp pin.

3. Raspberry Pi

Nó sẽ đảm nhiệm chức năng của 1 server và điều khiển phương tiện. Tôi đề nghị các bạn hãy sử dụng Pi3, vì theo kinh nghiệm của tôi Pi2 khá chậm, cài đặt Bluetooth USB stick khá khổ.

4. Điện thoại/máy ảnh với wifi

Tôi sử dụng 1 cái Android cũ cho mục đích này. Không may lắm vì tôi chả tìm được thiết bị nào hỗ trợ video streaming, băng thông Bluetooth thì quá chậm. Do đo wifi là phương án khả dĩ nhất.

5. Thật nhiều pin

6. Máy tính hỗ trợ Bluetooth LE

Nó sẽ giúp việc test nhanh hơn rất nhiều. Cái Thinkpad cổ đại của tôi chỉ hỗ trợ Bluetooth 2.0, do đó tôi đã mua 1 cái LogiLink BT0037 - khá hợp với SBrick.

Bắt tay vào build thôi nào!

Trong lần thử đầu tiên, bạn có thể build bất cứ cái gì, chỉ cần sử dụng SBrick, hãy thiết lập ứng dụng mặc định trên điện thoại và nghịch nó 1 chút.

Bạn sẽ học kiến thức: các kênh điều khiển động cơ nào, có cần đổi chiều không,...

Hiểu về Bluetooth LE và các hàm SBrick

Bluetooth LE đã xuất hiện từ phiên bản 4.0 trở đi, nó sử dụng ít năng lượng hơn Bluetooth truyền thống. Nói ngắn gọn, nó là 1 kiến trúc client-server, thiết bj BLE (server) sẽ phát dữ liệu cho client (notebook, raspberry pi, điện thoại,...) kết nối.

Client sẽ chọn 1 service và 1 characteristic (có thể xem nó như 1 API endpoint), nơi nó đọc và ghi dữ liệu. Server cũng sẽ gửi các thông báo đến client.

Nếu bạn muốn tìm hiểu thêm vấn đề này, đây là 1 bài viết để bắt đầu.

Thiết bị sẽ có 1 số service:

  • Generic GAP
  • Thông tin thiết bị
  • Service OTA để cập nhật firmware
  • Service điều khiển từ xa

Tôi đang cần tìm 1 service điều khiển từ xa có 2 đặc điểm:

  • Quick drive: cho phép điều khiển từ xa với packet dữ liệu nhỏ. Giới hạn chức năng.
  • Các câu lệnh điều khiển từ xa: cho phép toàn quyền điều khiển.

Trong project này tôi sử dụng 1 full package.

Sau khi học về giao thức, bạn có thể thấy rằng có hơn 40 câu lệnh, 1 số để điều khiển các kênh drive, một số khác để thiết lập thời gian giới hạn, tên thiết bị, suất điện động pin, nhiệt độ đơn vị,...

SBrick cũng có các tính năng bảo mật, tuy nhiên chúng không tương thích với ứng dụng di động. Tuy nhiên nếu bạn muốn, bạn vẫn có thể sử dụng những tính năng đó. Có 2 loại user, owner và guest, cả 2 đều có password. Trong trường hợp bạn không cài pass, bất cứ ai kết nối với SBrick đều là owner.

Một số câu lệnh chỉ có owner mới sử dụng được, bạn cũng chỉ có thể cài pass cho guest sau khi bạn cài owner pass. Nếu bạn cố chạy 1 câu lệnh không trong phạm vi quyền của bạn, SBrick sẽ ngắt kết nối với Bluetooth client.

Bluetooth trong Node.js

Trong thế giới Node, có 1 package xử lý BLE (Bluetooth Low Energy) là noble.

Package này có thể giúp quét các vùng ngoại vi, nhận diện các service, đặc tính, xử lý các thông báo. Viết 1 đặc tính thì khá ngắn gọn, chỉ cần sử dụng hàm write(). Tuy nhiên đọc thì không đơn giản: bạn cần gọi hàm write() cùng với "câu lệnh read" bất đồng bộ. Sau khi thành công, gọi hàm read(). Cuối cùng trong hàm callback bạn có thể truy cập kết quả.

Để cài package này, bạn cần thiết lập Bluetooth đúng cách. Tôi sẽ không đề cập chi tiết; bạn có thể tham khảo những link sau nếu có vấn đề:

Sau khi cài Bluetooth và package noble, chạy câu lệnh sau để SBrick được nhận diện:

node node_modules/noble/examples/advertisement-discovery.js

Nếu thành công, xin chúc mừng. Bạn đã qua được phần khó khăn nhất rồi đấy.

sbrick-protocol

Dựa trên miêu tả giao thức SBrick, tôi sẽ thực thi các hàm và publish chúng như 1 npm package của chính tôi: sbrick-protocol

Các tính năng chính:

1. Nhận diện thiết bị Bluetooth

File SBrickAdvertisementData.js nhận nhiệm vụ này: parse dữ liệu thông báo Bluetooth và trả về 1 đối tượng với UUID, phiên bản phần cứng và phần mềm, status bảo mật, nếu là 1 SBrick. Báo lỗi với các trường hợp khác.

2. Xử lý kết nối, mất kết nối, xác thực

Dữ liệu thông báo chứa các thông tin, nếu thiết bị được bảo mật với password, login sẽ được thực hiện với password được cụ thể. Giao thức description sẽ không cụ thể cách mã hóa password để điền vào ô input.

Trong file SBrickPasswordGeneratorMD5.js, tôi sử dụng hash MD5. Bạn hoàn toàn có thể sử dụng cách khác.

3. Tạo 1 giao diện promise-base với các hàm SBrick

4. Chạy vòng lặp cho các câu lệnh điều khiển

Nó hơi giống kiểu game-loop. Điều này là cần thiết, vì ta sẽ không chạy bất cứ câu lệnh nào 1 khoảng thời gian sau khi kết nối, bộ kiểm soát timeout SBrick sẽ ngắt kết nối với thiết bị. Ý tưởng ở đây sẽ là thiết lập 1 hàng đợi các câu lệnh (promise-queue), và định kì thêm vào các câu lệnh điều hướng của 4 kênh nếu chúng rỗng (hầu hết là thế).

Theo cách đó, ta có thể phát 1 câu lệnh mà không phải chờ quá lâu để nó được thực thi. Kết quả tôi nhận được là khảng thời gian tạm ngừng ~ 200ms. Bạn có thể tùy chỉnh lại nếu nó quá nhanh hay quá chậm so với bạn.

5. Truy xuất dữ liệu ADC (analogue-to-digital)

Thiết bị sẽ chứa các cảm biến hiệu điện thế và cảm biến nhiệt, và nếu bạn muốn hiển thị các giá trị hiện thời, chúng ta sẽ cần tìm hiểu nó. Trong phiên bản giao thức trước, việc này hoàn toàn tự động với các thông báo Bluetooth. Tuy nhiên ở phiên bản 17, ta cần đọc dữ liệu thủ công. Tôi mong là các nhà cung cấp sẽ sửa lỗi này.

Nếu bạn đã sẵn sàng để test, hãy thử với code mẫu ở đây.

sbrick-controller

Việc thực thi giao thức đã làm việc, tuy nhiên không quá tiện trong các trường hợp bình thường. Do đó tôi đã tạo ra 1 client full tính năng, sbrick controller. Code ở đây.

Cốt lõi của giải pháp này chính là 1 server express, sử dụng sbrick-protocol cho các liên lạc SBrick và socket.io để điều khiển real-time từ trình duyệt.

Client bây giờ sẽ được bảo vệ bởi password, mặc định là admin/adminPass - bạn có thể thay đổi nó bằng các biến môi trường.

Sau khi kết nối với SBrick, bạn có thể thiết lập phím tắt cho các kênh, lúc này thiết lập sẽ được lưu lại ở server. Đường đồ thị màu đỏ biểu diễn nhiệt độ, đơn vị độ C, trong khi đường màu xanh biểu diễn suất điện động của pin.

Ok, bây giờ hãy gắn camera vào xe thám hiểm nào. Tôi sử dụng 1 chiếc android cũ có cài IP Webcam.

Hãy chú ý, bạn không thể nhìn được chiếc xe theo góc nhìn này, do đó hãy cẩn thận tránh va chạm làm hỏng xe hay camera. Hãy gắn chắc camera!

Từ kinh nghiệm của mình, tôi đề nghị các bạn hãy thêm 1 vài động cơ để quay và nghiêng camera.

Bây giờ hãy test để xem xe có thể đi xa đến đâu, ừ đó tùy chỉnh các vòng loop trong code,... Nếu bạn đủ liều, hãy khởi động server trên con Raspberry với 1 trình quản lý process node như pm2, mở port trên route của bạn và đăng nhập vào. 

Chú ý rằng ứng dụng không bảo mật. Do đó cẩn thận không đâm vào mấy cục đá hay con chó con mèo dọc đường nhé!

Chúc bạn vui vẻ với thế giới vật lý giao thoa tin học :)

Bài viết được dịch từ: https://community.risingstack.com/node-js-iot-project-home-explorer-rover-with-lego-sbrick-raspberry-pi/