SDS-C: examples: Porovnání verzí

Řádek 3: Řádek 3:
 
Některá zařízení SDS používají FULL-C, pro který máme návody jinde na této WiKi.
 
Některá zařízení SDS používají FULL-C, pro který máme návody jinde na této WiKi.
 
</pre>
 
</pre>
 
  
 
== Příklady SDS-C ==
 
== Příklady SDS-C ==
  
 
Ideální pro seznámení se s jazykem SDS-C je prohlédnutí a vlastní úprava příkladů.
 
Ideální pro seznámení se s jazykem SDS-C je prohlédnutí a vlastní úprava příkladů.
 
  
 
Příklady jsou testovány s nejnovějším firmware - stáhnete jej zdarma z této WiKi.
 
Příklady jsou testovány s nejnovějším firmware - stáhnete jej zdarma z této WiKi.
 
  
 
Používejte vždy nejnovější firmware a EXE.
 
Používejte vždy nejnovější firmware a EXE.
Řádek 19: Řádek 16:
  
 
Využijeme konzolový (testovací) výstup pomocí funkce "echo".
 
Využijeme konzolový (testovací) výstup pomocí funkce "echo".
 
  
 
Tento příklad využívá globální proměnnou ''i''. Každý program se vždy začne vykonávat od funkce ''main''.
 
Tento příklad využívá globální proměnnou ''i''. Každý program se vždy začne vykonávat od funkce ''main''.
 
  
 
Ve funkci ''main'' se nejprve inicializuje obsah ''i'' na hodnotu '''0'''. Dále se provede smyčka, která zvyšuje hodnotu ''i'' o jedničku. Jakmile dosáhne ''i'' hodnoty '''20''', je smyčka ukončena a program skončí (pozor, jakmile ukončíme ''main'', je celý program spuštěn znovu od začátku, tedy přesněji ''main'' je spuštěno znovu).
 
Ve funkci ''main'' se nejprve inicializuje obsah ''i'' na hodnotu '''0'''. Dále se provede smyčka, která zvyšuje hodnotu ''i'' o jedničku. Jakmile dosáhne ''i'' hodnoty '''20''', je smyčka ukončena a program skončí (pozor, jakmile ukončíme ''main'', je celý program spuštěn znovu od začátku, tedy přesněji ''main'' je spuštěno znovu).
 
  
 
Pro každý průchod smyčkou je ''i'' testováno, je-li prvočíslem. To se provádí ve funkci ''test_na_prvocislo''. V této funkci je definována další proměnná ''j'' ('''pozor, i když je definována uvnitř funkce, je stále globální !!!'''). Následuje další smyčka, kde se provede test na zbytek po dělení (pokud vyjde nula, je ''i'' dělitelné a není prvočíslem, ale to už je teorie mimo SDS-C, že). Pokud tedy najdeme dělitel co nenechá zbytek, je funkce ''test_na_prvocislo'' předčasně ukončena vyhrazeným příkazem '''return'''.
 
Pro každý průchod smyčkou je ''i'' testováno, je-li prvočíslem. To se provádí ve funkci ''test_na_prvocislo''. V této funkci je definována další proměnná ''j'' ('''pozor, i když je definována uvnitř funkce, je stále globální !!!'''). Následuje další smyčka, kde se provede test na zbytek po dělení (pokud vyjde nula, je ''i'' dělitelné a není prvočíslem, ale to už je teorie mimo SDS-C, že). Pokud tedy najdeme dělitel co nenechá zbytek, je funkce ''test_na_prvocislo'' předčasně ukončena vyhrazeným příkazem '''return'''.
 
V opačném případě, po dokončení smyčky, je vypsáno potvrzení, že konkrétní ''i'' je prvočíslem (funkce ''echo'').
 
V opačném případě, po dokončení smyčky, je vypsáno potvrzení, že konkrétní ''i'' je prvočíslem (funkce ''echo'').
 
  
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
Řádek 71: Řádek 64:
  
 
Posílání emailu při poklesu teploty čidla '''0''' pod nastavenou mez.
 
Posílání emailu při poklesu teploty čidla '''0''' pod nastavenou mez.
 
  
 
Mez se nastaví ve funkci ''init'', tato funkce je zavolána pouze jednou při startu programu, a nikdy více.
 
Mez se nastaví ve funkci ''init'', tato funkce je zavolána pouze jednou při startu programu, a nikdy více.
 
  
 
Aby se nestalo, že email bude poslan při každém průchodu testovací smyčky, je zavedená proměnná '''odeslano'''. Ta se nastaví, jakmile odešleme email, a nuluje se až když se teplota vrátí nad určenou mez (aby při dalším poklesu opět byl odeslán email, jedenkrát).
 
