/*
Ovladani domu rozvadec 2. n.p.
Syntaxe prikazu:
<Roleta/Svetlo><#patro><#mistnost><Nord/Jih/Vychod/Zapad/A/B><Up/Down>
R2aNU - roleta, 2. n.p., mistnost 10, sever, nahoru
S12A - svetlo, 1. n.p., mistnost 2, prostredni
Rozmisteni desek:
[CAN]
[IN J] [IN D]
[OUT A] [CPU]
[OUT F] [OUT B] [OUT E]
*/
#include "main.h"
#case
#use fast_io(A) // Aby se neztracely znaky pri cteni prikazu
#use fast_io(B)
#use fast_io(E)
#use fast_io(F)
#use fast_io(D)
#use fast_io(J)
#define T_REVERS 5 // 5*256 ms = 1,25 s; pred prepnutim rele (zastaveni motoru a vybiti kondenzatoru)
#define T_START 1 // 256 ms; po prepnuti rele do sepnuti triaku
#define T_GO 117 // 117*256 ms = 30 s; max. beh rolety
#define T_GO_ZALUZIE 6 // cca 1,5 s; beh zaluzie (pouze na preklopeni lamel)
#define T_RECEIVE 10 // cca 2,6 s
#define ZAKMIT 2000 // pocet pruchodu hlavni smyckou pred opetovnou detekci prepnuti vypinace
#define OR106Z PIN_A0 // t1 Zaluzie trucovna zapad
#define OR110N PIN_A1 // t2 Zaluzie koupelna dole sever
#define OR104V PIN_A2 // t3 Roleta lab vychod
#define OR104J PIN_A3 // t4 Roleta lab jih
#define OR103V PIN_A4 // t5 Roleta loznice
#define OR202J PIN_A5 // t6 Roleta Kaklik
#define OR204Z PIN_A6 // t7 Roleta radiomistnost
#define OR207V PIN_A7 // t8 Roleta klubovna
#define OR208V PIN_F0 // t1 Roleta Zizala vychod
#define OR208J PIN_F1 // t2 Roleta Zizala jih
//??? #define OR107 PIN_F2 // t3
//??? #define OR107 PIN_F3 // t4
#define OR201Z PIN_F4 // t5 Roleta chodba nahore
#define OR205N PIN_F5 // t6 Roleta puda
//??? #define OR105 PIN_F6 // t7 Roleta kuchyn
//#define O... PIN_F7 // t8
#define OS103J PIN_B0 // t1 Svetla loznice
#define OS105Z PIN_B1 // t2 Svetlo kuchyn nad lavici
#define OS110N PIN_B2 // t3 Svetlo koupelna dole zachod a sprhca
#define OS106A PIN_B3 // t4 Svetlo trucovna stred
#define OS107A PIN_B4 // t5 Svetlo satna
#define OS109A PIN_B5 // t6 Svetlo technologicka mistnost
#define OS205A PIN_B6 // t7 Svetlo puda
#define OS204A PIN_B7 // t8 Svetlo radiomistnost
//#define OS105C PIN_C2
//#define PIN_C3 31763
//#define PIN_C4 31764
//#define PIN_C5 31765
//#define PIN_C6 31766 //TX
//#define PIN_C7 31767 //RX
#define OS102A PIN_E0 // t1 Svetlo chodba
#define OS105A PIN_E1 // t2 Svetlo kuchyne stred
#define OS207A PIN_E2 // t3 Svetlo klubovna
#define OS104A PIN_E3 // t4 Svetlo laborator
#define OS202A PIN_E4 // t5 Svetlo Kaklik stred
#define OS209A PIN_E5 // t6 Svetlo Zizala koupelna
#define OS203A PIN_E6 // t7 Svetlo Kaklik koupelna
#define RE PIN_E7 // t8 Rele pro rizeni smeru rolet
//#define I.... input(PIN_D0) // A
#define IS201AZ input(PIN_D1) // B Vypinac chodba 2.n.p. zapad u Kaklika
#define IS207AJ input(PIN_D2) // C Vypinac klubovna
#define IR207VD input(PIN_D3) // D Vypinac roleta klubovna dolu
#define IR207VU input(PIN_D4) // E Vypinac roleta klubovna nahoru
#define IS201AV input(PIN_D5) // F Vypinac chodba 2.n.p. vychod
#define IS209AJ input(PIN_D6) // G Vypinac koupelna Zizala
#define IS203AJ input(PIN_D7) // H Vypinac koupelna Kaklik
#define IS202AN input(PIN_J0) // A Vypinac svetlo Kaklik stred u dveri na chodbu
#define IR202ND input(PIN_J1) // B Vypinac roleta Kaklik dolu u dveri
#define IR202NU input(PIN_J2) // C Vypinac roleta Kaklik nahoru u dveri
#define IS205A input(PIN_J3) // D Vypinac svetlo puda
#define IS204AJ input(PIN_J4) // E Vypinac svetlo radiomistnost u dveri na chodbu
#define IR204ZD input(PIN_J5) // F Vypinac roleta radiomistnost dolu
#define IR204ZU input(PIN_J6) // G Vypinac roleta radiomistnost nahoru
//#define I.... input(PIN_J7) // H
int1 s201AV;
int1 s201AZ;
int1 s207AJ;
int1 s203AJ;
int1 s209AJ;
int1 r207VU;
int1 r207VD;
int1 s202AN;
int1 r202ND;
int1 r202NU;
int1 s205A;
int1 s204AJ;
int1 r204ZD;
int1 r204ZU;
#bit CREN = 0xFAB.4 // USART enable register
#define LED1 PIN_C0
#define LED2 PIN_C1
#define ON(port) output_low(port);
#define OFF(port) output_high(port);
typedef enum {RUN, STOP} roleta_state;
roleta_state rol[18]; // Stavy rolet
#define R103V 0
#define R110N 1
#define R104V 2
#define R104J 3
#define R207V 4
#define R202J 5
#define R204Z 6
typedef enum {UP, DOWN, REVERS_UP, REVERS_DOWN, RUN_UP, RUN_DOWN} relay_state;
relay_state relay; // Stavy rele
int8 timer_run; // Bezpecnostni casovac behu rolety
int8 timer_run_zaluzie; // Casovac zaluzie na preklopeni lamel
int8 timer_revers; // Prodleva na vybiti kondenzatoru pa zastaveni rolety pred prepnutim rele
int8 timer_start; // Prodleva na prepnuti rele pred startem rolety
int8 timer; // Casovac komunikace
#int_TIMER0
void TIMER0_isr(void)
{
if(timer>0) timer--;
if(timer_run>0) timer_run--;
if(timer_revers>0) timer_revers--;
if(timer_start>0) timer_start--;
if(timer_run_zaluzie>0) timer_run_zaluzie--;
output_toggle(LED2);
}
void stop_all() // Zastav vsechny rolety
{
int8 n;
for(n=0; n<18; n++) rol[n]=STOP;
output_a(0xFF);
output_f(0xFF);
}
void run_all() // Spust rolety
{
if (rol[R103V]==RUN) ON(OR103V);
if (rol[R110N]==RUN) ON(OR110N);
if (rol[R104V]==RUN) ON(OR104V);
if (rol[R104J]==RUN) ON(OR104J);
if (rol[R207V]==RUN) ON(OR207V);
if (rol[R202J]==RUN) ON(OR202J);
if (rol[R204Z]==RUN) ON(OR204Z);
}
/*
void up(state *status, int8 *timer) // Zmena stavu rolety smer nahoru
{
switch (*status)
{
case STOP:
case GO_DOWN:
*status=REVERS_UP;
*timer=REVERS;
break;
case REVERS_UP:
case GO_UP:
*status=STOP;
*timer=0;
break;
}
}
void down(state *status, int8 *timer) // Zmena stavu rolety smer dolu
{
switch (*status)
{
case STOP:
case GO_UP:
*status=REVERS_DOWN;
*timer=REVERS;
break;
case REVERS_DOWN:
case GO_DOWN:
*status=STOP;
*timer=0;
break;
}
}
#define run(x) { \
switch(r##x) \
{ \
case STOP: \
OFF(OR##x##U); \
OFF(OR##x##D); \
break; \
case GO_UP: \
OFF(OR##x##D); \
ON(OR##x##U); \
if(tr##x==0) {r##x=STOP;} \
break; \
case GO_DOWN: \
OFF(OR##x##U); \
ON(OR##x##D); \
if(tr##x==0) {r##x=STOP;} \
break; \
case REVERS_UP: \
OFF(OR##x##U); \
OFF(OR##x##D); \
if(tr##x==0) {r##x=GO_UP; tr##x=GO;} \
break; \
case REVERS_DOWN: \
OFF(OR##x##U); \
OFF(OR##x##D); \
if(tr##x==0) {r##x=GO_DOWN; tr##x=GO;} \
break; \
} \
}
*/
void main()
{
char buf[10]; // Buffer pro prijem prikazu
unsigned int16 zakmity=0; // Osetreni zakmitu vypinacu
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
set_tris_a(0); // Vystupy
set_tris_b(0);
set_tris_e(0);
set_tris_f(0);
set_tris_d(0xFF); // Vstupy
set_tris_j(0xFF);
output_a(0xFF); // Vsechno zhasni a zastav
output_b(0xFF);
output_f(0xFF);
output_e(0xFF);
stop_all();
timer_run=0; // Zastav vsechny casovace
timer=0;
timer_revers=0;
timer_start=0;
timer_run_zaluzie=0;
zakmity=0;
relay=RUN_UP; // Rele je na zacatku vypnuto
{
int n;
for(n=0;n<10;n++)
{
output_low(LED1); // Indikace restartu (pockame na nabiti kondenzatoru ve vstupnich obvodech)
delay_ms(100);
output_high(LED1);
delay_ms(100);
restart_wdt();
}
}
s201AV=IS201AV; // Precteme vychozi stav vypinacu
s201AZ=IS201AZ;
s207AJ=IS207AJ;
s203AJ=IS203AJ;
s209AJ=IS209AJ;
r207VU=IR207VU;
r207VD=IR207VD;
s202AN=IS202AN;
r202ND=IR202ND;
r202NU=IR202NU;
s205A=IS205A;
s204AJ=IS204AJ;
r204ZD=IR204ZD;
r204ZU=IR204ZU;
CREN=0; CREN=1; // Reinitialise USART
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
while(TRUE)
{
restart_wdt();
if(kbhit()) // Chce po nas nekdo neco?
{
buf[0]=getc();
if((buf[0]=='S')||(buf[0]=='R')) // Jinym znakem nesmi zacinat prikaz
{
int8 n=0; // Ukazatel do prijimaciho bufferu
timer=T_RECEIVE; // Timeout pro prijem znaku
do
{
if(kbhit()) // Je dalsi znak?
{
n++;
buf[n]=getc();
}
} while ((buf[n]!='\r')&&(timer>0)&&(n<7));
if (timer==0) { CREN=0; CREN=1; } // Reinitialise USART
output_toggle(LED1); // Ukonceni prijimani prikazu
if((timer>0))
{
if((buf[0]=='S')&&(n>=4)) // Zmena stavu svetla
{
if(buf[1]=='1')
{
switch(buf[2])
{
case '2':
output_toggle(OS102A);
break;
case '3':
output_toggle(OS103J);
break;
case '4':
output_toggle(OS104A);
break;
case '5':
if(buf[3]=='A') {output_toggle(OS105A);}
if(buf[3]=='Z') {output_toggle(OS105Z);}
break;
case '6':
output_toggle(OS106A);
break;
case '7':
output_toggle(OS107A);
break;
case '8':
// output_toggle(OS108A);
break;
case '9':
output_toggle(OS109A);
break;
case 'a':
// output_toggle(OS110J);
output_toggle(OS110N);
break;
}
}
}
if((buf[0]=='R')&&(n>=5)) // Zmena stavu rolety
{
if(buf[1]=='1')
{
switch(buf[2])
{
case '3':
//!!! if(buf[4]=='U') {up(&r103V,&tr103V);} else {down(&r103V,&tr103V);}
break;
case '4':
//!!! if(buf[3]=='V') if((buf[4]=='U'))
//!!! if(buf[3]=='J') if((buf[4]=='U')) {up(&r104J,&tr104J);} else {down(&r104J,&tr104J);}
break;
case 'a':
//!!! if((buf[4]=='U')) {up(&r110N,&tr110N);} else {down(&r110N,&tr110N);}
break;
}
}
}
}
}
}
//!!! switch(r110N) // Zaluzie ma specielni rizeni
// mistni vypinace z 2. n.p.
if (0==zakmity)
{
if(s201AV!=IS201AV) {s201AV=IS201AV; output_toggle(OS102A); zakmity=ZAKMIT;}
if(s201AZ!=IS201AZ) {s201AZ=IS201AZ; output_toggle(OS102A); zakmity=ZAKMIT;}
if(s207AJ!=IS207AJ) {s207AJ=IS207AJ; output_toggle(OS207A); zakmity=ZAKMIT;}
if(s203AJ!=IS203AJ) {s203AJ=IS203AJ; output_toggle(OS203A); zakmity=ZAKMIT;}
if(s209AJ!=IS209AJ) {s209AJ=IS209AJ; output_toggle(OS209A); zakmity=ZAKMIT;}
if(s205A!=IS205A) {s205A=IS205A; output_toggle(OS205A); zakmity=ZAKMIT;}
if(s204AJ!=IS204AJ) {s204AJ=IS204AJ; output_toggle(OS204A); zakmity=ZAKMIT;}
if(s202AN!=IS202AN) {s202AN=IS202AN; output_toggle(OS202A); zakmity=ZAKMIT;}
if(r207VU!=IR207VU) // Zmenil se stav vypinace
{
r207VU=IR207VU; // Poznamenej soucasny stav vypinace
if (rol[R207V]==RUN)
{
rol[R207V]=STOP; // Roleta jela, tak zastav
OFF(OR207V);
}
else
{
if ((relay==DOWN)||(relay==RUN_DOWN)) // Rele je prepnuto na druhou stranu!
{
relay=REVERS_UP; // Reverzuj
timer_revers=T_REVERS;
stop_all(); // Vsechno zastav
}
if (relay==RUN_UP)
{
ON(OR207V); // Jede se spravnym smerem, tak jenom pust roletu
}
rol[R104V]=RUN; // Poznamenej, ze se jede, a natahni bezpecnostni casovac
timer_run=T_GO;
}
zakmity=ZAKMIT;
}
if(r207VD!=IR207VD)
{
r207VD=IR207VD;
if (rol[R207V]==RUN)
{
rol[R207V]=STOP;
OFF(OR207V);
}
else
{
if ((relay==UP)||(relay==RUN_UP))
{
relay=REVERS_DOWN;
timer_revers=T_REVERS;
stop_all();
}
if (relay==RUN_DOWN)
{
ON(OR207V);
}
rol[R104V]=RUN;
timer_run=T_GO;
}
zakmity=ZAKMIT;
}
//!!! if(r202NU!=IR202NU) {r202NU=IR202NU; up(&r202J,&tr202J); zakmity=ZAKMIT;}
//!!! if(r202ND!=IR202ND) {r202ND=IR202ND; down(&r202J,&tr202J); zakmity=ZAKMIT;}
//!!! if(r204ZU!=IR204ZU) {r204ZU=IR204ZU; up(&r204Z,&tr204Z); zakmity=ZAKMIT;}
//!!! if(r204ZD!=IR204ZD) {r204ZD=IR204ZD; down(&r204Z,&tr204Z); zakmity=ZAKMIT;}
}
else zakmity--;
}
switch (relay)
{
case UP:
if (timer_start==0) // Rele prepnuto, muzeme sepnout triaky
{
relay=RUN_UP; // Zmen stav na "jede se"
run_all(); // Sepni triaky u rolet, ktere maji jet
timer_run=T_GO; // Natahni bezpecnostni casovac
}
break;
case DOWN:
if (timer_start==0) // Rele prepnuto, muzeme sepnout triaky
{
relay=RUN_DOWN; // Zmen stav na "jede se"
run_all(); // Sepni triaky u rolet, ktere maji jet
timer_run=T_GO; // Natahni bezpecnostni casovac
}
break;
case RUN_UP:
if (timer_run==0) // Vyprsel bezpecnostni casovac
{
stop_all(); // Vsechno zastav
}
break;
case RUN_DOWN:
if (timer_run==0) // Vyprsel bezpecnostni casovac
{
relay=REVERS_UP; // Vsechno zastav a reverzuj pro prepnuti rele do klidove polohy bez energizace civky
stop_all();
timer_revers=T_REVERS;
}
break;
case REVERS_UP:
if (timer_revers==0) // Uz se snad vybil kondenzator, muzeme reverzovat
{
relay=UP; // Prepni rele
OFF(RE);
timer_start=T_START; // Pockej na prepnuti rele
}
break;
case REVERS_DOWN:
if (timer_revers==0) // Uz se snad vybil kondenzator, muzeme reverzovat
{
relay=DOWN; // Prepni rele
ON(RE);
timer_start=T_START; // Pockej na prepnuti rele
}
break;
}
}