2k_v4_8_switch.cpp


1
/*
2
*******************************************************************
3
4
Autor:       Beck Martin (mit Vorlagen von Tobias Schneider)
5
Taktfrequenz:  8 MHz
6
Chip:      Atmel atMega 8
7
Datum:      August 2015
8
9
Bezeichnung:  2 Kanal 20 Funktionen Multiswitch - 2k20fms
10
Hintergund:    Grund für dieses Prgramm war die fehlende kostenguenstige Moeglichkeit mir nur
11
          2 Schaltknueppeln (jeweils 3 Wege Schalter) die 20 Funktionen meines
12
          meines Schleppschiffs = Rettungsschiffs zu steuern.
13
14
Funktionsbeschreibung:
15
16
Wenn ein Schalter von 0 = Neutralstellung in eine Endlage = 100 oder -100 gebracht wird, wird dies
17
als Schaltimpuls gewertet und dabei entweder als "lang" oder "kurz" gewertet.
18
Voreingestellt ist hier 500 ms = 0,5 Sekunden, was eine vernünftige Schaltfrequenz sein dürfte.
19
20
Beispiel:
21
22
- Schalter vom RC Sender auf 100 % für eine kurze Zeit von 0,35 s schaltet Ausgang 1
23
24
- Schalter vom RC Sender auf -100 % für eine kurze Zeit von 0,35 s schaltet Ausgang 2
25
 
26
- Schalter vom RC Sender auf 100 % für eine lange Zeit von >0,35 s schaltet Ausgang 3
27
 
28
- Schalter vom RC Sender auf -100 % für eine lange Zeit von >0,35 s schaltet Ausgang 4
29
 
30
Der Zustand bleibt bestehen (Memory) bis erneut der entsprechende Ausgang geschalten wurde.
31
Wahlweise kann der Ausgang auch "tastend" sein, was jedoch nur bei den "direkten" Schaltzustaenden
32
ohne Kombination wirklich sinnvoll ist.
33
34
Ausgelegt ist die Schaltung für 2 Schalter mit je 2 Tastfunktionen (oben / unten)
35
Sie mueßte jedoch auch mit Schaltern funktionieren, wurde jedoch nicht getestet.
36
37
Mein Test: Graupner MX-20 (Schalterumbau) mit 6 Kanalempfaenger
38
       Futaba FX-30 (Schalterumbau) mit 12 Kanalempfaenger
39
40
41
42
*******************************************************************
43
Wichtiger Hinweis zum Schluß:
44
 
45
__ -- Die vorliegende Software ist für private Zwecke frei verwendbar,          -- __
46
__ -- jedoch ist eine kommerzielle Verwendung, egal welcher Art nicht gestattet.  -- __
47
48
*******************************************************************
49
50
                              +------------+
51
         (PCINT14/RESET) PC6 -| 1       28 |- PC5 (ADC5/SCL/PCINT13)
52
           (PCINT16/RXD) PD0 -| 2       27 |- PC4 (ADC4/SDA/PCINT12)
53
           (PCINT17/TXD) PD1 -| 3       26 |- PC3 (ADC3/PCINT11)
54
           PCINT18/INT0) PD2 -| 4       25 |- PC2 (ADC2/PCINT10)
55
     (PCINT19/OC2B/INT1) PD3 -| 5       24 |- PC1 (ADC1/PCINT9)
56
        (PCINT20/XCK/T0) PD4 -| 6       23 |- PC0 (ADC0/PCINT8)
57
                         VCC -| 7       22 |- GND
58
                         GND -| 8       21 |- AREF
59
    (PCINT6/XTAL1/TOSC1) PB6 -| 9       20 |- AVCC
60
    (PCINT7/XTAL2/TOSC2) PB7 -| 10      19 |- PB5 (SCK/PCINT5)
61
       (PCINT21/OC0B/T1) PD5 -| 11      18 |- PB4 (MISO/PCINT4)
62
  (PCIN  T22/OC0A/AIN0) PD6 -| 12      17 |- PB3 (MOSI/OC2A/PCINT3)
63
         (PCINT23/AIN1) PD7 -| 13      16 |- PB2 (SS/OC1B/PCINT2)
64
        (PCINT0/CLKO/ICP1) PB0 -| 14      15 |- PB1 (OC1A/PCINT1)
65
                         +------------+
66
                         
67
                        
68
Verwendung in diesem Programm:
69
                         
70
                         
71
                              +------------+
72
             n.b.---  <- PC6 -| 1       28 |- PC5 -> A_6
73
                 A_7  <- PD0 -| 2       27 |- PC4 -> A_5
74
                 A_8  <- PD1 -| 3       26 |- PC3 -> A_4
75
               * E_1  -> PD2 -| 4       25 |- PC2 -> A_3
76
               * E_2  -> PD3 -| 5       24 |- PC1 -> A_2
77
                 A_9  <- PD4 -| 6       23 |- PC0 -> A_1
78
                         VCC -| 7       22 |- GND
79
                         GND -| 8       21 |- AREF
80
                 A_19 <- PB6 -| 9       20 |- AVCC
81
                 A_20 <- PB7 -| 10      19 |- PB5 -> A_18
82
                 A_10 <- PD5 -| 11      18 |- PB4 -> A_17
83
                 A_11 <- PD6 -| 12      17 |- PB3 -> A_16
84
                 A_12 <- PD7 -| 13      16 |- PB2 -> A_15
85
                 A_13 <- PB0 -| 14      15 |- PB1 -> A_14
86
                         +------------+                 
87
                         
88
89
*******************************************************************
90
*/
91
92
93
// *******************************************************************
94
// Hardwarespezifische Parameter - nur bei Bedarf und bewußt aendern!! - Bei Veraenderungen wird
95
// das Programm ggf. in dieser Form unbrauchbar und muß abgeaendert werden!!
96
97
98
// *******************************************************************
99
//
100
// allgemeine und Chip spezifische Parameter
101
//
102
// *******************************************************************
103
104
105
106
// --- Hardware definieren
107
108
#define F_CPU  8000000 // 8000000UL
109
110
// --- notwendige Hilfsdateien einbeinden
111
112
#include <avr/io.h>
113
#include <avr/interrupt.h>
114
#include <avr/wdt.h>
115
#include <util\delay.h>
116
117
118
// *******************************************************************
119
//
120
// selbst zu definierende Eingaenge, Ausgaenge und Parameter
121
//
122
// *******************************************************************
123
124
// --- Die Eingaenge ---  selbst zu definieren
125
126
#define TASTERPORT PINC
127
#define TASTERBIT PINC1
128
129
#define  E_1_Bit   PD2    //  Eingangssignal 1 vom Empfaenger (Kanal 4)
130
#define  E_1_Pin   PIND    //  PIN des Eingangssignals 1 vom Empfaenger (Kanal 4)
131
#define  E_1_Port   PORTD    //  Port des Eingangssignals 1 vom Empfaenger (Kanal 4)
132
133
#define  E_2_Bit   PD3     //  Eingangssignal 2 vom Empfaenger (Kanal 5)
134
#define  E_2_Pin   PIND  //  PIN des Eingangssignals 2 vom Empfaenger (Kanal 5)
135
#define  E_2_Port   PORTD    //  Port des Eingangssignals 2 vom Empfaenger (Kanal 5)
136
137
#define  E_DirReg  DDRD     //  Richtungsregister des Eingangssignals 1 und 2 vom Empfaenger (Kanal 4 und 5)
138
139
140
// --- Die Ausgaenge ---  selbst zu definieren -- ggf. im Hauptprogramm Ports anpassen
141
142
#define  A_1 PC0  //  Vor Rueck auf Rechts Links -> umschalten (an / aus)
143
#define  A_2 PC1  //  Schraube auf Geblaese -> umschalten (an / aus)
144
#define  A_3 PC2  //  Rettungsmaßnahme einholen -> ein / aus = automatischer Stop
145
#define  A_4 PC3  //  Rettungsmaßnahme 1 Abschuß -> ein / aus = automatischer Stop
146
#define  A_5 PC4  //  Rettungsmaßnahme 2 Abschuß -> ein / aus = automatischer Stop
147
#define  A_6 PC5  //  Licht innen (unten) -> an /aus
148
149
// #define A_21 PC6  //  -- nicht belegt da Reset
150
151
#define  A_7 PD0  //  Rauchgenerator -> an / aus - oder mit Fuellstandssensor bei "an")
152
#define  A_8 PD1  //  Ankerwinde -> auf / ab / Freier Fall (= Tastsignal auf Tiny übergeben)
153
#define  A_9 PD4  //  Sound Voegel / Geraeusche -> an / aus
154
#define A_10 PD5  //  Fahrtmusik von MP3 Spieler -> an = Tastsignal an Tiny - Fahrtmusik / Diverse Musik / aus
155
#define A_11 PD6  //  Nebelhorn - Sound (PIN = "tastend") MP3 Spieler -> an / aus
156
#define A_12 PD7  //  Licht Abschleppbereich (Heck) und Arbeitsbereich (Bug) -> an / aus
157
158
#define A_13 PB0  //  Positionslichter -> an / aus ("an" mit Helligkeitssensor)
159
#define A_14 PB1  //  Licht Suchscheinwerfer -> an / aus
160
#define A_15 PB2  //  Licht Steuerhaus -> an / aus
161
#define A_16 PB3  //  Licht Steuerkonsole -> an / aus
162
#define A_17 PB4  //  Querstahlruder -> an = Motor Querstahlruder Bug + Heck => Loeschmonitor A19 und A20 aus! / aus -> A19 mögl. ein
163
#define A_18 PB5  //  Loeschwasserpumpe -> an = Servo 1 = Monitor 1 drehen + Servo 2 = Monitor 2 drehen - nur wenn A18 und A20 aus! / aus 
164
#define A_19 PB6  //  Servo fuer Rettungsmaßnahme rechts / links -> nur wenn A18 aus und A19 aus !!
165
#define A_20 PB7  //  Kontroll LED für Microkontroller IC Feedback automatisch und Ton Feedback für Steuersignal (mit Jumper Signal ein / aus)
166
167
#define  A_1_6_Port   PORTC  //  Port des Ausgangssignals 1 bis 6
168
#define  A_7_12_Port   PORTD  //  Port des Ausgangssignals 7 bis 12
169
#define  A_13_20_Port   PORTB  //  Port des Ausgangssignals 16 bis 20
170
171
172
// --- Parameter ---  selbst zu definieren
173
174
volatile unsigned int schaltdauer = 350; // x10 ms;     // Zeit bis zum Wechsel des Schaltzustandes in ms für "langen Schaltzustand"
175
                      // Wert als vielfaches von 10
