-         

Ergebnis 1 bis 7 von 7

Thema: Schleife while(1) und for (...) läuft nur ein Mal :: gelöst

  1. #1
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.551

    Schleife while(1) und for (...) läuft nur ein Mal :: gelöst

    Anzeige

    Schönen Abend, allen,

    meine C-Kenntnisse sind bekannt schlecht. Wie schlecht habe ich bei der Adaption des ordentlich funktionierenden und vielfach getesteten Programms meines R2D03/Dottie an mein MiniD0/R3D01 gemerkt.

    Sachstand: Zur Aufnahme der Sprungfunktion muss ein Fahren des Gerätes ohne Regelung möglich sein. Daher habe ich die Regelung ausgeschaltet (wird garnicht aufgerufen). Für einen längeren Fahrtest sollten die Motoren jetzt getrennt fahren:
    Stop - allmählich schneller - niedrige Endgeschwindigkeit - allmählich langsamer - Stop
    nächster Motor (gleiche Fahrweise).

    Zur Sicherstellung, dass das ohne Störung geht - es ist eine gemeinsame Energieversorgung für Controller und Motoren, nur eine Pufferung mit 1x200µF und 1x100nF (ja - dazu noch die 100nF direkt am Controller) - sollte das Fahrzeug ne Weile fahren - da nur ein Motor dreht, gehts immer im Kreis. Codeschnippsel im main (AVRStudio, WinXPpro):

    Code:
    /*  while (1)
      {
        Motst_12();                 // Fahre ohne Regelung+Sensoren
        Motst_34();                 // Fahre ...
       }                             */
                                     
                                     
      for(i=0; i<200; i++)          // Fahrtest
      {                      
        Motst_12();                 // Fahre ohne Regelung+Sensoren
        Motst_34();                 // Fahre ...
      }
    Die for-Schleife habe ich gemacht, weil die while-Schleife nur 1mal durchlaufen wurde - danach stand alles - danach kommt auch nur noch das "return 0;". Leider läuft auch die for-Schleife nur 1 mal.

    Definiert wurde i als uint_8. Sowohl while(1)- als auch for-Schleifen laufen im Code unmittelbar vor diesem Testabschnitt störungsfrei. Für den Fall dass es hilfreich sein könnte, hier auch noch die aufgerufene Routine.
    Code:
    /* ============================================================================== */
    /*### Motortest 12 "auf-ab",  am 24 Mrz 2009, 1710
     ================================================================================ */
     void Motst_12(void)            // Motor12 vor+zur, aufab
    {                               
     uint16_t iwt=1000;             //wait-Dauer beim Hoch-/runterfahren der Motoren
                                     
     uint8_t mimo = 15, mamo = 50;  // Min-/Max-Geschwindigkeitsvorgabe Motoren
     uint8_t mdiff = 5;             // Auf-/Ab-Increment für Motorspeed
     uint8_t ll    = 0;             // Laufvariable
                                     
    // Einmal hinfahren (vorwärts) ...
                                    
            Mrechtsvor();
            Mlinksstop();
    	setPWMrechts(0);
    	waitms(40);
    
    	for(ll = mimo; ll<=mamo; ll = ll + mdiff)
    	{
    		kre=ll;
    		setPWMrechts(kre);
    		waitms(iwt);
    	}
    		setPWMrechts(mamo);
    	waitms(1000);
    
    	for(ll=mamo; ll>=mimo; ll = ll - mdiff)
    	{
    		kre=ll;
    		setPWMrechts(kre);
    		waitms(iwt);
    	}
                                   
    	waitms(10);
    	setPWMrechts(0);
    	setPWMlinks(0);
    	Mlinksstop();
    	Mrechtsstop();
    	waitms(10);
    
    // ... und einmal rückwärts
    // ... =================
    
    //        mimo    =  5;
    //        mamo    = 25;      
                                 
            Mlinksstop();
            Mrechtszur();
    	setPWMrechts(0);
    	waitms(40);
    
    	for( ll=mimo; ll<=mamo; ll = ll + mdiff)
    	{
    		kre=ll;
    		setPWMrechts(kre);
    		waitms(iwt);
    	}
    		setPWMrechts(mamo);
    
    	waitms(1000);
    	for( ll=mamo; ll>=mimo; ll = ll - mdiff)
    	{
    		kre=ll;
    		setPWMrechts(kre);
    		waitms(iwt);
    	}
    	waitms(10);
    	setPWMlinks(0);
    	setPWMrechts(0);
    
    	Mlinksstop();
    	Mrechtsstop();
    	waitms(10);
      return;
    }
    /* ============================================================================== */
    Als Massnahme des ratlosen Programmierers hatte ich erstmal die Optimierung von -Os geändert auf -O0. Keine Besserung - nur etwas längerer Hexfile.

    Danke für Hilfe
    Ciao sagt der JoeamBerg

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.781
    Blog-Einträge
    8
    Hallo

    Das "void" void Motst_12(void)... zeigt an dass die Funktion keinen Rückgabewert liefert. Dann darf am Ende wohl auch kein Return stehen. (Ich vermute die Werte werden über den Stack übergeben und ein Return zuviel nimmt die eigentliche Rücksprungadresse vom Stapel)

    Ist aber eher geraten als gewußt.

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  3. #3
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.551
    Hallo mic,

    danke für den Rat. Der Compiler (na ja, der Softwarer/Entwickler hinter dem Compiler) ist ja klüger als der Programmierer (ich) - der pollt seinen Stack richtig - egal ob da ein return steht oder nicht - wenn´s nur eine "void"-Funktion ist. Leider, oder besser: Gottseidank. Steht auch irgendwo in der Hilfe. Seit ich das gelesen hatte, mache ich meistens ein return hin und wundere mich, dass es auch ohne störungsfrei läuft.

    Nachtrag: steht auch so im C-Tutorial von RN.

    Danke.
    Ciao sagt der JoeamBerg

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.551
    Noch mehr Unklarheiten. Ich habe die for-Schleife geändert, meiner Meinung nach sind die drei Varianten zulässiges C und deckungsgleich bis auf den jeweils momentanen Wert von "i" innerhalb der Schleife. "Ich dachte halt...." dass vielleicht die Präfix-Notation oder die ausgeschriebene Form "richtiger" sei.
    Code:
    /*  for(i=0; i<200; i++)          // Fahrtest
    //  for(i=0; i<200; i = 1 + 1)  // Fahrtest
    //  for(i=0; i<200; ++i)          // Fahrtest
    Nun läuft die Schleife - einschließlich die mit der ursprünglichen Postfix-Notation i++ und auch die while(1)-Schleife funktioniert. Die Befriedigung der erreichten Funktion wird nur vom Frust übertroffen, dass die gleiche Schreibweise vor ein paar Stunden nicht ging.

    Was solls: das MiniD0 dreht seit rund 20 Minuten auf meiner PMMA-Teststrecke (350mmx500mm) eifrig und störungsfrei seine Runden - vor und zurück. Mal sehen, wann der Akku (4xAAA) leer oder die Hackeservos defekt sind . . . . . Und leise ist der Antrieb, man hört sozusagen die weggelassene Getriebestufe.
    Ciao sagt der JoeamBerg

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von vohopri
    Registriert seit
    11.09.2004
    Ort
    südlich der Alpen
    Beiträge
    1.708
    Hallo Joe,

    ja sowas gibt es einfach. Man fühlt sich dann oft um den angestrebten Erkenntnisgewinn betrogen, aber ich verspreche dir: Wenn das Problem wichtig ist, kommt es ohnehin wieder. Wirklich Wichtiges verschwindet nicht einfach so.

    Aber im Ernst: gratuliere zum Erfolg und den störungsfreien Runden.

    grüsse,
    Hannes

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    22.11.2005
    Ort
    Braunschweig
    Alter
    41
    Beiträge
    685
    Moin!
    @obeerallgeier:
    Nur eine kleine Anmerkung : Die mittlere Schleife in Deinem letzten Post macht nicht viel Sinn, weil i immer gleich 2 wäre (Tippfehler?), und zwischen 'i++' und '++i' gibt es einen Unterschied.
    Bei 'i++' wird erst der Wert der Variablen genommen und in diesem Fall verglichen, danach wird die Variable um eins erhöht, bei '++i' wird erst erhöht und dann verglichen.
    MfG
    Volker
    Meine kleine Seite
    http://home.arcor.de/volker.klaffehn
    http://vklaffehn.funpic.de/cms
    neuer Avatar, meine geheime Identität

  7. #7
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.551
    Hallo Volker,

    danke für Deinen Kommentar

    Zitat Zitat von vklaffehn
    ... Die mittlere Schleife in Deinem letzten Post macht nicht viel Sinn, weil i immer gleich 2 wäre ...
    Uuuuups - keine Ahnung wie die "1" statt des "i" reinkam. Ich habe leider diese dämlichen Zeilen schon ins elektronische Nirwana geschickt und kann den Fehler nicht nachvollziehen. Aber er ist mir schon klar. Danke.

    Zitat Zitat von vklaffehn
    ... zwischen 'i++' und '++i' gibt es einen Unterschied ...
    Danke, ja. Diese Geschichte mit der Post- und Präfix-Notation hatte ich vor einiger Zeit mühselig durchgefisselt und sozusagen verstanden. Wobei mir die Konsequenzen nicht wirklich ganz klar sind - oder besser ausgedrückt: der nutzbare Effekt. Das Beispiel im Kernighan-Ritchie dazu kommt mir ein bisschen konstruiert vor. Vermutlich verstehe ich das nicht wirklich, weil ich noch nie so komplexen Code geschrieben hatte, dass das von Bedeutung war oder gewesen wäre. Aber ich hoffe, dass ich mit meinen Cäh-(Er-)Kenntnissen weiter voranschreite.

    PS: die Akkus - ED 100% - sind noch immer nicht leer und die Motoren - ED 50% - weil abwechselnd - sind noch heil *ggggg*.
    Ciao sagt der JoeamBerg

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •