[RYA2013] MicroMouse SourceCode

2death

Cố Vấn CLB
Staff member
Chiều 10/08 các nhóm dự thi RYA2013 đã có buổi training thứ 2 về Firmware của MicroMouse Robot.
Source code và thư viện có thể download ở link sau:
https://github.com/RaiseYourArm/MicroMouse_RYA2013

có thể down bằng nhiều cách khác nhau, đơn giản nhất là click vào nút “Download ZIP” ở góc bên phải.



Download source này về, các em Import project vào CCS và bắt đầu xem qua nhé.

Các ý kiến trao đổi về source code, chúng ta post vào thread này để mọi người cùng theo dõi.


Các update source code sau này cũng sẽ được cập nhật trên github, các em nhớ theo dõi thread thường xuyên nhé :1cool_byebye:

Happy coding over9 :6cool_boss:
 

naebolo

Thành Viên PIF
Đề tài năm nay hay quá :). Tiếc là ko có time để lên tham gia các buổi training để hiểu đc đôi chút lý thuyết về nó và xem mọi người tham gia. Chúc các đội thi tốt, BTC thành công :)

Cách đây mấy năm về trước, đi kèm với cuộc thi Olympic tin học Sinh viên thì Hội Tin học VN luôn tổ chức thêm 1 cuộc thi MicroMouse kèm theo. Trường mình hình như năm nào cũng có giải (mà cũng chỉ có vài trường tham gia thôi). Mà nhân lực tham gia những lần đó hình như toàn bộ là CNTT.
Sau vài năm tổ chức MicroMouse thì phong trào đi xuống, và cách đây không lâu thì cuộc thi đó cũng đã huỷ :)
 

bigboy061293

Thành Viên PIF
sau khi build thử thì có các lỗi như sau:

+ lỗi không tìm thấy kiểu này extern str_Network_Frame RecceiveFrame;

+ các define như GPIO_PA0_U0RX, GPIO_PA1_U0TX, GPIO_PD6_U2RX, GPIO_PD7_U2TX ,... đại khái là các chân của uart thì không tìm thấy. Lỗi này mình đã gặp ở project vòng trước nhưng giờ vẫn không biết sửa sao, chỉ biết thay đĩa chỉ cụ thể GPIO_PA0_U0RX bằng 0x00000001 và GPIO_PA1_U0TX thành 0x00000401, ....

+ các define của timer cũng vậy INT_TIMER4A, INT_TIMER5A cũng không tìm thấy nhưng thay bằng INT_TIMER4A_BLIZZARD, INT_TIMER5A_BLIZZARD, ... (có thêm chữ blizzard) thì được. Các define có bắt đầu bằng INT (INT_GPIOC, INT_GPIOD) thì phải thêm blizzard mới được (mò trong hw_ints.h mới thấy cái này)

+ GPIO_PB6_T0CCP0, GPIO_PB4_T1CCP0, GPIO_PF3_T1CCP1 cũng không tìm thấy ...
 

hung303mc

Thành Viên PIF
Anh chị cho em hỏi cái API UpdateMap nằm trong chỗ nào với, @@. Em kiếm không ra nó.
 

bigboy061293

Thành Viên PIF
còn 1 biến ByteCount, ở dòng 218 InteruptHandler cũng không tìm thấy :)
phần "GPIO_PA0_U0RX, GPIO_PA1_U0TX, GPIO_PD6_U2RX, GPIO_PD7_U2TX", mình predefine ở đâu ?
 

honghiep

Cố Vấn CLB
Staff member
Xin lỗi bạn vì cái lỗi đầu tiên. Mình đã update lại source code, bạn vào down lại nhé
Về các thông báo: "GPIO_PA0_U0RX, GPIO_PA1_U0TX, GPIO_PD6_U2RX, GPIO_PD7_U2TX ,..." trong phần predefine bạn thêm dòng:
+ PART_TM4C123GH6PM
+ TARGET_IS_BLIZZARD_RB1
Bạn vào phần Properties->CCS Build->ARM Compiler->Advance Option->predefine symbol

Lưu ý thêm về phần source code với các bạn: Trong file main các bạn thêm dòng:
#include "include.h"
 

