1

Téma: Týdenní spínací hodiny s přímím určení spínaného výstupu

Dovolil jsem si použít části kódu ze spínacích hodin od Clouseau a od Jirsoft a upravit je k obrazu svému.
Důvodem bylo maximální využití uživatelských proměnných, tedy co jedna sys[14x], to kompletní zadání co se kdy sepne.
Zde je náhled programu:

// **********Týdenní spínací hodiny s určením relé které bude spínat**********


var REx,dow,den,pom,cas,on,off; //promenne pro spinaci hodiny
var spinacky_sys; //ukazatel sys
var thisminute; //flag že tuhle minutu už procedury proběhly



// *******  globalni procedury  **********


echotime
{
 ram[0]=sys[8] / 10;
 ram[1]=sys[8] % 10;
 ram[2]=sys[9] / 10;
 ram[3]=sys[9] % 10;
 ram[4]=sys[10] / 10;
 ram[5]=sys[10] % 10;
 echo(ram[0],ram[1]':',ram[2],ram[3]':',ram[4], ram[5]);
}




//procedury spínání relé a výstupů

relay1on
{
 if (sys[231]==0) {
    sys[231]=1;
    echotime();
    echo('RE1 zapnuto');
 }
}

relay1off
{
 if (sys[231]!=0) {
    sys[231]=0;
    echotime();
    echo('RE1 vypnuto');
 }
}

relay2on
{
 if (sys[232]==0) {
    sys[232]=1;
    echotime();
    echo('RE2 zapnuto');
 }
}

relay2off
{
 if (sys[232]!=0) {
    sys[232]=0;
    echotime();
    echo('RE2 vypnuto');
 }
}

D0on
{
 if (sys[301]==0) {
    sys[301]=1;
    echotime();
    echo('D0 zapnuto');
 }
}

D0off
{
 if (sys[301]!=0) {
    sys[301]=0;
    echotime();
    echo('D0 vypnuto');
 }
}




timecompare        // procedura vyhodnocení
{
 if (on!=off) {
    if (cas==on && den == dow && REx == 0) D0on(); // pro konkretni den (0-6)
    if (cas==off && den == dow && REx == 0) D0off();
    if (cas==on && REx == 0 && (den == 7 && (dow > 0 && dow < 6))) D0on(); // pro vsedni den (7)
    if (cas==off && REx == 0 && (den == 7 && (dow > 0 && dow < 6))) D0off();
    if (cas==on && REx == 0 && (den == 8 && (dow == 0 || dow == 6))) D0on(); // pro vykend (8)
    if (cas==off && REx == 0 && (den == 8 && (dow == 0 || dow == 6))) D0off();
    if (cas==on && REx == 0 && (den == 9 && (dow >= 0 && dow < 7))) D0on(); // pro všechny dny (9)
    if (cas==off && REx == 0 && (den == 9 && (dow >= 0 && dow < 7))) D0off();
    
    if (cas==on && den == dow && REx == 1) relay1on(); // pro konkretni den (0-6)
    if (cas==off && den == dow && REx == 1) relay1off();
    if (cas==on && REx == 1 && (den == 7 && (dow > 0 && dow < 6))) relay1on(); // pro vsedni den (7)
    if (cas==off && REx == 1 && (den == 7 && (dow > 0 && dow < 6))) relay1off();
    if (cas==on && REx == 1 && (den == 8 && (dow == 0 || dow == 6))) relay1on(); // pro vykend (8)
    if (cas==off && REx == 1 && (den == 8 && (dow == 0 || dow == 6))) relay1off();
    if (cas==on && REx == 1 && (den == 9 && (dow >= 0 && dow < 7))) relay1on(); // pro všechny dny (9)
    if (cas==off && REx == 1 && (den == 9 && (dow >= 0 && dow < 7))) relay1off();
 }
}

