Forum: Mikrocontroller und Digitale Elektronik Weihnachts-Blinklicht - AVR


von Johann (Gast)


Lesenswert?

Hallo zusammen.

Ich habe nun Urlaub und somit ist mir eine Idee gekommen, um die Zeit 
auch "sinnvoll" zu nutzen :)

Ich habe mit einen ATmega8 eine kleine Schaltung mit 3 LEDs aufgebaut, 
die ich auch einwandfrei einzeln ansteuern kann. Nun kamen heute Abend 
Taster hinzu, die folgendes bewirken sollen:

Für meine Modelleisenbahn habe ich einen Weihnachtsbaum in der 
Landschaft aufgestellt, der mittels eines ATmega8 angesteuert werden 
soll.

Dafür habe ich 4 Taster, die für jeweils einen anderen "Blinkintervall" 
ausgelegt werden sollen. Eine fünfte Taste soll den Blinkrhythmus 
komplett ausschalten ("reseten").
Bsp.:

Blink-Rhythmus 1)  an (3 sec.) aus (1 sec.)
Blink-Rhythmus 2)  an (1 sec.) aus (5 sec.)
Blink-Rhythmus 3)  an (10 sec.) aus (5 sec.)
Blink-Rhythmus 4)  ...

Nun gibt es aus meiner Sicht einige Fragen.

Zunächst dachte ich mir, die einzelnen Taster einfach an "die vielen" 
Interrupt-Eingänge zu hängen. Denn die würden ja darauf lauern, dass 
jemand eine Taste betätigt und daraufhin die jeweilige Funktion 
aufrufen.
Nun hat aber der Atmega8 nur zwei Interrupt-Eingänge.

Dann versuchte ich, in einer while-Schleife die einzelnen Pins (Taster) 
abzufragen, a la:
1
...
2
while (1)
3
{
4
 if (PINC & (1<<PINC0))   { show_rhythmus_1();  }
5
 if (PINC & (1<<PINC1))   { show_rhythmus_2();  }
6
 ...
7
}

Dabei wusste ich wiederum nicht, wie ich diese am einfachsten 
softwaremäßig entprellen könnte UND einen "neuen" Tastendruck wahrnehme, 
während ich in einer anderen Rhythmusfunktion bin.
(z.B. drücke ich anfangs Taste-1 für Rythmus-1. Während die Funktions 
für Rhythmus-1 aufgerufen wird, könnte ja die nächste Taste gedrückt 
werden und die Anforderung "Rhythmus-2" kommen).

Ich habe im Tutorial hier dankend bereits die Entprellroutinen gefunden. 
Diese werde ich austesten. Allerdings zweifle ich derweil noch an meiner 
"Architektur".

Könntet ihr mir helfen, dieses triviale Projekt umzusetzen?


Vielen lieben Dank und ein frohes Fest,
Johann!

von kopfkratzer (Gast)


Lesenswert?

Achja immer wieder die "Schnellstarter" :-P
Tu Dir einen Gefallen und lese hier einfach alle AVR Tutorials durch und 
auch die FAQ von Karl-Heinz.
Dann und ERST dann wenn Du damit nicht weiter kommst stelle 
Verständnisfragen dazu.
Taster werden NICHT via IRQ ausgewertet, sondern gepollt und entprellt.
Zeitvorgaben werden via TIMER erledigt und zwar in einem IRQ der Dir die 
Zeit hochzählt.

von Johann (Gast)


Lesenswert?

Hi!

>Taster werden NICHT via IRQ ausgewertet, sondern gepollt und entprellt.

Ok, das weiß ich. Polling wäre ja wie in meinem Beispiel beschrieben 
eine Schleife, in der nacheinander immer wieder die einzelnen Zustände 
der Eingänge des AVRs abgefragt wird.

Wie der Timer funktioniert weiß ich.

Mein größtes Verständnisproblem liegt darin, dass ich nicht weiß, wie 
man aus Unterprogramm-1 in Unterprogramm-2 springt, wenn z.b. von 
Rhythmus-1 in Rhythmus-2 gesprungen werden soll.

