/***************************************************************************/ /* Das Teichpumpen-Steuergerät-Programm */ /* -------------------------------------------------------------------- */ /* copyright (c) 2001 by Hubersoft Corp. All rights reserved. */ /***************************************************************************/ // Clock: 7.3728 MHz // Timer0-7: je 4 byte, 8 bit sec, 8 bit min, 16 bit h; // Timer0: Betriebsdauer aktueller Modus (sichtbarer Timer) ok // Timer1: Betriebsdauer gesamt Pumpe ok // Timer2: Betriebsdauer gesamt Modul ok // Timer3: Zeit seit letztem Pumpvorgang ok // Timer4: Zeit seit letzem Refresh ok // Timer5: Gesamtdauer Tank ungenutzt voll ok // Timer6: Dauer letzter Pumpvorgang ok // unsigned int Byte 32+33: Anzahl der Pumpvorgänge ok // unsigned int Byte 34+35: Anzahl der Refreshs ok // unsigned int Byte 46+47: Prüfsumme über Byte 0-45 ok #include #include #include #include #include #include //#TARGET AT90S8515; /***********************************************************************************/ #define MAXREFRESHTIMEOUT (43200) //nach xx Sekunden refreshen #define MAXPUMPTIMEOUT (1800) //max. xx Sekunden pumpen #define REFRESHDURATION (10) //xx Sekunden refreshen #define LINEOKTICKS (60) //xx Timerticks, bis ein Zustand akzeptiert wird. #define MAXKEYMARGIN (14) //max. Zeitspanne in (1/30) sec zwischen clicks #define MAXKEYCLICKS (20) //xx schnelle clicks, bis Timerblock gelöscht wird #define MAXAUTOSAVE (3600) //Sekunden, nach denen automatisch gespeichert wird #define MAXMODES (5) #define STANDBY (0) #define TEICHVOLL (1) #define STOERUNG (2) #define PUMPEN (3) #define REFRESH (4) /***********************************************************************************/ volatile unsigned int refreshtimeout=MAXREFRESHTIMEOUT; //Refreshtimeout volatile unsigned int pumptimeout=MAXPUMPTIMEOUT; //Pumptimeout volatile unsigned int autosavetimeout=MAXAUTOSAVE; //Automatisches Speichern volatile unsigned int keytimeout=0; //Timerblock löschen volatile unsigned char keyclicks=0; //Zähler für Tasten-Clicks volatile unsigned char infokey=0; //Info-Taste gedrückt volatile unsigned char lastkey=0; //Letzte Taste volatile unsigned char stoerung=0; //Störung aufgetreten? volatile unsigned char teichvollchecker=0; //Teichvoll noisekiller timer volatile unsigned char tankuntenchecker=0; //TankUnten noisekiller timer volatile unsigned char tankobenchecker=0; //TankOben noisekiller timer volatile unsigned char refreshtimer=0; //Refresh-Timer volatile unsigned char tankunten=0; //unterer Pegelschalter im Tank volatile unsigned char tankoben=0; //oberer Pegelschalter im Tank volatile unsigned char teichvoll=0; //Teich voll volatile unsigned char timer[48]; //8 Timer (je 8,8,16 Bit) volatile unsigned char pumpen=0; //Pumpe ist an volatile unsigned char statusvisible=1; //Timer sichtbar (bool) volatile unsigned char timermask=0; //Timermaske, welcher Timer läuft volatile unsigned char mode=255; //0=Standby; 1=Teich voll; 2=Störung; 3=Pumpen; 4=Refresh; volatile unsigned char commandflag=0; //Kommando-Flag der Scrollfunktion unsigned char scrollbuffer[17]; //Scrollpuffer unsigned char PROGMEM infotext[]= "Der letzte Pumpvorgang fand vor \x1C\x0E h, \x1B\x0D min und \x1B\x0C sec statt und dauerte \x1C\x1A h, \x1B\x19 min und \x1B\x18 sec. " "Die bisherige Betriebsdauer der Pumpe betr\xE1gt \x1C\x06 h, \x1B\x05 min und \x1B\x04 sec in \x1C\x20 Pumpvorg\xE1ngen. " "Das Fass war bisher \x1C\x16 h, \x1B\x15 min und \x1B\x14 sec ungenutzt voll, weil der Teich voll war. " "Der letzte Pumpen-Refresh fand vor \x1C\x12 h, \x1B\x11 min und \x1B\x10 sec statt. " "Bisher wurden \x1C\x22 Refreshs durchgef\365hrt. " "Dieses Modul l\xE1uft seit \x1C\x0A h, \x1B\x09 min und \x1B\x08 sec. "; unsigned char PROGMEM noerrortext[]= "Der Betrieb verl\xE1uft zur Zeit st\xEFrungsfrei."; unsigned char PROGMEM errortext[]= "Eine St\xEFrung ist aufgetreten. Der Pumpbetrieb wurde angehalten. Pr\365fen Sie bitte die Sensoren und die Pumpe und dr\365cken Sie dann 2x die Infotaste! "; /***********************************************************************************/ void delay(unsigned int ms) //ms Millisekunden { register unsigned char a, b, c; for (a=ms; a>0; --a) for (b=27; b>0; --b) for (c=91; c>0; --c); } /***********************************************************************************/ void waitstate(void) { register unsigned char a; for (a=100; a>0; --a); delay(1); } /***********************************************************************************/ void keyclick(void) { unsigned int i,w; for (w=0; w<30; w++) { cbi(PORTC,6); for (i=0;i<400;i++); sbi(PORTC,6); for (i=0;i<400;i++); } } /***********************************************************************************/ void wd(unsigned char data) { outp(data, PORTA); sbi(PORTC,1); sbi(PORTC,0); waitstate(); cbi(PORTC,0); waitstate(); } /***********************************************************************************/ void wc(unsigned char data) { outp(data, PORTA); cbi(PORTC,1); sbi(PORTC,0); delay(1); cbi(PORTC,0); delay(1); } /***********************************************************************************/ void write(char text[]) { unsigned char i=0; wc(128); while (*text) {if (i++==8) wc(192); wd(*text++);} } /***********************************************************************************/ void showtimer(void) { unsigned char temp[8]; unsigned char i; if ((statusvisible)&&(mode>nr);} void stoptimer(unsigned char nr) {timermask&=~(128>>nr);} /*****************************************/ void pumpean(void) { if (!pumpen){ sbi(PORTC,2); //Pumpe an cbi(PORTB,1); //ATX power on pumpen=1; starttimer(1); if (mode==PUMPEN) {resettimer(6); starttimer(6);} resetpumptimeout(); } } /*****************************************/ void pumpeaus(void) { if (pumpen){ cbi(PORTC,2); //Pumpe aus sbi(PORTB,1); //ATX power off pumpen=0; stoptimer(1); resetrefreshtimeout(); autosavetimeout=MAXAUTOSAVE; //Auto save zurücksetzen stoptimer(6); //Timer Dauer letzter Pumpvorgang auf jeden Fall stoppen if (mode==PUMPEN) resettimer(3); //wenn gerade gepumpt Zeit seit letzter Pumpvorgang zurücksetzen if (mode==REFRESH) resettimer(4); //wenn gerade refresht Zeit seit letzter Refresh zurücksetzen savetimer(); //alle Zähler speichern } } /***********************************************************************************/ SIGNAL(SIG_OUTPUT_COMPARE1A) //Echtzeituhr { unsigned char i; unsigned int temp; if (refreshtimeout>0) refreshtimeout--; if (refreshtimer>0) refreshtimer--; if (pumptimeout>0) pumptimeout--; if (autosavetimeout>0) autosavetimeout--; for (i=0;i<8;i++){ if (timermask&(128>>i)) { timer[i*4+0]++; if (timer[i*4+0]==60) {timer[i*4+0]=0; timer[i*4+1]++;} if (timer[i*4+1]==60) { timer[i*4+1]=0; temp=timer[i*4+2]+timer[i*4+3]*256; temp++; timer[i*4+2]=temp%256; timer[i*4+3]=temp/256; } } } showtimer(); } /***********************************************************************************/ void DoStandby(void) { if (mode!=0) { pumpeaus(); resettimer(0); mode=0; showtimer(); } } /*****************************************/ void DoTeichvoll(void) { if (mode!=1) { pumpeaus(); resettimer(0); mode=1; showtimer(); } } /*****************************************/ void DoStoerung(void) { if (mode!=2) { stoerung=1; pumpeaus(); resettimer(0); mode=2; showtimer(); } } /*****************************************/ void DoPumpen(void) { unsigned int temp; if (mode!=3) { mode=3; pumpean(); temp=timer[32]+timer[33]*256; temp++; timer[32]=temp%256; timer[33]=temp/256; resettimer(0); showtimer(); } } /***********************************************************************************/ void DoRefresh(void) { unsigned int temp; if (mode!=4) { mode=4; pumpean(); temp=timer[34]+timer[35]*256; temp++; timer[34]=temp%256; timer[35]=temp/256; resettimer(0); resetrefreshtimeout(); refreshtimer=REFRESHDURATION; showtimer(); } } /***********************************************************************************/ void scrollchar(unsigned char c) { unsigned char i; for(i=0;i<15;i++) scrollbuffer[i]=scrollbuffer[i+1]; scrollbuffer[15]=c; scrollbuffer[16]=0; write(scrollbuffer); delay(120); } /*****************************************/ void scrollinit(void) { unsigned char i; for(i=0;i<17;i++) scrollbuffer[i]=32; } /*****************************************/ void scrolldone(void) { unsigned char i; for(i=0;i<17;i++) scrollchar(32); } /*****************************************/ void lauftext(unsigned char* point) { unsigned char temp[6]; unsigned char i=0, c=255, nc; unsigned int tptr=0; unsigned int zahl; while ((c)&&(!infokey)){ c=PRG_RDB(&point[tptr++]); if ((c==27)||(c==28)) { nc=PRG_RDB(&point[tptr++]); zahl=timer[nc]; if (c==28) zahl=zahl+(256*timer[nc+1]); itoa(zahl,temp, 10); i=0; while (temp[i]) scrollchar(temp[i++]); } else { if (c!=0) scrollchar(c); } } } /***********************************************************************************/ void showmessage(void) { scrollinit(); if (stoerung) lauftext(errortext); else {lauftext(infotext);lauftext(noerrortext);} if (infokey) {wc(1); stoerung=0;} else scrolldone(); } /***********************************************************************************/ SIGNAL(SIG_OVERFLOW0) //Pumpen-Logik { unsigned char sample; sample=inp(PINC); if ((lastkey==0)&&((inp(PINB)&1)==0)) {infokey=1; keyclick(); keyclicks++;} lastkey=((inp(PINB)&1)==0); if (lastkey) keytimeout=MAXKEYMARGIN; else {if (keytimeout>0) keytimeout--;}; if (keytimeout==0) keyclicks=0; if (keyclicks>=MAXKEYCLICKS) { keyclicks=0; keytimeout=0; cleartimerblock(); savetimer(); infokey=1; } //********** Teichvoll noise killer: if (teichvoll){ if ((sample&32)==0) teichvollchecker=LINEOKTICKS; else { if (teichvollchecker>0) teichvollchecker--; else teichvoll=0; } } else { if ((sample&32)==0) { if (teichvollchecker0) tankuntenchecker--; else tankunten=0; } } else { if ((sample&16)==0) { if (tankuntenchecker0) tankobenchecker--; else tankoben=0; } } else { if ((sample&8)==0) { if (tankobenchecker