Raumklima

Aus Ethersex_Wiki
Version vom 29. Jänner 2011, 14:31 Uhr von Kiwi (Diskussion | Beiträge)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

hallo zusammen, da ich jetzt schon merhfach immer wieder gefragt worden bin nach dem programm, womit auto 1w sensor detection möglich ist, hier ist es mal :-)


// ################################################################################
// #                                                                              #
// # Daten Analyse und Programm Erstellung:                                       #
// #   Copyright (c) 2009-2010 - Michael Schultz <ethersex@keyb.de>               #
// #      Mit viel unterstuetzung/Geduld von: stesie, veyron und DanielW          #
// #                                                                              #
// # 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                                         #
// #                                                                              #
// #                                                                              #
// # Wetter-Funk-Daten Analyse Programm für Wetter Station der Firma              #
// #     Krippl Watches GmbH   --   http://www.produktservice.info                #
// # Protokoll analyse siehe:                                                     #
// #     http://www.ethersex.de/index.php/Funk-wetterstations-protokoll           #
// #                                                                              #
// ################################################################################

// Logging Destination Host: 10.0.0.77 on Port 95

#ifndef ONEWIRE_SUPPORT
#error Please define onewire support
#endif

#ifdef ONEWIRE_DETECT_SUPPORT
#error Please undefine onewire detect support
#endif


#define PRESCALER 1024
#define NS_PER_TICK     (PRESCALER * 1000000UL / F_CPU * 1000)
#define US_TO_TICKS(n)  ((n) * 1000UL / NS_PER_TICK)

uint16_t Count1;
uint16_t Count2;
                                        //         Timing                   @16mhz: Timer Count     Timer C. Hex    Decode
uint8_t  Time0 = US_TO_TICKS(1920);     // L       space 1920 bis 1999us            30-31,2         0x1E    0x1F    0
uint8_t  Time1 = US_TO_TICKS(3990);     // H       space 3990 bis 4049us            62,3-63,2       0x3E    0x3F    1
uint8_t  Time2 = US_TO_TICKS(2060);     // End-l   space 2060 bis 2089us            32,1-32,6       0x20    0x21    2
uint8_t  Time3 = US_TO_TICKS(4130);     // End-h   space 4130 bis 4169us            64,5-65,1       0x40    0x41    3
uint8_t  Time4 = US_TO_TICKS(8890);     // Start   space 8890 bis 8939us            138,9-139,6     0x8A    0x8C    4
uint8_t  Time5 = US_TO_TICKS(360);      // End-    pulse  360 bis 369us             5,6-5,7         0x05            5
uint8_t  Time6 = US_TO_TICKS(440);      // _       pulse  440 bis 519us             6,8-8,1         0x06    0x08    6
                                        // Pause
                                        //
uint8_t  BitPos = 0;                    // Bit Position innerhalb eines 36 bit worts (1 bis 37)
uint8_t  WordCound = 0;                 // Daten Wort Count (1 bis 9)
uint8_t  WordByte[50];                  // 1 Data Word = 5 Byte    /       Max 8 Data Words
uint8_t  WordBytePos = 0;               // Byte Pos in WordByte
uint8_t  MatchPos = 0;                  // meist vorkommene datenwort position im telegram
uint8_t  MatchCount = 0;                // wie viel treffer hatte dieses meist vorkommende telegram
                                        //
int16_t  Temp;                          // Temperatur Wert (-)76,8 bis (+)127,9 °C, Vorzeichen wird erst bei der ausgabe gesetzt.
uint16_t Feuchte = 0;                   // Luftfeuchte Wert 20-99 %
uint8_t  timer_0 = 0;                   // Timer Wert für zeitbestimming zwichen 2 Pegel änderungen (Interrupts)
                                        //
