Avr setzt Ausgänge nicht wie gewünscht.

OP #7559692

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

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

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.

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.

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.

OP

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.

Moderator (Firma: Titel) Persönliche Seite

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)

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

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.

Gast

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?

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 2 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.