spinaci_hodiny
{
 dow = ((sys[4] / 86400) + 4) % 7;        // určení dne v týdnu (výsledkem je 0-6)
 cas = sys[8] * 100 + sys[9];               // připravíme čas HHMM
 spinacky_sys=140;

spinacky1:
    on = sys[spinacky_sys] / 10000;             // rozebereme sys[14x] RDHHMMHHMM (on/off)
    off = sys[spinacky_sys] % 10000;        // výsledek je čas vypnutí
    pom = on / 10000;                // pomocný výpočet
    on = on % 10000;                // výsledek je čas zapnutí
    REx = pom / 10;                // výsledek je určení relé které se má sepnout
    den = pom % 10;        // výsledek je den v týdnu kdy budeme spínat ... 0-6=konkrétní den, 7=pracovní, 8=víkend, 9=každý den
 
 timecompare();           // volání procedury vyhodnocení

 spinacky_sys++;

 if (spinacky_sys<148) goto spinacky1;
 }

// *******  startovaci procedury  **********

init
{
 echotime();
 echo('Start programu');
 thisminute=0;

 // *******  uzivatelsky nastavitelne promenne  ***********
 

 sys[140]=1110001200;    // sepne rele 1 v pondělí v 10:00h - 12:00h
 sys[141]=0708001200;    // sepne výstup D0 každý všední den v 08:00h - 12:00h
 sys[142]=1820152130;    // sepne rele 1 každý víkend v 20:15h - 21:30h
 sys[143]=0905300600;    // sepne výstup D0 každý den v 05:30h - 06:00h
 sys[144]=1411151300;    // sepne rele 1 ve čtvrtek v 11:15h - 13:00h
 sys[145]=0812021300;    // sepne rele 1 v neděli v 15:00h - 16:00 
 sys[146]=0616031817;    // sepne výstup D0 v sobotu v 16:03h - 18:17h
 sys[147]=1323150000;    // sepne rele 1 ve středu v 23:15h - 00:00h
 
 
 
}

main
{
 // volani spinacich hodin

 if (sys[10]==0 && thisminute!=sys[9]){
    spinaci_hodiny();
    thisminute=sys[9];
 }
}

2

Re: Týdenní spínací hodiny s přímím určení spínaného výstupu

Sice používáte jen 2 relé (RE1 a D0), ale máte to zřejmě připraveno i pro RE2. Tam ale bude problém s přetečením (lépe řečeno s přechodem do záporných čísel).

Já jsem postupně svůj kód též upravoval, momentálně aktuální verze je tato (chybí deklarace proměnných):

tiskniDatumCas
{
    echoinline(den1, den2, '.', mes1, mes2, ':', rok1, rok2, rok3, rok4, ' ', hod1, hod2, ':', min1, min2, ':', sec1, sec2, ' ');
}

spinaci_hodiny                     //podle hodnot v SYS[140-147] nastaví stav výstupů, první 4 pro RE1, další pro RE2
{
    var i, i_spinani, spinani, i_rele, cas, on, off, dd, den, re, out, prg, h, m1, m2;
        
    cas = HOD * 100 + MIN;                //připravíme čas HHMM
    den = ((TIME / 86400) + 3) % 7;        //den v týdnu, 0=pondělí
    i = 0;
    i_rele = RELE;
    re = sys[i_rele] & 1;
    out = -1;
    
dalsi_program:
    i_spinani = PRG1 + i;
    spinani = sys[i_spinani];
    on = spinani / 10000;                //rozebereme PROGRAM DHHMMHHMM (on/off)
    off = spinani % 10000;
    dd = on / 10000;                    //program pro den v týdnu ... 0-6=konkrétní den, 7=pracovní, 8=víkend, 9=každý den
    on = on % 10000;
    if (dd<7 && dd!=den)
        goto pokracuj;                    //program pro aktuální den, který dnes není
    if (dd==7 && den>4)
        goto pokracuj;                    //program pro pracovní den, dnes je víkend
    if (dd==8 && den<5)
        goto pokracuj;                    // program pro víkend, dnes je pracovní den
                
                                        //porovnáváme časy, pokud on=off (nebo 0), nic neděláme
    if (cas==on && on!=off) { 
        out = 1;
        prg = i + 1;
    }
    if (cas==off && on!=off) { 
        out = 0;
        prg = i + 1;
    }
    
pokracuj:
    i += 1;
    if (i<4)
        goto dalsi_program;
        
    if (i!=4 && i!=8)
        goto preskoc;
        
    if (out!=re && out!=-1) {                        //pokud by se nic nezměnilo, nespínáme
        sys[i_rele] = out;
        h = cas / 100;
        m1 = (cas % 100)/10;
        m2 = cas % 10;
        tiskniDatumCas();
        echo('RELE: r[', i_rele,'] ... ', re,' -> ', out, ' (PROGRAM', prg, ')');
    }
    
    if (i<8) {
        i_rele += 1;
        re = sys[i_rele] & 1;
        out = -1;
    }
    
preskoc:
    if (i < 8)
        goto dalsi_program;    
}