176
177
// *******************************************************************
178
//
179
// diverse sonstige Variablen im Programm
180
//
181
// *******************************************************************
182
183
184
volatile unsigned int impuls_E1= 0;     // Impuls Signal Eingang 1
185
volatile unsigned int impuls_E2= 0;     // Impuls Signal Eingang 2
186
volatile unsigned int signal_1 = 0;    // Impulslänge Signal Eingang 1
187
volatile unsigned int signal_2 = 0;    // Impulslänge Signal Eingang 2
188
189
volatile unsigned int schaltzeit_cnt = 0;        // Zaehler für Schaltzeit
190
volatile unsigned int schaltzeit_cnt1 = 0;      // Zaehler für Schaltzeit E1
191
volatile unsigned int schaltzeit_cnt2 = 0;      // Zaehler für Schaltzeit E1
192
volatile unsigned char aus_E1 = 0;        // Aus Signal E1 kommend
193
volatile unsigned char aus_E2 = 0;        // Aus Signal E2 kommend
194
195
196
197
volatile unsigned char schaltzustand = 0;      // Allgemeiner Schaltzustand
198
volatile unsigned char schaltzustand_1 = 0;     // Schaltzusand E1 / E2 (je max. 255 Stück!!)
199
volatile unsigned char schaltzustand_2 = 0;      
200
// volatile unsigned int schaltzustand_ausgabe = 0;  // Ausgabe des Schaltzustandes für Hauptprogramm
201
volatile unsigned int schaltzyklus_cnt = 0;      // Zaehler für komplette Schaltzyklen
202
volatile unsigned int schalt_cnt_1_o = 0;      // Zaehler fuer Schaltzustaende E1_oben
203
volatile unsigned int schalt_cnt_1_u = 0;      // Zaehler fuer Schaltzustaende E1_unten
204
volatile unsigned int schalt_cnt_2_o = 0;      // Zaehler fuer Schaltzustaende E2_oben
205
volatile unsigned int schalt_cnt_2_u = 0;      // Zaehler fuer Schaltzustaende E2_unten
206
volatile unsigned int schaltzeit = 0;
207
208
209
210
volatile unsigned int   mid_1 = 0;      // signal_mittelwert_1 / 2
211
volatile unsigned int   mid_2 = 0;
212
volatile unsigned char  i1;        // Zählvariable Signal 1 / 2
213
volatile unsigned char  i2;        
214
volatile unsigned char  wechselabwarten_1 = 0;    // warten auf mittelstellung_1 / 2
215
volatile unsigned char  wechselabwarten_2 = 0;  
216
volatile unsigned char  t1 = 0;      // Merker fuer Schalter als TipTaster 1 - 10
217
volatile unsigned char  t2 = 0;
218
volatile unsigned char  t3 = 0;
219
volatile unsigned char  t4 = 0;
220
volatile unsigned char  t5 = 0;
221
volatile unsigned char  t6 = 0;
222
volatile unsigned char  t7 = 0;
223
volatile unsigned char  t8 = 0;
224
volatile unsigned char  t9 = 0;
225
volatile unsigned char t10 = 0;
226
volatile unsigned int  t_zaehler = 0;  // Zaehler fuer TipTaster Merker 
227
volatile unsigned char ton = 0;      // Merker fuer Signalhorn / Warnton 
228
volatile unsigned int  ton_zaehler = 0;  // Zaehler fuer Signalhorn / Warnton  
229
230
231
232
volatile unsigned char sound = 0;
233
volatile unsigned int soundpresc = 0;
234
volatile unsigned char watch = 0;
235
volatile unsigned int fail = 0;
236
237
238
// *******************************************************************
239
//
240
// Unterprogramme (void), Timer und Interrupts
241
//
242
// *******************************************************************
243
244
245
// Interrupts
246
247
ISR (TIMER1_COMPA_vect)  // 100.000 Hz = 10.000 mySekundy
248
{
249
250
  if(PIND & (1<<PD2))    // Signallänge messen -> an E1 = Kanal 1 empfangen
251
  {  
252
    impuls_E1++;
253
  }
254
  else if(impuls_E1!=0)
255
  {
256
    if(impuls_E1>255)
257
    signal_1=0;
258
    else
259
    signal_1=impuls_E1;
260
    impuls_E1=0;
261
  }
262
  
263
  if(PIND & (1<<PD3))    // Signallänge messen -> an E2 = Kanal 2 empfangen
264
  {  
265
    impuls_E2++;
266
  }
267
  else if(impuls_E2!=0)
268
  {
269
  
270
    if(impuls_E2>255)
271
    signal_2=0;
272
    else
273
    signal_2=impuls_E2;
274
    impuls_E2=0;
275
  }
276
  
277
  
278
  watch = 1;        //Signal fuer Hauptschlaeife, den (Wach)Hund zu fuettern
279
  fail++;          //Zeitramen fuer Plausibilitaetstest erhoehen
280
  // --- noch implementieren
281
      
282
                          
283
                                                  
284
}
285
286
287
ISR (TIMER2_OVF_vect)  //Alle 10 ms
288
{
289
290
  schaltzeit_cnt++;
291
292
TCNT2 = 178; // = 0b10110010 = 0xB2                 // TCNT2 = 0x06; // = 6
293
OCR2 = 77 ;  // = 0b01001101 = 0x4D  
294
295
296
297
}
298
299
300
301
// *******************************************************************
302
// Timer
303
304
305
306
307
void startTimer1()     // alle 10 uSec = 100.000 Hz
308
{
309
  TCNT1 = 0b1111111111110110;
310
  TCCR1B |= (1 << CS11) | (1 << WGM12); // | (1 << CS10)   //Timer1 CTC /8
311
  OCR1B = 0x0009;
312
  TIMSK |= (1 << OCIE1A) | (1<<TOIE1) ;  //| (1<<OCIE2) |(1 << OCIE1B) ;
313
  
314
  
315
  
316
}
317
318
319
void startTimer2()     // als Abfrage 500 ms als vielfaches von 10 (9.9840) ms
320
{            // 500 / 10 ms = 50 mal
321
322
  schaltzeit_cnt = 0;
323
  schaltzeit_cnt1 = 0;
324
  schaltzeit_cnt2 = 0;
325
326
  TCCR2 |= (1 << CS22) | (1 << CS21) | (1 << CS20); // = 0b00000111              // TCCR2 |= (1 << CS22);   // 64 Prescaler 2 ms
327
     
328
  TCNT2 = 178; // = 0b10110010 = 0xB2                 // TCNT2 = 0x06; // = 6
329
  OCR2 = 77 ;  // = 0b01001101 = 0x4D                 // OCR2 = 0xF9;  // = 249 
330
   TIMSK |= (1 << OCIE2) | (1<<TOIE2) ;
331
332
  
333
}
334
335
336
337
338
339
340
341
342
343
void stopTimer1() 
344
{
345
  TCCR1B  = 0b00000000;         // Prescaler auf 0 -> stopt Timer1
346
}
347
348
void stopTimer2() 
349
{
350
  TCCR2  = 0b00000000;         // Prescaler auf 0 -> stopt Timer2
351
}
352
353
354
355
356
357
358
359
360
// *******************************************************************
361
// Unterprogramme
362
363
364
void reset_zaehler ()
365
{
366
  schalt_cnt_1_u = 0;
367
  schalt_cnt_1_o = 0;
368
  schalt_cnt_2_u = 0;
369
  schalt_cnt_2_o = 0;
370
  
371
  schaltzustand = 0;
372
  schaltzustand_1 = 0;
373
  schaltzustand_2 = 0;
374
  
375
  schaltzeit_cnt = 0;
376
  schaltzeit_cnt1 = 0;
377
  schaltzeit_cnt2 = 0;
378
379
380
}
381
382
383
384
// *******************************************************************
385
//
386
//                         Hauptprogramm
387
//
388
// *******************************************************************
389
390
391
int main(void)      // Hauptprogramm Start
392
{
393
  cli();        // Interrupts aus für Initialisierung
394
  
395
  
396
// *******************************************************************
397
// Ports definieren und ggf. vorbelegen
398
  
399
  DDRC  = 0b11111111;    // Alles Ausgänge
400
  PORTC = 0b00000000;    //Alles aus
401
    
402
  DDRB  = 0b11111111;    // Alles Ausgänge
403
  PORTB = 0b00000000;    //Alles aus
404
  
405
// Port D mit Eingangsbits 2k20f Programm vorbelegen 
406
407
  DDRD  = 0b11110011;    // Alles Ausgänge
408
  PORTD = 0b00000000;    //Alles aus
409
  
410
  
411
  // A_13_20_Port = (1<<A_20);    // Signal LED ein
412
  // A_13_20_Port ^= (1<<A_20);    // Siganl LED aus
413
  // --- noch implementieren
414
  
415
// *******************************************************************
416
// Initialisieren
417
  reset_zaehler();
418
  startTimer1();
419
  
420
  schaltzeit = (schaltdauer / 10);
421
  
422
  sei();
423
  // wdt_enable( WDTO_15MS);    //Watchdog einschalten
424
  // --- noch implementieren
425
426
  
427
// *******************************************************************
428
// Pulslänge mitteln E1 und E2
429
  
430
  
431
  for(i1=0;i1<60;i1++)    //Mittlere Periodenlaenge E1 ueber 60 Pulse messen
432
  {      
433
    while(!signal_1);
434
    mid_1 += signal_1;
435
  }
436
  mid_1 /= 60;
437
  
438
  
439
  for(i2=0;i2<60;i2++)    //Mittlere Periodenlaenge E2 ueber 60 Pulse messen
440
  {      
441
    while(!signal_2);
442
    mid_2 += signal_2;
443
  }
444
  mid_2 /= 60;
445
  
446
  
447
  
448
// *******************************************************************
449
// Hauptschleife
450
  
451
  
452
  while(1)      // Hauptschleife Start
453
  {
454
    
455
    
456
    
457
// *******************************************************************
458
// Abfrage und Verarbeitung Eingang 1
459
    
460
    
461
    
462
    if(signal_1!=0)    //Neuer Impuls E2 ?
463
    {              
464
      schaltzeit_cnt1 =0;
465
      
466
      if(signal_1>mid_1+20 && !wechselabwarten_1)  //Knueppel nach unten und vorher in Mittelstellung?
467
      {  
468
        schaltzeit_cnt1 =0;
469
        schaltzeit_cnt = 0;
470
                
471
        startTimer2();
472
                    
473
        while((signal_1>mid_1+20) && !wechselabwarten_1)  //Knueppel nach unten und vorher in Mittelstellung?
474
        {      
475
          schaltzeit_cnt1 = schaltzeit_cnt;  
476
                    
477
          if (schaltzeit_cnt1 >= schaltzeit)    // war Schaltzeit lang ?
478
          {
479
              
480
            schaltzeit_cnt1 = 0;    // Zuweisung Schaltzustand
481
            schaltzustand_1 = 1;
482
            
483
          }  
484
          
485
        }
486
        stopTimer2();  
487
          
488
        wechselabwarten_1 = 1;
489
         schalt_cnt_1_u++;  // Anzahl der Schaltvorgaenge
490
         
491
         if ((1<schaltzeit_cnt1) && (schaltzeit_cnt1< schaltzeit))
492
        {
493
          
494
          schaltzeit_cnt1 = 0;    // Zuweisung Schaltzustand
495
          schaltzustand_1 = 2;
496
          
497
          
498
        }
499
        else
500
        {
501
          schaltzeit_cnt1 = 0;
502
        }
503
      }
504
      
505
      schaltzeit_cnt1 =0;
506
      
507
      if(signal_1<mid_1-20 && !wechselabwarten_1)  //Knueppel nach unten und vorher in Mittelstellung?
508
      {  
509
        schaltzeit_cnt1 =0;
510
        schaltzeit_cnt = 0;
511
                
512
        startTimer2();
513
                    
514
        while((signal_1<mid_1-20) && !wechselabwarten_1)  //Knueppel oben unten und vorher in Mittelstellung?
515
        {      
516
          schaltzeit_cnt1 = schaltzeit_cnt;  
517
              
518
        }
519
        stopTimer2();  
520
          
521
        wechselabwarten_1 = 1;
522
         schalt_cnt_1_o++;  // Anzahl der Schaltvorgaenge
523
         
524
         if ((1<schaltzeit_cnt1) && (schaltzeit_cnt1< schaltzeit))
525
        {
526
          
527
          schaltzeit_cnt1 = 0;    // Zuweisung Schaltzustand
528
          schaltzustand_1 = 4;
529
        }
530
        else if (schaltzeit_cnt1 >= schaltzeit)    
531
        {
532
          
533
          schaltzeit_cnt1 = 0;    // Zuweisung Schaltzustand
534
          schaltzustand_1 = 3;
535
        }  
536
                
537
        else
538
        {
539
          schaltzeit_cnt1 = 0;
540
        }
541
      }
542
      
543
        
544
      
545
      if(signal_1>mid_1-10 && signal_1<mid_1+10)    //Knueppel in Mittelstellung?
546
      {
547
        aus_E1 = 1;
548
        wechselabwarten_1 = 0;
549
      }
550
  
551
      fail=0;
552
      signal_1=0;
553
      
554
    }
555
    
556
      
557
      
558
// *******************************************************************
559
// Abfrage und Verarbeitung Eingang 2
560
    
561
        
562
                
563
    
564
    if(signal_2!=0)    //Neuer Impuls E2 ?
565
    {              
566
      schaltzeit_cnt2 =0;
567
      
568
      if(signal_2>mid_2+20 && !wechselabwarten_2)  //Knueppel nach unten und vorher in Mittelstellung?
569
      {  
570
        schaltzeit_cnt2 =0;
571
        schaltzeit_cnt = 0;
572
                
573
        startTimer2();
574
                    
575
        while((signal_2>mid_2+20) && !wechselabwarten_2)   // Schaltzeit abwarten
576
        {      
577
          schaltzeit_cnt2 = schaltzeit_cnt;  
578
                    
579
          if (schaltzeit_cnt2 >= schaltzeit)    // war Schaltzeit lang ?
580
          {
581
            schaltzeit_cnt2 = 0;        // Zuweisung Schaltzustand
582
            schaltzustand_2 = 1;
583
            
584
          }  
585
          
586
        }
587
        stopTimer2();  
588
          
589
        wechselabwarten_2 = 1;
590
         schalt_cnt_2_u++;  // Anzahl der Schaltvorgaenge
591
         
592
         if ((1<schaltzeit_cnt2) && (schaltzeit_cnt2< schaltzeit))  // war Schaltzeit kurz ?
593
        {
594
          
595
          schaltzeit_cnt2 = 0;    // Zuweisung Schaltzustand
596
          schaltzustand_2 = 2;
597
          
598
          
599
        }
600
        else
601
        {
602
          schaltzeit_cnt2 = 0;
603
        }
604
      }
605
      
606
      schaltzeit_cnt2 =0;
607
      
608
      if(signal_2<mid_2-20 && !wechselabwarten_2)  //Knueppel nach oben und vorher in Mittelstellung?
609
      {  
610
        schaltzeit_cnt2 =0;
611
        schaltzeit_cnt = 0;
612
                
613
        startTimer2();
614
                    
615
        while((signal_2<mid_2-20) && !wechselabwarten_2)  // Schaltzeit abwarten
616
        {      
617
          schaltzeit_cnt2 = schaltzeit_cnt;  
618
              
619
        }
620
        stopTimer2();  
621
          
622
        wechselabwarten_2 = 1;
623
         schalt_cnt_2_o++;  // Anzahl der Schaltvorgaenge
624
         
625
         if ((1<schaltzeit_cnt2) && (schaltzeit_cnt2< schaltzeit))  // war Schaltzeit kurz ?
626
        {
627
          
628
          schaltzeit_cnt2 = 0;    // Zuweisung Schaltzustand
629
          schaltzustand_2 = 4;
630
        }
631
        else if (schaltzeit_cnt2 >= schaltzeit)    // war Schaltzeit lang ?
632
        {
633
          
634
          schaltzeit_cnt2 = 0;    // Zuweisung Schaltzustand
635
          schaltzustand_2 = 3;
636
        }  
637
                
638
        else
639
        {
640
          schaltzeit_cnt2 = 0;    // Zaehler Schaltzeit ruecksetzen
641
        }
642
      }
643
      
644
        
645
      
646
      if(signal_2>mid_2-10 && signal_2<mid_2+10)    //Knueppel in Mittelstellung?
647
      {
648
        aus_E2 = 1;
649
650
        wechselabwarten_2 = 0;
651
      }
652
  
653
      fail=0;
654
      signal_2=0;
655
      
656
    }  
657
    
658
      
659
// *******************************************************************
660
// Zuweisung Ausgabepin je nach Schaltzustand
661
    
662
      
663
    switch (schaltzustand_1)    // Abfrage nach Schaltzustand 
664
    {
665
      case 1:  {PORTB ^= (1<<PB0); schaltzustand_1=0;}  
666
      break;
667
      case 2:  {PORTB ^= (1<<PB1); schaltzustand_1=0;}  
668
      break;
669
      case 3:  {PORTB ^= (1<<PB2); schaltzustand_1=0;}
670
      break;
671
      case 4:  {PORTB ^= (1<<PB3); schaltzustand_1=0;}
672
      break;
673
    }
674
    
675
    
676
    
677
    switch (schaltzustand_2)    // Abfrage nach Schaltzustand
678
    {
679
      case 1:  {PORTB ^= (1<<PB4); schaltzustand_2=0;}  
680
      break;
681
      //case !1: {PORTB &= ~(1 << PB4); schaltzustand_2=0;}  // falls 'aktiv', dann PB4 tastend
682
      //break;
683
      case 2:  {PORTB ^= (1<<PB5); schaltzustand_2=0;}  
684
      break;
685
      case 3:  {PORTB ^= (1<<PB6); schaltzustand_2=0;}
686
      break;
687
      case 4:  {PORTB ^= (1<<PB7); schaltzustand_2=0;}
688
      break;
689
    }
690
    
691
  
692
    
693
    
694
// *******************************************************************
695
// Watchdog ueberpruefen und ggf. zuruecksetzen
696
      
697
    
698
    // --- noch implementieren
699
700
    
701
// *******************************************************************
702
// Fail safe 
703
704
    // --- noch implementieren
705
    
706
  }      // Hauptschleife Ende
707
}        // Hauptprogramm Ende