- LiTime Speicher und Akkus         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 15

Thema: Viele Aufgaben gleichzeitig machen

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    25.03.2006
    Ort
    nahe Tulln (Niederösterreich)
    Alter
    33
    Beiträge
    460

    Viele Aufgaben gleichzeitig machen

    Hallo!
    Ich habe einen roboter mit einem sharp entfernungssensor, der von einem Schrittmotor gedreht wird.
    Alle 50 Microsteps wird ein Entfernungswert erfasst, d.h. 32 Entfernungswerte auf 180°.
    Außerdem ist der Controller noch für das Fahren, Spannungen, Lichtstärke, ... und tausend andere Sachen zuständig.

    Ich bin Anfänger, darum weiß ich nicht genau, wie ich das programmieren soll, dass er alles gleichzeitig machen kann.
    Also jetzt habe ich die enfernungssensor-dreh-steuerung so gemacht, das er einfach in einer endlosschleife folgende schritte macht:
    - Schrittmotor-Controller über I2C den Befehl geben, dass er 50 schritte drehen soll
    - Die Aktuelle Schrittmotor position abfragen, und warten bis der Schrittmotor seine Position erreicht hat
    - Mit der AD-Wandlung beginnen
    - Warten bis die AD-Wandlung fertig ist
    ...und alles wieder von vorne.

    Das war mal das Testprogramm für den Drehturm, bei diesem Test wurden alle anderen Funktionen vernachlässigt. Jetzt muss ich aber diese anderen funktionen wieder dazugeben, aber ich weiß nicht wie. Diese ganzen warteschleifen zerstören mir mein ganzes Programm.

    Ich glaube die lösung sind Interrupts, nur ich weiß nicht wie ich das mit denen machen soll. Ich glaube, das warten auf den AD wandler kann ich leicht mit einem interrupt umgehen, weil ich ja einstellen kann, dass der AD-Wandler einen Interrupt auslöst, wenn er fertig ist. Dann müsste ich nicht auf das AD-Wandler-fertig-Flag pollen.

    Wenn ich 100ms warten will, aber nebenbei auch was machen will, wie kann ich das machen? Kann ich einen Timer machen mit einem Interrupt auf diesen Timer, dann weiß ich in welchen Abständen der Interrupt ausgelöst wird. Dann zähle ich in der Interruptroutine eine globale variable hoch, und dies frage ich dann in meinem programm irgendwie ab und kann so mit einer if abfrage warten, bis irgendein wert erreicht ist, und dann irgendeine aktion machen?

    Geht das oder hab ich überhaupt nichts kapiert?
    Meine Idee klingt jedenfalls ziehmlich unprofessionell.

    lg Christoph

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Nein, deine Idee ist absolut nicht unprofessionell. Das arbeiten mit "wait" wäre es, das hast du aber schon selbst festgestellt.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

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

    der Sharp gibt das Ergebnis eines Messzyklus alle 40 ms heraus. Da Du vermutlich nicht weißt, wann ein Messzyklus des Sharp beginnt, solltest Du für genaue Messwerte 80 ms auf einer neuen Position warten und erst dann den ADC starten. Andernfalls könntest Du den letzten aktuellen Wert des Sharp mit dem ADC einlesen.

    Warum 80 ms? Nehmen wir im schlechtesten Fall an, Du erreichst die neue Sensorposition gerade zu Beginn eines angelaufenen Messzyklus - dann wird das Ergebnis dieses Zyklus nicht korrekt sein => also warte knapp 40 ms bis der nächste Zyklus startet. Nun beginnt der Sharp die neue, korrekte Messung - die ist nach weiteren 40 ms fertig. Jetzt bekommt der ADC korrektes Futter . . . .

    Wenns bei mir schnell gehen soll, lasse ich in solchen Fällen den ADC frei laufen, lese den ständig ein und freu mich halt "irgendwann" über einen neuen Messwert. Dieses Verfahren ist aus der Schublade quick&dirty, klar.
    Ciao sagt der JoeamBerg

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    25.03.2006
    Ort
    nahe Tulln (Niederösterreich)
    Alter
    33
    Beiträge
    460
    Danke für die Antworten, ich hab das oben beschriebene mal als "programm" geschrieben:

    Code:
    volatile uint8_t zaehler;
    
    (Interrupt routine)
    zaehler=zaehler+1;  //prescaler so einstellen, dass alle 1ms zaehler erhöht wird
    
    (main)
    ...
    ...
    if(ad-wandlung-fertig-flag==1)
    {    ad-wert speichern;
          setpos(schritte);     //Befehl geben, dass er 50 schritte drehen soll
    }
    else
    {   if(ap==tp)             //wenn aktuelle position==target pos dann weitermachen
         {     if(zähler ist 80 mal erhöht worden)   //ka wie ich das mach
                {    ad-wandlung starten;
                }
         }
    }
    ...
    ...
    Das mit dem ADC immer aktivieren hab ich jetzt nicht gemacht, weil ich sonst nicht weiß wann er fertig ist mit der wandlung, weil wenn ich ihn immer eingeschaltet lasse setzt er das flag ja nicht wenn er fertig ist glaub ich.

    Kann mein "programm" so funktionieren?
    Wie mache ich die Abfrage, ob zaehler 80 mal erhöht worden ist?

    lg christoph

  5. #5
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Code:
    ISR(ADC_vect){			/* Interrupt auslösen wenn ADC-conversion komplett*/
    Messwert=ADC;			 /*Register auslesen, */
    flag.ADC_Mess=1;       /* Flag messen fertig */
    
    }
    ISR(TIMER1_COMPA_vect){		/*Takt 1 mSek*/
    Zähler ++;
    
    }
    
    if(flag.ADC_Mess){
      ADC_Messwert abarbeiten
      }
    
    if(Zähler >=80){
       Mach was
      }
    So könnte das etwa aussehen.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  6. #6
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Einen Zähler bis 80 kann manoft besser rückwärts machen, also von 80 runter bis 0. Der test ist einfach den Wert des Zählers anschauen. Oft ist das auch dann sinnvoll wenn man ohnehin einen andernen Wert jedesmal erhöht.

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von Felix G
    Registriert seit
    29.06.2004
    Ort
    49°32'N 8°40'E
    Alter
    40
    Beiträge
    1.780
    Vielleicht noch zwei Hinweise um die Zuverlässigkeit und die Lesbarkeit des Codes zu verbessern:

    1. Falls man längere Zeiten messen möchte, muss man logischerweise eine größere Timer-Variable nehmen, z.B. 16 oder sogar 32 Bit. Hier können aber Probleme auftauchen, da der AVR mehr als einen Befehl braucht um eine solche Variable zu lesen. In diesem Fall würde ich dringend eine Zugriffsfunktion wie GetTime() oder sowas empfehlen, die den Lesezugriff atomar durchführt (Interrupts aus, Variable lesen, Interrupts wieder an), denn sonst wirst du sicher früher oder später mal über seltsame, sporadisch auftretende Bugs stolpern.

    2. Mach dir doch noch eine Funktion wie TimedOut(Start, End, Timeout) die dir überprüft, ob die gewünschte Zeitspanne bereits abgelaufen ist oder nicht. Das macht den Code noch etwas leichter lesbar, und außerdem muss man so wenger Tippen . Die kann dann auch gleich einen evtl. aufgetretenen Überlauf (Start > End) berücksichtigen (das ist sinnvoll um durch einen Überlauf ausgelöste Bugs zu vermeiden).
    So viele Treppen und so wenig Zeit!

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    25.03.2006
    Ort
    nahe Tulln (Niederösterreich)
    Alter
    33
    Beiträge
    460
    Ich will mir eh noch ein paar funktionen machen, aber ich verstehe die Abfrage noch nicht so richtig.

    Wenn Zähler jetzt eine 8 bit Variable ist, zählt er von 0 bis 255 in 1ms Schritten.

    Wenn der Zähler gerade bei 40 ist, und dann kommt diese If Abfrage

    if(Zähler >=80)
    { Mach was
    }
    Dann wartet er bis der Zähler bei 80 ist, dann wird 255-80=175ms das "mach was" ausgeführt, und dann wieder 80 ms Pause gemacht, usw...

    Wenn ich aber 80ms warten will, dann irgendwas abarbeiten will, was ca. 0,5ms dauert, und dann wieder 80ms warten will, wie soll das gehen?
    Ich weiß ja nicht wie lange das abarbeiten dauert, 0,5ms sind nur geschätzt.

    lg Christoph

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    18.11.2005
    Beiträge
    21
    Hallo Christoph2, ich habe hier interessantes entdeckt ...

    http://www.mikrocontroller.net/topic/132436#new

    Bindet Assemblerroutinen ein!

    Solche Multitaskingprogrammierung, wird unter anderem sehr gut beschrieben von Manfred Schwabel - Schmidt, im Buch „Systemprogrammierung für AVR - Mikrocontroller".

    lg

    albert

  10. #10
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Christoph2
    Die "if" Abfrage wartet nicht, wenn die Abfrage nicht wahr ist, wird nach der geschwungenen Klammer weitergemacht.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

LiTime Speicher und Akkus