bigboy061293

Thành Viên PIF
mình nghĩ nên đóng gói code nền này thành 1 project hoàn chỉnh để mọi người tải về rồi dùng cho tiện
 

honghiep

Cố Vấn CLB
Staff member
mình nghĩ nên đóng gói code nền này thành 1 project hoàn chỉnh để mọi người tải về rồi dùng cho tiện
Thực ra việc đưa cho các bạn 1 project hoàn chỉnh cũng không khó khăn gì đối với team support. Tuy nhiên khi đó kĩ năng tạo project, add thư viện, xử lí các lỗi cơ bản của các bạn sẽ không được nâng cao.
Và thực tế cũng cho thấy tuy nhiều bạn đã qua vòng khởi động nhưng vẫn chưa tự tay tạo được một project hoàn chỉnh. Mình hy vọng đây cũng là một cơ hội để các bạn nâng cao tay nghề của mình
Chúc các bạn thành công! :)
 

mafiaWolf

Chủ tịch Hội phụ nữ PIF
ý nghĩa của predefined symbols với 2 cái dưới là gì vậy Hiệp ^^
+ PART_TM4C123GH6PM
+ TARGET_IS_BLIZZARD_RB1
 

honghiep

Cố Vấn CLB
Staff member
ý nghĩa của predefined symbols với 2 cái dưới là gì vậy Hiệp ^^
+ PART_TM4C123GH6PM
+ TARGET_IS_BLIZZARD_RB1
Cái PART_TM4C123GH6PM khai báo tương ứng với VĐK đang sử dụng. Vì ARM-M4 có nhiều con khác nhau từ thứ tự chân cẳng đến chức năng từng chân nên cần khai báo để compiler biết mà chọn các chức năng, địa chỉ các module thích hợp.
TARGET_IS_BLIZZARD_RB1 sẽ liên quan đến các lệnh trên ROM của VĐK, cần khai báo để lấy được địa chỉ các hàm tương ứng trên ROM khi chạy chương trình
 

oatuan

Thành Viên PIF
Mình thấy biến ADCStatus được mã hóa khá phức tạp. Team support có thể trình bài ý tưởng của việc sử dụng biến này.
 

ctcngh

Thành Viên PIF
Mình thấy biến ADCStatus được mã hóa khá phức tạp. Team support có thể trình bài ý tưởng của việc sử dụng biến này.
Theo mình thì: việc đọc ADC sẽ theo trình tự bật từng IR Led rồi đọc ADC, sau đó tắt hết LED đọc 1 lần nữa rồi xử lí. Việc ra lệnh lấy mẫu được thực hiện bằng Timer 4. Trong Timer4ISR, bạn sẽ thấy là mỗi lần vào ngắt timer thì chỉ làm 1 bước, và ADCStatus sẽ kiểm soát là đang ở bước nào. Ví dụ ADCStatus =0 thì bật IR LED đầu tiên, lần ngắt thứ 2 thì đọc ADC, ....
 

oatuan

Thành Viên PIF
Mình thấy biến ADCStatus được mã hóa khá phức tạp. Team support có thể trình bài ý tưởng của việc sử dụng biến này.
Theo mình thì: việc đọc ADC sẽ theo trình tự bật từng IR Led rồi đọc ADC, sau đó tắt hết LED đọc 1 lần nữa rồi xử lí. Việc ra lệnh lấy mẫu được thực hiện bằng Timer 4. Trong Timer4ISR, bạn sẽ thấy là mỗi lần vào ngắt timer thì chỉ làm 1 bước, và ADCStatus sẽ kiểm soát là đang ở bước nào. Ví dụ ADCStatus =0 thì bật IR LED đầu tiên, lần ngắt thứ 2 thì đọc ADC, ....
Như thế giá trị của ADCStatus chỉ cần từ 0 đến 9. Vậy tại sao phải reset ADCStatus ở 20 (câu lệnh ADCStatus %= 20;) mà không phải ở 10. Đồng thời mình nghĩ việc thực hiện phép chia dư sẽ tốn nhiều chu kì máy hơn là sử dung lệnh if (ADCStatus>9);
 

ctcngh

