Heizkoerper Thermostat Programm
Version vom 14. Mai 2010, 06:10 Uhr von Kiwi (Diskussion | Beiträge) (Die Seite wurde neu angelegt: <source lang="c"> // ################################################################################ // # This program is free software; you can redistribute i...)
// ################################################################################
// # This program is free software; you can redistribute it and/or modify it #
// # under the terms of the GNU General Public License (either version 2 or #
// # version 3) as published by the Free Software Foundation. #
// # #
// # This program is distributed in the hope that it will be useful, #
// # but WITHOUT ANY WARRANTY; without even the implied warranty of #
// # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
// # GNU General Public License for more details. #
// # #
// # You should have received a copy of the GNU General Public License #
// # along with this program; if not, write to the Free Software #
// # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #
// # #
// # For more information on the GPL, please go to: #
// # http://www.gnu.org/copyleft/gpl.html #
// # #
// # #
// # Programm Erstellung: #
// # Copyright (C) 2009-2010 - Michael Schultz <ethersex@keyb.de> #
// # #
// ################################################################################
/* Fuses: Extended 0xFF
* High 0x9A
* Low 0xFF
*http://frank.circleofcurrent.com/fusecalc/fusecalc.php?chip=atmega169&LOW=FF&HIGH=9A&EXTENDED=FF&LOCKBIT=FF
*/
#include <hardware/lcd/hr20.h>
#include <hardware/adc/hr20-temp.h>
/* jump to bootloader = 1024 words */
void (*jump_boot)(void) = (void *)0x1E00;
static uint8_t RXLine ;
static uint16_t Message = 0 ;
static uint16_t RingCount = 0 ;
static uint16_t Int0Cnt = 0 ;
static uint16_t Int0CntOld = 0 ;
static uint16_t Int0RingCountOld = 0 ;
static uint16_t Int0StopPos = 900 ;
static uint8_t t1 ; // Taste, Links, Auto/Manu
static uint8_t t2 ; // Taste, Mitte, Prog
static uint8_t t3 ; // Taste, Rechts, Temp
static uint8_t t4 ;
static uint8_t t5 ;
static uint8_t Counter1 = 0 ;
static uint16_t Counter2 = 0 ;
static uint8_t rotate = 5 ;
static uint8_t DisplayMode = 1; // Anzeige Modus
static uint8_t DisplayChar0 ;
static uint8_t DisplayChar1 ;
static uint8_t DisplayChar2 ;
static uint8_t DisplayChar3 ;
static uint8_t MotorRun = 0;
static uint16_t BattSpannung;
static uint16_t TempGrad;
//########################################################################################################################
void motor_off() {
PORTG &= ~_BV(PG3); // PORTG(PG3) = 0 Motor Aus
PORTG &= ~_BV(PG4); // PORTG(PG4) = 0 Motor Aus
MotorRun = 0;
}
void motor_open() {
PORTG &= ~_BV(PG3); // PORTG(PG3) = 0 Motor Vorwärts ( Ventil Auf )
PORTG |= _BV(PG4); // PORTG(PG4) = 1 Motor Vorwärts ( Ventil Auf )
MotorRun = 1;
Int0RingCountOld = RingCount ;
Int0Cnt = 0;
Int0CntOld = 0;
}
void motor_close() {
PORTG |= _BV(PG3); // PORTG(PG3) = 1 Motor Rückwärts ( Ventil Zu )
PORTG &= ~_BV(PG4); // PORTG(PG4) = 0 Motor Rückwärts ( Ventil Zu )
MotorRun = 1;
Int0RingCountOld = RingCount ;
Int0Cnt = 0;
Int0CntOld = 0;
}
void motor_hang_check() {
if ( RingCount >= ( Int0RingCountOld + 6 ) || Int0Cnt > Int0StopPos ) {
motor_off();
} else {
if ( Int0Cnt > Int0CntOld ) {
Int0RingCountOld = RingCount ;
Int0CntOld = Int0Cnt ;
}
}
Counter2 = Int0Cnt;
}
//########################################################################################################################
#include <protocols/ecmd/ecmd-base.h>
int16_t parse_cmd_motor_stop(char *cmd, char *output, uint16_t len) {
while (*cmd == ' ')
cmd++;
if (*cmd == '\0') {
return ECMD_FINAL(snprintf_P(output, len, PSTR("%d"), Int0StopPos));
} else {
uint16_t NewInt0StopPos = strtoul(cmd, NULL, 10);
if (!NewInt0StopPos)
return ECMD_ERR_PARSE_ERROR;
Int0StopPos=NewInt0StopPos;
return ECMD_FINAL_OK;
}
}
int16_t parse_cmd_motor_pos(char *cmd, char *output, uint16_t len) {
return ECMD_FINAL(snprintf_P(output, len, PSTR("%d"), Int0Cnt));
}
int16_t parse_cmd_motor_open(char *cmd, char *output, uint16_t len) {
motor_open();
return ECMD_FINAL_OK;
}
int16_t parse_cmd_motor_close(char *cmd, char *output, uint16_t len) {
motor_close();
return ECMD_FINAL_OK;
}
//########################################################################################################################
CONTROL_START
dnl ECMD_GLOBAL(EcmdVal, 0, uint16_t);
THREAD(DisplayOut)
BattSpannung=HR20_GET_BATT ();
TempGrad=hr20_temp_get ();
switch(DisplayMode) {
case 1: // Anzeige Datum und uhrzeit
DisplayChar3=((datetime.hour / 10) % 10);
DisplayChar2=(datetime.hour % 10);
DisplayChar1=((datetime.min / 10) % 10);
DisplayChar0=(datetime.min % 10);
break;
case 2: // Anzeige Batterie Spannung
DisplayChar3=HR20_LCD_CHAR_SPACE;
DisplayChar2=((BattSpannung / 100) % 10);
DisplayChar1=((BattSpannung / 10) % 10);
DisplayChar0=( BattSpannung % 10);
LCD_SEG_CLEAR (LCD_SEG_COL1);
LCD_SEG_SET (LCD_SEG_COL2);
break;
case 3: // Anzeige Temperatur
DisplayChar3=((TempGrad / 100) % 10);
DisplayChar2=((TempGrad / 10) % 10);
DisplayChar1=( TempGrad % 10);
DisplayChar0=HR20_LCD_CHAR_DEG;
LCD_SEG_CLEAR (LCD_SEG_COL1);
LCD_SEG_SET (LCD_SEG_COL2);
break;
case 4: // Counter2 wert anzeige
// DisplayChar3=HR20_LCD_CHAR_SPACE;
DisplayChar3=((Counter2 / 1000) % 10);
DisplayChar2=((Counter2 / 100) % 10);
DisplayChar1=((Counter2 / 10) % 10);
DisplayChar0=(Counter2 % 10);
}
if ( DisplayMode >= 1 ) {
LCD_SEG_TOGGLE (LCD_SEG_COL1);
LCD_SEG_TOGGLE (LCD_SEG_COL2);
hr20_lcd_putchar(3, DisplayChar3);
hr20_lcd_putchar(2, DisplayChar2);
hr20_lcd_putchar(1, DisplayChar1);
hr20_lcd_putchar(0, DisplayChar0);
}
WAIT(1);
THREAD_END(DisplayOut)
ON STARTUP DO
// vorbereitung für tasten und wahlrad
DDRB = 0;
PORTB = (1<<PB7) | (1<<PB6) | (1<<PB3) | (1<<PB2) | (1<<PB1) | (1<<PB0);
// Lichtschranke vorbereiten
// DDRE &= ~_BV(PE4); // DDRE(PE4) = 0 Eingang Schalten für lichschranken ausgang
// PORTE &= ~_BV(PE4); // PORTE(PE4) = 0 Pullup deaktivieren für lichschranken ausgang
// DDRE |= _BV(PE2); // DDRE(PE2) = 1 Lichtschranke pinne, vorbereiten
// DDRE |= _BV(PE3); // DDRE(PE3) = 1 Lichtschranke pinne, vorbereiten
// PORTE |= _BV(PE2); // PORTE(PE2) = 1 Lichtschranke aktivieren ( port output and high )
// PORTE |= _BV(PE3); // PORTE(PE3) = 1 Lichtschranke aktivieren ( port output and high )
// PCMSK0 |= _BV(PCINT4); // PCMSK0(PCINT4) = 1 interrupt für den pin aktivieren
// EIMSK |= _BV(PCIE0); // EIMSK(PCIE0) = 1 interrupt generell f.r pereferie 0 aktivieren
// Interrupt für Tasten und Wahlrad
// PCMSK1 |= _BV(PCINT12); dnl Interrupt aktivierung f.r wahlrad
// PCMSK1 |= _BV(PCINT13); dnl Interrupt aktivierung f.r wahlrad
// EIMSK |= _BV(PCIE1); // EIMSK(PCIE1) = 1 Pin Change Interrupt Enable 1
DDRE = (1<<PE3) | (1<<PE2);
PORTE = (1<<PE3) | (1<<PE2);
PCMSK0 = (1<<PCINT4);
PCMSK1 = (1<<PCINT12) | (1<<PCINT13);
EIMSK = (1<<PCIE0) | (1<<PCIE1);
RXLine = 1 ;
TCP_CONNECT(10.2.0.33, 95, message_handler);
clock_set_time(1273785514);
THREAD_START(DisplayOut)
END
RingCount ++ ;
if ( RingCount >= 32768 ) { RingCount = 0 ; }
TCP_HANDLER_PERSIST(message_handler)
for (;;) {
if ( MotorRun == 0 ) {
TCP_SEND("Message=%d BattSpannung=%d TempGrad=%d\n", Message, BattSpannung, TempGrad);
}
Message ++;
if ( Message >= 32768 ) { Message = 0 ; }
WAIT(60);
}
TCP_HANDLER_END();
//########################################
if (!(PINB & 0b00000001)) {
t1 ++ ;
if ( t1 >= 251 ) { t1 = 250 ; }
} else {
t1=0 ;
}
if (!(PINB & 0b00000010)) {
t2 ++ ;
if ( t2 >= 251 ) { t2 = 250 ; }
} else {
t2=0 ;
}
if (!(PINB & 0b00000100)) {
t3 ++ ;
if ( t3 >= 251 ) { t3 = 250 ; }
} else {
t3=0 ;
}
//########################################
// Jump to Bootloader
if ( t1 == 100 && t3 == 100 ) {
jump_boot();
}
// motor_open
if ( t1 >= 10 ) {
motor_open();
}
// motor_close
if ( t3 >= 10 ) {
motor_close();
}
//
if ( t2 >= 10 ) {
DisplayMode ++;
if ( DisplayMode >= 5 ) { DisplayMode = 0 ; }
t2 = 0;
}
if ( MotorRun == 1 ) { motor_hang_check(); }
//########################################
CONTROL_END
//########################################################################################################################
// Interrupt für dir motor Lichtschranke
ISR(PCINT0_vect) {
Int0Cnt ++;
}
//########################################################################################################################
// Interrupt für Tasten und Wahlrad
ISR(PCINT1_vect) {
if (!(PINB & 0b00010000)) { // PB4 (entprellt)
t4 = 1 ;
if ( t4 >= 251 ) { t4 = 250 ; }
} else {
t4 = 0 ;
}
if (!(PINB & 0b00100000)) { // PB5
t5 = 1 ;
if ( t5 >= 251 ) { t5 = 250 ; }
} else {
t5 = 0 ;
}
if ( t4 == 1 && t5 == 0 && rotate == 5 ) { rotate = 6 ; }
if ( t4 == 1 && t5 == 1 && rotate == 6 ) { rotate = 7 ; }
if ( t4 == 0 && t5 == 1 && rotate == 7 ) { rotate = 8 ; }
if ( t4 == 0 && t5 == 0 && rotate == 8 ) { rotate = 5 ; Counter1 ++ ; }
if ( t4 == 0 && t5 == 1 && rotate == 5 ) { rotate = 4 ; }
if ( t4 == 1 && t5 == 1 && rotate == 4 ) { rotate = 3 ; }
if ( t4 == 1 && t5 == 0 && rotate == 3 ) { rotate = 2 ; }
if ( t4 == 0 && t5 == 0 && rotate == 2 ) { rotate = 5 ; Counter1 -- ; }
}
//########################################################################################################################
/*
-- Ethersex META --
ecmd_feature(motor_open, "motor open", Moror Open)
ecmd_feature(motor_close, "motor close", Moror Close)
ecmd_feature(motor_stop, "motor stop",[value], Display/Set the current thermy value.)
ecmd_feature(motor_pos, "motor pos", Moror Pos)
*/