Forum: Mikrocontroller und Digitale Elektronik Verzögerte Schaltung


von Nils (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

ich suche eine Schaltung die zeitverzögert immer einen Ausgang (Relais 
oder ein Transistor) schaltet.
Im Anhang ist ein Bild, welches gut beschreibt was ich meine.
Ich habe drei Relais oder Transistoren (A,B,C) und möchte A als erstes 
schalten und halten. Danach kommt B und danach C.
Zum Schluß sollen alle gemeinsam gelöscht werden.
Die gesamte Zeit ist relativ egal (hauptsache tges<500ms).

Vielen Dank :)

von HildeK (Gast)


Lesenswert?

ATTiny und ein kleines Programm.

von MaWin (Gast)


Lesenswert?

Wodurch bestimmst du denn T1 und T4 ?

Ein- und Ausschalten der Stromversorgung durch einen Hauptschalter ?

Obwohl es tausend Möglichkeiten gibt, von diskreten Transistoren über 
NE556 und Reset-Controllern bis hin zum unsäglichen Overkill eines 
Mikrocontrollers für Leute so wenig Elektronikkenntnisse haben, daß sie 
nicht mal wissen, daß der Microcontroller zuvor auch noch programmiert 
werden muss und daher die aufwändigste aller Lösungen ist, würde ich 
einen LM358 vorschlagen, damit kostet die Schaltung (ohne Relais) keinen 
EUR:
1
  +-----+----+---------+-----+-----+----+----+----+-----+  +12V
2
  |     |    |         |     |     |    |    |    |     |
3
  |   100k 100k      Relais2 |    100k 100k  |  Relais3 |
4
  |     |    |         |     |     |    |    |    |     |
5
  |     |    +-1M------+-|>|-+     |    +-1M-)----+-|>|-+
6
  |     |    |         |     |     |    |    |    |1N4148
7
  |     |    +---|+\   |     |     |    +---|+\   |
8
  |     |    |   |  >--+     |     |    |   |  >--+
