PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : AtMega32 - Delay wird bei Tasterdruck nicht richtig ausgelöst



ijjiij
20.07.2012, 22:03
Hallo!

Also folgendes, ich habe gerade einen Taster an meinen AtMega32 angeschlossen und wollte damit bisschen die herumexperimentieren. In weiterer Folge soll daraus (total unkreativ) ein Anstoßsensor für meinen Roboter realisiert werden.

So, ich habe den Taster an PB0 angeschlossen und möchte jetzt einfach bei Tastendruck eine LED ausgehen lassen, diese dann eine Sekunde ausgeschaltet lassen und danach wieder einschalten. Das war das Ziel.

Hier dazu mein Code:

#include <avr/io.h>
#include <util/delay.h>

#define LEDRED PD6
#define Bumper1 PB0

#ifndef F_CPU
#define F_CPU 8000000
#endif


int main(void)
{
//DDRB |= (0<<Bumper1);
DDRD |= (1<<LEDRED) | (1<<PD7);

//PORTB |= (0<<Bumper1);
PORTD |= (1<<LEDRED);


while(1)
{
if(PINB & (1<<PINB0)) //wenn Taster gedrückt
{
PORTD &= ~(1<<LEDRED);
_delay_ms(1000); //warte 1 sek
}
else
{
PORTD |= (1<<LEDRED);
}
}
}

Die LED geht auch brav an und wieder aus, sowie geplant, allerdings eben nur so lange, wie der Taster gedrückt ist.

In der Theorie sollte das Programm doch eingentlich an dieser Stelle

if(PINB & (1<<PINB0)) //wenn Taster gedrückt
{
PORTD &= ~(1<<LEDRED);
_delay_ms(1000); //warte 1 sek
}
für 1 Sek verharren und damit die LED ausgeschaltet lassen, bevor dann der Zyklus fortgesetzt wird, oder?
Warum bleibt die LED nicht an?

LG

debegr92
20.07.2012, 23:01
Hallo ähh phuu naja egal... ;-)
Also kann es den sein, dass dein ATmega gar nicht mit der Frequenz läuft, die du angegeben hast? Ist denn wirklich ein 8MHz Quarz neschlossen? Sind die Fuses des ATmegas auch alle so eingestellt, dass dieser mit 8MHz läuft? Was auch noch sein kann, dass F_CPU schon vor deinem Code definiert wurde, heißt deine redefinition wird nicht übernommen.

Grüße
Dennis

Hubert.G
21.07.2012, 09:29
Du hast ja nach einer Sekunde den Taster immer noch gedrückt, damit ist die if Bedingung wahr und die Led bleibt weiter aus.
Wenn du die Taste loslässt, kommt das else zum tragen und schaltet die Led wieder ein.

ijjiij
23.07.2012, 14:02
Hallo,

Also der Quarz ist definitiv ein 8.0Mhz, andere Programme (z.B. LEDs immer 1 sek an, 1 sek auszuschalten) funktionieren auch ganz problemlos. Fuses passen also auch dafür, wie gesagt, alle anderen Programme mit _delay_ms(x) machen keinerlei probleme.

@Hubert.G: Es macht leider keinen Unterschied wie lange ich den Taster gedrückt halte, auch wenn ich den Taster nur kurz "antippe" geht die LED nur für genau die Zeit an, die der Taster gedrückt ist. Unabhängig davon ob ich den Taster antippe oder für 10 sek halte, die LED bleibt exakt so lange an wie der taster gedrückt ist.

HeXPloreR
23.07.2012, 18:01
Hallo,
macht deine LED auch das was sie machen soll, weil du schreibst sie geht brav AN und auch wieder AUS. Laut deinem Programm müsste sie ja von anfang an AN sein?

Baue doch mal ein delay zum prüfen in den else-Teil ein, funktioniert dieses delay?

mfg

ijjiij
23.07.2012, 19:58
Sry da habe ich mich in meiner letzten Antwort verschrieben, bin ich vor lauter herumprobieren übers Wochenende durcheinander gekommen.