Aby se nestalo, že email bude poslan při každém průchodu testovací smyčky, je zavedená proměnná '''odeslano'''. Ta se nastaví, jakmile odešleme email, a nuluje se až když se teplota vrátí nad určenou mez (aby při dalším poklesu opět byl odeslán email, jedenkrát).
 
  
 
Tento příklad také ukazuje možnost použití ''#define'' za účelem zpřehlednění programu a snadných změn.
 
Tento příklad také ukazuje možnost použití ''#define'' za účelem zpřehlednění programu a snadných změn.
 
  
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
Řádek 113: Řádek 102:
 
   RELE = 1;
 
   RELE = 1;
 
}
 
}
 
  
 
uz_je_nad
 
uz_je_nad
Řádek 139: Řádek 127:
  
 
Příklad - řízení DC 12V ventilátoru pomocí PWM výstupy (SDS-MICRO), cílem je regulace teploty.
 
Příklad - řízení DC 12V ventilátoru pomocí PWM výstupy (SDS-MICRO), cílem je regulace teploty.
 
  
 
Údaj o teplotě se bere ze ''sys[310]'', hodnota PWM-duty-cycle se zapisuje do ''sys[192]''.
 
Údaj o teplotě se bere ze ''sys[310]'', hodnota PWM-duty-cycle se zapisuje do ''sys[192]''.
 
  
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
Řádek 184: Řádek 170:
  
 
Pomocí programu v SDS-C lze rozšířit funkčnost zařízení o '''ICMP PING''', a to i na více IP adres.
 
Pomocí programu v SDS-C lze rozšířit funkčnost zařízení o '''ICMP PING''', a to i na více IP adres.
 
  
 
Pozor! Funkce '''ping()''' je dostupná teprve od verze SDS-C č. '''04''' !
 
Pozor! Funkce '''ping()''' je dostupná teprve od verze SDS-C č. '''04''' !
 
  
 
V jednu chvíli lze mít pouze jeden aktivní ICMP PING poslaný z SDS-C programu (a současně lze mít i aktivní IP Watchdog, nebude se to negativně ovlivňovat, nicméně SDS-C program může mít aktivní jen jeden ICMP PING). Při každém novém zavolání funkce '''ping()''' jsou zahozeny informace o předchozím odeslaném ICMP PING REQUEST paketu, takže případná odpověď na ten předchozí ICMP PING REQUEST je ignorována a zařízení převezme pouze odpověď na ten nejposledněji odeslaný paket funkcí '''ping()''' (což je ale zcela ok - pokud např. nedostaneme odpověď ve stanoveném čase, už nás nezajímá že přijde případně později).
 
V jednu chvíli lze mít pouze jeden aktivní ICMP PING poslaný z SDS-C programu (a současně lze mít i aktivní IP Watchdog, nebude se to negativně ovlivňovat, nicméně SDS-C program může mít aktivní jen jeden ICMP PING). Při každém novém zavolání funkce '''ping()''' jsou zahozeny informace o předchozím odeslaném ICMP PING REQUEST paketu, takže případná odpověď na ten předchozí ICMP PING REQUEST je ignorována a zařízení převezme pouze odpověď na ten nejposledněji odeslaný paket funkcí '''ping()''' (což je ale zcela ok - pokud např. nedostaneme odpověď ve stanoveném čase, už nás nezajímá že přijde případně později).
 
  
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
  
var ping_seq;
+
var ping_seq;
var koho;
+
var koho;
var doba;
+
var doba;
  
posli_ping();
+
posli_ping();
{
+
{
 
   //kazdy odeslany paket musi mit jine SEQUENCE NUMBER (vzajemne odliseni pri posilani na stejnou IP atd.).
 
   //kazdy odeslany paket musi mit jine SEQUENCE NUMBER (vzajemne odliseni pri posilani na stejnou IP atd.).
 
   ping_seq++;
 
   ping_seq++;
Řádek 210: Řádek 193:
 
   if (koho == 3) { ping(192,168,1,45,ping_seq); return; };
 
   if (koho == 3) { ping(192,168,1,45,ping_seq); return; };
 
   
 
   
}
+
}
  
main
+
main
{
+
{
 
   echo('SDS-C IP watchdog SPUSTEN');
 
   echo('SDS-C IP watchdog SPUSTEN');
  
Řádek 261: Řádek 244:
  
 
   goto next_ping;
 
   goto next_ping;
}
+
}
  
 
</syntaxhighlight>
 
</syntaxhighlight>
 
  
 
Program je celkem jednoduchý, postupně posílá ping podle obsahu proměnné '''koho''', přičemž konkrétní IP adresy jsou ručně zadány.
 