9
  +-|<|-+----(---|-/         +-|<|-+----(---|-/
10
  |     |    |               |     |    |    |
11
Relais1 1uF 100k           100nF  2u2F 100k  |
12
  |     |    |               |     |    |    |
13
  +-----+----+---------------+-----+----+----+ GND
Falls die Relais mehr als 20mA benötigen, kann auch ein NE556
sinnvoll sein (bis 200mA).

: Bearbeitet durch User
von danke (Gast)


Lesenswert?

MaWin schrieb:
> NE556 und Reset-Controllern bis hin zum unsäglichen Overkill eines
> Mikrocontrollers für Leute so wenig Elektronikkenntnisse haben, daß sie
> nicht mal wissen, daß der Microcontroller zuvor auch noch programmiert
> werden muss und daher die aufwändigste aller Lösungen ist, würde ich

Ich mag dich, MaWin.

von Nils P. (commanda)


Angehängte Dateien:

Lesenswert?

@MaWin: Vielen Dank für die Schaltung!
Ich hab die Schaltung in Eagle mal nachgebaut. Ich hoffe die stimmt so.
Kann ich die Schaltung auch mit +5V betreiben?
Vielen Dank
Grüße

von Harald W. (wilhelms)


Lesenswert?

Nils P. schrieb:

> Kann ich die Schaltung auch mit +5V betreiben?

Es gibt nur wenige Relais, die mit <5V und 20mA arbeiten.

von Nils P. (commanda)


Lesenswert?

Harald Wilhelms schrieb:
> Nils P. schrieb:
>
>> Kann ich die Schaltung auch mit +5V betreiben?
>
> Es gibt nur wenige Relais, die mit <5V und 20mA arbeiten.

Ich benutze das na5w-k Miniatur-Relais. Das funktioniert mit 5V und 
brauch nur 100mW => 20mA. Sollte hoffentlich funktionieren.
Grüße

von Blub (Gast)


Lesenswert?

Nils schrieb:
> Zum Schluß sollen alle gemeinsam gelöscht werden.
Hättest du vieleicht auch einzeichnen können.
So erfüllt die Schaltung das noch nicht.

von Thomas E. (thomase)


Lesenswert?

Obwohl es tausend Möglichkeiten gibt, von diskreten Transistoren über
NE556 und Reset-Controllern bis hin zum unsäglichen Operationsverstärker 
mit RC-Gliedern für Leute, die so wenig Elektronikkenntnisse haben, daß 
sie nicht mal wissen, daß das Timing niemals exakt ist und wegen der 
Bauteiltoleranzen mühsam ausgetüftelt werden muß und daher die 
aufwändigste aller Lösungen ist, würde ich einen Attiny13 vorschlagen, 
damit kostet die Schaltung (ohne Relais) keine 70ct.

mfg.

von Moin (Gast)


Lesenswert?

Wie du evtl mitbekommen kannst gibt es hier 2 gute/einfache 
Möglichkeiten.
Mikrocontroller oder kleine Operationsverstärkerschaltung mit 
RC-Gliedern.

Wenn du programmieren kannst, das nötige zusätzliche Equip für den 
controller und bereits etwas Erfahrung hast. Nimm den Controller!
Es ist die Lösung die dir das Einstellen des Timings am einfachsten 
ermöglicht.

Wenn das genaue Timing keine Rolle spielt bzw. du keine Ahnung von 
mikrocontrollern haben solltest. Nimm die vorgeschlagene Schaltung von 
MaWin und bau sie so auf das du das Timg ändern kannst(Sockel für R und 
C, Potis oder Steckbrett aufbau) und experimentier solange bis es passt. 
Die genannten bauteiltoleranzen machen etwas experimentieren oder SEHR 
großzügiges auslegen der Werte nötig...

von Harald W. (wilhelms)


Lesenswert?

Thomas Eckmann schrieb:

> Ich würde einen Attiny13 vorschlagen,
> damit kostet die Schaltung (ohne Relais) keine 70ct.

Plus viele Monate Einarbeitungszeit...

von Nils P. (commanda)


Lesenswert?

Na gut. Dann muss ich doch wieder den Programmierer rauskramen :D

Vielen Dank für alle Hilfestellungen!

von Thomas E. (thomase)


Lesenswert?

Harald Wilhelms schrieb:
> Plus viele Monate Einarbeitungszeit...
In der Zeit, die man braucht, das Progrämmchen für diese Anwendung zu 
schreiben, hast du noch nicht mal die Hälfte der Bauteile für egal 
welches Analoggefriggel zusammgesucht.

mfg.

von Michael W. (Gast)


Lesenswert?

Man könnte ja auch einige der Widerstände als Potie/Trimmer ausführen - 
ich denke da so an R2 und R5 ... :-)

von MaWin (Gast)


Lesenswert?

Nils P. schrieb:
> Kann ich die Schaltung auch mit +5V betreiben?

Da das TXS2 bei 4.5V mit 11.4mA auskommt: Ja.

Harald Wilhelms schrieb:
> Es gibt nur wenige Relais, die mit <5V und 20mA arbeiten.

Du hättest nachgucken können, welches er verwendet.

Nils P. schrieb:
> Ich benutze das na5w-k Miniatur-Relais

Scheisse natürlich wenn der I/$&& ein anderes in den Schaltplan zeichent 
als er dann wirklich verwenden will.

Thomas Eckmann schrieb:
> In der Zeit, die man braucht, das Progrämmchen für diese Anwendung zu
> schreiben, hast du noch nicht mal die Hälfte der Bauteile für egal
> welches Analoggefriggel zusammgesucht

Warum steht das Programm dann nicht in deinem Beitrag?
Du hattest endlos viel Zeit für Dummschwatz, aber offenbar nicht genug 
für ein ausgetestetes fehlerfreies Programm.

von dolf (Gast)


Angehängte Dateien:

Lesenswert?

Thomas Eckmann schrieb:
> würde ich einen Attiny13 vorschlagen

schaut mal ob man das so machen kann.
als speicher hab ich nen 4015 genommen.
clock, date, reset und vier ausgänge.
dazu noch nen 4093 für den takt und die logic.

von Thomas E. (thomase)


Lesenswert?

MaWin schrieb:
> Du hattest endlos viel Zeit für Dummschwatz, aber offenbar nicht genug
> für ein ausgetestetes fehlerfreies Programm.
Du bist doch nur sauer, daß ich dein dummes Geschwätz umgedichtet habe.

mfg.

: Bearbeitet durch User
von nicht "Gast" (Gast)


Lesenswert?

Thomas Eckmann schrieb:
>
> In der Zeit, die man braucht, das Progrämmchen für diese Anwendung zu
> schreiben, hast du noch nicht mal die Hälfte der Bauteile für egal
> welches Analoggefriggel zusammgesucht.

Leider sind viele Ingenieure unfähig, realistische Zeitpläne 
aufzustellen - du bist da keine Ausnahme.

von asdf (Gast)


Lesenswert?

Nimm ein beliebiges Schmitt Trigger IC und schalte RC-Glieder 
entsprechend den gewuenschten Verzoegerungszeiten vor die Eingaenge.

von Harald W. (wilhelms)


Lesenswert?

Thomas Eckmann schrieb:

>> Plus viele Monate Einarbeitungszeit...
> In der Zeit, die man braucht, das Progrämmchen für diese Anwendung zu
> schreiben, hast du noch nicht mal die Hälfte der Bauteile für egal
> welches Analoggefriggel zusammgesucht.

...und das schaffst Du auch, wenn Du nie zuvor einen µC programmiert 
hast?

von MaWin (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> Du bist doch nur sauer, daß ich dein dummes Geschwätz umgedichtet habe.

Hast du doch gar nicht.

Du hast aus einer stichhaltigen Bemerkung
bloss dummes Geschwätz gemacht, und gleich selbst den Beleg
geliefert, daß es dummes Geschwätz ist.
Denn von mir kam ein Schaltplan, von dir kein Programm.

von Thomas E. (thomase)


Angehängte Dateien:

Lesenswert?

MaWin schrieb:
> Hast du doch gar nicht.
Stimmt. Ich habe ihm einen Sinn gegeben.

> von dir kein Programm.
Darauf kannst du warten, bis du schwarz wirst.
Aber einen Schaltplan kann ich dir geben.

mfg.

: Bearbeitet durch User
von Esgasto (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> Aber einen Schaltplan kann ich dir geben.

Die Schaltung links verstehe ich. Die rechts leider nicht... :(

von Uwe (Gast)


Lesenswert?

je naach Belieben muß man nur den Port ändern :

#include <avr/io.h>
#define F_CPU 1000000
#include <util/delay.h>

int main (void){
DDRC=0b00000111;
_delay_ms(500);
PORTC = 0b11111110;
_delay_ms(500);
PORTC = 0b11111100;
_delay_ms(500);
PORTC = 0b11111000;
_delay_ms(500);
PORTC = 0b11111111;
while(1)
}

ODER :

#include <avr/io.h>
#define F_CPU 1000000
#include <util/delay.h>

int main (void){
DDRC=0b00000111;
_delay_ms(500);
PORTC = 0b00000001;
_delay_ms(500);
PORTC = 0b00000011;
_delay_ms(500);
PORTC = 0b00000111;
_delay_ms(500);
PORTC = 0b00000000;
while(1)
}

und Freilaufdioden nicht vergessen.

von Nils P. (commanda)


Lesenswert?

Ich habe das nun mit einem ATTiny13 gelöst.
Meine Frage ist: ich starte immer das Programm immer indem ich RST mit 
GND kurzschließe...ist das richtig so? Oder gibt es eine bessere Lösung?
Achso ist der Code auch i.O.? (Funktionieren tut er...)

Vielen Dank !!!

1
#include <avr/io.h>
2
#ifndef F_CPU
3
#define F_CPU 1000000     
4
#endif
5
#include <util/delay.h>
6
 
7
int main( void )
8
{
9
  DDRB = ( 1 << PB3 )|( 1 << PB4 )|( 1 << PB2 );     
10
 
11
                 
12
  PORTB ^= ( 1 << PB3 ); 
13
  _delay_ms(100);       
14
  PORTB ^= ( 1 << PB4 );    
15
  _delay_ms(100);
16
  PORTB ^= ( 1 << PB2 );
17
  _delay_ms(100);
18
  PORTB ^= ( 1 << PB3 ); 
19
  PORTB ^= ( 1 << PB4 ); 
20
  PORTB ^= ( 1 << PB2 );
21
22
23
  while( 1 ) {}
24
return 0;
25
}

von c-hater (Gast)


Lesenswert?

Harald Wilhelms schrieb:

> Plus viele Monate Einarbeitungszeit...

Ach watt.

Wenn man ein grundlegendes Gefühl für Logik hat (also: nicht weiblich, 
kein Politiker oder BWLer oder Sozial-Tütü ist), also schlicht: 
naturwissenschaftlich zumindest beim Schulstoff ohne größere Probleme 
mitgekommen ist, dann sind das keine Monate sondern höchstens ein paar 
Tage.

Es ist jedenfalls mit Sicherheit deutlich einfacher, ein µC-Programm zu 
schreiben, welches das gewünschte Timing erzeugt als eine Schaltung mit 
OVs aufzubauen, die dasselbe mit gleicher Zuverlässigkeit leistet.

Soviel ist mal sicher. Denn die OV-Lösung erfordert sehr viel mehr als 
einfache allgemeingültige Logik der Klasse "if A>b then do C", sie 
erfordert ein tiefgreifendes Verständnis der Schaltung bis hin zur 
sachgerechten Anwendung irgendwelcher Exponentialfunktionen.

OK, auch das sollte eigentlich für jeden Absolventen des deutschen 
Schulsystems kein Problem darstellen, aber wie das so ist: was man nicht 
braucht, vergißt man. Grundlegende Logik aber braucht man (im Gegensatz 
zu Exponentialfunktionen) stets und ständig.

Deswegen ist die µC-Lösung einfacher. Billiger und und mit weniger 
Bauelementen umzusetzen ist sie sowieso.

von Thomas E. (thomase)


Lesenswert?

Da du mit Reset immer neu startest ist das Toggeln der Ports von der 
Funktion her schon OK. Ich würde es allerdings explizit auf H bzw. L 
setzen.
1
PORTB |= (1 << PB3);
2
...
3
...
4
PORTB &= ~(1 << 3);

Vor allem aus dem Grund, da ich nicht per Reset triggern würde. Sondern 
mit einem normalen Eingang. Dann geht es auch verzögerungsfrei.

Also:
1
int main(void)
2
{
3
  DDRB = ( 1 << PB3 )|( 1 << PB4 )|( 1 << PB2 );
4
  PORTB |= (1 << 0);
5
  while(1)
6
  {
7
    if(!(PINB & (1 << 0)))
8
    {
9
      PORTB |= ( 1 << PB3 ); 
10
      _delay_ms(100);       
11
      PORTB |= ( 1 << PB4 );    
12
      _delay_ms(100);
13
      PORTB |= ( 1 << PB2 );
14
      _delay_ms(100);
15
      PORTB &= ~(( 1 << PB3 ) | ( 1 << PB4 ) | ( 1 << PB2 ));
16
17
      //Wenn Triggersignal länger als Tges
18
      while(!(PINB & (1 << 0)));
19
    }
20
  }
21
}

mfg.

: Bearbeitet durch User
von Nils P. (commanda)


Lesenswert?

Vielen Dank!!! Sehr nett!

Wie trigger ich eigentlich? PB1 mit PB0 kurzschließen?? Oder 5V auf 
PB1?? (PB0, PB1, PB5 sind ja noch frei)
Paar Zeilen verstehe ich auch nicht ganz:

1
int main(void)
2
{
3
  DDRB = ( 1 << PB3 )|( 1 << PB4 )|( 1 << PB2 );
4
  PORTB |= (1 << 0);  //was macht das hier? PB1 statt 0?
5
  while(1)
6
  {
7
    if(!(PINB & (1 << 0)))   //was macht das hier? PB1 statt 0?
8
    {
9
      PORTB |= ( 1 << PB3 ); 
10
      _delay_ms(100);       
11
      PORTB |= ( 1 << PB4 );    
12
      _delay_ms(100);
13
      PORTB |= ( 1 << PB2 );
14
      _delay_ms(100);
15
      PORTB &= ~(( 1 << PB3 ) | ( 1 << PB4 ) | ( 1 << PB2 ));
16
17
      while(!(PINB & (1 << 0))); //mit was trigger ich denn? Muss ich noch den Pin ergänzen? PB1 statt 0?
18
    }
19
  }
20
}

: Bearbeitet durch User
von Thomas E. (thomase)


Lesenswert?

Nils P. schrieb:
> Vielen Dank!!! Sehr nett!
>
> Wie trigger ich eigentlich? PB1 mit PB0 kurzschließen?? Oder 5V auf
Zum Triggern wird ein kurzer Impuls (GND) auf PB0 gegeben.
1
int main(void)
2
{
3
  DDRB = ( 1 << PB3 )|( 1 << PB4 )|( 1 << PB2 );
4
  PORTB |= (1 << 0);  //Schaltet den internen Pullup von PB0 ein.
5
  //PB0 ist jetzt High.
6
  while(1)
7
  {
8
    if(!(PINB & (1 << 0)))   //Hier passiert nichts solange PB0 High ist.
9
    //Wird GND auf PB0 gelegt, ist die Bedingung true und die Sequenz
10
    //laeuft ab.
11
    {
12
      PORTB |= ( 1 << PB3 ); 
13
      _delay_ms(100);       
14
      PORTB |= ( 1 << PB4 );    
15
      _delay_ms(100);
16
      PORTB |= ( 1 << PB2 );
17
      _delay_ms(100);
18
      PORTB &= ~(( 1 << PB3 ) | ( 1 << PB4 ) | ( 1 << PB2 ));
19
20
      while(!(PINB & (1 << 0))); //Das Triggern erfordert nur einen
21
      //kurzen Impuls. Ist der Impuls laenger als die Gesamtzeit(300ms)
22
      //wuerde die Sequenz nochmal ablaufen. Das wird hier verhindert,
23
      //indem gewartet wird, bis PB0 wieder High ist.
24
    }
25
  }
26
}

mfg.

: Bearbeitet durch User
von Blondchen (Gast)


Lesenswert?

> Wenn man ein grundlegendes Gefühl für Logik hat (also: nicht weiblich,
> kein Politiker oder BWLer oder Sozial-Tütü ist, ...

... oder keinen so bekloppten Nick wie c-hater hat, dann ...

von Nils P. (commanda)


Lesenswert?

Vielen Dank!!! Jetzt läuft alles wie ich es mir vorgestellt habe :):)

von Nils P. (commanda)


Lesenswert?

Ich habe doch noch eine Frage: Ich trigger jetzt mit PB0 gegen GND. Kann 
ich auch abfragen ob gegen GND oder VCC getriggert wurde?

Ich würde gerne
wenn PB0 gegen GND dann setze PB3,PB4,PB2 auf high.
wenn PB0 gegen VCC dann setze PB3,PB4,PB1 auf high.

Oder gibt es eine andere Möglichkeit? Mir fehlt eigentlich noch ein Pin, 
sonst würde ich einen anderen Pin gegen GND schalten... Und PB5 ist der 
Reset Pin, den kann man nicht wirklich benutzen oder?


Vielen Dank!!!

von HildeK (Gast)


Lesenswert?

Nils schrieb: (Datum: 09.04.2014 22:41)
> ich suche eine Schaltung die

HildeK schrieb: (Datum: 09.04.2014 22:50)
> ATTiny und ein kleines Programm.

MaWin schrieb: (Datum: 09.04.2014 23:14)
> bis hin zum unsäglichen Overkill eines
> Mikrocontrollers

Harald Wilhelms schrieb: (Datum: 10.04.2014 12:22)
> Plus viele Monate Einarbeitungszeit...

Nils P. schrieb: (Datum: 11.04.2014 10:50)
> Paar Zeilen verstehe ich auch nicht ganz:

Nils P. schrieb: (Datum: 11.04.2014 16:28)
> Vielen Dank!!! Jetzt läuft alles wie ich es mir vorgestellt habe :):)

Das waren jetzt kaum 42 Stunden. SCNR!

Gut, Uwe (Gast) und Thomas Eckmann hat ihm mit einem Stück Code geholfen 
(ist ja auch der Zweck dieses Forums).
Trotzdem, mit der analogen Variante wäre auch ein Geübter nur ähnlich 
schnell gewesen. Genau aus dem Grund habe ich mich vor einigen Jahren, 
eigentlich viel zu spät, mit den µCs auseinandergesetzt. Für solch eine 
Aufgabe ist der µC eben gerade nicht der Overkill, sondern die einfache 
und flexible Lösung, die eine Analogschaltung oftmals nicht bietet. Und, 
Wünsche nach noch einer kleiner Verhaltensänderung der Schaltung kommen 
fast immer ...

von Eumel (Gast)


Lesenswert?

c-hater schrieb:
> nicht weiblich

Ach deswegen bist du immer so anal drauf, weil es mit den Damen nicht 
klappt.

von Harald W. (wilhelms)


Lesenswert?

HildeK schrieb:

> Harald Wilhelms schrieb: (Datum: 10.04.2014 12:22)
>> Plus viele Monate Einarbeitungszeit...

> Das waren jetzt kaum 42 Stunden. SCNR!

Nun, anscheinend hatte Nils aber Vorkenntnisse mit dem Programmieren.

von HildeK (Gast)


Lesenswert?

Harald Wilhelms schrieb:
> Nun, anscheinend hatte Nils aber Vorkenntnisse mit dem Programmieren.

Ja und auch deshalb habe ich eben ein wenig widersprochen bei den 
oftmals pauschalen Aussagen. Es hätte sich so oder anderes im Laufe des 
Threads herausstellen können - und, es war ein zu schönes Beispiel, um 
deine Aussage nicht zu zitieren :-)!