Also die LED ist beim Programmstart AN und soll mit Tastendruck für exakt eine Sek AUSgehen.
Unabhängig davon wie lange ich den Taster gedrückt halte, also sowohl bei antippen als auch bei halten, ist die LED immer nur so lange auus wie der Taster gehalten wird.

Hubert.G
23.07.2012, 20:16
Hab das gerade noch mal getestet, aber eigentlich ganz klar.
Du drückst die Taste, wird erkannt, LED geht aus, delay läuft. Jetzt kommt es darauf an wann du die Taste auslässt.
Lässt du sie unmittelbar vor dem Ablauf des delay los, hast du keine Verzögerung mehr.
Es ist also Glückssache wie lange die LED noch aus bleibt.
So wie du es willst, müsste das delay nach dem loslassen der Taste beginnen.

ijjiij
23.07.2012, 20:18
@Hubert.G: Dann müsste aber auch bei "antippen" des Tasters die LED für mindestens eine Sekunde aus bleiben, passiert aber auch nicht sondern die LED blinkt nur ganz kurz auf.

Hubert.G
23.07.2012, 20:22
Bei mir tut es das schon.
Hast du auf deiner Taste auch einen PullDown oder ist der Eingang offen wenn keine Taste gedrückt?

ijjiij
23.07.2012, 20:27
Habe hier keinen PullDown, der Taster ist nur mit Krokodilklemmen an den Port und GND geklemmt.

HeXPloreR
23.07.2012, 20:33
okay,

in einem andere Beitrag hast du geschrieben das Du die Warnungnen des Compilers aus hast, hast Du sie heir an? Meldet er was?

Ich kann es mir nicht vorstellen, aber ich würde fast sagen das hört sich wie ein Reset an.

Bist Du sicher das der den else-Teil durchläuft? Tausche doch bitte mal die Anweisung aus, so das die LED bei taster drücken an geht und ansonsten aus ist. Vielleicht noch eine extra LED an einem PORT hängen und mit _delay_ms(200) einschalten lassen sobald das programm an main vorbei gelaufen ist - nicht wieder ausschalten. Wenn der jetzt immer neu startet würde dann würde diese LED blinken.

Verursacht ein Kurzschluss möglicherweise einen Reset?

Was weißt Du über den Watchdog? hat der m32 einen? ist der aktiviert? Möglicherweise muß der ausgeschaltet oder zurückgestzt werden, damit er nicht "denkt" dein Program ist abgestürzt?

mfg

Hubert.G
23.07.2012, 20:34
Und wie bringst du dann den Pin auf high? Kein PullUp aktiviert.
Ändert aber auch an deinem Problem nichts, ausser das es nicht so funktionieren kann wie du es beschrieben hast.
Wenn der Pin auf GND liegt ist die LED aus, von GND weg kommt die LED mit der von mir beschriebenen Verzögerung, Voraussetzung der PullUp ist aktiviert.

Hubert.G
23.07.2012, 20:43
Noch was:
if(PINB & (1<<PINB0)) //wenn Taster gedrückt
Wie soll das gehen wenn du den Pin auf GND legst?

ijjiij
23.07.2012, 20:44
Warnungen sind eingeschaltet, werden aber keine ausgegeben.

Watchdog sagt mir leider kaum was, also ich hab schon mal davon gelesen im AtMega32 Datenblatt glaub ich.

HeXPloreR
23.07.2012, 21:05
okay, der Hubert schient etwas wichtiges angespochen zu haben.
Setze einen 1kOhm Widerstand zwischen GND und PORT TASTER, den Taster auch mit an PORT TASTER und die andere Seite vom Taster auf VCC(+5V). Damit hast du solange "0" am PORT TASTER solange du nicht drückst. Drückst Du geht er auf "1". Und ist somit der von Hubert bemängelte PullDown.

Viel Erfolg

mfg