vratDatumCas                     //přiřadí do proměnných datum a čas
{
    aden = DEN;                    //data do proměnné kvůli možné změně ve funkci
    ames = MES;
    arok = ROK;
    ahod = HOD;
    amin = MIN;
    asec = SEC;
    atime = TIME;
    
    den1 = aden / 10;
    den2 = aden % 10;
    mes1 = ames / 10;
    mes2 = ames % 10;
    rok1 = arok;
    rok4 = rok1 % 10;
    rok1 /= 10;
    rok3 = rok1 % 10;
    rok1 /= 10;
    rok2 = rok1 % 10;
    rok1 /= 10;
    hod1 = ahod / 10;
    hod2 = ahod % 10;
    min1 = amin / 10;
    min2 = amin % 10;
    sec1 = asec / 10;
    sec2 = asec % 10;
}

Pro jistotu jsem ošetřil i situaci, kdy jedním programem zapnu a druhým vypnu - projdu programy a vlastní ovládání relé provedu až na závěr...
Přidal jsem i podporgramy pro získání a výpis časové značky do konzole (zde chybí #define HOD sys[]... pro jednotlivé systémové proměnné)

3

Re: Týdenní spínací hodiny s přímím určení spínaného výstupu

Tak řekl bych že hlavní plus vidím v tom že narozdíl od první verze spínaček tyhle sepnou (rozepnou) správně i uprostřed intervalu - při výpadku a nebo při novým nahrání programu... to druhý je u mne dost často..  smile Mne v programu zbylo ze spínaček fakt jen kousek - limituju tam čas od kdy do kdy má být sepnutý boiler. Ale hlavní slovo tam má hlídání výkonu elektrárny.... podle toho se pak děje všechno ostatní....

4

Re: Týdenní spínací hodiny s přímím určení spínaného výstupu

Přidávám námět - chtěl jsem časovací hodiny které jsou obdobou těch spínacích mechanických - nastavením příznaku pro konkrétní časový interval určím zda se má být sepnuto či nikoliv a celkový počet sepnutí a rozepnutí je určen jen minimální délkou intervalu.
Vyřešil jsem to tedy tak že, za pomoci tří sys[14x] a kódu který tady kdysi zveřejnil Adamn ukládám předvolby pro každou hodinu do pole proměnných ram(hod)  kdy obsahem je šestimístná kombinace "1" a "0" kdy každý znak reprezentuje příznak pro desetiminutovku v rámci hodiny. Vždy po uplynutí deseti minut v tomto poli testuji příslušnou buňku a podle toho sepnu či rozepnu příslušné relé.  Pokud bude mít někdo zájem kódy mohu přidat.

5

Re: Týdenní spínací hodiny s přímím určení spínaného výstupu

Ahoj,
můžeš to tu tedy celé dát?
Dík

6

Re: Týdenní spínací hodiny s přímím určení spínaného výstupu

ahoj,
mám SDS BIG  a potřeboval bych pomoc s programem.
Použil bych tyto spínací hodiny, ale potřeboval bych nastavit  automatické sepnutí relé ob den a v případě, že teplota na teplotním čidel 1 bude vyšší než 28stupňu tak sepnout na 24hod.  toto relé i mimo plánované dny.
Jak bych měl tento program vypadat?

díky za info