Selbst wenn er gar keine Vorkenntnisse gehabt hätte, wäre es mit ein 
wenig technischem Verständnis und Interesse an der Sache über die 
Osterferien zu schaffen gewesen - einschließlich einem großen Gewinn an 
neuen Erkenntnissen. Die Tutorials am Rand dieses Forums helfen da 
wirklich weiter!

Wie ich schon angedeutet habe: vor einigen Jahren hätte ich auch gesagt, 
µC an der Stelle ist Overkill, das geht doch mit ein paar analogen oder 
digitalen Bausteinen. Heute denke ich anders.

von MaWin (Gast)


Lesenswert?

Thomas Eckmann schrieb:
>> von dir kein Programm.
> Darauf kannst du warten, bis du schwarz wirst.

Siehst du, du bist offenbar unfähig oder es ist dir zu viel Arbeit, das 
muss Uwe für dich machen.

> Aber einen Schaltplan kann ich dir geben.

Ich sehe dort keine Relais. Die Schaltung erfüllt also nicht die 
Aufgabenstellung.

Und vor allem: Es fehlt die Schaltung, mit der man den uC erst noch 
programmieren muss, heute an USB.

Nils P. schrieb:
> Vielen Dank!!! Jetzt läuft alles wie ich es mir vorgestellt habe
> :):)

