Ứng dụng thư viện bất đồng bộ để điều khiển bất đồng bộ nhiều (hàng chục) servo - Hư cấu chăng?

Mô tả dự án: 

Cũng đã khá lâu kể từ lúc mình xuất bản thư viện xử lý bất đồng bộ với Arduino. Tuy nhiên, mình vẫn chưa có nhiều ví dụ để thực sự kêu gọi các bạn sử dụng thư viện này trong dự án, hôm nay, sau khi được trao đổi với nhiều bạn, mình thấy vấn đề điều khiển nhiều servo có thể ứng dụng thư viện của mình vào một cách dễ dàng. Nên mình sẽ viết một bài ví dụ để hướng dẫn các bạn điều khiển rất nhiều Servo với thư viện của mình.

Đặt vấn đề

Bài toán đặt ra

Bạn có 3 servo (ở đây có thể mở rộng lên rất nhiều, phụ thuộc vào số chân tín hiệu), bạn muốn điều khiển 3 servo này đến 3 vị trí khác nhau, sao cho cả 3 cùng đến đích cùng một lúc!

Hướng giải quyết

Để di chuyển đến đích, mỗi servo sẽ cần một thời gian nhất định. Thời gian tổng để cả 3 cùng về tới tích đó là thời gian chậm nhất để đưa cái servo có quảng đường di chuyển xa nhất về đến đích.

Mở rộng vấn đề, trong một khoảng thời gian t (mili giây), chúng ta phải đưa 3 servo về đến đích, sao cho chúng về đích cùng một lúc.

Ta chia khoảng thời gian t này thì nhiều đoạn (period) liên tục, mỗi đoạn, servo sẽ di chuyển một số delta bước.

Để làm được điều này, ta cần tính delta của từng servo trong mỗi đoạn (period), từ đó, ở mỗi period sẽ cho servo[i] di chuyển một bước là delta[i].

Vấn đề nảy sinh đó là, làm thế nào tính toán delta trong thời thực để servo di chuyển đúng vị trí của nó và tạo được hiệu ứng "mượt"?

Liên tưởng đến thư viện bất đồng bộ của mình

Đầu tiên, bạn cần phải hiểu, thư viện bất đồng bộ của mình hoạt động như thế nào?

Thư viện bất đồng bộ của mình, hướng đến việc tiếp cận mọi thứ thông qua các tiến trình. Nghĩa là? toàn bộ chương trình trong Arduino được phân bổ thành từng tiến trình với chu trình lặp đi lặp lại. Ví dụ: led 1 blink với chu kỳ 1000ms, led 2 blink với chu kỳ 1234ms, led 3 blink với chu kỳ 4321ms. Lúc đó, ta sẽ chia hiệu ứng từng led trở thành những tiến trình. Ví dụ: tiến trình led_1_blink, chu kỳ 1000ms; tiến trình led_2_blink, chu kỳ 1234ms; tiến trình led_3_blink, chu kỳ 4321ms. Cao cấp hơn, thì chỉ có 1 tiến trình được gọi 3 lần, blink với 3 lần cài đặt tiến trình riêng!

Thư viện Bất đồng bộ

Quay về bài toán của chúng ta, chúng ta sẽ xem từng servo sẽ là một tiến trình riêng biệt với từng chu kỳ riêng HOẶC một tiến trình duy nhất với chu kỳ là thời gian cho từng đoạn period. Nghĩa là sau thời gian period, mỗi servo sẽ di chuyển theo từng bước delta của chúng!

Ví dụ

Servo 1, 2, 3 đang ở tọa độ 0;

Ra lệnh: Servo 1, 2, 3 lần lượt tiến đến vị trí 100, 100, 20 trong thời gian 1000ms.

Xử lý: Ta cho rằng mỗi period là 10ms, nghĩa là cứ 10ms ta sẽ phải cập nhập tọa độ của Servo 1, 2, 3. Ta sẽ tính delta cho từng servo như sau:

Số lượng period = Thời gian / thời gian mỗi period

delta[i] = (tọa độ mới của servo[i] - tọa độ cũ của servo[i]) / số lượng period

Như vậy, ta chỉ cần ứng dụng vào là chạy được ngay devil

Nối mạch