Program je celkem jednoduchý, postupně posílá ping podle obsahu proměnné '''koho''', přičemž konkrétní IP adresy jsou ručně zadány.
 
Když přijde správný PING REPLY (popř. se zjišťuje ARP) do zvolené doby (nastaveno na 500 msec), program se posune na další IP adresu. Pokud však do nastavené doby PING REPLY nedorazí, je pomocí funkce '''echo''' vypsána na konzoli chybová hláška.
 
Když přijde správný PING REPLY (popř. se zjišťuje ARP) do zvolené doby (nastaveno na 500 msec), program se posune na další IP adresu. Pokud však do nastavené doby PING REPLY nedorazí, je pomocí funkce '''echo''' vypsána na konzoli chybová hláška.
 
  
 
Program lze snadno doplnit o celou řadu dalších funkcí.
 
Program lze snadno doplnit o celou řadu dalších funkcí.

Verze z 18. 3. 2021, 14:08

Tato stránka popisuje programovací jazyk SDS-C, který je dostupný na vybraných zařízeních SDS. 
Některá zařízení SDS používají FULL-C, pro který máme návody jinde na této WiKi.

Příklady SDS-C

Ideální pro seznámení se s jazykem SDS-C je prohlédnutí a vlastní úprava příkladů.

Příklady jsou testovány s nejnovějším firmware - stáhnete jej zdarma z této WiKi.

Používejte vždy nejnovější firmware a EXE.


Výpis prvočísel

Využijeme konzolový (testovací) výstup pomocí funkce "echo".

Tento příklad využívá globální proměnnou i. Každý program se vždy začne vykonávat od funkce main.

Ve funkci main se nejprve inicializuje obsah i na hodnotu 0. Dále se provede smyčka, která zvyšuje hodnotu i o jedničku. Jakmile dosáhne i hodnoty 20, je smyčka ukončena a program skončí (pozor, jakmile ukončíme main, je celý program spuštěn znovu od začátku, tedy přesněji main je spuštěno znovu).

Pro každý průchod smyčkou je i testováno, je-li prvočíslem. To se provádí ve funkci test_na_prvocislo. V této funkci je definována další proměnná j (pozor, i když je definována uvnitř funkce, je stále globální !!!). Následuje další smyčka, kde se provede test na zbytek po dělení (pokud vyjde nula, je i dělitelné a není prvočíslem, ale to už je teorie mimo SDS-C, že). Pokud tedy najdeme dělitel co nenechá zbytek, je funkce test_na_prvocislo předčasně ukončena vyhrazeným příkazem return. V opačném případě, po dokončení smyčky, je vypsáno potvrzení, že konkrétní i je prvočíslem (funkce echo).

var i;

test_na_prvocislo
{
 var j;

 j = i;

next:
 j -= 1;

 if (j > 1 && i % j == 0) return;

 if (j != 0) goto next;

 echo(i,' je prvocislo!');

}

main
{

 i = 0;

smycka:

 i += 1;

 test_na_prvocislo();

 if (i < 20) goto smycka;
}


Další příklady

Posílání emailu při poklesu teploty čidla 0 pod nastavenou mez.

Mez se nastaví ve funkci init, tato funkce je zavolána pouze jednou při startu programu, a nikdy více.

Aby se nestalo, že email bude poslan při každém průchodu testovací smyčky, je zavedená proměnná odeslano. Ta se nastaví, jakmile odešleme email, a nuluje se až když se teplota vrátí nad určenou mez (aby při dalším poklesu opět byl odeslán email, jedenkrát).

Tento příklad také ukazuje možnost použití #define za účelem zpřehlednění programu a snadných změn.

//prvni rele
#define RELE sys[196]  

var mez, odeslano;

init 
{
  //nastaveni hodnot po resetu zarizeni

  mez = 3015;  //tj 30.15 °C
  odeslano = 0; 
}

posli_email
{
  if (odeslano == 0) 
  {

    //jeste neodeslal, takze...

    smtp_send('pepa@duh.cz', 'teplotni alarm', 'Hlasim ze teplota (',sys[310],'°C) poklesla pod ',mez,'°C .');

  }

  odeslano = 1;  // VELMI DULEZITE - jedno z moznych reseni - ABY TO NEPOSILAL NEUSTALE DOKOLA, ale jen jednou kdyz se to stane !

  //treba muzeme zapnout rele pro topeni...
  RELE = 1;
}

uz_je_nad
{
  odeslano = 0; //nuluj, aby to mohl znovu poslat, jakmile teplota zase klesne

  //a ted treba to rele pro topeni vypneme
  RELE = 0;
}

