Avr setzt Ausgänge nicht wie gewünscht.

OP #7559692
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.

Angehängte Dateien:
OP #7559694
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
    }
Gast #7559698
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.

#7559713
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.

#7559724
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.

Moderator (Firma: Titel) Persönliche Seite #7559836
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.

(Firma: matzetronics) #7559844
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.

Moderator (Firma: Titel) Persönliche Seite #7559862
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren