Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2017:pool-ctrl

Rozdíly

Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.

Odkaz na výstup diff

Obě strany předchozí revize Předchozí verze
Následující verze
Předchozí verze
2017:pool-ctrl [2018/01/14 03:34]
Adam Bartoš pridané komplet vlastné zdrojáky
2017:pool-ctrl [2018/01/14 19:28] (aktuální)
Adam Bartoš [Software] opravený kód
Řádek 14: Řádek 14:
  
  
-Ako vývojový HW boli použité nasledujúce moduly. FRDM-K64F ako hlavná riadiaca doska, CY7C68013A na debugovanie I2C zbernice a vlastný modul obsahujúci spínanie zariadení (čerpadlo, generátor ozónu) pomocou relé a zároveň integrujúci obvod reálneho času (RTC). ​+Ako vývojový HW boli použité nasledujúce moduly. FRDM-K64F ako hlavná riadiaca doska, CY7C68013A na debugovanie I2C zbernice a vlastný modul obsahujúci spínanie zariadení (čerpadlo, generátor ozónu, svetlo) pomocou relé a zároveň integrujúci obvod reálneho času (RTC). ​
  
  
Řádek 22: Řádek 22:
  
 {{ :​2017:​xbarto78:​frdm_k64f_reve4_header_pinout.jpg?​direct&​650 |}} {{ :​2017:​xbarto78:​frdm_k64f_reve4_header_pinout.jpg?​direct&​650 |}}
 +
 +{{ :​2017:​xbarto78:​final_photo.jpg?​direct&​600 |{{ :​2017:​xbarto78:​final_photo.jpg?​direct&​600 |}}
  
 ---- ----
Řádek 29: Řádek 31:
  
  
-K modulu FRDM-K64F bol navrhnutá externá doska obsahujúca relé a obvod reálneho času (RTC), ktorý komunikuje s procesorom pomocou I2C zbernice. Zapojenie a plošný spoj je vyobrazený nižšie. Pull-up rezistory na I2C dátovej zbernici nie sú použité z dôvodu, že ich obsahuje priamo doska FRDM-K64F, na ktorej je na túto zbernicu pripojený akcelerometer. Bolo preto potrebné vyvarovať sa použitiu rovnakých adries zariadení. Obvod reálneho času používa 5V úrovne, zatiaľ čo K64F 3.3V úrovne, a preto by ani nemohli byť pull-up rezistory použité a zapojené medzi 5V napájaciu vetvu a I2C zbernice. Obvod reálneho času DS1307 avšak bezproblémovo funguje aj v takomto zapojení. ​+K modulu FRDM-K64F bol navrhnutá externá doska obsahujúca relé a obvod reálneho času (RTC), ktorý komunikuje s procesorom pomocou I2C zbernice. Zapojenie a plošný spoj je vyobrazený nižšie. Pull-up rezistory na I2C dátovej zbernici nie sú použité z dôvodu, že ich obsahuje priamo doska FRDM-K64F, na ktorej je na túto zbernicu pripojený akcelerometer. Bolo preto potrebné vyvarovať sa použitiu rovnakých adries zariadení. Obvod reálneho času používa 5V úrovne, zatiaľ čo K64F 3.3V úrovne, a preto by ani nemohli byť pull-up rezistory použité a zapojené medzi 5V napájaciu vetvu a I2C zbernice. Obvod reálneho času DS1307 avšak bezproblémovo funguje aj v takomto zapojení. Čas je zálohovaný pomocou 3V líthiovej batérie, ktorá v prípade výpadku napájania udrží aktuálny čas až po dobu cca 10 rokov
  
 **Schéma zapojenia** **Schéma zapojenia**
Řádek 71: Řádek 73:
  
  
-Softwarové riešenie je možné rozdeliť na 2 časti - klientskú a serverovú. Klientská časť obsahuje samotnú web stránku v HTML a javascripte. Serverová časť sa skladá z jednoduchého webového servera schopného obsluhovať požiadavky GET a POST. Pomocou požiadavok POST sa následne vykonávajú všetky dostupné príkazy, ktoré museli byť ručne vytvorené a následne sa v kóde spracovávajú. Stránka sa načítava z microSD karty na ktorú sú umiestnené súbory index.html a api.js. Taktiež je tu možné umiestniť jQuery a Bootstrap javascript knižnice, avšak načítavanie stránky by kvôli nízkemu výkonu serveru zabralo značne dlhú dobu, preto sú tieto nalinkované na externé servery. ​+Softwarové riešenie je možné rozdeliť na 2 časti - klientskú a serverovú. Klientská časť obsahuje samotnú web stránku v HTML a javascripte. ​Stránka obsahuje použitý Boostrap toolkit, ktorý pomáha zabezpečiť responzívnosť webu. Na interaktivitu so serverom je použitý Javasript.  
 +Serverová časť sa skladá z jednoduchého webového servera schopného obsluhovať požiadavky GET a POST. Pomocou požiadavok POST sa následne vykonávajú všetky dostupné príkazy, ktoré museli byť ručne vytvorené a následne sa v kóde spracovávajú. ​ 
 + 
 +Stránka sa načítava z microSD karty na ktorú sú umiestnené súbory index.html a api.js. Taktiež je tu možné umiestniť jQuery a Bootstrap javascript knižnice, avšak načítavanie stránky by kvôli nízkemu výkonu serveru zabralo značne dlhú dobu, preto sú tieto nalinkované na externé servery. Na SD karte sa nachádzajú aj textové súbory obsahujúce zapísaný aktuálny stav ovládaných zariadení a intervaly automatickej prevádzky. Preto po výpadku napájania, prípadne reštarte zariadenia nabehne zariadenie do pôvodného stavu, resp. v prípade automatického režimu do stavu definovaného intervalmi
  
  
 **Web stránka - HTML kód** **Web stránka - HTML kód**
 +Stránka sa skladá z jednoduchého HTML kódu doplneného o Bootstrap položky. Zabezpečenie prístupu nebolo implementované kvôli využívaniu web stránky čisto na lokálnej sieti. ​
 +
 <code html> <code html>
  
Řádek 80: Řádek 87:
 <html lang="​en">​ <html lang="​en">​
     <​head>​     <​head>​
- <​title>​Swimmingpool controller</​title>​+ <​title>​Swimmingpool controller</​title>​
         <meta charset="​utf-8">​         <meta charset="​utf-8">​
         <meta name="​viewport"​ content="​width=device-width,​ initial-scale=1">​         <meta name="​viewport"​ content="​width=device-width,​ initial-scale=1">​
Řádek 91: Řádek 98:
     <​body>​     <​body>​
         <div class="​container">​         <div class="​container">​
-            ​<div class="​row"​ id="​last_update_time">​ +            <button type="​button"​ class="​btn btn-primary"><​h1>​Swimmingpool controller</​h1></​button
-            </​div>​ +            <div class="​row"​ id="​last_update_time"></​div>
- <button type="​button"​ class="​btn btn-primary"><​h1>​Swimmingpool controller</​h1></​button>​ +
             <div class="​row"​ id="​light_control">​             <div class="​row"​ id="​light_control">​
                 <div class="​col-xs-12">​                 <div class="​col-xs-12">​
Řádek 265: Řádek 271:
  
 **Web stránka - Javascript kód** **Web stránka - Javascript kód**
 +
 +Keďže server nie je práve výkonný a pre dané použitie to ani nie je potrebné, javascript kód zabezpečuje aktualizovanie údajov na stránke každých 20 sekúnd. Nízky výkon servera spôsobuje občasné neobslúženie requestu webového klienta, preto bol do Javascriptu vytvorený timeout, kedy sa daný request príkaz znova odošle, ak predchádzajúce odoslanie do 2 sekúnd zlyhalo. Toto spôsobuje síce pomalšie aktualizovanie jednotlivých položiek stránky, avšak zabezpečí to 100% načítanie všetkých hodnôt. ​
 +
 <code javascript>​ <code javascript>​
-var update_interval = 20; +var update_interval = 20; //update interval (sec) of refreshing actual light, pump and ozone state 
-var error_resend_timeout = 2000;+var error_resend_timeout = 2000; // timeout (ms) for resending request if previous request failed ​
  
 +/*    Change status of output on webpage ​ */
 function set_status(controller,​ new_status) { function set_status(controller,​ new_status) {
     if (new_status == 0) {     if (new_status == 0) {
Řádek 282: Řádek 292:
 } }
  
 +/*    Change state of output ​  */
 function set_state(controller,​ new_state) { function set_state(controller,​ new_state) {
     if (new_state == 0) {     if (new_state == 0) {
Řádek 292: Řádek 303:
 } }
  
 +/*    Update actual time on website ​  */
 function update_time(tmv) { function update_time(tmv) {
     var d = new Date();     var d = new Date();
Řádek 303: Řádek 315:
     d.setSeconds(tmv.sec);​     d.setSeconds(tmv.sec);​
     $("#​last_update_time"​).html("​Last update: " + d.toLocaleString());​     $("#​last_update_time"​).html("​Last update: " + d.toLocaleString());​
- 
-    $("#​sel_year"​).val(tmv.year);​ 
-    $("#​sel_month"​).val(tmv.month);​ 
-    $("#​sel_date"​).val(tmv.date);​ 
-    $("#​sel_day"​).val(tmv.day);​ 
-    $("#​sel_hour"​).val(tmv.hour);​ 
-    $("#​sel_min"​).val(tmv.min);​ 
-    $("#​sel_sec"​).val(tmv.sec);​ 
 } }
  
 +/*    Send post with actual time to server ​   */
 function set_clock_ajax(data_string) { function set_clock_ajax(data_string) {
     $.ajax({     $.ajax({
Řádek 322: Řádek 327:
         success: function(result) {         success: function(result) {
             update_time(result.time);​             update_time(result.time);​
 + $("#​sel_year"​).val(tmv.year);​
 + $("#​sel_month"​).val(tmv.month);​
 + $("#​sel_date"​).val(tmv.date);​
 + $("#​sel_day"​).val(tmv.day);​
 + $("#​sel_hour"​).val(tmv.hour);​
 + $("#​sel_min"​).val(tmv.min);​
 + $("#​sel_sec"​).val(tmv.sec);​
         },         },
         error: function (request, status, error) {         error: function (request, status, error) {
Řádek 332: Řádek 344:
 } }
  
 +/*    Parse time to string ​   */
 function set_clock() { function set_clock() {
     var year = $("#​sel_year"​).val().toString();​     var year = $("#​sel_year"​).val().toString();​
Řádek 344: Řádek 357:
 } }
  
 +/*    Set status, state and update time via AJAX    */
 function trigger_ajax(controller,​ action) { function trigger_ajax(controller,​ action) {
     $.ajax({     $.ajax({
Řádek 363: Řádek 377:
 } }
  
 +/*     ​Trigger action ​   */
 function trigger(controller,​ action) { function trigger(controller,​ action) {
     console.log(controller + "​_"​ + action);     console.log(controller + "​_"​ + action);
Řádek 368: Řádek 383:
 } }
  
 +/*     ​Update status of all controlled devices ​   */
 function update_all() { function update_all() {
     trigger("​light",​ "​status"​);​     trigger("​light",​ "​status"​);​
Řádek 374: Řádek 390:
 } }
  
 +/*     ​Maximal number of intervals in table   */
 var max_intervals = { var max_intervals = {
     "​pump":​ 10,     "​pump":​ 10,
Řádek 383: Řádek 400:
 }; };
  
 +/*    Function for adding new interval ​   */
 function add_interval(ctrl) { function add_interval(ctrl) {
     console.log("​adding " + ctrl + " interval"​);​     console.log("​adding " + ctrl + " interval"​);​
Řádek 404: Řádek 422:
 } }
  
 +/*    Set parameters of interval - start hour+min and end hour+min ​   */
 function set_interval(interval,​ values) { function set_interval(interval,​ values) {
     $(interval).find("​[name=start_hour] input"​).val(values["​start_hour"​]);​     $(interval).find("​[name=start_hour] input"​).val(values["​start_hour"​]);​
Řádek 411: Řádek 430:
 } }
  
 +/*    Set all intervals ​   */
 function set_intervals(ctrl,​ intervals, tmv) { function set_intervals(ctrl,​ intervals, tmv) {
     for (var i = 0; i < intervals.length;​ i++) {     for (var i = 0; i < intervals.length;​ i++) {
Řádek 419: Řádek 439:
 } }
  
 +/*    Clears interval table    */
 function clear_intervals(ctrl) { function clear_intervals(ctrl) {
     $("#"​ + ctrl + "​_intervals tbody"​).empty();​     $("#"​ + ctrl + "​_intervals tbody"​).empty();​
Řádek 424: Řádek 445:
 } }
  
 +/*     Post interval parameters to server via AJAX    */
 function update_intervals_ajax(ctrl,​ act, data_values) { function update_intervals_ajax(ctrl,​ act, data_values) {
     $.ajax({     $.ajax({
Řádek 446: Řádek 468:
 } }
  
 +/*    Update intervals on webpage via data from webserver ​   */
 function update_intervals(ctrl,​ act) { function update_intervals(ctrl,​ act) {
     console.log("​update " + ctrl + " intervals"​);​     console.log("​update " + ctrl + " intervals"​);​
Řádek 467: Řádek 490:
  
 update_all();​ update_all();​
-setInterval(update_all,​ update_interval * 1000);+setInterval(update_all,​ update_interval * 1000); ​
 update_intervals("​pump",​ "​get"​);​ update_intervals("​pump",​ "​get"​);​
 update_intervals("​ozone",​ "​get"​);​ update_intervals("​ozone",​ "​get"​);​
 +
  
 </​code>​ </​code>​
  
 ** Serverová časť ** ** Serverová časť **
-Zo serverovej časti sú zverejnené iba niektoré zaujímavé časti kódu. ​Knižnice a základný + 
-kód servera je možné nájsť na odkazoch priložených na konci dokumentácie. ​Taktiež ​je tam +Zo serverovej časti sú v dokumentácii ​zverejnené iba niektoré zaujímavé časti kódu. ​Prevzaté knižnice ​pre ovládanie RTC DS1307 ​čítanie/​zápis na SD kartu, ďalej prevzatý funkčný ​základný kód web servera je možné nájsť na odkazoch priložených na konci dokumentácie. ​Kompletný kód tohoto projektu pre FRDM-K64F ​je na nasledujúcom odkaze: 
-priložený odkaz na publikovaný kompletný ​mbed os kód, ktorý je voľne sprístupnený na použitie+[[https://​os.mbed.com/​users/​zelatina/​code/​projekt-mpoa-final/​]]
  
 <code c> <code c>
Řádek 514: Řádek 538:
 } }
 </​code>​ </​code>​
 +
 +** Ukážka komunikácie na I2C zbernici pri získavaní nového času **
 +
 +{{ :​2017:​xbarto78:​i2c_komunikacia.png?​direct&​800 |}}
  
 <code c> <code c>
Řádek 619: Řádek 647:
 void handle_post_cmd(char *cmd, std::string payload) void handle_post_cmd(char *cmd, std::string payload)
 { {
-    uart.printf("​Sending:​ header"​);​+    uart.printf("​Sending:​ header\n");
     sprintf(httpHeader,"​HTTP/​1.1 200 OK\r\nContent-Type:​ application/​json\r\nConnection:​ Close\r\n\r\n"​);​     sprintf(httpHeader,"​HTTP/​1.1 200 OK\r\nContent-Type:​ application/​json\r\nConnection:​ Close\r\n\r\n"​);​
     client.send(httpHeader,​strlen(httpHeader));​     client.send(httpHeader,​strlen(httpHeader));​
Řádek 627: Řádek 655:
 } }
 </​code>​ </​code>​
 +
 +** Ukážka - výpis na sériovú zbernicu pri komunikácii web serveru s klientom**
 +
 +<​code>​
 +Connection from: 192.168.1.7
 +Recieved Data: 458
 +
 +POST /​light_status HTTP/1.1
 +Host: 192.168.1.5
 +Connection: keep-alive
 +Content-Length:​ 0
 +Accept: application/​json,​ text/​javascript,​ */*; q=0.01
 +Origin: http://​192.168.1.5
 +X-Requested-With:​ XMLHttpRequest
 +User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/​537.36 (KHTML, like Gecko) Chrome/​63.0.3239.132 Safari/​537.36
 +DNT: 1
 +Referer: http://​192.168.1.5/​index.html
 +Accept-Encoding:​ gzip, deflate
 +Accept-Language:​ cs,​sk;​q=0.9,​en;​q=0.8
 +
 +
 +Payload: ​
 +Sending: header.
 +Current time got successfully:​ 2018/1/14 (Sunday) 15:56:18
 +Done sending header.
 +Checking and executing auto intervals.
 +Current time got successfully:​ 2018/1/14 (Sunday) 15:56:20
 +
 +Wait for new connection...
 +</​code>​
 +
  
 <code c> <code c>
Řádek 632: Řádek 691:
 bool is_in_interval(int sh, int sm, int eh, int em, int hour, int min) bool is_in_interval(int sh, int sm, int eh, int em, int hour, int min)
 { {
-    if ((sh < hour && hour < eh) | +    if ((sh < hour && hour < eh) |
-            (sh <= hour && sm <= min && (hour < eh | (hour <= eh && min <= em))) |+            (sh <= hour && sm <= min && (hour < eh || (hour <= eh && min <= em))) ||
             (sh < hour && hour <= eh && min <= em)) {             (sh < hour && hour <= eh && min <= em)) {
         return true;         return true;
Řádek 659: Řádek 718:
         int em = it->​end_min;​         int em = it->​end_min;​
         ​         ​
-        if (sh <= eh && sm <= em) {+        ​ 
 +        ​if ((sh < eh) || (sh == eh && sm <= em)) {
             /*             /*
              * Timeline:              * Timeline:
Řádek 723: Řádek 783:
  
  
 +Na demonštračnom videu sú predvedené funkcie zariadenia, nastavenie hodín, automatický a manuálny režim. Ako si pozornejší určite všimnú, ovládacia automatika riadenia ozónu je zapnutá, avšak podľa intervalu a aktuálneho času by generátor ozónu nemal byť zapnutý. Je to spôsobené vytvorením nového intervalu bez zaslania na server pomocou tlačítka "​Update"​. Automatika preto beží na pôvodne nastavené intervaly uložené na SD karte. V prípade čerpadla (Pump) bol ukážkový interval odoslaný na server a preto ovládacia automatika funguje správne. ​
  
 +{{ youtube>​0scd_KOdYsA?​medium }}
 ---- ----
  
Řádek 730: Řádek 792:
  
  
 +Zadaný projekt bol dokončený do plne funkčného stavu. Funguje ako manuálne, tak aj automatické ovládanie. Automatika funguje podľa zadaných intervalov, nezávisle pre bazénové čerpadlo a pre generátor ozónu. Riadenie je zabezpečované na základe aktuálneho času, ktorý je uložený v obvode reálneho času (RTC) DS1307, tento obvod je zálohovaný,​ takže aj po výpadku napájania je čas stále aktuálny. Zálohované sú aj aktuálne stavy výstupov a časové intervaly pre automatickú prevádzku. Stránka je kvôli použitiu toolkitu Bootstrap responzívna a dá sa pohodlne ovládať či už na PC alebo aj na mobilných zariadeniach. ​
  
 +Jediný problém spôsobuje malý výkon zariadenia a z toho vyplývajúce problémy pri pripojení viacerých zariadení. Toto avšak bolo testované iba kvôli vyladeniu softwéru, reálne bude k serveru pristupovať naraz iba jedno zariadenie, čo tento server bez väčších problémov zvláda. Väčšinu problémov spôsobených dlhou odozvou sa podarilo vyriešiť opakovaným posielaním requestov a externým načítavaním jQuery a Bootstrap knižníc. ​
 +
 +Do kódu pre K64F bolo pôvodne riadenie automatickej obsluhy implementované pomocou paralelného threadu a RTOS, avšak nepodarilo sa toto riešenie správne odladiť. Pravdepodobne chyby v knižnici pre SD kartu spôsobovali pri čítaní/ zápise a použití paralelného threadu náhodné zamrznutie procesora. Preto je táto časť kódu momentálne volaná v nekonečnej slučke popri čakaní HTTP servera na prístup. ​
 +
 +Absentuje zabezpečenie prístupu na web stránku, čo v prípade použitia v lokálnej sieti nevadí. Pre použitie s prístupom z vonkajšej siete nie je problém do HTML kódu vložiť jednoduchý blok kódu zabezpečujúci overenie užívateľa pomocou hesla. ​
 ---- ----
  
  
-====== Odkazy na použité zdroje ======+====== Odkazy na použité zdroje, prílohy ​======
  
  
Řádek 743: Řádek 811:
 Boostrap na web stránke - [[https://​www.w3schools.com/​bootstrap/​]] Boostrap na web stránke - [[https://​www.w3schools.com/​bootstrap/​]]
  
 +jQuery na web stránke - [[https://​jquery.com/​download/​]]
  
 +Podklady pre výrobu DPS, HTML, Javascript kód, Mbed binárka - [[http://​www.urel.feec.vutbr.cz/​MPOA/​_media/​2017/​xbarto78/​xbarto78_mpoa_priloha.zip|Komprimovaný súbor zip]]
  
 +Vlastný Mbed repozitár - [[https://​os.mbed.com/​users/​zelatina/​code/​projekt-mpoa-final/​]]
2017/pool-ctrl.1515897273.txt.gz · Poslední úprava: 2018/01/14 03:34 autor: Adam Bartoš