Forum: Mikrocontroller und Digitale Elektronik Avr setzt Ausgänge nicht wie gewünscht.


von Johannes M. (jojo20)


Angehängte Dateien:

Lesenswert?

Hi,

bin gerade für meine Nichte so einen "Kirmesgreifer" am nachbauen.

Dazu hab ich folgendes rundimentäre Testprogramm für einen ATMEGA8515 
geschrieben, der über 2x L298N die XY und Z Achsen ansteuern soll.

Leider funktioniert das nicht. Mal fährt der Greifer nur einmal nach 
rechts oder links und dann nichts mehr. Mal geht es belibig rechts und 
links, aber nicht vor und zurück.

Die Ausgänge für die H Brücke bleiben dann einfach alle auf LOW oder 
alle auf High.

Die Ein und Ausgänge sind folgendermaßen beschaltet:

//PA 0+1 = x Achse
//PA 2+3 = y Achse
//PA 4+5 = z Achse
//PA6 = Enable Motoren
//PA7 = LED
//PC 0...3 = Joystick

Das ist meine Schleife zum testen der Ansteuerung durch den Joystick:
1
while (1) 
2
    {
3
    
4
    if (status.led==0){PORTA |= (1<<PA7);}else{PORTA &= ~(1<<PA7);}
5
    //if ( !(PINE & (1<<PINE0))){PORTA |= (1<<PA7);}else{PORTA &= ~(1<<PA7);}
6
    
7
      
8
    if ( !(PINC & (1<<PINC0))){PORTA |= (1<<PA2);PORTA &= ~(1<<PA2);} //vor
9
    if ( !(PINC & (1<<PINC1))){PORTA |= (1<<PA3);PORTA &= ~(1<<PA3);} //zurück
10
      
11
    if (((PINC & (1<<PINC0)) && (PINC & (1<<PINC1)))){PORTA |= (1<<PA2);PORTA |= (1<<PA3);}
12
    
13
    
14
    if ( !(PINC & (1<<PINC2))){PORTA &= ~(1<<PA1);PORTA |= (1<<PA0);} //rechts
15
    if ( !(PINC & (1<<PINC3))){PORTA &= ~(1<<PA0);PORTA |= (1<<PA1);} //links
16
    if (((PINC & (1<<PINC2)) && (PINC & (1<<PINC3)))){PORTA |= (1<<PA0);PORTA |= (1<<PA1);}
17
    
18
    
19
      
20
    if ( !(PINC & (1<<PINC4))){}else{} //Button
21
    
22
    }
Das volle Programm ist im Anhang.

Wo hab ich den Denkfehler? Warum setzt der AVR die Eingänge einfach 
nicht wie gewünscht? Ich stehe gerade total auf dem Schlauch.

: Bearbeitet durch Moderator
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

1
{PORTA |= (1<<PA2);PORTA &= ~(1<<PA2);}

schaltet den Pin sehr kurz ein und dann nach <1µs wieder aus. Soll das 
so?

von Johannes M. (jojo20)


Lesenswert?

Das war tatsächlich ein Tippfehler vom ganzen rumprobieren.

Aber auch so ändert es nichts:
1
while (1) 
2
    {
3
    
4
    if (status.led==0){PORTA |= (1<<PA7);}else{PORTA &= ~(1<<PA7);}
5
    //if ( !(PINE & (1<<PINE0))){PORTA |= (1<<PA7);}else{PORTA &= ~(1<<PA7);}
6
    
7
      
8
    if ( !(PINC & (1<<PINC0))){PORTA |= (1<<PA2);PORTA &= ~(1<<PA3);} //vor
9
    if ( !(PINC & (1<<PINC1))){PORTA |= (1<<PA3);PORTA &= ~(1<<PA2);} //zurück
10
      
11
    if (((PINC & (1<<PINC0)) && (PINC & (1<<PINC1)))){PORTA |= (1<<PA2);PORTA |= (1<<PA3);}
12
    
13
    
14
    if ( !(PINC & (1<<PINC2))){PORTA &= ~(1<<PA1);PORTA |= (1<<PA0);} //rechts
15
    if ( !(PINC & (1<<PINC3))){PORTA &= ~(1<<PA0);PORTA |= (1<<PA1);} //links
16
    if (((PINC & (1<<PINC2)) && (PINC & (1<<PINC3)))){PORTA |= (1<<PA0);PORTA |= (1<<PA1);}
17
    
18
    
19
      
20
    if ( !(PINC & (1<<PINC4))){}else{} //Button
21
    
22
    }

: Bearbeitet durch Moderator
von Steve van de Grens (roehrmond)


Lesenswert?

Teste Motortreiber und Aufbau erst mal ohne Mikrocontroller, um sicher 
zu stellen, dass die Hardware in Ordnung ist.

Ein Schaltplan wäre hilfreich, sonst müssen wir davon ausgehen, dass 
Aufbau und Programm zusammen passen. Aber genau das ist gerade nicht 
sicher  jedenfalls nicht für uns.

: Bearbeitet durch User
von Thomas (kosmos)


Lesenswert?

Anfänger machen oft folgenden Fehler.

Sie fragen einen Pin ab, führen dann eine Aktion aus, es wird aber nie 
mehr im Code abgefragt ob die Bedingung wieder entfallen ist. um die 
Aktion zu stoppen.

