{"id":154,"date":"2021-12-27T23:09:47","date_gmt":"2021-12-27T22:09:47","guid":{"rendered":"https:\/\/zappp.pl\/blog\/?p=154"},"modified":"2022-01-20T17:05:20","modified_gmt":"2022-01-20T16:05:20","slug":"library-1-sterownik-silnika-krokowego-na-stm32f429-disco-part-3","status":"publish","type":"post","link":"https:\/\/www.zappp.pl\/blog\/library-1-sterownik-silnika-krokowego-na-stm32f429-disco-part-3\/","title":{"rendered":"Library 1 \u2013 sterownik silnika krokowego na STM32F429 DISCO (part 3)."},"content":{"rendered":"\n<p class=\"has-drop-cap wp-block-paragraph\"><strong>Komunikacja pomi\u0119dzy PC, a p\u0142ytk\u0105 DISCOVERY oparta zosta\u0142a na interfejsie UART. W celu pod\u0142\u0105czenia urz\u0105dze\u0144 wymagana jest przej\u015bci\u00f3wka USB-UART, najlepiej, wyposa\u017cona w uk\u0142ad FT232. Konfiguracja mikrokontrolera pod obs\u0142ug\u0119 UART przedstawiona zosta\u0142a w <a href=\"https:\/\/zappp.pl\/blog\/library-1-sterownik-silnika-krokowego-na-stm32f429-disco-part-1\/\">cz\u0119\u015bci 1<\/a> omawianej biblioteki.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Projekt do pobrania z: <\/strong><a href=\"https:\/\/github.com\/PiotrPoterala\/stm32f429i-disco_stepper_motor\">https:\/\/github.com\/PiotrPoterala\/stm32f429i-disco_stepper_motor<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>oraz biblioteki: <\/strong><a href=\"https:\/\/github.com\/PiotrPoterala\/PP_Library\">https:\/\/github.com\/PiotrPoterala\/PP_Library<\/a><\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Struktura klas<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Mechanizm odbioru\/wysy\u0142ania danych oparty zosta\u0142 na wzorcu projektowym <em>Dekorator<\/em>. Pozwala on na:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>dynamiczne dodawanie nowych funkcji do istniej\u0105cych klas w trakcie dzia\u0142ania programu,<\/li><li>\u201eopakowanie\u201d oryginalnej klasy w klas\u0119 \u201edekoruj\u0105c\u0105\u201d.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full is-style-twentytwentyone-border\"><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"282\" src=\"https:\/\/zappp.pl\/blog\/wp-content\/uploads\/2021\/12\/decorator_diagram.gif\" alt=\"\" class=\"wp-image-155\"\/><\/figure>\n\n\n\n<div class=\"wp-block-columns alignwide is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"224\" height=\"961\" src=\"https:\/\/zappp.pl\/blog\/wp-content\/uploads\/2022\/01\/class_p_serial_port_r_t_x5__inherit__graph.png\" alt=\"\" class=\"wp-image-172\" srcset=\"https:\/\/www.zappp.pl\/blog\/wp-content\/uploads\/2022\/01\/class_p_serial_port_r_t_x5__inherit__graph.png 224w, https:\/\/www.zappp.pl\/blog\/wp-content\/uploads\/2022\/01\/class_p_serial_port_r_t_x5__inherit__graph-70x300.png 70w\" sizes=\"auto, (max-width: 224px) 100vw, 224px\" \/><\/figure><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"394\" height=\"999\" src=\"https:\/\/zappp.pl\/blog\/wp-content\/uploads\/2022\/01\/classdef_o_r_t_x5at_command_interpreter__coll__graph.png\" alt=\"\" class=\"wp-image-174\" srcset=\"https:\/\/www.zappp.pl\/blog\/wp-content\/uploads\/2022\/01\/classdef_o_r_t_x5at_command_interpreter__coll__graph.png 394w, https:\/\/www.zappp.pl\/blog\/wp-content\/uploads\/2022\/01\/classdef_o_r_t_x5at_command_interpreter__coll__graph-118x300.png 118w\" sizes=\"auto, (max-width: 394px) 100vw, 394px\" \/><\/figure><\/div>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">W przypadku omawianego projektu:<\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\"><li><em>Component<\/em> to <em>PIOdevice \u2013 <\/em>wirtualna klasa bazowa, dostarczaj\u0105ca interfejs do realizacji wysy\u0142ania\/odbierania danych po UART,<\/li><li><em>ConcreteComponent <\/em>to<em> PSerialPortRTX5 <\/em>\u2013 dziedziczy po <em>PIOdevic;<\/em> klasa implementuj\u0105ca metody zdefiniowane w klasie bazowej z wykorzystaniem funkcji specyficznych dla zastosowanego systemu czasu rzeczywistego. W przypadku korzystania z FreeRTOS\u2019a jako <em>ConcreteComponent <\/em>mog\u0142aby funkcjonowa\u0107 np. klasa <em>PSerialPortFreeRTOS<\/em>.<\/li><li><em>Decorator <\/em>to<em> PIOdeviceDecorator <\/em>\u2013 dziedziczy po <em>PIOdevice <\/em>i agreguje referencj\u0119 do obiektu klasy <em>PIOdevice.<\/em> Zawieraj\u0105c ten sam zestaw metod jak obiekt docelowy (<em>Component<\/em>) i deleguj\u0105c mu wszystkie \u017c\u0105dania stanowi interfejs dla \u201enak\u0142adek\u201d.<\/li><li><em>ConcreteDecorator <\/em>to<em> defORTX5atCommandInterpreter \u2013 <\/em>\u201enak\u0142adka\u201d; dziedziczy po<em> PIOdeviceDecorator; <\/em>implementuje tylko te metody wirtualne, kt\u00f3rych ostateczny wynik dzia\u0142ania ma by\u0107 zmieniony, dodaj\u0105c pewne operacje, przed lub po przekazaniu \u017c\u0105dania do obiektu docelowego (<em>Component<\/em>). W przypadku omawianego projektu, do metody <em>readLine() <\/em>dodane zosta\u0142y operacje:<ul><li>interpretacji danych odebranych z portu UART,<\/li><li>przes\u0142ania obrobionych danych (poprzez kolejk\u0119) do w\u0105tku realizuj\u0105cego podstawowe zadania projektu (a wi\u0119c obr\u00f3t wirnika silnika o okre\u015blony k\u0105t, z okre\u015blon\u0105 trajektori\u0105 pr\u0119dko\u015bci obrotowej).<\/li><\/ul><\/li><\/ol>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>UART \u2013 wysy\u0142anie&nbsp;danych w projekcie opartym na RTX5<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Bezpo\u015brednie wys\u0142anie danych na port UART<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PIOdevice*serialPort= new PSerialPortRTX5(USART1);\r\nserialPort->open(PIOdevice::ReadWrite);\t\r\nserialPort->write(\"test\");\r\nserialPort->close();\r<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Wys\u0142anie danych za po\u015brednictwem <em>PTextStream<\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PIOdevice* serialPort = new PSerialPortRTX5(USART1);\nPTextStream out(serialPort);\nserialPort->open(PIOdevice::ReadWrite);\t\nout&lt;&lt;\u201dtest\u201d;\nserialPort->close();<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Metoda <em>write()<\/em> przepisuje ci\u0105g znak\u00f3w do kolejki nadawczej <em>sendQueue<\/em>, (i poniewa\u017c UART nie jest wstanie jednocze\u015bnie nadawa\u0107 i odbiera\u0107 danych) wy\u0142\u0105cza odbieranie danych przez port UART (CR1_RE) i w\u0142\u0105cza przerwania od pustego rejestru transmisji danych (CR1_TXEIE=1).<\/p>\n\n\n\n<h6 class=\"wp-block-heading\">pp_rtx5_serial_port.cpp<\/h6>\n\n\n\n<pre class=\"wp-block-code\"><code>bool PSerialPortRTX5::write(string &amp;data){\r\n\tbool answer=true;\r\n\t\r\n\tif(openMode==WriteOnly || openMode==ReadWrite){\r\n\t\tfor(auto it: data){\r\n\t\t\tif(osMessageQueuePut(sendQueue, &amp;it, 0, osWaitForever)==osOK){\r\n\t\t\t\tname->CR1&amp;=~USART_CR1_RE;\t\r\n\t\t\t\tname->CR1|=USART_CR1_TXEIE;\r\n\t\t\t}else{\r\n\t\t\t\tanswer=false;\r\n\t\t\t\tbreak;\r\n\t\t\t}\t\t\t\t\r\n\t\t}\r\n\t}else{\r\n\t\tanswer=false;\r\n\t}\r\n\r\n\treturn answer;\r\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">W przypadku, gdy SR_TXE=1 (bit ustawiany sprz\u0119towo) wywo\u0142ywany jest podprogram przerwania, w kt\u00f3rym poprzez metod\u0119 <em>portListen()<\/em>, pobierany jest znak z kolejki nadawczej <em>sendQueue<\/em> i wstawiany do rejestru DR (pe\u0142ni\u0105cego funkcj\u0119 bufora nadawczego).<\/p>\n\n\n\n<h6 class=\"wp-block-heading\">pp_rtx5_serial_port.cpp <\/h6>\n\n\n\n<pre class=\"wp-block-code\"><code>void PSerialPortRTX5::portListen(){\n\t\n\tif(port->SR &amp; USART_SR_RXNE){  \n\t\treceiveSignAndWriteToReceiveQueue();\n  }else if(port->SR &amp; USART_SR_TXE){  \n\t\tsendSignFromSendQueue();\n  }\n}\n\n...\n\nint PSerialPortRTX5::sendSignFromSendQueue(){\n\t\tchar sign;\t\n\t\tosStatus_t status;\n\n\t\tstatus=osMessageQueueGet(sendQueue, &amp;sign, NULL, 0);\n\t\tif(status==osOK){\n\t\t\tport->DR=sign;\n\t\t}else{\n\t\t\tport->CR1&amp;=~USART_CR1_TXEIE;\t\n\t\t\tport->CR1|=USART_CR1_RE;\t\t\t\n\t\t}\n\n\t\treturn status;\n }<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Po wys\u0142aniu wszystkich znak\u00f3w z kolejki nadawczej, nast\u0119puje wy\u0142\u0105czenie przerwania od pustego rejestru CR1_TXEIE i ponowne w\u0142\u0105czenie odbieranie danych przez port UART.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>UART \u2013 odbieranie&nbsp;danych w projekcie opartym na RTX5<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">W omawianym projekcie, odbieranie danych jest domy\u015blnym trybem pracy portu UART, a wi\u0119c domy\u015blnie ustawiony jest bit RE w rejestrze CR1 oraz w\u0142\u0105czone jest przerwanie od pe\u0142nego rejestru odbioru danych (CR1_ RXNEIE=1).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">W przypadku, gdy SR_RXNE=1 (bit ustawiany sprz\u0119towo)&nbsp; wywo\u0142ywany jest podprogram przerwania, w kt\u00f3rym poprzez metod\u0119 <em>portListen()<\/em>, pobierany jest znak z rejestru DR i wstawiany do kolejki odbiorczej <em>receiveQueue<\/em>.<\/p>\n\n\n\n<h6 class=\"wp-block-heading\">pp_rtx5_serial_port.cpp <\/h6>\n\n\n\n<pre class=\"wp-block-code\"><code>void PSerialPortRTX5::receiveSignAndWriteToReceiveQueue(){\n\tchar receiveChar;\n\t\n\treceiveChar=(uint8_t)(port->DR); \n\tosMessageQueuePut (receiveQueue, &amp;receiveChar, 0, 0); \n\t\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Pojawienie si\u0119 danych w kolejce <em>receiveQueue <\/em>odblokowuje w\u0105tek <em>vReceiveAndInterpretDataFromComUartThread<\/em> w kt\u00f3rym pobierane s\u0105 dost\u0119pne dane z <em>receiveQueue <\/em>i zapisywane w zmiennej <em>receiveString, <\/em>a\u017c do napotkania znaku nowej linii (pojawienie si\u0119 znaku nowej linii powoduje ustawienie flagi <em>getStringFlag <\/em>na warto\u015b\u0107 <em>true<\/em>). Powy\u017csze operacje zaimplementowane zosta\u0142y w metodzie <em>waitForReadyRead ()<\/em> wywo\u0142ywanej w ciele p\u0119tli w\u0105tku <em>vReceiveAndInterpretDataFromComUartThread.<\/em> Do momentu wywo\u0142ania <em>readLine() <\/em>nie przyjmowane s\u0105 dane z kolejki <em>receiveQueue.<\/em> Je\u017celi metoda <em>readLine() zwraca pusty ci\u0105g znak\u00f3w (readLine().empty()==true) oznacza to, \u017ce dane do odczytu nie s\u0105 gotowe.<\/em><\/p>\n\n\n\n<h6 class=\"wp-block-heading\">pp_rtx5_serial_port.cpp  <\/h6>\n\n\n\n<pre class=\"wp-block-code\"><code>bool PSerialPortRTX5::waitForReadyRead(int usec){\r\n\t\tchar receiveChar;\r\n\t\tint tick;\r\n\t\r\n\t\tif(usec==osWaitForever){\r\n\t\t\ttick=osWaitForever;\r\n\t\t}else{\r\n\t\t\ttick=(OS_TICK_FREQ\/1000000)*usec;\r\n\t\t}\r\n\t\r\n\t\tif(getStringFlag==false){\r\n\t\t\tif(osMessageQueueGet(receiveQueue, &amp;receiveChar, NULL, tick) == osOK){\r\n\r\n\t\t\t\treceiveString+=receiveChar; \r\n\r\n\t\t\t\tif(receiveChar=='\\n'){\r\n\r\n\t\t\t\t\tgetStringFlag=true;\r\n\r\n\t\t\t\t}else if(receiveString.size()>64){\r\n\t\t\t\t\t\treceiveString.clear();\r\n\t\t\t\t\t\r\n\t\t\t\t}\r\n\t\t\t\treturn true;\r\n\t\t\t}  \r\n\t\t}\r\n\t\t\r\n\t\treturn false;\r\n\t\r\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Interpretacja odebranych danych<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Interpretacja odebranych danych, w postaci AT komend, nast\u0119puje w \u201edekoracji\u201d metody <em><em>readLine().<\/em><\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">W przypadku podes\u0142ania AT+TRVV (przejazd o warto\u015b\u0107) lub AT+TRVCO (przejazd na wsp\u00f3\u0142rz\u0119dne) parametry danej operacji wysy\u0142ane s\u0105 z wykorzystaniem kolejki <em>taskCommunicationQueues<\/em> do w\u0105tku <em>vRealizationFunctionThread<\/em> odpowiadaj\u0105cego za realizacj\u0119 podstawowych zada\u0144 projektu, a wi\u0119c za kontrol\u0119 obrot\u00f3w silnika krokowego. Ramka danych \u201e\u0142adowana\u201d do kolejki zawiera informacje o:<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"a\"><li>\u0179r\u00f3dle wywo\u0142ania danej operacji(w tym przypadku jest to AT komenda),<\/li><li>Typie operacji do realizacji,<\/li><li>Parametrach operacji.<\/li><\/ul>\n\n\n\n<h6 class=\"wp-block-heading\">pp_rtx5_at_commands_interpreter.cpp<\/h6>\n\n\n\n<pre class=\"wp-block-code\"><code>string defORTX5atCommandInterpreter::readLine(){\r\n\t\r\n\tstring receiveString=PIOdeviceDecorator::readLine();\r\n\t\r\n\tif(receiveString.empty()==false){\r\n\t\r\n\t\tPString data(receiveString);\r\n\t\tstring answer=\"FAIL\\r\\n\";\r\n\t\tint index=0;\r\n\t\t if(data.find(\"AT+TRVV\")!=string::npos){\r\n\t\t\t\tmap&lt;char, double> values;\r\n\t\t\t\tvector&lt;int> valuesToSend;\r\n\t\t\t\tindex=data.find(\"AT+TRVV\");\r\n\t\t\t\tdata.erase(0, index+7);\r\n\t\t\t\tvalues=data.findValuesAfterAcronims();\r\n\t\t\t \r\n\t\t\t\tif(!values.empty()){\r\n\t\t\t\t\tvaluesToSend.push_back(qMARK_ATC);\r\n\t\t\t\t\tvaluesToSend.push_back(AT_TAG_TRVV);\r\n\t\t\t\t\tvaluesToSend.push_back(values.size());\r\n\t\t\t\t\t\r\n\t\t\t\t\tfor(auto it=values.begin(); it!=values.end(); ++it){\r\n\t\t\t\t\t\tvaluesToSend.push_back((*it).first);\r\n\t\t\t\t\t\tvaluesToSend.push_back((*it).second*pow(10.0, phyCoord->getParamUnit((*it).first)));\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\ttaskCommunicationQueues->xQueueSendConteinerToBackWithSemaphore(valuesToSend);\r\n\t\t\t\t\tanswer=\"OK\\r\\n\";\r\n\t\t\t\t};\r\n\t\t }else if(data.find(\"AT+TRVCO\")!=string::npos){\r\n\t\t\t\tmap&lt;char, double> values;\r\n\t\t\t\tvector&lt;int> valuesToSend;\r\n\t\t\t\tindex=data.find(\"AT+TRVCO\");\r\n\t\t\t\tdata.erase(0, index+8);\r\n\t\t\t\tvalues=data.findValuesAfterAcronims();\r\n\t\t\t \r\n\t\t\t\tif(!values.empty()){\r\n\t\t\t\t\tvaluesToSend.push_back(qMARK_ATC);\r\n\t\t\t\t\tvaluesToSend.push_back(AT_TAG_TRVCO);\r\n\t\t\t\t\tvaluesToSend.push_back(values.size());\r\n\t\t\t\t\t\r\n\t\t\t\t\tfor(auto it=values.begin(); it!=values.end(); ++it){\r\n\t\t\t\t\t\tvaluesToSend.push_back((*it).first);\r\n\t\t\t\t\t\tvaluesToSend.push_back((*it).second*pow(10.0, phyCoord->getParamUnit((*it).first)));\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\ttaskCommunicationQueues->xQueueSendConteinerToBackWithSemaphore(valuesToSend);\r\n\t\t\t\t\tanswer=\"OK\\r\\n\";\r\n\t\t\t\t};\r\n\t\t }else if(data.find(\"AT+BASEC\")!=string::npos){\r\n\t\t\t\tindex=data.find(\"AT+BASEC\");\r\n\t\t\t\tif(data.at(index+8)=='?'){\t\r\n\t\t\t\t\tanswer=\"BASEC \";\r\n\t\t\t\t\tanswer+=baseCoord->getStringWithParams();\r\n\t\t\t\t\tanswer+=\"\\r\\n\";\r\n\t\t\t\t}else{\t\t\r\n\t\t\t\t\tdata.erase(0, index+8);\r\n\t\t\t\t\tbaseCoord->setParamsBasedString(&amp;data);\r\n\t\t\t\t\tanswer=\"OK\\r\\n\";\r\n\t\t\t\t}\r\n\t\t\t}else if(data.find(\"AT+PHYC\")!=string::npos){\r\n\t\t\t\tindex=data.find(\"AT+PHYC\");\r\n\t\t\t\tif(data.at(index+7)=='?'){\t\r\n\t\t\t\t\tanswer=\"PHYC \";\r\n\t\t\t\t\tanswer+=phyCoord->getStringWithParams();\r\n\t\t\t\t\tanswer+=\"\\r\\n\";\r\n\t\t\t\t}else{\t\t\r\n\t\t\t\t\tdata.erase(0, index+8);\r\n\t\t\t\t\tphyCoord->setParamsBasedString(&amp;data);\r\n\t\t\t\t\tanswer=\"OK\\r\\n\";\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(response)PIOdeviceDecorator::write(answer);\r\n\t\t}\r\n    \r\n\t\treturn receiveString;\r\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Lista interpretowanych AT komend<\/strong><\/h4>\n\n\n\n<figure class=\"wp-block-table alignwide is-style-stripes\"><table><tbody><tr><td><strong>AT+BASEC X&lt;x&gt;\\r\\n<\/strong><\/td><td>Ustawienie wsp\u00f3\u0142rz\u0119dnych operatora &nbsp; <br><br>Odpowied\u017a: <br><strong>OK<\/strong>: zatwierdzenie odbioru danych,<br><strong>FAIL<\/strong>: brak parametr\u00f3w, <br><br>Parametry: <br><strong>&lt;x&gt;:<\/strong> nowa warto\u015b\u0107 wsp\u00f3\u0142rz\u0119dnej X [mm],<\/td><\/tr><tr><td><strong>AT+BASEC? \\r\\n<\/strong><\/td><td>Pobranie wsp\u00f3\u0142rz\u0119dnych operatora. &nbsp; <br><br>Odpowied\u017a:<strong> BASEC X&lt;x&gt;\\r\\n<\/strong> <br><br>Parametry: <br><strong>&lt;x&gt;:<\/strong> warto\u015b\u0107 wsp\u00f3\u0142rz\u0119dnej X [mm]<\/td><\/tr><tr><td><strong>AT+PHYC X&lt;x&gt; \\r\\n<\/strong><strong><\/strong><\/td><td>Ustawienie wsp\u00f3\u0142rz\u0119dnych fizycznych. &nbsp; <br><br>Odpowied\u017a: <br><strong>OK<\/strong>: zatwierdzenie odbioru danych,<br><strong>FAIL<\/strong>: brak parametr\u00f3w, <br><br>Parametry: <br><strong>&lt;x&gt;:<\/strong> nowa warto\u015b\u0107 wsp\u00f3\u0142rz\u0119dnej X [mm],<\/td><\/tr><tr><td><strong>AT+PHYC? \\r\\n<\/strong><\/td><td>Pobranie wsp\u00f3\u0142rz\u0119dnych fizycznych. &nbsp; <br><br>Odpowied\u017a:<strong> PHYC X&lt;x&gt;\\r\\n<\/strong> <br><br>Parametry: <br><strong>&lt;x&gt;:<\/strong> warto\u015b\u0107 wsp\u00f3\u0142rz\u0119dnej X [mm],<\/td><\/tr><tr><td><a><strong>AT+TRVCO X&lt;x&gt;\\r\\n<\/strong><\/a><strong><\/strong><\/td><td>Przejazd na wsp\u00f3\u0142rz\u0119dne. &nbsp; <br><br>Odpowied\u017a: <br><strong>OK<\/strong>: zatwierdzenie odbioru danych,<br><strong>FAIL<\/strong>: brak parametr\u00f3w,  <br><br>Parametry: <br><strong>&lt;x&gt;:<\/strong> wsp. operatora X na jak\u0105 ma przejecha\u0107 maszyna [mm], &nbsp;<\/td><\/tr><tr><td><strong>AT+TRVV X&lt;x&gt; r\\n<\/strong><strong><\/strong><\/td><td>Przejazd o warto\u015b\u0107. &nbsp; <br><br>Odpowied\u017a: <br><strong>OK<\/strong>: zatwierdzenie odbioru danych,<br><strong>FAIL<\/strong>: brak parametr\u00f3w, <br><br>Parametry: <br><strong>&lt;x&gt;:<\/strong> warto\u015b\u0107 przejazdu po osi X [mm],<\/td><\/tr><\/tbody><\/table><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Komunikacja pomi\u0119dzy PC, a p\u0142ytk\u0105 DISCOVERY oparta zosta\u0142a na interfejsie UART. W celu pod\u0142\u0105czenia urz\u0105dze\u0144 wymagana jest przej\u015bci\u00f3wka USB-UART, najlepiej, wyposa\u017cona w uk\u0142ad FT232. Konfiguracja mikrokontrolera pod obs\u0142ug\u0119 UART przedstawiona zosta\u0142a w cz\u0119\u015bci 1 omawianej biblioteki. Projekt do pobrania z: https:\/\/github.com\/PiotrPoterala\/stm32f429i-disco_stepper_motor oraz biblioteki: https:\/\/github.com\/PiotrPoterala\/PP_Library Struktura klas Mechanizm odbioru\/wysy\u0142ania danych oparty zosta\u0142 na wzorcu projektowym Dekorator.&hellip; <a class=\"more-link\" href=\"https:\/\/www.zappp.pl\/blog\/library-1-sterownik-silnika-krokowego-na-stm32f429-disco-part-3\/\">Czytaj dalej <span class=\"screen-reader-text\">Library 1 \u2013 sterownik silnika krokowego na STM32F429 DISCO (part 3).<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[13,7,11,10,6,12],"class_list":["post-154","post","type-post","status-publish","format-standard","hentry","category-stm32f429-disco","tag-at-commands","tag-disco","tag-rtx5","tag-stepper-motor-driver","tag-stm32f429","tag-uart","entry"],"_links":{"self":[{"href":"https:\/\/www.zappp.pl\/blog\/wp-json\/wp\/v2\/posts\/154","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.zappp.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.zappp.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.zappp.pl\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.zappp.pl\/blog\/wp-json\/wp\/v2\/comments?post=154"}],"version-history":[{"count":9,"href":"https:\/\/www.zappp.pl\/blog\/wp-json\/wp\/v2\/posts\/154\/revisions"}],"predecessor-version":[{"id":175,"href":"https:\/\/www.zappp.pl\/blog\/wp-json\/wp\/v2\/posts\/154\/revisions\/175"}],"wp:attachment":[{"href":"https:\/\/www.zappp.pl\/blog\/wp-json\/wp\/v2\/media?parent=154"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.zappp.pl\/blog\/wp-json\/wp\/v2\/categories?post=154"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.zappp.pl\/blog\/wp-json\/wp\/v2\/tags?post=154"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}