Erstaunlicherweise scheint Nils den AVR und die Programmierschaltung 
schon gehabt zu haben:

Nils P. schrieb:
> Na gut. Dann muss ich doch wieder den Programmierer rauskramen

Dann ist es natürlich erstaunlich warum er bei einer so simplen Aufgabe 
dennoch fragt.

von Thomas E. (thomase)


Lesenswert?

Nils P. schrieb:
> Ich habe doch noch eine Frage: Ich trigger jetzt mit PB0 gegen GND. Kann
> ich auch abfragen ob gegen GND oder VCC getriggert wurde?
> Ich würde gerne
> wenn PB0 gegen GND dann setze PB3,PB4,PB2 auf high.
> wenn PB0 gegen VCC dann setze PB3,PB4,PB1 auf high.
So, wie die Schaltung jetzt ist, nicht.
Das bedeutet natürlich nicht, daß es mit einer kleinen Änderung nicht 
trotzdem ginge.

> Oder gibt es eine andere Möglichkeit? Mir fehlt eigentlich noch ein Pin,
> sonst würde ich einen anderen Pin gegen GND schalten... Und PB5 ist der
> Reset Pin, den kann man nicht wirklich benutzen oder?
Das Abschalten des Resetpins ist natürlich möglich. Allerdings wäre das, 
da du nur einen ISP-Programmer hast, die letzte und vor allem eine 
einmalige Option. Danach kannst du per ISP nicht mehr auf den Controller 
zugreifen und ihn programmieren. Ohne HV-Programmer scheidet diese 
Möglichkeit also aus.