ijjiij
26.07.2012, 18:07
Also ich hab jetzt den von euch angesprochenen 1k Ohm Widerstand hineingeklemmt, macht aber leider auch keinerlei Unterschied zu vorhin. Also die LED Schaltet noch immer genau so lange, wie der Taster gedrückt wurde und nicht eben mindestens eine Sekunde.

HeXPloreR
26.07.2012, 19:47
Also einen Unterschied wird das schon machen... ich habe soetwas mal ohne PullDown gemacht, und da fing meine dazu gehörige LED an zu flackern hin und her .unbeständig... >> nicht gut!
Um zu prüfen ob Du einen reset auslöst, würde ich eine LED vor der while-Schleife einschalten-mit etwa 200ms delay davor ; einfach um zu sehen ob der überhaupt richtig läuft? Tausche doch sonst bitte mal die Anweiseungen aus damit Du sehen kannst ob der Taster-Eingang überhaupt erstmal die Bedingung erfüllt - als wenn Taster gedrückt wird, LED geht aus...dann nach 1 sek wieder an. Dann schauen wir weiter ;)

Hast Du Dir die weiteren Anmerkungen von Hubert durchgesehen?

Schaltung prüfen.
Sonst kannst Du eigentlich nur noch ganz genau deine Schaltung hier zeigen.

ijjiij
26.07.2012, 21:13
Ok also folgende Ergebnisse hat mein aktueller Test gebracht:

Schaltung am Taster:
PB0 --> 1k Ohm --> Taster --> GND

Programm:
Vor der Schleife lass ich die Grüne LED am PD7 ein paar mal blinken.
Habe das Ganze jetzt mal ohne Taster versucht, also den "Taster" durch ein und ausstecken eines Kabels simuliert.
Nachdem ich hier schon interessante Ergebnisse erzielt habe, hab ich den richtigen Taster wieder angeschlossen.

So, wie lauft das ganze jetzt ab?
Also beim Drücken des Tasters (für ca. gefühlte 0.5 Sekunden, kürzer hat absolut keinen Effekt) geht nach ca einer Sekunde "Wartezeit" die LED für ca 1 Sek. aus, danach wieder an, so wie gewünscht!

Also das Problem ist damit ja ziemlich behoben.
Jetzt stellen sich mir noch ein Paar Verständnisfragen:
1.) Hubert.G meinte ja, das Ganze sollte garnicht funktionieren wenn der Taster am GND hängt. Warum denn nicht? Bzw. warum funktioniert es trotzdem?
2.) Woher kommt die Verzögerung zwischen Tastendruck und Schalten der LED? Kommt die aus einer "Rechenzeit" im µC? Kann man die iwie minimieren? Wenn das in weiterer Folge in meinem Roboter verbaut werden soll wären diese Wartezeiten zwar auch nicht so dramatisch, aber man könnte sie ja auch minimieren.

Danke für die vorläufigen Erfolge auf jeden Fall einmal. :)

HeXPloreR
26.07.2012, 21:55
okay,
momentan hast Du eigentlich immer noch einen offen liegenden Eingang wenn nicht gedrückt ist. Einfach den Widerstand in Reihe mit dem Taster und Ground bring keinen effekt der dir hier hilft. Schau mal hier Bild1 : http://www.elektronik-kompendium.de/public/schaerer/pullr.htm


Du müsstest den Widerstand als PullUp zu VCC einbauen wenn du den taster zu GND schaltest. Oder den internen benutzen und extern dann weglassen.
Dann musst Du in Deinem Programm allerdings beachten, das der Pin beim drücken auf low gezogen wird. Dazu müssen die dann Bedingungen angepasst werden - ich fürchte genau das meinte Hubert auch.


Es kann eigentlich nicht sein das es wirklich merklich viel Rechenzeit benötigt bis sich was tut. Also antippen müsste ausreichen um den vorgang zu starten.

Deinen neuen Code, könntest Du den ochmal zeigen?