Ansonsten könnte ich mir noch vorstellen das der Eingang Störungen oder 
Prellen einfängt. Schalte die Pullups der Eingänge ein und ziehe die 
Pins gegen Masse. Oder du verwendest Pulldowns und gibts dann VCC auf 
den entsprechenden Eingang.

Auch die Aktoren können Störungen verursachen. Hier ggf. Freilaufdioden 
verwenden und die Spannungsversorgung des µC ertüchtigen.

Ein Bild des Aufbaues kann helfen den Fehler zu finden.

von Norbert (der_norbert)


Lesenswert?

Vielleicht noch eine Anmerkung:

Man sollte den Sourcecode so schreiben und formatieren, das es nicht 
gleich so aussieht als wenn man sich beim Verzehr von Buchstabensuppe 
den Finger  tief in den Hals gesteckt hätte.

Interessanterweise kann man dann nämlich etwaige Fehler viel schneller 
erkennen und beheben.

von Johannes M. (jojo20)


Lesenswert?

Ich glaube ich habe den Denkfehler gerade selber entdeckt. Das Stichwort 
heißt Flankenerkennung.

Ich frage die Position des Joysticks ab und setzte so lange dieser 
beätigt ist immer und immer wieder die Ausgänge.

Mal ausprobieren ob es anders funktioniert.

von Steve van de Grens (roehrmond)


Lesenswert?

Ein paar LEDs an den Ein- und Ausgängen können zur Kontrolle hilfreich 
sein, wenn man schon keinen Debugger hat. Damit man nicht völlig im 
Dunklen tappt.

von Wendels B. (wendelsberg)


Lesenswert?

Hat schon jemand Entprellung gesagt?

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Wendels B. schrieb:
> Hat schon jemand Entprellung gesagt?

»Ach wie gut das niemand weiß, das ich Tastenprellen heiß.«

Keine Sorge, kommt später… ;-)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Johannes M. schrieb:
> if (status.led==0){PORTA |= (1<<PA7);}else{PORTA &= ~(1<<PA7);}
Wenn schon so, dann gleich so:
1
  (status.led==0) ? PORTA|=(1<<PA7) : PORTA&=~(1<<PA7);

Ich würde es aber so schreiben:
1
   if (status.led==0) PORTA |= (1<<PA7); 
2
   else               PORTA &= ~(1<<PA7);

Johannes M. schrieb:
> Das Stichwort heißt Flankenerkennung.
> Ich frage die Position des Joysticks ab und setzte so lange dieser
> beätigt ist immer und immer wieder die Ausgänge.
Und was ist daran eine Flankenerkennung? Denn eine FLanke hat eben genau 
keine Dauer.

Es ist übrigens eine gute Art, einen Port 1x am Schleifenanfang 
einzulesen und dann im Programmdurchlauf mit diesem "Prozessabbild" zu 
arbeiten. Denn dann ist während des gesamten Schleifendurchlaufs der 
EIngang stabil und es ist eben nicht in der ersten Schleifenhälte ein 
Portpin low und in der zweiten Hälfte high.

Mit PAE (Prozessabbild Eingänge), Zyklusdurchlauf (mainloop), Merkern 
und Schrittketten (Finite Zustandsautomaten) und PAA (Prozessabbild 
Ausgänge) schafft es jeder Schlosser, mit einer SPS eine Anlage zu 
steuern.

: Bearbeitet durch Moderator
von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Lothar M. schrieb:
> und dann im Programmdurchlauf mit diesem "Prozessabbild" zu
> arbeiten.

Und am Schluss der Schleife guckste dann, ob der Knüppel immer noch 
aktiv ist und falls nicht, schalteste alle Motoren ab. Anderenfalls 
gehts wieder zur Joystickabfrage hoch.
Zündet man die Schleife mit einem Timer, dann hat man auch definierte 
Zeitschlitze und kein Prellgezitter.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Matthias S. schrieb:
> Und am Schluss der Schleife guckste dann, ob der Knüppel immer noch
> aktiv ist und falls nicht, schalteste alle Motoren ab
Halb so wild, denn das Ende der Schleife ist nicht der Weltuntergang, 
sondern der Anfang der nächsten Schleife. Und diese Schleife wird 
schnellstmöglich durchlaufen und das Abschalten der Motoren passiert 
dann ja kurz darauf am Ende des nächsten Schleifendurchlaufs.

Wie gesagt, jede SPS arbeitet prinzipiell so.

: Bearbeitet durch Moderator
von Steve van de Grens (roehrmond)


Lesenswert?

Johannes M. schrieb:
> Ich frage die Position des Joysticks ab und setzte so lange dieser
> beätigt ist immer und immer wieder die Ausgänge.

Daran ist im Grunde genommen nichts falsch. Du willst doch, dass die 
Motoren so lange laufen, wie der Joystick gedrückt wird, oder nicht?

von Bernd G. (Gast)


Lesenswert?

Johannes M. schrieb:
> Ich frage die Position des Joysticks ab und setzte so lange dieser
> beätigt ist immer und immer wieder die Ausgänge.

Flankenerkennung am Einfachsten mit Speicherung und EXOR beim nächsten 
Loop.

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.