Kommen wir zur kleinen Änderung:
PB0 bietet leider nicht die Möglichkeit als ADC-Eingang geschaltet zu 
werden. Da PB1 das leider auch nicht tut, nehmen wir jetzt PB4 als 
Eingang. Die Ausgänge sind dann PB0, 1, 2 und 3.

An PB4 kommen 2 gleiche Widerstände. Z.B. 10K. Einer an Vcc. Der zweite 
kommt an einen der Taster. Also an das "untere Ende" dieses 
Spannungsteilers, der andere in die Mitte direkt an PB4. Beide Taster 
tasten gegen GND.

Mit dem AD-Wandler wird jetzt die Spannung gemessen, die in Ruhe Vcc 
beträgt. Im 8-Bit-Modus des AD-Wandlers liefert dieser einen Wert von 
nominal 255.
Betätigt man den "unteren" Taster ist dieser Wert ca. 127(Vcc/2), 
betätigt man den "mittleren", ist er 0(GND).

1
#include <avr/io.h>
2
#include <avr/interrupt.h> 
3
4
volatile unsigned char nAdc = 255;
5
6
void InitAdc(void)
7
{
8
  ADMUX |= (1 << ADLAR) | (1 << MUX1);
9
  ADCSRA |= (1 << ADEN) | (1 << ADATE) | (1 << ADIE);
10
  ADMUX |= (1 << ADSC);
11
}
12
13
ISR(ADC_vect)
14
{
15
  nAdc = ADCH;
16
}
17
18
int main(void)
19
{
20
  //DDRB = ( 1 << PB3 )|( 1 << PB4 )|( 1 << PB2 );
21
  //PORTB |= (1 << 0);  //Schaltet den internen Pullup von PB0 ein.
22
  //PB0 ist jetzt High.
23
24
  DDRB = ( 1 << PB3 )|( 1 << PB2 )|( 1 << PB1 )|( 1 << PB0);
25
  InitAdc();
26
  sei();
27
28
  while(nAdc < 240);
29
30
  while(1)
31
  {
32
    //if(!(PINB & (1 << 0)))   //Hier passiert nichts solange PB0 High ist.
33
    //Wird GND auf PB0 gelegt, ist die Bedingung true und die Sequenz
34
    //laeuft ab.
35
    if((nAdc < 224) && (nAdc > 32))  //Taster unten
36
    {
37
      PORTB |= ( 1 << PB3 ); 
38
      _delay_ms(100);       
39
      PORTB |= ( 1 << PB2 );    
40
      _delay_ms(100);
41
      PORTB |= ( 1 << PB1 );
42
      _delay_ms(100);
43
      PORTB &= ~((1 << PB3) | (1 << PB2) | (1 << PB1) | (1 << PB0));
44
45
      //while(!(PINB & (1 << 0))); //Das Triggern erfordert nur einen
46
      //kurzen Impuls. Ist der Impuls laenger als die Gesamtzeit(300ms)
47
      //wuerde die Sequenz nochmal ablaufen. Das wird hier verhindert,
48
      //indem gewartet wird, bis PB0 wieder High ist.
49
      while(nAdc > 240);
50
      _delay_ms(50);
51
    }
52
    
53
    if(nAdc < 16)  //Taster Mitte
54
    {
55
      PORTB |= ( 1 << PB3 ); 
56
      _delay_ms(100);       
57
      PORTB |= ( 1 << PB2 );    
58
      _delay_ms(100);
59
      PORTB |= ( 1 << PB0 );
60
      _delay_ms(100);
61
      PORTB &= ~((1 << PB3) | (1 << PB2) | (1 << PB1) | (1 << PB0));
62
63
      while(nAdc < 16);
64
      _delay_ms(50);
65
    }
66
  }

Hab das weder kompiliert noch getestet, sollte aber funktionieren.

Mit dieser Methode liessen sich durchaus noch ein paar mehr Taster 
einlesen. Mit 5 sinnvoll zusammgeschalteten Widerständen sogar ein 
Drehgeber mit Taster.

mfg.

von Nils P. (commanda)


Angehängte Dateien:

Lesenswert?

Vielen Dank für deine Antwort!
Das macht alles Sinn. Ich habe es versucht deine Lösung zu 
verwirklichen, aber leider klappt es nicht auf Anhieb.
Im Anhang ist die Schaltung die ich aus deiner Anleitung gebaut habe. 
Ist die korrekt?
Wenn ich die Schalter schließe passiert leider nichts...  :´(
Kompilieren und so ging alles auf Anhieb...

: Bearbeitet durch User
von Thomas E. (thomase)


Lesenswert?

Nils P. schrieb:
> Vielen Dank für deine Antwort!
> Das macht alles Sinn. Ich habe es versucht deine Lösung zu
> verwirklichen, aber leider klappt es nicht auf Anhieb.
> Im Anhang ist die Schaltung die ich aus deiner Anleitung gebaut habe.
> Ist die korrekt?
> Wenn ich die Schalter schließe passiert leider nichts...  :´(
> Kompilieren und so ging alles auf Anhieb...

Die Schaltung ist OK.

Hab das jetzt getestet.

War eine Kleinigkeit, ein Schwachsinn und eine grundsätzliche 
Unzulänglichkeit drin. Die ist da allerdings immer noch drin.
1
#ifndef F_CPU
2
  #error F_CPU not defined.
3
#endif
4
5
#include <avr/io.h>
6
#include <util\delay.h>
7
#include <avr/interrupt.h> 
8
9
volatile unsigned char nAdc = 255;
10
11
void InitAdc(void)
12
{
13
  ADMUX |= (1 << ADLAR) | (1 << MUX1);
14
  ADCSRA |= (1 << ADEN) | (1 << ADATE) | (1 << ADIE) | (1 << ADSC);  
15
  //ADSC hatte ich vorher in ADMUX geschrieben. Schwachsinn.
16
}
17
18
ISR(ADC_vect)
19
{
20
  nAdc = ADCH;
21
}
22
23
int main(void)
24
{
25
  //DDRB = ( 1 << PB3 )|( 1 << PB4 )|( 1 << PB2 );
26
  //PORTB |= (1 << 0);  //Schaltet den internen Pullup von PB0 ein.
27
  //PB0 ist jetzt High.
28
29
  DDRB = ( 1 << PB3 )|( 1 << PB2 )|( 1 << PB1 )|( 1 << PB0);
30
  InitAdc();
31
  sei();
32
33
  while(nAdc < 240); 
34
35
  while(1)
36
  {
37
    //if(!(PINB & (1 << 0)))   //Hier passiert nichts solange PB0 High ist.
38
    //Wird GND auf PB0 gelegt, ist die Bedingung true und die Sequenz
39
    //laeuft ab.
40
    if((nAdc < 224) && (nAdc > 32))  //Taster unten
41
    {
42
      cli();  // Und das ist... naja...
43
      PORTB |= ( 1 << PB3 ); 
44
      _delay_ms(100);       
45
      PORTB |= ( 1 << PB2 );    
46
      _delay_ms(100);
47
      PORTB |= ( 1 << PB1 );
48
      _delay_ms(100);
49
      PORTB &= ~((1 << PB3) | (1 << PB2) | (1 << PB1) | (1 << PB0));
50
      sei();
51
      //while(!(PINB & (1 << 0))); //Das Triggern erfordert nur einen
52
      //kurzen Impuls. Ist der Impuls laenger als die Gesamtzeit(300ms)
53
      //wuerde die Sequenz nochmal ablaufen. Das wird hier verhindert,
54
      //indem gewartet wird, bis PB0 wieder High ist.
55
      while(nAdc < 240); //Das war falsch rum. Kleinigkeit.
56
      _delay_ms(50);
57
    }
58
59
    if(nAdc < 16)  //Taster Mitte
60
    {
61
      cli(); // Und das ist... naja...
62
      PORTB |= ( 1 << PB3 ); 
63
      _delay_ms(100);       
64
      PORTB |= ( 1 << PB2 );    
65
      _delay_ms(100);
66
      PORTB |= ( 1 << PB0 );
67
      _delay_ms(100);
68
      PORTB &= ~((1 << PB3) | (1 << PB2) | (1 << PB1) | (1 << PB0));
69
      sei();
70
      while(nAdc < 16);
71
      _delay_ms(50);
72
    }
73
  }
74
}

In den Sequenzen wird der Interrupt abgeschaltet. Sonst sorgt das 
Interrupt-Feuerwerk des ADC dafür, daß die Delays ewig brauchen, da sie 
ständig unterbrochen werden. Das ist jetzt ein echter Würgaround.
Sowas macht man mit einem Timer. Dieses Programm zeigt sehr schön warum.

Wenigstens tut es jetzt, was es soll. Aber zeig das niemandem und erzähl 
niemandem, wo du das her hast.

mfg.

von Nils P. (commanda)


Lesenswert?

PERFEKT :) Das läuft...
Vielen Dank!!!

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.