Thành Viên PIF
Theo mình thì ADC status tăng từ 0 -> 19 chắc do không cần lấy mẫu nhanh nên dư ra để delay. Mình nghĩ ARM cũng mạnh không cần phải tính toán kĩ thế.
 

honghiep

Cố Vấn CLB
Staff member
Mình thấy biến ADCStatus được mã hóa khá phức tạp. Team support có thể trình bài ý tưởng của việc sử dụng biến này.
Theo mình thì: việc đọc ADC sẽ theo trình tự bật từng IR Led rồi đọc ADC, sau đó tắt hết LED đọc 1 lần nữa rồi xử lí. Việc ra lệnh lấy mẫu được thực hiện bằng Timer 4. Trong Timer4ISR, bạn sẽ thấy là mỗi lần vào ngắt timer thì chỉ làm 1 bước, và ADCStatus sẽ kiểm soát là đang ở bước nào. Ví dụ ADCStatus =0 thì bật IR LED đầu tiên, lần ngắt thứ 2 thì đọc ADC, ....
Như thế giá trị của ADCStatus chỉ cần từ 0 đến 9. Vậy tại sao phải reset ADCStatus ở 20 (câu lệnh ADCStatus %= 20;) mà không phải ở 10. Đồng thời mình nghĩ việc thực hiện phép chia dư sẽ tốn nhiều chu kì máy hơn là sử dung lệnh if (ADCStatus>9);
Về việc sử dụng ADC đọc giá trị hồng ngoại giống như bạn ctcngh nói.
Còn về việc tại sao lại là ADCStatus %= 20; thì do mình muốn vòng PID bám tường có chu kì lớn hơn vòng PID vận tốc thôi, và việc tính PID này chỉ thực hiện 1 lần trong 20ms đó
 

cowboyhere

Cố Vấn CLB
Staff member
Firmware 1.2 is available, ready to use :1cool_byebye:
đã fix các lỗi cơ bản, tối ưu các hàm và thêm comment. Các bạn đọc kĩ comment, link giữa các hàm... trước khi đạt câu hỏi.
tổng hợp các lỗi ở luồng này để tiện làm FAQ
thân
 

ctcngh

Thành Viên PIF
Mình có thắc mắc là: biến EncRightCount và EncLeftCount đếm encoder xem như vận tốc trong vòng PID vận tốc, vậy thì mình phải reset về 0 sau mỗi lần tính toán giá trị đọc về đúng không? Sao mình thấy nó không reset như vậy mà lại được reset sau mỗi vòng PID vị trí. (Timer5ISR).
 

honghiep

Cố Vấn CLB
Staff member
Mình có thắc mắc là: biến EncRightCount và EncLeftCount đếm encoder xem như vận tốc trong vòng PID vận tốc, vậy thì mình phải reset về 0 sau mỗi lần tính toán giá trị đọc về đúng không? Sao mình thấy nó không reset như vậy mà lại được reset sau mỗi vòng PID vị trí. (Timer5ISR).
Bạn lưu ý với hàm: void PIDVerCalc(PIDType *p_PIDVer, int32_t *Speed, int32_t MaxResponse)
khi tính toán, ta sẽ đưa vào đối số thứ 2 là địa chỉ của biến đếm Encoder vận tốc. Trong hàm này đã có lệnh reset biến đếm này dựa vào địa chỉ của nó
 

ctcngh

Thành Viên PIF
Mình có thắc mắc là: biến EncRightCount và EncLeftCount đếm encoder xem như vận tốc trong vòng PID vận tốc, vậy thì mình phải reset về 0 sau mỗi lần tính toán giá trị đọc về đúng không? Sao mình thấy nó không reset như vậy mà lại được reset sau mỗi vòng PID vị trí. (Timer5ISR).
Ah. Mình thấy rồi, cảm ơn bạn.
 

ntan234

Trứng gà
sao mãi mà ko cho con robot chạy được, dùng lệnh move, turn left ... cũng ko được. Dùng lệnh SetPWM(TIMER1_BASE, TIMER_A, DEFAULT, 50); SetPWM(TIMER0_BASE, TIMER_A, DEFAULT, 50); cũng ko xong lun.
Có ai giúp mình với!
 
Top