main
{

 //udelame nekonecnou smycku

testuj_znovu:

 if (sys[310] < mez) posli_email() else uz_je_nad();

 goto testuj_znovu;
}


Příklad - řízení DC 12V ventilátoru pomocí PWM výstupy (SDS-MICRO), cílem je regulace teploty.

Údaj o teplotě se bere ze sys[310], hodnota PWM-duty-cycle se zapisuje do sys[192].

var pwm, old_pwm;
var cilova_teplota;

init 
{
  //inicializace - co je zde je provedeno jen jednou po resetu 

  sys[191] = 400; //frekvence PWM 
  sys[192] = 0; //PWM-duty-cycle

  pwm = 0;
  old_pwm = 0;
}

main
{

 cilova_teplota = 2050;  // 20.5°C

smycka:

   if (sys[310] < cilova_teplota) { pwm--; };  //pokud je chladnejsi, zpomalime

   if (sys[310] > cilova_teplota) { pwm++; };  //pokud je teplejsi, zrychlime

   if (pwm != old_pwm) { sys[192] = pwm; }; //pri rozdilu nastavit novou hodnotu

   wait(1000); //pockame 1000 msec, protoze teplota se meni jen pomalu, tak at se projevi vliv zmeny pwm

 goto smycka;
}


Vícenásobný ping

Pomocí programu v SDS-C lze rozšířit funkčnost zařízení o ICMP PING, a to i na více IP adres.

Pozor! Funkce ping() je dostupná teprve od verze SDS-C č. 04 !

V jednu chvíli lze mít pouze jeden aktivní ICMP PING poslaný z SDS-C programu (a současně lze mít i aktivní IP Watchdog, nebude se to negativně ovlivňovat, nicméně SDS-C program může mít aktivní jen jeden ICMP PING). Při každém novém zavolání funkce ping() jsou zahozeny informace o předchozím odeslaném ICMP PING REQUEST paketu, takže případná odpověď na ten předchozí ICMP PING REQUEST je ignorována a zařízení převezme pouze odpověď na ten nejposledněji odeslaný paket funkcí ping() (což je ale zcela ok - pokud např. nedostaneme odpověď ve stanoveném čase, už nás nezajímá že přijde případně později).

var ping_seq;
var koho;
var doba;

posli_ping();
{
   //kazdy odeslany paket musi mit jine SEQUENCE NUMBER (vzajemne odliseni pri posilani na stejnou IP atd.).
   ping_seq++;

   //IP adresy jsou v tomto prikladu zapsany zde

   if (koho == 0) { ping(192,168,1,1,ping_seq); return; };
   if (koho == 1) { ping(192,168,1,10,ping_seq); return; };
   if (koho == 2) { ping(192,168,1,123,ping_seq); return; };
   if (koho == 3) { ping(192,168,1,45,ping_seq); return; };
 
}

main
{
   echo('SDS-C IP watchdog SPUSTEN');

   koho = 0; //zacneme pekne od zacatku seznamu

next_ping:

   //odeslu ICMP PING
   posli_ping();

   //pockam na odezvu: zapamatuji si msec-uptime cas v tomto okamziku
   doba = sys[45];
 
cekaci_smycka:

   //definujeme si maximalni cekaci dobu:
   //uz uplynulo 500 msec? 
   // poznamka: pozor, toto neni osetreno na nulovani sys[45] po 2^31msec provozni doby
   if (sys[45] - doba > 500) goto mam_timeout;
   
   //uz prisla odpoved?
   if (sys[92] != 8) goto cekaci_smycka;
 
   //ok, prisla odpoved a nebyl timeout, takze jsem zde

   goto dalsi_cil;
  

mam_timeout:

   //neni ok
   
   echo('Nedostal jsem PING REPLY od (',koho,'), chybovy kod je ',sys[92],', doba je ',doba,' msec, RTT je ',sys[94],' msec');

   //tady muzu napr. jeste odeslat email, cvaknout s rele, a tak dale...

   //...


dalsi_cil:

   //ok, dalsi cil 
   koho = koho + 1;

   //uz mam vsechy? pokud ano, zacnu zase od zacatku (0)
   if (koho > 3) { koho = 0; }; 

   goto next_ping;
}

Program je celkem jednoduchý, postupně posílá ping podle obsahu proměnné koho, přičemž konkrétní IP adresy jsou ručně zadány. Když přijde správný PING REPLY (popř. se zjišťuje ARP) do zvolené doby (nastaveno na 500 msec), program se posune na další IP adresu. Pokud však do nastavené doby PING REPLY nedorazí, je pomocí funkce echo vypsána na konzoli chybová hláška.

Program lze snadno doplnit o celou řadu dalších funkcí.