Mục lục:
2025 Tác giả: John Day | [email protected]. Sửa đổi lần cuối: 2025-01-13 06:58
Giáng sinh vui vẻ! Bạn có muốn có một cây thông Noel có thể tương tác với bạn?
Bước 1: Những thứ được sử dụng trong dự án này
Các thành phần phần cứng
- Seeeduino V4.2
- Cơ sở Shield V2
- Grove - Cảm biến chuyển động PIR có thể điều chỉnh
- Grove - Cảm biến độ ồn
- Grove - WS2813 RGB LED Strip chống thấm nước - 60 LED / m - 1m
Ứng dụng phần mềm và dịch vụ trực tuyến
Arduino IDE
Bước 2: Kết nối phần cứng
Kết nối Cảm biến PIR, Cảm biến độ ồn và dải đèn LED với cổng D2, A0 và D6 của Base Shield riêng biệt. Cắm Base Shield vào Seeduino, tất cả đã hoàn tất.
Bước 3: Lập trình phần mềm
Các thư viện sau đây cần phải cài đặt trước khi lập trình, vui lòng tải xuống và nhập chúng vào IDE Arduino của bạn theo cách thủ công:
- Led_Strip
- MsTimer2
- Arduino_Vector
Để làm cho mã ngắn gọn hơn, chúng tôi đã đóng gói nó. Lớp CheerLight là lớp ứng dụng của dự án này.
ứng dụng lớp:: CheerLight
: public application:: interface:: IApplication {public: void setup (void); vòng lặp void (void); void setPIRSensorPin (uint8_t pin); void setLoudnessSensorPin (uint8_t pin); void MeasureSensors (vô hiệu); void changeAnimation (void * args); void changeSpeed (void * args); void changeColor (void * args); ứng dụng tĩnh:: CheerLight * getInstance (void); được bảo vệ: trình điều khiển:: LEDStrip _ledStrip; trình điều khiển:: PIRSensor _pirSensor; trình điều khiển:: LoudnessSensor _loudnessSensor; uint8_t _animation; phần mềm trung gian:: Delegate _detectedDelegate; phần mềm trung gian:: Delegate _absoluteLoudnessDelegate; middleware:: Delegate _relativeLoudnessDelegate; CheerLight (vô hiệu); ứng dụng tĩnh:: CheerLight _instance; };
Lớp CheerLight được thiết kế bởi Singleton Patterns, có nghĩa là chỉ có một thể hiện cho nó, bạn có thể gọi CheerLight:: getInstance () cho thể hiện đó. Nếu kết nối của Bộ cảm biến khác với Kết nối phần cứng, bạn có thể thay đổi chúng bằng cách gọi phương thức setPIRSensorPin () và setLoudnessSensorPin ().
Chúng tôi khuyến nghị gọi phương thức MeasureSensors () trong ngắt bộ định thời để làm cho các cảm biến được đo kịp thời, nhưng việc gọi các phương thức changeAnimation (), changeSpeed () hoặc changeColor () theo cách thủ công là không cần thiết. Họ sẽ được gọi thông qua Đại biểu khi các cảm biến đo.
Đại biểu là gì?
Như chúng ta đã biết, chúng ta có thể khai báo một con trỏ hàm và làm cho nó trỏ đến một hàm trong C:
void func1 (void);
void (* pFunc) (void) = func1;
và sử dụng nó để gọi hàm mà nó trỏ tới
pFunc ();
Nhưng có sự khác biệt trong C ++, nếu bạn cố gắng biên dịch mã sau:
lớp A {
public: void func1 (void); }; void (* pFunc) (void) = & A:: func1;
trình biên dịch sẽ báo lỗi chuyển đổi kiểu, đây là ví dụ phù hợp:
void (A:: * pFunc) (void) = & A:: func1;
Khi chúng tôi cố gắng sử dụng nó để gọi phương thức đó, lại xảy ra lỗi. Lý do cho lỗi đó là một đối tượng-phương thức phải được gọi bởi một đối tượng. Vì vậy, chúng tôi tạo một đối tượng để gọi nó:
A a;
a. * pFunc ();
Lần này không có vấn đề gì. Vì vậy, có lớp Đại biểu trong Delegate.h.
bản mẫu
class middleware:: Delegate: public middleware:: interface:: IDelegate {public: Delegate (T * object, void (T:: * method) (void *)); void gọi (void * args); được bảo vệ: T * _object; void (T:: * _ method) (void *); }; template inline middleware:: Delegate:: Delegate (T * object, void (T:: * method) (void *)): _object (object), _method (method) {} template inline void middleware:: Delegate:: invoke (void * args) {(_object -> * _ method) (args); }
Bởi vì lớp Đại biểu là một lớp mẫu, có nghĩa là Đại biểu khác với Đại biểu, làm thế nào để làm cho chúng được trỏ bởi con trỏ có cùng kiểu? Câu trả lời là giao diện, vì vậy có giao diện IDelegate trong IDelegate.h.
lớp trung gian:: interface:: IDelegate {
public: virtual void invoke (void * args) = 0; };
Trong lớp của Cảm biến PIR và Cảm biến độ ồn, có một biến có tên _delegates được sử dụng để lưu trữ con trỏ của các Đại biểu và có một phương thức tên là invokeAllDelegates () được sử dụng để gọi tất cả các Đại biểu trong _delegates, nó sẽ được gọi trong phương thức Measure ().
LƯU Ý: Các phương thức ủy nhiệm, chẳng hạn như changeAnimation (), changeSpeed () và changeColor () sẽ được gọi trong ngắt timer2, vì vậy KHÔNG sử dụng delay () hoặc hàm dựa trên ngắt khác trong nó.