uint8_t  Analysis[10] ;                 // Daten Analyse array
dnl uint8_t  Analysis[15] ;                     // Daten Analyse array
                                        // Analysis[0 bis 7]               Treffer der Daten Packets Übereinstimmung.
                                        // Analysis[8] - bit(0) = 1        Daten Liegen an und können vearbeitete werden
                                        // Analysis[8] - bit(1) = 1        Datenanalyse erfolgreich, Mindestens 3 Übereinstimmungen
                                        // Analysis[8] - bit(2) = 1        Daten sind Verarbeitet und können gesendet werden
                                        // Analysis[9]                     Array Positions Counter fuer analyse
uint16_t InterruptCall = 0 ;            // Interrupt0 aufrufs counter
uint16_t InterruptCallOld = 0 ;

uint8_t  OW_RomAddrLst[128] ;           // Maximum 16 Sensors to find
uint8_t  OW_SensorsFound;

uint8_t  Motor1Pwm ;
uint8_t  Motor2Pwm ;
uint8_t  Motor1PwmCount = 0;
uint8_t  Motor2PwmCount = 0;

uint8_t  OWSend;
uint16_t OWGetTimer = 0;
int16_t  OWTemp;
uint8_t  OWSendSensor;
uint8_t  OWSendSensorOld;

uint8_t   Channel;

uint16_t NetWatchDog = 0;

uint8_t  ManuSend;

uint8_t MessageCnt = 0;

uint16_t SendMessage = 0;
uint16_t MarkSending = 0;
uint16_t MarkCnt = 0;

dnl     uint8_t   reset;