Das gleiche Szenario eben auch "von Rhythmus-X auf alle LEDs 
ausschalten".
Sobald eine Taste gedrückt wurde, verharre ich doch bis zur 
Unendlichkeit in dieser Funktion und bekomme weitere Tastendrücke nicht 
mit?!

Gruß

von Chr. M. (snowfly)


Lesenswert?

Für deine Anforderung brauchst du doch weder (externen)Interrupt noch 
Entprellung.

Du machst einfach einen Timer Interrupt der alle 100ms(oder 10ms)
in der IRQ Routine abfragt welche Taste gedrückt ist,
bei Taste 1 setzt du ein TastenFlag auf 1, bei Taste 2 auf 2, usw
wenn keine Taste gedrückt ist machst du nichts.
Und im Programm lässt du dann je nach Flaginhalt entsprechend warten.

Ist zwar Quick&Dirty aber wenn das Programm nichts anderes machen soll 
dann reicht das doch.

: Bearbeitet durch User
von kopfkratzer (Gast)


Lesenswert?

Johann schrieb:
> Hi!
>
>>Taster werden NICHT via IRQ ausgewertet, sondern gepollt und entprellt.
>
> Ok, das weiß ich. Polling wäre ja wie in meinem Beispiel beschrieben
> eine Schleife, in der nacheinander immer wieder die einzelnen Zustände
> der Eingänge des AVRs abgefragt wird.
>

Ja und PeDa hat hier eine sehr mächtige Entprellroutine eingestellt die 
keine Wünsche übrig läßt.
Einfach mal danach suchen.


> Wie der Timer funktioniert weiß ich.
>

Das heißt Du kannst die Sekunden ausgeben ?

> Mein größtes Verständnisproblem liegt darin, dass ich nicht weiß, wie
> man aus Unterprogramm-1 in Unterprogramm-2 springt, wenn z.b. von
> Rhythmus-1 in Rhythmus-2 gesprungen werden soll.
>

Was Du haben willst ist eine Statemachine, das macht man i.d.R. mit 
einer globalen Variable die den aktuellen Zustand definiert und dann im 
Hauptprogramm mittels switch/case umgestellt wird.
Wenn Du allerdings noch nicht weißt wie Funktionen in C programmiert 
werden solltest Du erstmal ein C Buch hernehmen und Dich durcharbeiten.

> Das gleiche Szenario eben auch "von Rhythmus-X auf alle LEDs
> ausschalten".
> Sobald eine Taste gedrückt wurde, verharre ich doch bis zur
> Unendlichkeit in dieser Funktion und bekomme weitere Tastendrücke nicht
> mit?!

Deswegen Statemachine, Du mußt von einem Zustand zum nächsten wechseln.
Nimm Dir ein Blatt Papier und male Dir alle für Dein Projekt relevanten 
Zustände auf und zeichne dann Pfeile ein die die Zustände wechseln und 
an die Pfeile schreibst Du die Übergangsbedingung.
In C macht man sowas üblicherweise so:
1
#define ZUSTAND_A 0
2
#define ZUSTAND_B 1
3
#define ZUSTAND_C 2
4
5
main()
6
{
7
 uint8t uZustand = ZUSTAND_A;
8
 while(1)
9
 {
10
  switch(uZustand)
11
  {
12
   case ZUSTAND_A: uZustand = ZUSTAND_B;
13
   break;
14
   case ZUSTAND_B: uZustand = ZUSTAND_C;
15
   break;
16
   case ZUSTAND_C: uZustand = ZUSTAND_A;
17
   break;
18
  }
19
 }
20
}
Verstehst Du was das Programm macht ?

von Johann (Gast)


Lesenswert?

>Du machst einfach einen Timer Interrupt der alle 100ms(oder 10ms)
Ok. Das ist eine gute Idee! Danke!


>Das heißt Du kannst die Sekunden ausgeben ?
Ja, über den Prescaler heruntergeteilt komme ich genau auf eine Sekunde 
(habe damit eine LED blinken lassen).

>Wenn Du allerdings noch nicht weißt wie Funktionen in C programmiert werden
Doch, das weiß ich! :)

>Verstehst Du was das Programm macht ?
Aus meiner Sicht wird der Reihe nach jede case-Anweisung "gepolt".