Arduino Uno Servo 1 Servo 2 Servo 3
5V 5V 5V 5V
GND GND GND GND
2 Tín hiệu    
3   Tín hiệu  
4     Tín hiệu

 

Lập trình

Cái này, bạn nào rành lập trình là hiểu ngay, còn các bạn mới nghiên cứu thì hơi nặng! Nhớ xem kỹ hướng mình dẫn dắt ở trên nhé :). Mình có kết hợp với thư viện SerialCommand để dễ test. Để kiểm thử, các bạn dùng dòng lệnh SERVO <thời gian muốn đến đích> <Đích của servo thứ 1> <Đích của servo thứ 2> ... <Đích của servo thứ n>. Với n được sét ở biến SERVO_COUNT. Cùng thưởng ngoạn bạn nhé!

Lưu ý

DEFAULT_PERIOD_SERVO: thời gian mỗi period là bao nhiêu

SERVO_COUNT  số lượng servo

servoPin: chân nào của Arduino sẽ kết nối với Servo!

Demo

Mình sẽ cập nhập demo trong thời gian tới.

Youtube: 
Demo 3 servo
lên
21 thành viên đã đánh giá bài viết này hữu ích.
Các dự án được truyền cảm hứng

Xe điều khiển bằng tay game Dual Shock3 thông qua Bluetooth

Vừa bắt đầu với arduino được hơn 1 tuần, có tham khảo qua các nguồn từ "trung ương đến địa phương", nắm được 1 số kiến thức cơ bản nên mình bắt đầu thực hiện 1 sản phẩm để đúc kết kinh nghiệm. Trong số đó thì xe điều khiển là dễ nhất. Kết hợp với cái tay game ps3 nằm lăn lóc ở góc nhà. Thế là có 1 chiếc xe điều khiển từ xa. Bắt đầu nhé.

lên
17 thành viên đã đánh giá bài viết này hữu ích.

Làm xe điều khiển từ xa bằng Bluetooth - Điều khiển bằng Android với App Inventor

Mình rất thích điện tử nhưng không học về ngành điện tử. Rất may là có Adruino, rồi có cộng đồng Adruino Việt Nam, đặc biệt là sự nhiệt tình của tất cả các bạn trong cộng đồng, mình đã làm được 1 chiếc xe điều khiển từ xa. Cho con chơi là lí do phụ thôi, còn tìm hiểu, học tập là chính. Hôm nay chia sẻ cùng các bạn, cùng gửi lời cảm ơn đến tất cả các bạn trong cộng đồng. Có bạn thì giúp đỡ trực tiếp, có bạn thì viết bài, rồi có bạn thì bình luận, nêu câu hỏi. Tất cả đều có giá trị đối với mình.

Ngại viết bài nên mình đăng dưới dạng ảnh.

lên
26 thành viên đã đánh giá bài viết này hữu ích.
Các bài viết cùng tác giả

Bài 8: Dùng button (nút bấm) để điều khiển một đèn LED

Chúng ta đã tìm được cách để đọc được trạng thái của một button qua bài viết Bài 3: Xác định trạng thái của một nút nhấn (button) rồi, đúng không nào? Bây giờ, chúng ta sẽ dựa vào trạng thái của các button ấy để điều khiển các đèn LED. Thực chất, đây là một bài viết vô cùng đơn giản, bạn có thể bỏ qua nếu đã biết và xem bài tiếp theo!

 

lên
29 thành viên đã đánh giá bài viết này hữu ích.
Từ khóa: 

iNut platform là gì?

Nhắc tới dòng mạch iNut dùng để lập trình, cái đầu tiên mà người ta thường nói tới chính là dòng iNut Cảm biến – một trong các mạch cho việc lập trình IoT. Hiện dòng mạch này đã phát triển tới thế hệ thứ 2 (iNut Sensor R2). Bạn sẽ bắt đầu đến với nền tảng iNut Platform thông qua mạch này. Bạn có thể dùng firmware iNut cảm biến cũng được nhưng bạn nên dùng bo mạch iNut Sensor R2 vì nó rất gọn và tương thức với Arduino Uno và Arduino Mega.

lên
4 thành viên đã đánh giá bài viết này hữu ích.
Từ khóa: