Tạo một quy trình công nghiệp với các bước bằng Arduino

I. Giới thiệu

Như đã nói ở vấn đề trước Xử lý nhiều tiến trình cùng một lúc trên Arduino - Có thể hay không?, chúng ta có thể xử lý nhiều tiến trình trên Arduino theo cơ chế bất đồng bộ. Tuy nhiên, một vấn đề khá hay mà từ các bình luận ở bài viết đó, mình mới ngộ ra được, đó là làm thế nào để xây dựng một quy trình công việc thực sự trên một board mạch Arduino. Thiết nghĩ, điều đó, hoàn toàn có thể thực hiện được, và xin chia sẻ với mọi người qua bài viết này nhằm giúp tất cả chúng ta có một thư viện chuẩn để làm những công việc phức tạp hơn.

II. Cơ sở từ bài trước

Ở bài viết về xử lý "đa nhiệm" theo cơ chế bất đồng bộ của mình, chúng ta đã dùng lại thư viện Timer của anh Đại Huỳnh và viết lại thư viện WorkScheduler một tý theo cách của mình để dễ dàng thực hiện các công việc hơn. Nếu các bạn để ý một tý, với cách tiếp cận Timer như vậy, chúng ta hoàn toàn có thể viết một thư viện quản lý các tiến trình trong một chu trình. Ở đây, mình xin phép kế thừa thư viện Timer và viết thêm thư viện kCalendar với mẫu thiết kế hướng đối tương singleton nhằm thực hiện được mục tiêu đã nêu.

III. Cách sử dụng

1. Với người dùng phổ thông

Để đơn giản hóa với người dùng phổ thông, mình chỉ xin rút gọn các thông tin cần thiết để sử dụng được thư viện này.

Đầu tiên, mình xin thống nhất định nghia quy trình công việc mà bài viết này hướng đến là gì. 

Quy trình công việc mà thư viện này hướng đến như hình trên. Có nghĩa là từ một điểm bắt đầu, nó sẽ thực thi những tiến trình tiếp theo cho đến khi quay lại chính tiến trình thứ nhất. Nghĩa là, các tiến trình nối tiếp nhau mà không rẻ nhánh. 

Để sử dụng được thư viện này, người dùng cần lưu ý các vấn đề sau:

  • Luôn khởi tạo thư viện Timer trong hàm setup càng sớm càng tốt.

    • Timer::getInstance()->initialize();
  • Tiếp đó là khởi tạo thư viện kCalendar trong hàm setup, cũng càng sớm càng tốt
    • kCalendar::getInstance()->initialize();
  • Sau khi khởi tạo 2 thư viện trên, các bạn sẽ tuần tự thêm các task (process) trong toàn bộ quy trình vào, với ý nghĩa:
    • kCalendar::getInstance()->addJob(<tên hàm>, <vị trí thêm vào>);
  • Để bắt đầu tính giờ quy trình, tại cuối hàm setup, các bạn thêm dòng lệnh này vào để thư viện hoạt động chính xác. Vì có thể trong quá trình setup sẽ mất một lượng delta giây để các bộ trong chương trình của bạn khởi động xong.
    • kCalendar::getInstance()->startFirstJob();
  • Trong hàm loop, bạn chỉ việc thêm 3 lệnh này vào là xong. À trong hàm loop chỉ nên có 3 dòng lệnh này thôi nhé, vì sao? Vì chúng ta đã muốn Arduino viết một chương trình để làm một quy trình công việc, như vậy thì nó chỉ có duy nhất 1 quy trình đó, mà thư viện của chúng ta sẽ đảm nhận vấn đề đó, thành ra, bạn không cần thiết và cũng không nên thêm code vào đó, mà hãy viết những task cho quy trình.
    • Timer::getInstance()->update();
    • kCalendar::getInstance()->update();
    • Timer::getInstance()->resetTick();

Các bạn có thể xem chương trình sau để dễ dàng nắm bắt nhé. (Có nút Download ở bên góc trên phải đó nhé laugh)

Serial monitor cho đủ bộ 

Trong code trên, mình có một quy trình công việc như sau:

  1. Chạy job1 ở thời điểm 0
  2. Chạy job2 ở thời điểm 1000 ms sau khi kết thúc job1
  3. Cho delay 2000ms trước khi thực hiện lại job1

2. Với lập trình viên

Mình dùng struct kJob để lưu trữ thông tin về một tiến trình

struct kJob {
	void (*func)();
	unsigned long atTime;
};

Trong đó bao gồm 2 thông tin là địa chỉ hàm sẽ được gọi và thời điểm bắt đầu của hắn trong quy trình.

Để tiết kiệm thời gian kiểm tra process tiếp theo, mình có dùng một tham số trong thư viện kCalendar là m_lastCheckedJobId để lưu lại process cuối cùng mà nó được xử lý. Từ đó kiểm tra những process tiếp theo nếu nó thỏa mãn thì thực hiện, không thì dừng ngay lại. Rồi lần loop tiếp theo sẽ kiểm tra lại :D. Mình dùng mẫu singleton để thiết kế nên cũng không quá phức tạp, các bạn xem là hiểu ngay. Hiện tại, trong thư viện này còn những vấn đề như là: quy trình rẻ nhánh, số lần lặp lại của quy trình,... mong các bạn góp ý và cập nhập để thư viện hoàn thiện hơn nữa nhé.

IV. Kết luận

Thư viện rất đơn giản và dễ sử dụng với người dùng phổ thông, nhưng thiết nghĩ, nó vẫn còn nhiều vấn đề mà lúc viết mình chưa nghĩ ra, mong các bạn khi dùng thực tế có những phản hồi để mình cập nhập lại. Điều đó sẽ rất có ý nghĩa với cộng đồng Việt Nam đấy heart!

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

Bộ điều khiển PID - ứng dụng phần 2 - xe dò line dùng thuật toán PID

Tiép nối bài viết về xe dò line cảm ơn Đỗ Hữu Toàn đã viết hộ mình phần 4. hôm nay mình sẽ làm cho chiếc xe dò line đi mượt và có hồn hơn 

lên
34 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 2: Cách làm đèn LED nhấp nháy theo yêu cầu

Hôm nay, chúng ta sẽ tìm hiểu cách để điều khiển một con đèn led nhấp nháy. Nếu bạn muốn điều khiển nhiều con LED hơn, đừng lo, hãy xem bài forarray, từ đó hãy sáng tạo để làm điều mình muốn nhé smiley!

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

LED_BUILTIN

Hầu hết các mạch Arduino đều có một pin kết nối với một on-board LED (led nằm trên mạch) nối tiếp với một điện trở. LED_BUILTIN là một hằng số thay thế cho việc tuyên bố một biến có giá trị điều khiển on-board LED. Hầu hết trên các mạch Arduino, chúng có giá trị là 13

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