von kopfkratzer (Gast)


Lesenswert?

Johann schrieb:
>
>>Verstehst Du was das Programm macht ?
> Aus meiner Sicht wird der Reihe nach jede case-Anweisung "gepolt".

Was meinst Du mit "gepolt" ?
Hast Du mal Deine ganzen Zustände wenigstens aufgeschrieben ?
Wie wertest Du Deine Taster aktuell aus, wenn sie nicht entprellt sind ?
Wie ist der Zusammenhang Deiner Zustände mit den Tastern ?
Was ist Dein Startzustand ?
So und nu überlege mal ;-)

von Johann (Gast)


Lesenswert?

>Hast Du mal Deine ganzen Zustände wenigstens aufgeschrieben ?

Wenn ich wüsste wie.

von Johann (Gast)


Angehängte Dateien:

Lesenswert?

Habe nun mal eine Skizze angefertigt.

Aber wirklich helfen tut mir das auch nicht :-(

von kopfkratzer (Gast)


Lesenswert?

Johann schrieb:
> Habe nun mal eine Skizze angefertigt.
>
> Aber wirklich helfen tut mir das auch nicht :-(

Dann schreibe mal die im Bild zu sehenden einzelnen Zustände in einer 
Liste auf.
Überlege Dir welcher Zustand in welchen übergehen soll und was die 
Bedingung dazu ist (d.h. Du hast an die Pfeile noch nichts geschrieben 
...).
Außerdem hast Du das Prinzip noch nicht ganz verstanden, lies mal das 
hier durch:
http://de.wikipedia.org/wiki/Endlicher_Automat
Kleiner Tipp wofür ist denn Dein RESET Knopf gedacht, welcher Zustand 
soll damit erreicht werden ?
Na klingelt's ?

von Johann (Gast)


Lesenswert?

>wofür ist denn Dein RESET Knopf gedacht

Der ist dazu da, den momentanen State (welcher es auch immer sein mag) 
zu unterbrechen und alle LEDs auszuschalten.
Den endlichen Automaten habe ich von Wiki als eine Hilfe hergenommen.

>Na klingelt's ?

NEIN. Sonst hätte ich hier nicht gefragt.

von kopfkratzer (Gast)


Lesenswert?

Johann schrieb:
>>wofür ist denn Dein RESET Knopf gedacht
>
> Der ist dazu da, den momentanen State (welcher es auch immer sein mag)
> zu unterbrechen und alle LEDs auszuschalten.
> Den endlichen Automaten habe ich von Wiki als eine Hilfe hergenommen.
>
>>Na klingelt's ?
>
> NEIN. Sonst hätte ich hier nicht gefragt.

Schwere Geburt, was ist also Dein Grundzustand ?

von Johann (Gast)


Lesenswert?

Mein Grundzustand ist reset? ;)

von kopfkratzer (Gast)


Lesenswert?

Johann schrieb:
> Mein Grundzustand ist reset? ;)

Nein das ist Dein Übergang !
Wieviele einzelne FSM hast Du insgesamt ?
Schau mal in Deine Zeichnung was fällt Dir dabei auf ?
Vergleiche die mal mit den Beispielen aus dem WiKi ...

von Ohmannohmann (Gast)


Lesenswert?

kopfkratzer=quälmeister

von Johann (Gast)


Lesenswert?

Also.


>kopfkratzer=quälmeister
Könnte sich vielleicht jemand bemühen, mir zu helfen?

Ich weiß nicht mehr darüber als ich geschrieben habe.

Schließlich ist das Forum ja nicht da, um jemanden ständig zu eröffnen, 
wie dumm er doch eigentlich ist.

von Johann (Gast)


Lesenswert?

Hallo zusammen.

Habe nun noch folgendes programmiert, aber irgendwie tut das nicht was 
es  soll.

Könntet ihr mir helfen?

Ich habe nun einen Timer (Timer0), der alle x ms den Zustand der Taster 
erfragt und die globale Variable "Taster" entsprechend mit einem Wert 
beschreibt.

