This shows you the differences between two versions of the page.
pm:prj2021:abasoc:api_arc_board [2021/05/03 20:00] robert_mihai.lica [Software Design] |
pm:prj2021:abasoc:api_arc_board [2021/06/03 02:45] (current) robert_mihai.lica [Bibliografie/Resurse] |
||
---|---|---|---|
Line 31: | Line 31: | ||
- Un receiver de dimensiuni mici pe 2.4Ghz compatibil cu radio telecomenzile FlySky. Este folosit pentru a da o comanda de kill masinii daca este pe cale sa se loveasca de ceva. | - Un receiver de dimensiuni mici pe 2.4Ghz compatibil cu radio telecomenzile FlySky. Este folosit pentru a da o comanda de kill masinii daca este pe cale sa se loveasca de ceva. | ||
====== Software Design ====== | ====== Software Design ====== | ||
- | + | ===<timer.hpp>=== | |
- | \\ | + | |
- | \\ | + | |
- | ===<Timer.hpp>=== | + | |
==Notes:== | ==Notes:== | ||
Biblioteca foloseste timmer-ul FTM1.\\ | Biblioteca foloseste timmer-ul FTM1.\\ | ||
\\ | \\ | ||
==Metode:== | ==Metode:== | ||
- | Timer& get_instance(void) \\ | + | static Timer& get_instance(void) \\ |
Returneaza o referinta catre obiect si la prima apelare este initializat obiectul. | Returneaza o referinta catre obiect si la prima apelare este initializat obiectul. | ||
Timer& instance = Timer::get_instance(); | Timer& instance = Timer::get_instance(); | ||
Line 47: | Line 44: | ||
auto elapsed = instance.micros(); | auto elapsed = instance.micros(); | ||
\\ | \\ | ||
- | uint32_t millis() \\ | + | uint32_t millis(void) \\ |
Returneaza un unsigned int ce reprezinta timpul in milisecunde de la primul apel Timer::get_instance(). | Returneaza un unsigned int ce reprezinta timpul in milisecunde de la primul apel Timer::get_instance(). | ||
auto elapsed = instance.millis(); | auto elapsed = instance.millis(); | ||
Line 64: | Line 61: | ||
instance.add_irq_handler(function); | instance.add_irq_handler(function); | ||
\\ | \\ | ||
- | void call_irq_handlers() \\ | + | void call_irq_handlers(void) \\ |
Metoda apelata de rutina de tratare a intreruperii de ceas (0.2 sec) pentru a executa toate functiile din vectorul "irq_handlers" | Metoda apelata de rutina de tratare a intreruperii de ceas (0.2 sec) pentru a executa toate functiile din vectorul "irq_handlers" | ||
instance.call_irq_handlers(); | instance.call_irq_handlers(); | ||
Line 70: | Line 67: | ||
\\ | \\ | ||
- | ===<Servo.hpp>=== | + | ===<motor_driver.hpp>=== |
==Notes:== | ==Notes:== | ||
- | Biblioteca foloseste timmer-ul FTM2.\\ | + | Biblioteca foloseste timmer-ul FTM0 si canalele 0, 1, 2, 3.\\ |
+ | ==Metode:== | ||
+ | static Motors& get_instance(void) \\ | ||
+ | Returneaza o referinta catre obiect si la prima apelare este initializat obiectul. | ||
+ | Motors& instance = Motors::get_instance(); | ||
+ | \\ | ||
+ | static void give_config(struct motor_config_t& conf) \\ | ||
+ | Pentru viitor: mod avansat de a configura clasa inaintea primului apel catre Motors::get_instance(); momentan este folosita configuratia default. | ||
+ | Motors::give_config(custome_config); | ||
+ | \\ | ||
+ | void enable_motor_driver(void) \\ | ||
+ | Activeaza puntile H ale placii. Pentru detalii consultati schemele {{ :pm:prj2021:abasoc:robert_mihai.lica-nxp_cup_arc_ingenierie_schematic_prints.pdf | placii}} si a [[https://www.nxp.com/docs/en/data-sheet/MC33887.pdf | puntii-H]] | ||
+ | instance.enable_motor_driver(); | ||
+ | \\ | ||
+ | void disable_motor_driver(void) \\ | ||
+ | Dezactiveaza puntile H ale placii. Pentru detalii consultati schemele {{ :pm:prj2021:abasoc:robert_mihai.lica-nxp_cup_arc_ingenierie_schematic_prints.pdf | placii}} si a [[https://www.nxp.com/docs/en/data-sheet/MC33887.pdf | puntii-H]] | ||
+ | instance.disable_motor_driver(); | ||
+ | \\ | ||
+ | void enable_motor_outputs(void) \\ | ||
+ | Activeaza output-urile puntilor-H. Pentru detalii consultati schemele {{ :pm:prj2021:abasoc:robert_mihai.lica-nxp_cup_arc_ingenierie_schematic_prints.pdf | placii}} si a [[https://www.nxp.com/docs/en/data-sheet/MC33887.pdf | puntii-H]] | ||
+ | instance.enable_motor_output(); | ||
+ | \\ | ||
+ | void disable_motor_outputs(void) \\ | ||
+ | Dezactiveaza output-urile puntilor-H. Pentru detalii consultati schemele {{ :pm:prj2021:abasoc:robert_mihai.lica-nxp_cup_arc_ingenierie_schematic_prints.pdf | placii}} si a [[https://www.nxp.com/docs/en/data-sheet/MC33887.pdf | puntii-H]]. | ||
+ | instance.disable_motor_output(); | ||
+ | \\ | ||
+ | void update_motor_status(void) \\ | ||
+ | Configureaza puntile-H conform starii interne a obiectului. Aceasta metota nu ar trebuii sa fie utilizata decat daca pinii uC-ului au fost setati nu prin API-ul current si a aparut o discrepanta intre configurare si starea interna a obiectului. | ||
+ | instance.update_motor_status(); | ||
+ | \\ | ||
+ | void set_rps_target(const float rps) \\ | ||
+ | Seteaza un nr. de rotatii pe secunda (rps) dorit si bucla PID interioara se ocupa de atingerea tintei daca aceasta este activata (default activa). | ||
+ | instance.set_rps_target(15.5f); | ||
+ | \\ | ||
+ | void get_rps_target(void) \\ | ||
+ | Returneaza nr. de rotatii pe secunda dorit, folosit de bucla PID interioara se ocupa de atingerea tintei daca aceasta este activata (default activa). | ||
+ | instance.set_rps_target(15.5f); | ||
+ | \\ | ||
+ | void enable_pid_control(const int8_t new_command = 0) \\ | ||
+ | Daca bucla PID era dezactivata, este activat controlul prin PID, rps_targhet-ul este setat la 0, comanda la motoare este setata ca "new_command" (default 0). | ||
+ | instance.enable_pid_control(); | ||
+ | \\ | ||
+ | void disable_pid_control(void) \\ | ||
+ | Daca bucla PID era activata, este dezactivat controlul prin PID, rps_targhet-ul este setat la 0, comanda la motoare este setata la 0. | ||
+ | instance.disable_pid_control(); | ||
+ | \\ | ||
+ | static void pid_update(void) \\ | ||
+ | Functie apelata de intreruperea de ceas pentru a itera prin bucla PID de control a motoarelor daca aceasta este activata. Functia este lasata publica in caz ca user-ul doreste o iterare mai frecventa. | ||
+ | Motors::pid_update(); | ||
+ | \\ | ||
+ | void set_command(int8_t command) \\ | ||
+ | Seteaza comanda (-100 <= command <= 100) ce reprezinta duty cycle-ul semnalului pentru motoare. Pentru valori negative polaritatea motoarelor este inversata automat. Este folosit de bucla PID pentru a da o comanda motoarelor, dar poate fi folosita si de utilizator. Daca se seteaza o comanda in timp ce bucla PID este activa, la urmatoarea intrerupere de ceas aceasta va fi suprascrisa de rezultatul buclei PID. | ||
+ | instance.set_command(-50); | ||
+ | \\ | ||
+ | int8_t get_command(void) \\ | ||
+ | Ar trebuii sa returneze ultima comanda data puntilor-H. Daca bucla PID este activa, returneaza ultima commanda calculata de aceasta, iar daca este inactiva returneaza ultima commanda data de utilizator manual explicit sau prin diferite functii (exemplu "enable/disable_pid_control"). | ||
+ | auto command = instance.get_command(); | ||
+ | \\ | ||
+ | void stop_interrupt(const bool state) \\ | ||
+ | Pentru "state = true", opreste de urgenta puntile-H la declansarea unei intreruperi pe pinul de Signal Kill. Altfel activeaza la loc puntile-H daca acestea erau activate inaintea semnalului de kill. | ||
+ | instance.stop_interrupt(true); | ||
+ | \\ | ||
+ | |||
+ | \\ | ||
+ | ===<speed_sensor.hpp>=== | ||
+ | ==Notes:== | ||
+ | Acronimul rps inseamna "rotatii pe secunda" \\ | ||
+ | Biblioteca ofera suport pentru pana la 2 senzori de viteza a cate 2 canale fiecare. \\ | ||
\\ | \\ | ||
==Metode:== | ==Metode:== | ||
- | Servo& get_instance(void) \\ | + | static SpS& get_instance() \\ |
+ | Returneaza o referinta catre obiect si la prima apelare este initializat obiectul. | ||
+ | SpS& instance = SpS::get_instance(); | ||
+ | \\ | ||
+ | float get_rps_a(void) \\ | ||
+ | Returneaza nr. de rps a senzorului de viteza A daca acesta exista. Daca nu, intoarce viteza senzorului B sau 0 daca nici acesta nu exista. Functia este folosita la interarea buclei PID. | ||
+ | auto speed_a = instance.get_rps_a(); | ||
+ | \\ | ||
+ | float get_rps_b(void) \\ | ||
+ | Returneaza nr. de rps a senzorului de viteza B daca acesta exista. Daca nu, intoarce viteza senzorului A sau 0 daca nici acesta nu exista. Functia este folosita la interarea buclei PID. | ||
+ | auto speed_b = instance.get_rps_b(); | ||
+ | \\ | ||
+ | void sensor_interrupt(void) \\ | ||
+ | Functia este apelata de rutina de tratare a intreruperii pentru a verifica daca aceasta a venit pe pinii senzorilor de viteza. Este calculat noul nr. de rps per motor si se afla directia de rotatie prin cuadratura. | ||
+ | sensor_interrupt(); | ||
+ | \\ | ||
+ | |||
+ | \\ | ||
+ | ===<kill_switch.hpp>=== | ||
+ | ==Notes:== | ||
+ | Este folosit pinul PTA13 care deregula este folosit pentru unul din senzorii hall. \\ | ||
+ | Prezenta unui modul radio pe masina este interzisa in cadrul competitiei NXP Cup. Acesta poate fi activat sau dezactivat usor doar schimband in fisierul "kill_switch.hpp" | ||
+ | #define KILL_SWITCH_ENABLE 1 // to enable the kill_switch | ||
+ | // #define KILL_SWITCH_ENABLE 0 // to disable the kill_switch | ||
+ | ==Functii:== | ||
+ | void kill_switch_init(void) \\ | ||
+ | Configureaza pinul si activeaza intreruperea pe ambele fronturi de semnal. | ||
+ | kill_switch_init(); | ||
+ | \\ | ||
+ | void kill_switch_interrupt(void) | ||
+ | Daca acest pin a declansat intreruperea, puntile-H vor fi dezactivate sau activate in functie de starea actualal a pinului. Aceasta functie este folosita in rutina de tratare a intreruperii. | ||
+ | kill_switch_interrupt(); | ||
+ | \\ | ||
+ | |||
+ | \\ | ||
+ | ===<servo.hpp>=== | ||
+ | ==Notes:== | ||
+ | Biblioteca foloseste timmer-ul FTM2 si canalele 0, 1.\\ | ||
+ | \\ | ||
+ | ==Metode:== | ||
+ | static Servo& get_instance(void) \\ | ||
Returneaza o referinta catre obiect si la prima apelare este initializat obiectul. | Returneaza o referinta catre obiect si la prima apelare este initializat obiectul. | ||
Servo& instance = Timer::get_instance(); | Servo& instance = Timer::get_instance(); | ||
Line 84: | Line 188: | ||
\\ | \\ | ||
void set_dutycycle(ftm_chnl_t sv, uint8_t dc)\\ | void set_dutycycle(ftm_chnl_t sv, uint8_t dc)\\ | ||
- | Primeste ca si parametru channel-ul (SV1_FTM_CHANNEL sau SV2_FTM_CHANNEL) la care este conectat servo-motorul si dutycycle-ul dorit (0 <= dc <= 100) sa fie scris pe pinul de semnal. | + | Primeste ca si parametru channel-ul (SV1_FTM_CHANNEL sau SV2_FTM_CHANNEL) la care este conectat servo-motorul si duty cycle-ul dorit (0 <= dc <= 100) sa fie scris pe pinul de semnal. |
set_dutycycle(SV1_FTM_CHANNEL , 2U); | set_dutycycle(SV1_FTM_CHANNEL , 2U); | ||
\\ | \\ | ||
Line 94: | Line 198: | ||
Pentru portare a trebuit sa implementez comunicatia pe SPI blocanta si functiile de "delay" si "millis" din <Timer.hpp>. | Pentru portare a trebuit sa implementez comunicatia pe SPI blocanta si functiile de "delay" si "millis" din <Timer.hpp>. | ||
\\ | \\ | ||
+ | \\ | ||
\\ | \\ | ||
===<SPI.h>=== | ===<SPI.h>=== | ||
Line 101: | Line 205: | ||
Biblioteca de Pixy2 se asteapta ca comunicatia de SPI sa fie blocanta. Pentru viitor comunicatia sa nu mai fie blocanta si sa se foloseasca intreruperi sau eDMA.\\ | Biblioteca de Pixy2 se asteapta ca comunicatia de SPI sa fie blocanta. Pentru viitor comunicatia sa nu mai fie blocanta si sa se foloseasca intreruperi sau eDMA.\\ | ||
==Metode:== | ==Metode:== | ||
- | void begin() \\ | + | static void begin(void) \\ |
Pentru a fi folosit pe viitor cand configurarea nu mai este facuta din GUI-ul din MCUXpresso. | Pentru a fi folosit pe viitor cand configurarea nu mai este facuta din GUI-ul din MCUXpresso. | ||
SPI::begin(); | SPI::begin(); | ||
\\ | \\ | ||
- | void send(uint8_t *buf, uint8_t len) \\ | + | static void send(uint8_t *buf, uint8_t len) \\ |
Trimite prin SPI un vector de bytes fara a intoarce ce citeste pe SPI. Comunicatia este blocanta. | Trimite prin SPI un vector de bytes fara a intoarce ce citeste pe SPI. Comunicatia este blocanta. | ||
SPI::send(buffer, n); | SPI::send(buffer, n); | ||
\\ | \\ | ||
- | void recv(uint8_t *buf, uint8_t len) \\ | + | static void recv(uint8_t *buf, uint8_t len) \\ |
Primeste prin SPI un vector de bytes in timp ce trimite pe SPI \0. Comunicatia este blocanta. | Primeste prin SPI un vector de bytes in timp ce trimite pe SPI \0. Comunicatia este blocanta. | ||
SPI::recv(buffer, n); | SPI::recv(buffer, n); | ||
====== Rezultate Obținute ====== | ====== Rezultate Obținute ====== | ||
- | TODO | + | Functioneaza, gata sa fie folosit de cineva care stie niste teorie de auto-reglare pentru a o face sa mearga pe pista.\\ |
+ | Demo pe [[https://youtu.be/A627lpIsANQ | youtube]] | ||
====== Concluzii ====== | ====== Concluzii ====== | ||
- | TODO | + | Pregatit sa fie programat mai departe pentru competitia NXP CUP 2022. |
====== Download ====== | ====== Download ====== | ||
- | TODO | + | [[https://github.com/Robert-ML/API_NXP-CUP_release | GitHub]] |
- | + | ||
- | ====== Jurnal ====== | + | |
- | TODO | + | |
====== Bibliografie/Resurse ====== | ====== Bibliografie/Resurse ====== | ||
- | TODO | + | {{ :pm:prj2021:abasoc:robert_mihai.lica-pagina_ocw.pdf | Pagina OCW }}\\ |
+ | {{ :pm:prj2021:abasoc:robert_mihai.lica-pagina_ocw_finala.pdf | Pagina OCW Finala}}\\ | ||
+ | [[https://stackoverflow.com | stackoverflow]] [[https://google.github.io/styleguide/cppguide.html | Google Coding Style]] [[https://en.cppreference.com/w/ | cppreference]] [[https://docs.pixycam.com/wiki/doku.php?id=wiki:v2:start | Pixy2 Docs]] [[https://developer.arm.com/support | developer.arm]] [[https://www.geeksforgeeks.org | geeksforgeeks]] |