dnl     char YearMonth[13][4] = {"---", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

//########################################################################################################################
#include "hardware/onewire/onewire.h"
#include "core/bit-macros.h"

void noinline ow_set_address_bit(struct ow_rom_code_t *rom, uint8_t idx, uint8_t val);

int8_t noinline ow_search_rom(uint8_t first) {
        /* reset discover state machine */
        if (first) {
                ow_global.last_discrepancy = -1;
                /* reset rom code */
                for (uint8_t i = 0; i < 8; i++) {       ow_global.current_rom.bytewise[i] = 0;          }
        } else {
                /* if last_discrepancy is below zero, discovery is done */
                if (ow_global.last_discrepancy < 0) {           return 0;               }
        }
        uint8_t discrepancy = -1;
        if (!reset_onewire()) {         return -1;      }       /* reset the bus */
        ow_write_byte(OW_ROM_SEARCH_ROM);                       /* transmit command byte */
        for (uint8_t i = 0; i <64; i++) {
                uint8_t bit1 = ow_read();                       /* read bits */
                uint8_t bits = (ow_read() << 1) | bit1;
                if (bits == 3) {
                        return 0;               /* no devices, just return */
                } else if (bits == 0) {
                        if (i == ow_global.last_discrepancy) {
                                ow_set_address_bit(&ow_global.current_rom, i, 1);       /* set one */
                                bit1 = 1;                                               /* transmit one next time */
                        } else if (i > ow_global.last_discrepancy) {
                                ow_set_address_bit(&ow_global.current_rom, i, 0);               /* set zero */
                                discrepancy = i;
                        } else {
                                uint8_t rom_bit = ow_global.current_rom.bytewise[i / 8] & _BV(i % 8);
                                if (rom_bit == 0)
                                discrepancy = i;
                                bit1 = rom_bit;         /* transmit last bit next time */
                        }
                } else {
                        ow_set_address_bit(&ow_global.current_rom, i, bit1);            /* normal case, no discrepancy */
                }
                OW_CONFIG_OUTPUT();
                ow_write(bit1);                 /* select next bit */
        }
        ow_global.last_discrepancy = discrepancy;
        return 1;               /* new device discovered */
}

void save_onewire_list() {
        OW_SensorsFound=0;
        for (uint8_t i = 0; i < (129); i++) {
                OW_RomAddrLst[i] = 0 ;
        }
        int16_t ret;
        onewire_list_loop:
        if (ow_global.lock == 0) {
                /* make sure only one conversion happens at a time */
                ow_global.lock = 1;
                uint8_t sreg = SREG;            /* disable interrupts */
                cli();
                ret = ow_search_rom_first();
                SREG = sreg;                    /* re-enable interrupts */
dnl             if (ret <= 0) {                 /* no devices on the bus */
dnl                     OW_SensorsFound=0;
dnl             }
        } else {
                uint8_t sreg = SREG;            /* disable interrupts */
                cli();
                ret = ow_search_rom_next();
                SREG = sreg;                    /* re-enable interrupts */
        }
        if (ret == 1) {
                for (uint8_t i = 0; i < 8; i++) {
                        OW_RomAddrLst[((OW_SensorsFound * 8) + i )] = ow_global.current_rom.bytewise[i] ;
                }
                OW_SensorsFound ++;
                goto onewire_list_loop;
        } else if (ret == 0) {
                ow_global.lock = 0;
        }
}

int16_t ow_read_temp (struct ow_rom_code_t *rom)
{
        int16_t retval = 0x7FFF;  /* error */
        uint8_t sreg = SREG;            /* disable interrupts */
        cli();
        struct ow_temp_scratchpad_t sp;
        if (ow_temp_read_scratchpad(rom, &sp) != 1)
                goto out1;  // scratchpad read failed
        uint16_t temp = ow_temp_normalize(rom, &sp);
        uint8_t sign = ((int16_t) temp < 0);
        if (sign) {     temp = -temp;           }
        retval = HI8(temp) * 10 + HI8(((temp & 0x00ff) * 10) + 0x80);
        if (sign) { retval = retval * - 1; }
        out1:
        SREG = sreg;                    /* re-enable interrupts */
        return retval;
}

int16_t ow_temp (struct ow_rom_code_t *rom)
{
        int16_t retval = 0x7FFF;  /* error */
        uint8_t sreg = SREG;            /* disable interrupts */
        cli();
        if (ow_temp_start_convert_wait(rom) != 1)
                goto out2;
        retval=ow_read_temp(rom);
        out2:
        SREG = sreg;                    /* re-enable interrupts */
        return retval;
}

//########################################################################################################################
dnl     /* jump to bootloader */
dnl     void (*jump_boot)(void) = (void *)BOOTLOADER_SECTION ;

#include "protocols/ecmd/ecmd-base.h"

dnl     int16_t parse_cmd_res(char *cmd, char *output, uint16_t len) {
dnl     //      status.request_reset = 1;
dnl             reset=1;
dnl             return ECMD_FINAL_OK;
dnl     }

int16_t parse_cmd_nwd(char *cmd, char *output, uint16_t len) {
        NetWatchDog = 0;
        return ECMD_FINAL_OK;
}

int16_t parse_cmd_m1on(char *cmd, char *output, uint16_t len) {
        while (*cmd == ' ')
        cmd++;
        if (*cmd == '\0') {
                Motor1Pwm = 1;
                return ECMD_FINAL_OK;
        } else {
                uint8_t NewMotor1Pwm = strtoul(cmd, NULL, 10);
                if (!NewMotor1Pwm)
                        return ECMD_ERR_PARSE_ERROR;
                Motor1Pwm=NewMotor1Pwm;
                return ECMD_FINAL_OK;
        }
}

int16_t parse_cmd_m1off(char *cmd, char *output, uint16_t len) {
        PORTC   &= ~(1 << PC3);                 //
        Motor1Pwm = 0;
        return ECMD_FINAL_OK;
}

int16_t parse_cmd_m2on(char *cmd, char *output, uint16_t len) {
        while (*cmd == ' ')
        cmd++;
        if (*cmd == '\0') {
                Motor2Pwm = 1;
                return ECMD_FINAL_OK;
        } else {
                uint8_t NewMotor2Pwm = strtoul(cmd, NULL, 10);
                if (!NewMotor2Pwm)
                        return ECMD_ERR_PARSE_ERROR;
                Motor2Pwm=NewMotor2Pwm;
                return ECMD_FINAL_OK;
        }
}

int16_t parse_cmd_m2off(char *cmd, char *output, uint16_t len) {
        PORTC   &= ~(1 << PC5);                 //
        Motor2Pwm = 0;
        return ECMD_FINAL_OK;
}

int16_t parse_cmd_charge(char *cmd, char *output, uint16_t len) {
        PORTA   &= ~(1 << PA7);
        return ECMD_FINAL_OK;
}

int16_t parse_cmd_discharge(char *cmd, char *output, uint16_t len) {
        PORTA   |=  (1 << PA7);
        return ECMD_FINAL_OK;
}

int16_t parse_cmd_owrl(char *cmd, char *output, uint16_t len) {
        save_onewire_list();
        return ECMD_FINAL_OK;
}
//########################################################################################################################
CONTROL_START
        ON STARTUP DO
                Analysis[8]     |= (1 << 2);            //      nach start einmal ausgabe, um zu schauen wann das ding gebootet ist...
                _TCCR0_PRESCALE |=  _BV(CS02);          //      TCCR0B(CS02)=1
                _TCCR0_PRESCALE &= ~_BV(CS01);          //      TCCR0B(CS01)=0
                _TCCR0_PRESCALE |=  _BV(CS00);          //      TCCR0B(CS00)=1

                DDRD    &= ~(1 << DDD2);                //
                PORTD   |=  (1 << PD2);                 //
                MCUCR   &= ~(1 << PUD);                 //

                DDRC    |=  (1 << DDC3);                //
                DDRC    |=  (1 << DDC5);                //

                DDRA    |=  (1 << DDA7);                //
//              PORTA   &= ~(1 << PA7);
                PORTA   |=  (1 << PA7);                 //      discharge the accu after reboot

//              PORTD   &= ~(1 << DDD0);                //      USART RX PIN Inout
//              PORTD   |=  (1 << PD0);                 //      USART RX PIN

//              PORTD   |=  (1 << DDD1);                //      USART RX PIN Output
//              PORTD   |=  (1 << PD1);                 //      USART TX PIN


//              PD1/TXD PD0/RXD
//      PUOE    TXEN    RXEN
//      PUOV    0       PORTD0 · PUD
//      DDOE    TXEN    RXEN
//
//      s50


                _EIMSK          |=  _BV(INT0);          //      EIMSK(INT0) = 1         Interrupt, Input Data on INT0 / PD2
                _EICRA          &= ~_BV(ISC01);         //      EICRA(ISC01) = 0        interrupt on any edge, asyncronously
                _EICRA          |=  _BV(ISC00);         //      EICRA(ISC00) = 1        interrupt on any edge, asyncronously
                _TIMSK_TIMER0   |=  _BV(TOIE0);         //      TIMSK0(TOIE0) = 1       Interrupt on Timer Overflow aktivieren
                TCP_CONNECT(10.0.0.77, 95, message_handler);
                save_onewire_list();
        END


        if ( Motor1Pwm != 0 ) {
                Motor1PwmCount ++;
                PORTC |=  (1 << PC3);
                if ( Motor1PwmCount >= Motor1Pwm ) {
                        PORTC &= ~(1 << PC3);
                }
                if ( Motor1PwmCount >= 5 ) { Motor1PwmCount = 0; }
        }

        if ( Motor2Pwm != 0 ) {
                Motor2PwmCount ++;
                PORTC |=  (1 << PC5);
                if ( Motor2PwmCount >= Motor2Pwm ) {
                        PORTC &= ~(1 << PC5);
                }
                if ( Motor2PwmCount >= 5 ) { Motor2PwmCount = 0; }
        }



        TCP_HANDLER_PERSIST(message_handler)
        for (;;) {
                if ( SendMessage >= 50 ) {
                        SendMessage = 0;
                        InterruptCallOld = InterruptCall;
                        MessageCnt ++;

                        // Lösche ale Analysis Counter
                        for (Count1 = 0; Count1 < 8; Count1 ++) Analysis[ (Count1) ] = 0 ;

                        // wie oft matcht welsches telegram mit allen anderen 8 telegrammen
                        for (Count1 = 0; Count1 < 8; Count1 ++)
                                for (Count2 = 0; Count2 < 8; Count2 ++)
                                        if (memcmp(&WordByte[ (Count1) * 5 ], &WordByte[ ( Count2 + 1 ) * 5], 5) == 0)
                                                { Analysis[ (Count1) ] ++ ; }

                        // nim nur das telegram mit der größten anzahl an treffer
                        for (Count1 = 8; Count1 > 1; Count1 --)
                                for (Count2 = 0; Count2 < 8; Count2 ++)
                                        if ( Analysis[ (Count2) ] == Count1 ) {
                                                MatchPos = Count2 ;
                                                MatchCount = Count1 ;
                                                WordByte[45] = WordByte[ ( MatchPos * 5 )     ] ;
                                                WordByte[46] = WordByte[ ( MatchPos * 5 ) + 1 ] ;
                                                WordByte[47] = WordByte[ ( MatchPos * 5 ) + 2 ] ;
                                                WordByte[48] = WordByte[ ( MatchPos * 5 ) + 3 ] ;
                                                WordByte[49] = WordByte[ ( MatchPos * 5 ) + 4 ] ;
                                        }
                        Channel = 0;
                        if ( WordByte[45] & ( 1 << 2 ) ) { Channel = 1; }
                        if ( WordByte[45] & ( 1 << 3 ) ) { Channel = Channel + 2; }

                        if ( WordByte[46] & ( 1 << 4 ) ) { ManuSend = 1; } else { ManuSend = 0; }

                        // binär analyse der temperatur
                        Temp = 0 ;
                        if ( WordByte[46] & ( 1 << 3 ) ) { Temp = Temp + 1    ; }
                        if ( WordByte[46] & ( 1 << 2 ) ) { Temp = Temp + 2    ; }
                        if ( WordByte[46] & ( 1 << 1 ) ) { Temp = Temp + 4    ; }
                        if ( WordByte[46] & ( 1 << 0 ) ) { Temp = Temp + 8    ; }
                        if ( WordByte[47] & ( 1 << 7 ) ) { Temp = Temp + 16   ; }
                        if ( WordByte[47] & ( 1 << 6 ) ) { Temp = Temp + 32   ; }
                        if ( WordByte[47] & ( 1 << 5 ) ) { Temp = Temp + 64   ; }
                        if ( WordByte[47] & ( 1 << 4 ) ) { Temp = Temp + 128  ; }
                        if ( WordByte[47] & ( 1 << 3 ) ) { Temp = Temp + 256  ; }
                        if ( WordByte[47] & ( 1 << 2 ) ) { Temp = Temp + 512  ; }
                        if ( WordByte[47] & ( 1 << 1 ) ) { Temp = Temp + 1024 ; }
                        if ( WordByte[47] & ( 1 << 0 ) ) { Temp = Temp * - 1  ; }

                        // binär analyse der luftfeuchtigkeit
                        Feuchte = 0 ;
                        if ( WordByte[48] & ( 1 << 7 ) ) { Feuchte = Feuchte + 1  ; }
                        if ( WordByte[48] & ( 1 << 6 ) ) { Feuchte = Feuchte + 2  ; }
                        if ( WordByte[48] & ( 1 << 5 ) ) { Feuchte = Feuchte + 4  ; }
                        if ( WordByte[48] & ( 1 << 4 ) ) { Feuchte = Feuchte + 8  ; }
                        if ( WordByte[48] & ( 1 << 3 ) ) { Feuchte = Feuchte + 10 ; }
                        if ( WordByte[48] & ( 1 << 2 ) ) { Feuchte = Feuchte + 20 ; }
                        if ( WordByte[48] & ( 1 << 1 ) ) { Feuchte = Feuchte + 40 ; }
                        if ( WordByte[48] & ( 1 << 0 ) ) { Feuchte = Feuchte + 80 ; }

                        TCP_SEND("%02d:%02d:%02d %s temp: Msg=%d   i=%04x ch=%d t=%d h=%d m=%d M=%d/%d d=%02x%02x%02x%02x%02x\n",
                                CLOCK_HOUR(), CLOCK_MIN(), CLOCK_SEC(), CONF_HOSTNAME, MessageCnt, InterruptCall, Channel, Temp, Feuchte, ManuSend, MatchPos, MatchCount, WordByte[45],  WordByte[46],  WordByte[47],  WordByte[48],  WordByte[49]);

                        for (Count1 = 0; Count1 < 45; Count1 ++) { WordByte[Count1] = 0; }
                }

                if ( OWSend >= 1 ) {
                        OWSend = 0;
                        TCP_SEND("%02d:%02d:%02d %s OneWire:   Sensor=%d: Fam=%02x ID=%02x%02x%02x%02x%02x%02x crc=%02x Temp=%d\n",
                                CLOCK_HOUR(), CLOCK_MIN(), CLOCK_SEC(), CONF_HOSTNAME,
                                (OWSendSensor + 1),
                                OW_RomAddrLst[((OWSendSensor * 8)     )],
                                OW_RomAddrLst[((OWSendSensor * 8) + 1 )], OW_RomAddrLst[((OWSendSensor * 8) + 2 )],
                                OW_RomAddrLst[((OWSendSensor * 8) + 3 )], OW_RomAddrLst[((OWSendSensor * 8)  )],
                                OW_RomAddrLst[((OWSendSensor * 8) + 5 )], OW_RomAddrLst[((OWSendSensor * 8) + 6 )],
                                OW_RomAddrLst[((OWSendSensor * 8) + 7 )],
                                OWTemp);
                }

                MarkSending ++;
                if ( MarkSending >= 150 ) {
                        MarkCnt ++;
                        MarkSending = 0;
                        TCP_SEND("%02d:%02d:%02d %s MarkCnt=%d   Sensors=%d\n",
                                CLOCK_HOUR(), CLOCK_MIN(), CLOCK_SEC(), CONF_HOSTNAME, MarkCnt, OW_SensorsFound)
                }

                PT_YIELD(pt);
        }
        TCP_HANDLER_END();
                OWGetTimer ++;
                if ( OWGetTimer >= 3000 ) {
                        if ( OWGetTimer == 3001 ) {
                                ow_temp_start_convert(NULL,0);
                                OWSendSensorOld=255;
                        }
                        if ( OWGetTimer >= 3250 ) {
                                OWSendSensor=(OWGetTimer - 3250) / 100;
                                if ( OWSendSensor >= OW_SensorsFound ) {
                                        OWGetTimer = 0;
                                        goto NoSend;
                                }
                                if ( OWSendSensor == OWSendSensorOld ) {        goto NoSend;            }
                                struct ow_rom_code_t ow_rom = {{ .bytewise = {
                                        OW_RomAddrLst[((OWSendSensor * 8)     )], OW_RomAddrLst[((OWSendSensor * 8) + 1 )],
                                        OW_RomAddrLst[((OWSendSensor * 8) + 2 )], OW_RomAddrLst[((OWSendSensor * 8) + 3 )],
                                        OW_RomAddrLst[((OWSendSensor * 8) + 4 )], OW_RomAddrLst[((OWSendSensor * 8) + 5 )],
                                        OW_RomAddrLst[((OWSendSensor * 8) + 6 )], OW_RomAddrLst[((OWSendSensor * 8) + 7 )],
                                }}};
                                OWTemp = ow_temp(&ow_rom);
                                OWSend = 1;
                                OWSendSensorOld = OWSendSensor;
                                NoSend:
                                OWGetTimer=OWGetTimer;
                        }
                }



        if ( InterruptCall != InterruptCallOld ) {
                SendMessage ++;
        }

        NetWatchDog ++;
        if ( NetWatchDog == 15000 ) {                   // 5 Min
                init_enc28j60();
        } else {
                if ( NetWatchDog == 30000 ) {           // 10 Min
                        status.request_reset = 1;
                }
        }

dnl     if ( reset == 1) {
dnl             EndlessLoop:
dnl             goto EndlessLoop;
dnl     }

CONTROL_END
// ###############################################################################################################################
void CalcWordBytePos () {
        WordBytePos=(( BitPos / 8 ) + ( WordCound * 5 ));
        if ( WordBytePos >= 40 ) {
                BitPos = 0 ;
                WordCound = 0 ;
                WordBytePos=(( BitPos / 8 ) + ( WordCound * 5 ));
        }
}

ISR(INT0_vect) {
        timer_0 = TCNT0;
        InterruptCall ++;
        CalcWordBytePos();
        if ( timer_0 >= Time6 && timer_0 <= ( Time6 + 3 ) ) {                   // _               (puls)
        } else if ( timer_0 == Time0 || timer_0 == ( Time0 + 1 ) ) {            // L       0       (L - Bit - Normal)
                WordByte[WordBytePos] &= ~(1 << ( 7 - (BitPos % 8)));           // WordByte[n] = 0;
                BitPos ++ ;
        } else if ( timer_0 == Time1 || timer_0 == ( Time1 + 1 ) ) {            // H       1       (H - Bit - Normal)
                WordByte[WordBytePos] |= 1 << ( 7 - (BitPos % 8));              // WordByte[n] = 1;
                BitPos ++ ;
        } else if ( timer_0 == Time2 || timer_0 == ( Time2 + 1 ) ) {            // End-l   2       (Ende Datenwort L)
                WordByte[WordBytePos] &= ~(1 << ( 7 - (BitPos % 8)));           // WordByte[n] = 0;
                BitPos ++ ;
        } else if ( timer_0 == Time3 || timer_0 == ( Time3 + 1 ) ) {            // End-h   3       (Ende Datenwort H)
                WordByte[WordBytePos] |= 1 << ( 7 - (BitPos % 8));              // WordByte[n] = 1;
                BitPos ++ ;
        } else if ( timer_0 >= Time4 && timer_0 <= ( Time4 + 5 ) ) {            // Start   4      (Start Datenwort)
                if ( BitPos != 1 ) {
                        WordCound ++ ;
                        CalcWordBytePos();
                        WordByte[ ( WordBytePos )     ] = 0 ;
                        WordByte[ ( WordBytePos + 1 ) ] = 0 ;
                        WordByte[ ( WordBytePos + 2 ) ] = 0 ;
                        WordByte[ ( WordBytePos + 3 ) ] = 0 ;
                        WordByte[ ( WordBytePos + 4 ) ] = 0 ;
                }
                BitPos = 0;
        } else {                                                                // ?       8       (Nicht Erkanntes Timing)
                BitPos ++ ;
        }
        TCNT0 = 0;
}
// ###############################################################################################################################
ISR(TIMER0_OVF_vect) {
        if ( WordCound >= 3 ) {
                // zeitüberschreitung, warscheinlich ende einer übertragung, ausgabe aktivieren
                Analysis[8] |= (1 << 2);
        }
        BitPos = 0;
        WordCound = 0;
}
// ###############################################################################################################################
dnl ecmd_feature(res,           "res",          res)
/*
    -- Ethersex META --
    ecmd_feature(nwd,           "nwd",          Network Watchdog)

    ecmd_feature(m1on,          "m1on", [value], Motor 1 on)
    ecmd_feature(m1off,         "m1off",        Motor 1 off)
    ecmd_feature(m2on,          "m2on", [value], Motor 2 on)
    ecmd_feature(m2off,         "m2off",        Motor 2 off)
    ecmd_feature(charge,        "charge",       Charge Accu)
    ecmd_feature(discharge,     "discharge",    Discarge Accu)
    ecmd_feature(owrl,          "owrl",         ow refresh list)
*/