Edit: nochmal als tipp: Hardware muss zur Software passen! - baust Du deine Schaltung mit dem Taster zu GND auf, musst Du einen PullUp zu VCC schalten (intern aktivieren ODER erxtern fest einbauen). Damit ist der EingangsPin auf "high" = 1. Und das wiederum wird dann im Code üblicherweise abgefragt, also ob high weg ist = 0 (oder !=1).

Ich persönlich ziehe es momentan vor meine Programme so zu schreiben und meine Schaltungen so aufzubauen, das meine TasterEingänge auf "low" gezogen sind wenn sie nicht gedrückt werden, und auf high gehen wenn man drückt. Dafür verbaue ich einen PullDown. Warum? Ganz einfach, ich finde es sinnvoller einen Kontakt zu schliessen und das messen zu lassen (PullDown>GND, mit Taster>VCC) , als einen bestehenden Kontakt zu unterbrechen und darauf zu reagieren (PullUp>VCC, mit Taster>GND).
Egal wie man es macht, die Schaltung muss mit dem Code zusammen passen!

konkret zu 2: Ich meine du bist da in deinem delay gelandet-daher die Verzögerung. Das bedeutet Deine if-Bedingung ist schon erfüllt, obwohl Du noch nicht gedrückt hast, jetzt drückst Du und der else-Teil läuft.

Viel Erfolg

ijjiij
27.07.2012, 08:51
Sehr gut, jetzt hab ich meine Schaltung (war ja nur am Steckbrett) so umgebaut wie auf dem Bild dargestellt aufgebaut, das du mir in deinem Link gepostet hast (Abbildung rechts oben am Bild).

Zack, schon funktionierts. Also ich habe jetzt einen Widerstand zwischen Port und GND, und den Taster zwischen Port und VCC.
Funktioniert jetzt wirklich wie erwartet, also auch bei "antippen" wird sofort reagiert und der delay dann auch korrekt ausgeführt.
War also ein Fehler im Anschluss des Tasters. Dazu könnte man ja mal einen RN-Wiki Eintrag verfassen, um sowas vorzubeugen. ;)

Riesen Dankeschön nochmal!

Hubert.G
27.07.2012, 09:23
Gut wenn es jetzt funktioniert.
Etwas einfacher wäre es wenn der Taster zwischen Port und GND liegt und der interne PullUp des Kontroller aktiv ist.
Die Abfrage muss natürlich dann angepasst werden.

ijjiij
27.07.2012, 09:48
Habe dazu jetzt noch einen kurzen Artikel in die Wiki gestellt mit dem Titel "Tastsensoren", um anderen Usern den Einstieg in dieses Thema zu erleichtern.

Ich habe versucht den Artikel so vollständig und richtig wie möglich zu halten, wäre aber super wenn den jemand nochmal durchlesen könnte ob sich da nicht doch noch irgendwo etwas eingeschlichen hat.

HeXPloreR
27.07.2012, 12:33
Tausche bitte im letzten Codebeispiel den Kommentar "Taster ist nicht gedrückt" und "Taster ist gedrückt" um, denke so macht das dann Sinn mit der Abfrage auf low.
Ansonsten sieht es für mich für den Einstieg recht brauchbar aus. Das hast Du gut gemacht.
Allerdings habe ich den Artikel nur gefunden, weil es ein Neuer ist. Wo finde ich den morgen oder übermorgen? Es gibt den Beitrag "Taster-Abfragen in C" in der Kategorie Software, oder "Pullup Pulldown Widerstand" vielleicht da irgendwo mit hin oder sogar dazu in den Beitrag? Was hier anscheinend nur fehlt ist der zusammenhang Schaltung und Software.

Es freut mich das wir helfen konnten und nun kann das Wochenende ja ruhig kommen :)

Viel Erfolg weiterhin...Geduld Du haben, das Du bewiesen ;)

ijjiij
27.07.2012, 13:08
EDIT: Habs gefunden und habe den Beitrag jetzt dem "Sensoren" Verzeichnis hinzugefügt.