Ngày nay khoa học công nghệ ngày càng phát triển, vi điều khiển AVRvàvi điều khiển PIC ngày càng thông dụng và hoàn thiện hơn, nhưng có thể nói sựxuất hiện của Arduino vàonăm 2005 tại It
TỔNGQUAN VỀHỆTHỐNG
Đặtvấn đề
Với sự tiến bộ của khoa học kỹ thuật, nhiều loại đồng hồ ra đời nhằm xác định thời gian một cách chính xác và rõ ràng hơn, nổi bật là đồng hồ cơ và đồng hồ số Đồng hồ số mang lại những tính năng vượt trội so với đồng hồ cơ và các loại đồng hồ cổ xưa ở các mặt như chi phí, độ chính xác và nhiều chức năng khác Do đó, khi so sánh các dòng đồng hồ, người tiêu dùng thường cân nhắc giữa kinh phí và hiệu suất để chọn loại phù hợp với nhu cầu sử dụng.
Lýdo chọn đềtài
Hiện nay trên thị trường chỉ có một số loại đồng hồ kim và đồng hồ số để xem giờ Thiết kế của các mẫu này nổi bật với LED nháy theo nhạc ngoài nhằm hỗ trợ người dùng theo dõi thời gian một cách trực quan; đồng thời đây là một sản phẩm gần gũi, có tính mới lạ, đẹp mắt và dễ dàng sử dụng.
Thiết bị hoạt động dựa trên vi điều khiển để xử lý dữ liệu, nhờ vậy có độ chính xác cao và giao tiếp trực tiếp với các module thông dụng thành một hệ thống đồng bộ Nhờ sự tích hợp này, thiết bị giúp bạn và các thành viên trong gia đình sắp xếp và quản lý thời gian hiệu quả hơn với độ tin cậy cao, từ đó nâng cao chất lượng cuộc sống và sự tiện nghi trong sinh hoạt hàng ngày.
Mục đích nghiêncứuđềtài
Chúng tôi thiết kế và thi công đồng hồ thời gian thực với độ chính xác cao, đảm bảo hiển thị thời gian đúng giờ Đồng hồ tích hợp đèn LED nháy theo nhạc, mang lại hiệu ứng thị giác sống động và cuốn hút Giao diện người dùng được thiết kế tiện lợi và đẹp mắt, giúp người dùng thao tác dễ dàng và trực quan.
Giảiphápthiếtkế
Hệ thống được thiết kế gồm 6 khối: Khối nguồn, khối thời gian, khối viđiềukhiển,khối hiểnthị, khối điềukhiển,khối cảm biếnâmthanh.
Hình 1: Sơ đồ khốiChứcnăng củacáckhối:
Khối xử lý trung tâm đóng vai trò não của hệ thống, tiếp nhận và xử lý tín hiệu từ khối thời gian thực và khối cảm biến âm thanh, từ đó hiển thị thông tin đã xử lý lên khối hiển thị Đồng thời, khối xử lý trung tâm nhận tín hiệu điều khiển để điều chỉnh trạng thái hoạt động của hệ thống.
- Khối hiển thị: Hiển thị các thông số thời gian như giờ, phút, giâyvà
Khối RTC (Real-Time Clock) thực chất là một chip thời gian thực, được sử dụng như một đồng hồ thời gian chuẩn cho hệ thống Nó có chức năng duy trì và cập nhật thời gian liên tục, kể cả khi nguồn cấp bị mất nhờ pin dự phòng Trong sơ đồ hệ thống, khối RTC đảm nhiệm chức năng cung cấp thời gian chính xác cho quá trình điều khiển và xử lý, từ đó đồng bộ hóa các tác vụ và nâng cao độ ổn định của hệ thống.
- Khối điều khiển: Sử dụng nút bấm.T h ự c h i ệ n c h ứ c n ă n g n h ậ p các dữ liệu đưa đến vi điều khiển và bao gồm thao tác thay đổihiểnthị.
- Khối cảm biến âm thanh: Cảm biến âm thanh có chức nặng nhậnbiếtđượcâm thanh giúpLEDnháy theođiệu nhạc.
CƠSỞLÝ THUYẾT
Tìm hiểu về hệđiều hành nhúng thờigianthựcFreeRTOS
Hệ điều hành thời gian thực (RTOS) là loại hệ điều hành dành cho hệ thống nhúng, được thiết kế nhằm tiết kiệm tài nguyên và đảm bảo độ tin cậy cao Do phần cứng của hệ thống nhúng thường có giới hạn về RAM và ROM, RTOS có phạm vi chức năng thu hẹp và được tùy biến cho từng ứng dụng nhằm đạt được hiệu suất và đáp ứng thời gian thực mong muốn Để tận dụng tối đa công suất của CPU, các nhà phát triển có thể viết các mã quan trọng trực tiếp bằng ngôn ngữ máy hoặc dùng ngôn ngữ portable như C để cân bằng giữa tốc độ, chi phí và khả năng bảo trì.
Trong số các hệ điều hành nhúng phổ biến hiện nay có QNX, PDOS, pSOS, VxWorks, Nucleus, ERCOS, EMERALDS và Windows CE Tuy nhiên, trong đồ án môn học chúng ta lại dùng FreeRTOS làm nền tảng thời gian thực FreeRTOS phù hợp cho nghiên cứu và học tập về các kỹ thuật và công nghệ điều hành nhúng thời gian thực, đồng thời cho phép phát triển mở rộng các thành phần của hệ điều hành bằng cách bổ sung mô-đun, trình điều khiển và chuyển đổi môi trường thực thi để đáp ứng các yêu cầu thực tiễn.
2.1.1 LịchsửpháttriểncủahệđiềuhànhnhúngthờigianthựcFreeRTOSFreeRTOS là lõi của hệ điều hành thời gian thực miễn phí Hệ điều hànhnày được Richard Barry công bố rộng rãi từ năm 2003, phát triển mạnh đến nayvà được cộng đồng mạng mã nguồn mở ủng hộ FreeRTOS có tính khả chuyển,mã nguồn mở, lõi có thể down miễn phí và nó có thể dùng cho các ứng dụngthươngmại.Nóphùhợpvớinhữnghệnhúngthờigianthựcnhỏ.Hầuhết các codeđượcviếtbằngngônngữCnênnócótínhphùhợpcaovớinhiềunềnkhácnhau. Ưu điểm của nó là dung lượng nhỏ và có thể chạy trên những nền mànhiều hệ không chạy được Có thể port cho nhiều kiến trúc vi điều khiển vànhững công cụ phát triển khác nhau Mỗi port chính thức bao gồm những ứngdụng ví dụ tiền cấu hình biểu hiện sự riêng biệt của lõi, kiến thức mới và hướngphát triển Những hỗ trợ miễn phí được cung cấp bởi cộng đồng mạng.
Hỗ trợthươngmạivới nhữngdịch vụ pháttriểnđầy đủcũngđược cungcấp
FreeRTOS được cấp giấy phép GPL (General Public License) với phiên bản đã chỉnh sửa và có thể được sử dụng trong các ứng dụng thương mại dưới giấy phép này Ngoài FreeRTOS còn có OpenRTOS và SafeRTOS; OpenRTOS là bản thương mại của FreeRTOS.org và không liên quan gì đến GPL SafeRTOS về cơ bản dựa trên FreeRTOS nhưng được phân tích, chứng minh bằng tài liệu và kiểm tra nghiêm ngặt theo chuẩn IEC 61508, và chuẩn IEC 61508 SIL3 được tạo ra và phát triển độc lập để hoàn thiện tài liệu cho SafeRTOS.
RTOS là một thành phần của hệ thống phần mềm thời gian thực, đảm nhiệm việc điều phối và quản lý các task trong chương trình Nó thực hiện lập lịch thực thi, phân mức ưu tiên cho từng task và xử lý các thông điệp, tín hiệu giữa các task nhằm nâng cao khả năng giao tiếp và đồng thời của hệ thống Nhờ cơ chế quản lý thời gian và ưu tiên, RTOS cho phép đáp ứng nhanh các sự kiện quan trọng, tối ưu hóa thời gian phản hồi và đảm bảo tính tin cậy cũng như hiệu suất của hệ thống thời gian thực.
RTOS khá phức tạp, nhưng có thể hiểu đơn giản là nó thực hiện việc xử lý các trạng thái máy (State Machine) Để giải quyết các bài toán có nhiều trạng thái máy, chúng ta thường dùng một vòng lặp vô hạn để liên tục quản lý và chuyển đổi giữa các trạng thái dựa trên sự kiện và điều kiện hệ thống Mô hình này giúp điều phối các tác vụ và hành vi của hệ thống thời gian thực một cách có tổ chức, tối ưu hóa phản hồi và hiệu suất Trong thực tế, câu lệnh vòng lặp như while(1) là khuôn mẫu phổ biến để duy trì trạng thái máy và đảm bảo hệ thống luôn sẵn sàng xử lý sự kiện mới.
{ case1://CodeforTask1; state=2; case2://CodeforTask2; state=3; case3://CodeforTask3; state=4; case 4: //Code for Task
Chương trình sẽ thực thi từ states 1 tới states 4 sau đó quay vòng lại. Bấtkìkhi nàostates thay đổi,chươngtrìnhsẽnhảy quaphụcvụ taskđó.
Nhược điểm của phương pháp này là tài nguyên được sử dụng chung, dẫn tới việc hạn chế hiệu suất do tài nguyên bị chia sẻ Tốc độ chuyển đổi trạng thái trở nên chậm khi phải hoàn thành từng tác vụ trước khi chuyển sang tác vụ khác, khiến hệ thống khó thích ứng với các thay đổi liên tục Khi có nhiều tác vụ đồng thời, việc kiểm soát và quản lý các tác vụ trở nên phức tạp, dễ xảy ra cạnh tranh tài nguyên và khó tối ưu hóa quá trình vận hành.
Hình2.1:Cách hoạtđộngcủaRTOSNhân Kernel sẽ điều phối sự hoạt động của các tác vụ (Task), mỗi task sẽcó một mức ưu tiên (prioritize) và thực thi theo chu kì cố định Nếu có sự tácđộng như ngắt, tín hiệu hoặc tin nhắn giữa các Task, Kernel sẽ điều phối chuyểntớiTasktươngứng với Codeđó.
Sự chuyển dịch giữa các Task rất linh động, độ trễ thấp mang lại độ tincậycaochochươngtrình.
Quản lý công việc: Ứng dụng được chia thành cácđ ơ n v ị c h ư ơ n g t r ì n h nhỏ gọi là các Task (tác vụ), có thể lập lịch và tuần tự được gọi là 'Chủ đề' hoặc'Nhiệm vụ' Điều này được thực hiện để đạt được tính đồng thời trong Ứng dụngthời gian thực Quản lý tác vụ bằng Kernel bao gồm Tạo tác vụ thời gian thực,kết thúc, thay đổi mức độ ưu tiên, v.v Tạo tác vụ liên quan đến việc tạo Khốiđiều khiển tác vụ (TCB) có thông tin về id tác vụ, mức độ ưu tiên, trạng thái tácvụ tức là nếu tác vụ đang ở (nhàn rỗi, đang chạy, sẵn sàng , đã kết thúc) trạngthái, v.v.
Trong hệ thống, lập lịch tác vụ ghi nhận trạng thái của từng tác vụ và xác định tác vụ có mức độ ưu tiên cao nhất để thực thi; tác vụ đang chạy bị tạm ngừng và bộ xử lý sẽ thực thi tác vụ ưu tiên cao hơn Đồng bộ hóa tác vụ đảm bảo thông tin được trao đổi an toàn giữa các tác vụ, ví dụ từ tác vụ sản xuất sang tác vụ tiêu thụ, đồng thời cho phép các tác vụ chia sẻ tài nguyên như bộ đệm và thiết bị I/O.
Quản lý bộ nhớ: Nó phân bổ bộ nhớ cho mỗi chương trình Có hai loạiQuảnlý Bộnhớ cho RTOS.Họ đang:quản lýngăn xếp hoặcquản lýđống.
Quản lý thời gian: Để lên lịch cho các tác vụ cần được thực hiện trongkhoảngthờigianxácđịnh,cầncóngắtđịnhkỳ.DođóphầncứngTimerđ ượclậptrìnhđể ngắtbộ xửlý Ngắtthời gianđượcgọilàSystemTick.
Xử lý ngắt là cơ chế phần cứng cho phép CPU nhận thông báo về các sự kiện không đồng bộ thông qua ngắt Quá trình này xác định trình xử lý ngắt phù hợp và kích hoạt dịch vụ ngắt (ISR), đồng thời quản lý việc tạo và xóa các dịch vụ ngắt để đảm bảo xử lý sự kiện nhanh chóng và hiệu quả.
Quản lý I/O thiết bị cung cấp khung thống nhất qua API (Giao diện lập trình ứng dụng), cho phép phần mềm giao tiếp với các thiết bị phần cứng một cách nhất quán Nó giúp truy cập trình điều khiển của thiết bị cụ thể và định vị, chọn đúng thiết bị phù hợp với yêu cầu I/O của ứng dụng, từ đó tối ưu hiệu suất và tăng tính tương thích khi làm việc với nhiều thiết bị khác nhau trong hệ thống.
Giới thiệu cácthiếtbị phần cứngsửdụng
Khi nhắc tới lập trình và nghiên cứu chế tạo bằng Arduino, người dùng thường bắt đầu với Arduino Uno, dòng sản phẩm phổ biến nhất và hiện nay đã ở thế hệ thứ ba (R3) Với người mới bắt đầu, nên ưu tiên nghiên cứu Arduino Uno R3 thay cho các dòng Arduino khác, vì Uno R3 dễ sử dụng, có cộng đồng hỗ trợ lớn và thiết kế thân thiện giúp người mới tiếp cận lĩnh vực lập trình và điện tử dễ dàng hơn.
Hình2.2:BoardArduino UnoArduino Uno là một bo mạch thiết kế với bộ xử lí trung tâm là vi điềukhiểnAVRAtmega328.Cấutạochính bao gồm cácthành phầnsau:
- CổngU S B : đ â y l à l o ạ i c ổ n g g i a o t i ế p đ ể t a u p l o a d c o d e t ừ P C l ê n v i điều khiển Đồng thời nó cũng là giao tiếp serial để truyền dữ liệu giữa vi điềukhiểnvà máytính.
Để cấp nguồn cho Arduino, ta có thể dùng nguồn từ cổng USB trên máy tính, nhưng không phải lúc nào cũng có thể cắm với máy tính được Lúc đó ta cần một nguồn ngoài với điện áp từ 9V đến 12V để Arduino vận hành ổn định.
- Có 14 chân vào/ra số đánh số thứ tự từ 0 đến 13, ngoài ra có một chânnốiđất (GND)và mộtchânđiệnáptham chiếu(AREF).
- ViđiềukhiểnAVR: đâylàbộxửlítrungtâmcủatoànbomạch.Với mỗi mẫu Arduino khác nhau thì con chip là khác nhau Ở con Arduino Uno nàythìsử dụng ATMega328.
- Chânvào/ra(I/O)số:14(6châncóthể chođầuraPWM)
Arduino UNO sử dụng 3 vi điều khiển thuộc họ 8-bit AVR là ATmega8, ATmega168 và ATmega328, với não xử lý cho các tác vụ như nhấp nháy LED, xử lý tín hiệu cho xe điều khiển từ xa và xây dựng trạm đo nhiệt độ - độ ẩm hiển thị lên màn hình LCD.
Thiết kế tiêu chuẩn của Arduino UNO sử dụng vi điều khiển ATmega328P với giá khoảng 90.000 đồng Tuy nhiên, nếu phần cứng của bạn không đòi hỏi cao hoặc túi tiền không cho phép, bạn có thể dùng các vi điều khiển khác có chức năng tương đương nhưng rẻ hơn như ATmega8 (bộ nhớ flash 8 KB) với giá khoảng 45.000 đồng hoặc ATmega168 (bộ nhớ flash 16 KB) với giá khoảng 65.000 đồng.
Arduino UNO có thể được cấp nguồn 5V thông qua cổng USB hoặc cấpnguồn ngoài với điện áp khuyên dùng là 7-12V DC vàgiới hạnl à 6 -
Để cấp nguồn cho Arduino UNO khi bạn không có nguồn từ cổng USB, dùng pin vuông 9V là phương án hợp lý; nhưng nếu cấp nguồn vượt quá ngưỡng giới hạn, bạn sẽ làm hỏng Arduino UNO.
- GND ( Ground ) : cực âm của nguồn điện cấp cho Arduino UNO Khi bạndùng các thiết bị sử dụng những nguồn điện riêng biệt thì những chân nàyphảiđượcnối với nhau
- 5V;cấpđiệnáp5Vđầu ra.Dòng tốiđachophépởchânnàylà500mA.
- 3.3V:cấpđiệnáp3.3Vđầura.Dòng tốiđacho phép ởchânnày là50mA.
- Vin ( Voltage Input ) : để cấp nguồn ngoài cho Arduino UNO , bạn nốicựcdươngcủanguồnvớichân nàyvàcựcâmcủa nguồnvớichân GND.
IOREF là chân tham chiếu điện áp hoạt động của vi điều khiển trên Arduino UNO và có thể đo được ở chân này Trên Arduino UNO, IOREF thường ở mức 5V, nhưng IOREF không phải là nguồn cấp điện Không nên lấy nguồn 5V từ IOREF để cấp nguồn cho shield hoặc thiết bị khác, vì chức năng của IOREF là tham chiếu điện áp chứ không cung cấp nguồn.
- RESET : việc nhấn nút Reset trên board để reset vi điều khiển tươngđươngvớiviệcchânRESETđượcnốivớiGNDqua1 điệntrở10K.
Vi điều khiển có 32KB bộ nhớ Flash để lưu trữ toàn bộ mã chương trình bạn viết Những đoạn mã và dữ liệu sẽ được lưu trực tiếp trong bộ nhớ Flash của vi điều khiển, giúp chương trình khởi động và chạy ổn định Trong số 32KB Flash này, có khoảng vài KB dành cho bootloader để hỗ trợ quá trình khởi động hệ thống Đừng lo lắng quá, bạn hiếm khi cần tới gần 20KB cho bootloader bởi bootloader thường chiếm một phần nhỏ của bộ nhớ Flash.
SRAM (Static Random Access Memory) là nơi lưu trữ giá trị của các biến được khai báo khi lập trình Bạn càng khai báo nhiều biến thì càng cần nhiều bộ nhớ RAM Tuy nhiên, RAM thực tế là bộ nhớ tạm thời và dữ liệu trên SRAM sẽ bị mất khi nguồn điện bị ngắt.
1KBchoEEPROM(ElectricallyErasebleProgrammableReadOnlyMemory ): dâygiống nhưmộtchiếcổ cứngmini –nơibạncóthểđọcvà ghidữ liệucủamìnhvàođâymàkhôngphảilobịmấtkhicúpđiệngiốngnhưdữliệutrênSR
Arduino UNO có 14 chân digital dùng để đọc hoặc xuất tín hiệu, hoạt động ở hai mức điện áp 0 V và 5 V với dòng tối đa mỗi chân là 40 mA Ở mỗi chân đều có các điện trở pull-up nội tại được tích hợp trong vi điều khiển ATmega328, mặc định các điện trở này không được kết nối.
- 2 chấn Serial : 0 ( RX ) và 1 ( TX ): dùng để gửi ( transmit -
TTL Serial cho phép gửi và nhận dữ liệu qua hai chân TX và RX trên Arduino Uno Việc này cho phép Arduino Uno giao tiếp với các thiết bị khác thông qua hai chân này và hình thành một kết nối Serial không dây, thường được mô tả là kết nối Serial không dây bằng Bluetooth Nếu bạn không cần giao tiếp Serial, bạn nên tránh dùng hai chân TX và RX để tiết kiệm tài nguyên và tránh xung đột giao tiếp.
Chân PWM trên Arduino gồm các chân 3, 5, 6, 9, 10 và 11 cho phép xuất xung PWM với độ phân giải 8 bit, với giá trị từ 0 đến 255 tương ứng với 0 V đến 5 V, thông qua hàm analogWrite() Nói cách khác, bạn có thể điều chỉnh điện áp ra ở các chân PWM này từ 0 V đến 5 V thay vì cố định ở 0 V hoặc 5 V như ở các chân khác.
- ChângiaotiếpSPI:10(SS),11(MOSI ),12(MISO)13( SGK ) Ngoài các chức năng thông thường , 4 chân này còndùng để truyền phát dữ liệu bằng giao thức SPI với các thiết bịkhác ,
- LED13trênArduinoUNOcó1đènledmàucam(kíhiệuchữL ) Khi bấm nút Reset , bạn sẽ thấy đèn này nhấp nháy để bảohiệu N ó đ ư ợ c n ố i v ớ i c h â n s ố 1 3 K h i c h â n n à y đ ư ợ c n g ư ờ i dùngsử dụng , LEDsẽsảng.
- Arduino UNO có 6 chân analog ( A0 A5 ) cung cấp độ phân giảitínhiệu10bit(0–210-1)đểđọcgiátrịđiệnáptrongkhoảng0v
Với chân AREF trên board, bạn có thể cấp điện áp tham chiếu cho các chân analog Ví dụ, khi cấp 2.5V vào chân AREF, các chân analog có thể đo được điện áp từ 0V đến 2.5V với độ phân giải 10 bit.
- Đặc biệt , Arduino UNO có 2 chân A4 ( SDA ) và A5 ( SCL ) hỗtrợgiaotiếpI2C/TWI với cácthiếtbị khác.
Ngắt (interrupt) là quá trình dừng chương trình chính để ưu tiên thực thi một chương trình khác, chương trình này được gọi là chương trình phục vụ ngắt (ISR – Interrupt Service Routine) Sau khi ISR thực thi xong, vi điều khiển quay lại tiếp tục công việc trước đó Trong các quá trình ngắt, ta phân biệt thành hai loại: ngắt cứng và ngắt mềm, tương ứng với ngắt do phần cứng kích hoạt và ngắt do phần mềm phát sinh, mỗi loại có đặc điểm riêng về nguồn kích hoạt và cách xử lý.
Ngắt cứng là một loại ngắt do các linh kiện điện tử tác động lên hệ thống và khác với ngắt mềm, vốn được khởi động bên trong máy tính Đối với Arduino, ngắt Timer chủ yếu dùng để xác định các khoảng thời gian cố định, phát ra xung ở tần số tùy chỉnh trên các chân đầu ra hoặc để kiểm tra dữ liệu truyền nối tiếp Tùy theo loại board Arduino mà số lượng Timer có thể khác nhau.
Arduino UNO có 3 Timer là Timer0, Timer1 và Timer2 Các Timer này đếm theo xung nhịp của Arduino, tức là tăng giá trị đếm dựa trên tần số hệ thống Khi bạn đặt giá trị so sánh cho một Timer, nó sẽ tiếp tục tăng cho tới khi đạt tới giá trị đã đặt và sẽ phát sinh một ngắt khi trùng với giá trị đó.
THIẾTKẾVÀ THICÔNGSẢNPHẨM
Thiết kếvàthicông phầncứng
Hình 3.1 cho thấy mô phỏng mạch trên Proteus và cách nối các module bằng cáp 7 màu Trong thực tế, chúng em dùng cáp 7 màu để kết nối các module với nhau, nhờ đó các thiết bị vận hành ổn định và dễ dàng cho việc nâng cấp cũng như bảo trì thiết bị.
Hình3.2:Thiếtkếvàthicông vỏhộpđểchứavàbảovệcác thiết bị
Thiết kếvàthicông phầnmềm
Hiểnthịthôngtinlênledmatrậnnóichungvàledp10nóiriêngthườngsửdụ ng phươngpháp quét led.
Thuật toán quét LED thường gặp hiện tượng đơ LED khi sử dụng các phương pháp lập trình thông thường, do quá trình xử lý chồng chập và mất thời gian khiến người dùng khó chịu và làm giảm chất lượng hiển thị Để khắc phục tình trạng này, chúng tôi đã áp dụng phương pháp ngắt timer để triển khai thuật toán quét LED, như một module quét LED tự động và điều khiển việc hiển thị trên màn hình một cách trơn tru và ổn định.
Để hệ thống hoạt động đúng, giữa chương trình và hàm ngắt phải có một mối liên hệ nhất định: khi hàm main quyết định nội dung cần hiển thị thì hàm ngắt sẽ nghe theo bằng cách lấy dữ liệu từ buffer hiển thị Phương pháp này dựa trên một buffer hiển thị (bộ đệm hiển thị) — một mảng dữ liệu chứa các dữ liệu cần hiển thị Khi hàm main muốn hiển thị gì, chỉ cần ghi dữ liệu vào buffer Còn hàm ngắt sẽ tự động lấy dữ liệu từ buffer để hiển thị một cách định kỳ và tự động.
Hình 3.4 trình bày phương pháp nháy bằng timer để thực hiện thuật toán quét LED áp dụng cho LED P10 (32×16), với tổng cộng 512 LED tương đương 512 pixel cần được quản lý bằng 512 bit để điều khiển ma trận Mỗi LED là sự kết hợp của 3 màu RGB nên cần thêm một chiều dữ liệu để quản lý màu sắc, cho phép điều khiển đồng thời cả cường độ và sắc thái của từng điểm ảnh trên ma trận LED.
Khai bảo một mảng 3 chiều:char Buffer_display[3][16][4]đ ể q u ả n l ýmatrậnLEDvàlàm bộ đệmchochươngtrìnhngắt Timer.
Xây dựng chương trình ngắt quét LED dựa trên bộ Timer1 của Arduino để điều khiển LED P10 Để không gây mỏi mắt và quá tải não bộ, tần số quét lý tưởng nằm ở khoảng 24–30fps; trong bài này chúng tôi sử dụng 33fps Với LED P10, cứ 8 lần quét sẽ hoàn thành một khung hình và mỗi lần ngắt chỉ có thể sáng một hàng Thời gian dành cho mỗi lần ngắt được tính là 1 / (8 × 33) ≈ 0.0037 giây.
3.2.2 Thiết kế chương trình chính.Lưuđồthuậttoáncủachươngtrìnhchín h.
Chương trình chính gồm hai tác vụ: taskRealTime đọc và hiển thị các tham số thời gian (giờ, phút, giây); taskAnimation có chức năng hiển thị các hiệu ứng chuyển động theo nhịp nhạc Các tác vụ giao tiếp với nhau qua hàng đợi "mode" và được điều khiển bởi chương trình điều khiển ở mục 3.2.3.
Hình 3 6: Lưu đồ thuật toán tác vụ taskRealTimeLưuđồ thuật toán tácvụ “animation”:
Hình3.7: Lưuđồthuật toántácvụ “animation” 3.2.3 Chương trình điều khiển sản phẩm.Sơđồ điềukhiểnsảnphẩm
Chương trình điều khiển nhận dữ liệu trực tiếp từ người dùng thông qua nútnhấn.Đểquátrình tươngtácnày điễnravà đápứngthờigianthựcchúngem sửdụngtính năng ngắt cứng trênarduino uno.
TỔNGKẾT
Nhận xét, đánhgiá
Sản phẩm hoạtđộng ổn định,đạt yêucầuđã đặtra, tuynhiênvẫn cònmộtsốhạn chếnhư sau:
Hướng pháttriển
- Có thêm hiểnthị nhiệtđộ và độẩm.
- Tích hợp thêm nhiều hiệu ứng có thể chuyển mode qua nút nhấn,không dây smartphone hoặc PC thông qua các chuẩn không dây(bluetooth,wifi, NFC, )
- TíchhợpphátnhạctrựctiếptừSDCardhoặcUSBcóthêmcácc hức năng như máynghe nhạc
- Thiếtkế mô hìnhvới kíchthướcnhỏ gọn, kiểudángđẹp hơn.
Kếtluận
Trong suốt quá trình thực hiện đề tài này, nhờ sự cố gắng và nỗ lực của chúng em cùng với sự hướng dẫn tận tình của cô Lê Thị Hồng Vân, chúng em đã hoàn thành đề tài Tuy nhiên vẫn còn một số hạn chế trong khâu thiết kế Đây là một hành trang quý báu cho những sinh viên bước vào cuộc sống nghề nghiệp sau này.
Mặc dù đã có nhiều cố gắng, nhưng do hạn chế về thời gian và khả năng nên vẫn còn một số sai sót Rất mong nhận được sự đóng góp ý kiến của thầy và các bạn để chúng ta hoàn chỉnh nội dung và tối ưu hóa cho SEO.
GVPhạmHùngKimKhánh[2].Từcáctrangweb:www.dientuvietnam.ne t ,codientu.org
TậpTrangWebtham khảo http://arduino.vn/bai-viet/369-giao-tiep-i2c-va-su-dung-module-realtime- clock-ds1307
#define STB 12#define A A0#define B A1#define C
[4];TaskHandle_t animationHandle NULL;TaskHandle_t danceOfMusicHandle N
2]; intwday, day, month, year; charcolor_row[4]={0x01,0x03,0x06,0x02};const char font [][7]
}; const char miniFont [][3] {0xf8,0x88, 0xf8,// 0
40xe8, 0xa8, 0xb8,// 50xf8, 0xa8,
ISR(TIMER1_OVF_vect)//ChươngtrìnhngắtTimer1
{ static unsigned char z = 0;// biến đếm hàng;unsignedchar i; digitalWrite (OE, HIGH); // tắt hết
LEDfor(i =0; i >i; digitalWrite (R1, byte_r1 & mask);digitalWrite (G1, byte_g1 & mask);digitalWrite (B1, byte_b1 & mask);digitalWrite
(R2, byte_r2 & mask);digitalWrite(G2,byte_g2&mask); digitalWrite(B2,byte_b2&mask); digitalWrite(CLK,LOW);digitalWrite(CLK,HIGH);//tạoxungclk chophép chuyển dữ liệu
This Arduino-style function rows accepts an unsigned char row_number and uses a switch statement to drive three output pins A, B, and C using digitalWrite For each case from 0 to 7, it assigns a specific HIGH or LOW combination to A, B, and C to encode the row_number as a three-bit pattern For example, row 0 yields all pins LOW, while row 7 yields all pins HIGH, with the intermediate rows following the exact A/B/C patterns shown in the code The switch-case structure ends each case with a break, providing a clear, deterministic mapping that can drive a 3-to-8 decoder, an LED array, or other hardware in an Arduino project.
} void set_pixel (unsigned char x, unsigned char y, unsigned charcolor){ if(x>31||x15||y>(x%8)); else Buffer_display[0][y][x/8] = Buffer_display[0][y][x/8]
&(~(0x80>>(x %8))); if((color&0x02)!=0)B u f f e r _ d i s p l a y [1][y][x/8]=Buffer_display[1] [y][x/8]|(0x80>>(x%8)); else Buffer_display[1][y][x/8] =Buffer_display[1][y][x/8]
&(~(0x80>>(x %8))); if((color&0x04)!=0)B u f f e r _ d i s p l a y [2][y][x/8]=Buffer_display[2] [y][x/8]|(0x80>>(x%8)); else Buffer_display[2][y][x/8] =Buffer_display[2][y][x/8]
} void put_char (int i, int j, char txt, char color)
{charx =0,y=0, z=txt; for(y=0;yx))!=0)set_pixel(x+i,y+j,color); else set_pixel(x+i,y+j,0x00);
} void drawRow(int x,int height)
{inti; if (height > 14) height 14;height -height; for (i = 14; i > height +1; i ) set_pixel(x,i,0x02);if(i = 0;i ) set_pixel(x,i,0x00);col[x]=height;
} intbcd2dec(bytenum){ return((num/16*10)+(num%16));
} intdec2bcd(bytenum){ return((num/10*16)+(num%10));
7);day=Wire.read(); day Wire.read();dayWire.read(); wday = bcd2dec
(Wire.read());day = bcd2dec
(Wire.read());monthd2dec(Wire.read()); yeard2dec(Wire.read());
((byte)0x00);Wire.endTransmission ();Wire.requestFrom(0x68,7); int x; x = bcd2dec (Wire.read() &
0x7f);put_mini_number(24,3,x/10,0 x03);put_mini_number(28,3,x
%10,0x03);if(x %2 ==0){ draw_point(11,2,0x01); draw_point(11,5,0x01);
(Wire.read());put_char(13,1, x/10,0x02);put_char(18, 1, x
(Wire.read());put_char(1,1, x/10,0x02);put_char(6, 1, x
((byte)0x00);Wire.endTransmission ();Wire.requestFrom(0x68,7); int x; x = bcd2dec (Wire.read() &
0x7f);if(x %2 ==0){ draw_point(15,5,0x02); draw_point(15,9,0x02);
(Wire.read());put_mini_number_2(18,
(Wire.read());put_mini_number_2(1,3,x/10,
} void draw_point (int x, int y, char color)
{set_pixel(x ,y, color); set_pixel (x+1,y, color);set_pixel (x+1,y+1, color);set_pixel(x,y+1,color);
} void put_mini_number(int i, int j, char txt, char color) {charx, y; for(y=0;y x)) != 0) set_pixel(y+i,x+j,color); elseset_pixel(y+i,x+j,0x00);
} void put_mini_number_2(int i, int j, char txt, char color) {charx, y; for(y=0;y x))!=0)draw_point(2*y +i,x*2+j,color); elsedraw_point(2*y+i,x*2+j,0x00);
} void draw_icon(int x, int y, char color)
{set_pixel(x , y, color); set_pixel (x+1 , y+1, color);set_pixel (x+1 , y, color);set_pixel(x+2,y, color);