In der Endlosschleife in main() wird dann entsprechend ausgewertet, 
welcher Taster gedrückt wurde und letztlich das "Blinkmuster" 
aufgerufen.

Hier der Code:
1
/*************************************************
2
*  Projekt:  Christbaumbeleuchtung - Eisenbahn
3
*  Autor:    
4
*  Datum:    22.12.2013
5
*************************************************/
6
7
8
#include <avr/io.h>
9
#include <avr/interrupt.h>
10
#include <util/delay.h>
11
12
#define F_CPU      8000000
13
14
#define TASTER_RESET  PINC0
15
#define TASTER_1     PINC1
16
#define TASTER_2     PINC2
17
#define TASTER_3     PINC3
18
#define TASTER_4    PINC4
19
20
unsigned char Taster;
21
22
23
void init_timer_0(void)
24
{
25
  TCCR0 |= (1 << CS02) | (1 << CS00);              // Prescaler auf F_CPU / 1024
26
  TIMSK |= (1 << TOIE0);                  // overflow interrupt erlauben
27
}
28
29
30
31
ISR (TIMER0_OVF_vect)                    // Interrupt Service Routine (bei Timer-Overflow von Timer0)
32
{
33
  if((PINC & (1 << TASTER_1))      { Taster = 1; }
34
  if((PINC & (1 << TASTER_2))      { Taster = 2; }
35
  if((PINC & (1 << TASTER_3))      { Taster = 3; }
36
  if((PINC & (1 << TASTER_4))     { Taster = 4; }
37
  if((PINC & (1 << TASTER_RESET))  { Taster = 0; }
38
  
39
}
40
41
void main (void)
42
{
43
  Taster = 0;
44
  DDRC = 0;                        // Port C als Eingang
45
  DDRD |= (1 << DDRD0);                  // Port D als Ausgang
46
  
47
  init_timer_0();
48
  sei();
49
  
50
  while(1)
51
  {
52
    switch(Taster)
53
    {
54
      case TASTER_1:    
55
              PORTD |= (1 << PD0);      //3 Sek. ein, 1 Sek. aus
56
              _delay_ms(3000);
57
              PORTD &= ~(1 << PD0);
58
              _delay_ms(1000);
59
              break;
60
              
61
      case TASTER_2:    
62
              PORTD |= (1 << PD0);      //1 Sek. ein, 5 Sek. aus
63
              _delay_ms(1000);
64
              PORTD &= ~(1 << PD0);
65
              _delay_ms(5000);
66
              break;
67
              
68
      case TASTER_3:    
69
              PORTD |= (1 << PD0);      //10 Sek. ein, 5 Sek. aus
70
              _delay_ms(10000);
71
              PORTD &= ~(1 << PD0);
72
              _delay_ms(5000);
73
              break;      
74
75
      case TASTER_4:    
76
              PORTD |= (1 << PD0);      //10 Sek. ein, 3 Sek. aus
77
              _delay_ms(10000);
78
              PORTD &= ~(1 << PD0);
79
              _delay_ms(3000);
80
              break;        
81
              
82
      case TASTER_RESET:    
83
              PORTD &= ~(1 << PD0);      //...ausschalten
84
              break;      
85
    }  
86
  }
87
}


Vielen Dank schon mal.

Grüße
Johann

von kopfkratzer (Gast)


Lesenswert?

kopftisch
Was steht in diesem Post was Du erstmal tun solltest:
Beitrag "Re: Weihnachts-Blinklicht - AVR"

Letzter Versuch:
1. Welches Schlüsselwort braucht eine Variable die in einer IRQ 
verändert wird ?
2. Wie werden Tasten entprellt und wo/wie sollte das geschehen ?
3. Wofür ist der Timer da ?

Geh erstmal hin und lasse EINE LED mit hilfe eines Timers im 
Sekundentakt blinken OHNE delay !
Wenn das dann geht erweiterst Du das Programm um EINEN Taster der 
erstmal nur die blinkende LED an- und ausschaltet.

von Maximilian S. (maximilian1996)


Lesenswert?

Hallo Johann,
wie wäre es denn, wenn du dir die vier Schalter nimmst und jeden an 
einen normalen Port anschließt. Desweitern schließt du an jeden Schalter 
eine Diode an und verbindest dann die Dioden. Diese verbundenen Dioden 
schließt du dann an einen Interupteingang an. Wenn nun irgendeiner der 
Schalter gedrückt wird wird der Interrupt aktiviert. In der 
Interruptroutine schaust du dann, welcher der vier anderen Ports, an 
denen je einer deiner Schalter hängt, seinen Zustand auf high geändert 
hat.

MfG Maximilian

von Johann (Gast)


Lesenswert?

>1. Welches Schlüsselwort braucht eine Variable die in einer IRQ
>verändert wird ?

volatile

>2. Wie werden Tasten entprellt und wo/wie sollte das geschehen ?

Laut " Chr. Messener" benötigt man hierfür keine Entprellung.
Das hat man mir zumindest so gesagt.


>3. Wofür ist der Timer da ?
Zielst du auf die _delay_ms() ab?
Oder auf den Timer, der die Tastenzustände "überwacht"?

von Chr. M. (snowfly)


Lesenswert?

Johann schrieb:
> case TASTER_1:

ich kann zwar nur sehr wenig c, aber sollte hier dann nicht stehen:
case 1:

Die "Taster" Variable wird in deinem Programm wohl nie den Wert "PINC1"
enthalten.

: Bearbeitet durch User
von Johann (Gast)


Lesenswert?

>Die "Taster" Variable wird in deinem Programm wohl nie den Wert "PINC1"
enthalten

Wenn Taster_1  gedrückt wird (entspricht PINC1), dann wird anhand der 
ISR() der Wert der Variablen Taster auf 1 gesetzt, oder?

Die defines sind ja nur alias. Anstelle von PINC1 schreibe ich im 
weiteren Code "Taster_1" um -im Falle einer Pinänderung- nur die Define 
ändern zu müssen.

von Markus (Gast)


Lesenswert?

Chr. Messener schrieb:
> Johann schrieb:
>> case TASTER_1:
>
> ich kann zwar nur sehr wenig c, aber sollte hier dann nicht stehen:
> case 1:

Ja, oder besser
1
const int PROG_1 = 1;
2
case PROG_1:
(TASTER_1 ist schon definiert)

oder mit #define

von Johann (Gast)


Lesenswert?

Wo war mein Fehler?

von Chr. M. (snowfly)


Lesenswert?

Johann schrieb:
> wird anhand der
> ISR() der Wert der Variablen Taster auf 1 gesetzt, oder?

eben, die Variable "Taster" hat dann den Inhalt "1"

Du fragst in der case abfage aber ab ob die Variable
den Inhalt "TASTER_1" hat.
Und durch das #define hast du dem Compiler die Anweisung gegeben
alle "TASTER_1" durch "PINC1" zu ersetzen.
Also fragst du in der case "hat die Variable Taster den Inhalt PINC1? 
dann mach ..."

Du musst aber fragen "hat die Variable Taster den Inhalt 1? dann mach 
..."


Zum enprellen: wenn der Taster hier prellt macht das nichts,
weil wenn gerade im gedrückt Zustand abgefragt wird dann setzt
es den richtigen Wert und wenn die IRQ-Routine gerade das "nicht 
gedrückt prellen" erwischt dann passiert halt nichts.
Wenn oft genug abgefagt wird ist die Chance den gedückt Zustand zu 
verpassen doch recht klein, und wenn die Variable mehrmals auf den 
gleichen Wert gesetzt wird ist das auch egal.

von Dirk M. (dmd)


Lesenswert?

Wie sieht denn deine Schaltung aus? Hast du irgendwo Pullup- oder 
Pulldown-Widerstände? Die internen benutzt du ja nicht - oder kann ich 
nicht gucken? Wenn du die internen Pullup's benutzt, musst du die Taster 
natürlich auf logisch '0' prüfen. Ansonsten wurde ja schon alles 
(vieles) gesagt..
Siehe "case: 1:"

-Dirk-

von Johann (Gast)


Lesenswert?

Ah ok. Da hatte ich wohl einen 'Denkfehler' :) Danke!

Nun der abgeänderte Code:
1
/*************************************************
2
*  Projekt:  Christbaumbeleuchtung - Eisenbahn
3
*  Autor:    
4
*  Datum:    22.12.2013
5
*************************************************/
6
7
8
#include <avr/io.h>
9
#include <avr/interrupt.h>
10
#include <util/delay.h>
11
12
#define F_CPU      8000000
13
14
#define TASTER_RESET  PINC0
15
#define TASTER_1     PINC1
16
#define TASTER_2     PINC2
17
#define TASTER_3     PINC3
18
#define TASTER_4    PINC4
19
20
#define OUTPUT_PORT    PORTD
21
#define OUTPUT_PIN    PD0  
22
23
volatile unsigned char Taster;
24
25
26
void init_timer_0(void)
27
{
28
  TCCR0 |= (1 << CS02) | (1 << CS00);              // Prescaler auf F_CPU / 1024
29
  TIMSK |= (1 << TOIE0);                  // overflow interrupt erlauben
30
}
31
32
33
34
ISR (TIMER0_OVF_vect)                    // Interrupt Service Routine (bei Timer-Overflow von Timer0)
35
{
36
  if((PINC & (1 << TASTER_1))      { Taster = 1; }
37
  if((PINC & (1 << TASTER_2))      { Taster = 2; }
38
  if((PINC & (1 << TASTER_3))      { Taster = 3; }
39
  if((PINC & (1 << TASTER_4))     { Taster = 4; }
40
  if((PINC & (1 << TASTER_RESET))  { Taster = 0; }
41
  
42
}
43
44
void main (void)
45
{
46
  Taster = 0;
47
  DDRC = 0;                        // Port C als Eingang
48
  DDRD |= (1 << DDRD0);                  // Port D als Ausgang
49
  OUTPUT_PORT = 0;
50
  
51
  init_timer_0();
52
  sei();
53
  
54
  while(1)
55
  {
56
    switch(Taster)
57
    {
58
      case 1:    
59
              OUTPUT_PORT |= (1 << OUTPUT_PIN);      //3 Sek. ein, 1 Sek. aus
60
              _delay_ms(3000);
61
              OUTPUT_PORT &= ~(1 << OUTPUT_PIN);
62
              _delay_ms(1000);
63
              break;
64
              
65
      case 2:    
66
              OUTPUT_PORT |= (1 << OUTPUT_PIN);      //1 Sek. ein, 5 Sek. aus
67
              _delay_ms(1000);
68
              OUTPUT_PORT &= ~(1 << OUTPUT_PIN);
69
              _delay_ms(5000);
70
              break;
71
              
72
      case 3:    
73
              OUTPUT_PORT |= (1 << OUTPUT_PIN);      //10 Sek. ein, 5 Sek. aus
74
              _delay_ms(10000);
75
              OUTPUT_PORT &= ~(1 << OUTPUT_PIN);
76
              _delay_ms(5000);
77
              break;      
78
79
      case 4:    
80
              OUTPUT_PORT |= (1 << OUTPUT_PIN);      //10 Sek. ein, 3 Sek. aus
81
              _delay_ms(10000);
82
              OUTPUT_PORT &= ~(1 << OUTPUT_PIN);
83
              _delay_ms(3000);
84
              break;        
85
              
86
      case 0:    
87
              OUTPUT_PORT &= ~(1 << OUTPUT_PIN);      //...ausschalten
88
              break;      
89
    }  
90
  }
91
}

von Markus (Gast)


Lesenswert?

Johann schrieb:
> Nun der abgeänderte Code:

Schon mal kompiliert?

von Johann (Gast)


Lesenswert?

Ja, hatte wohl noch zwei Klammern in der ISR in der If-Anweisung 
vergessen.

Trotzdem läufts nicht :(

von Ingo (Gast)


Lesenswert?

Es fehlen noch schließende Klammern in deiner Tasten Abfrage

von Johann (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen.

Hier möchte ich euch noch meine Schaltung schicken, so wie ich es 
aufgebaut habe.

Das Relais (rechts) schaltet den Verbraucher (in meinem Fall eine 
Glühlampe). Habe das Lampensymbol nicht gefunden, deshalb ein 
Lautsprecher ;-)


Stimmt die Schaltung denn überhaupt so? Nicht dass ich bereits darin 
einen Fehler habe?!


Danke und Gruß

von Uili (Gast)


Lesenswert?

Wofür die LED in der Relais-Masche? Kannst du das Relais mit <3V 10mA 
schalten?

von Johann (Gast)


Lesenswert?

>Wofür die LED in der Relais-Masche?

Die soll auf meinem "Schaltpult" das Blinken darstellen.

Als Relais habe ich so eines mit 5V Steuerspannung:

http://www.reichelt.de/Miniaturrelais/HF-46F-5V/3/index.html?&ACTION=3&LA=446&ARTICLE=112506&GROUPID=3292&artnr=HF+46F+5V&SEARCH=5v+relais


Gruß

von Markus (Gast)


Lesenswert?

- Das 5V-Relais K1 darf nicht in Serie mit der LED1 und dem 
Vorwiderstand R3 sein. Der Strom wird zu klein sein für das Relais. Das 
Relais muss parallel mit der LED1 und Vorwiderstand sein und dann 
gemeinsam zum Transistor.

- Der Basiswiderstand R2 muss kleiner für sein (330 - 1k) damit der 
BC548 gut durchschaltet.

- Für die Eingänge der Taster S1 -S5 müssen Pullup-Widerstände eingebaut 
oder im ATmega eingschalten werden.

- Der 7805L ist zu klein. Vorallem weil auch noch das Realais daran 
hängt. Nimm ein 7805 im T220, sonst wird der zu heiss.

Und poste doch nochmal (aber als Anhang ) den letzten compilierbaren 
Code.

von Johann (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Markus,

danke für deine Hilfe!


>Das 5V-Relais K1 darf nicht in Serie mit der LED1 und dem
>Vorwiderstand R3 sein
Ich habe nun die LED mit Vorwiderstand aus der Schaltung entfernt.
-War eine Schnapsidee von mir.

>Der Basiswiderstand R2 muss kleiner für sein (330 - 1k)
Ich habe ihn nun auf 330 Ohm in der Schaltung abgeändert

>Für die Eingänge der Taster S1 -S5 müssen Pullup-Widerstände eingebaut
>oder im ATmega eingschalten werden
Ich habe im Code die internen Pullups des ATmega8 eingeschaltet.

>Nimm ein 7805 im T220
Ok, werde ich mir besorgen.

Der abgeänderte Schaltplan und der compilierbare Code ist im Anhang.
Könntest du nochmal einen Blick auf beides werfen?

Vielen Dank schon mal! :-)

Gruß
Johann

von Markus (Gast)


Lesenswert?

Johann schrieb:
>>Nimm ein 7805 im T220
> Ok, werde ich mir besorgen.
Sollte TO-220 heissen, sorry.

Johann schrieb:
> Ich habe nun die LED mit Vorwiderstand aus der Schaltung entfernt.
Schalte die LED ruhig dazu parallel, so siehst du was genau passiert:

Und deine Status LEDs kanns du auch gleich noch einschalten, so siehst 
du in welchem Mode du dich befindest.

Das
1
#define F_CPU      8000000
 noch vor die Includes verschieben.

Deine Taster werden auf High-Pegel (1) abgefragt.
Sie sind aber LOW-Aktiv, d.h. du musst sie überprüfen ob sie == 0 sind.

(Und nur um die Taster so abzufragen, braucht es die ISR eigentlich 
nicht, weil mit dem Delays alles blockiert wird. Die Überprüfung könnte 
genauso gut im Main-Loop stattfinden. Der Timer-ISR wäre anstelle des 
Delay sinnvoll. Aber lass das erst mal. Das wäre das nächste Projekt 
Blinkschaltung mit Timer.)

von Johann (Gast)


Angehängte Dateien:

Lesenswert?

Ok vielen Dank! :)

Habe nun noch den Schaltplan entsprechend abgeändert (Kollektor -> LED) 
und die Status-LEDs programmiert.

Im Anhang noch mal der kompilierbare Code und der Schaltplan.

Jetzt müsste es doch stimmen, oder? :)

Danke Dir!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.