- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 14 von 14

Thema: blockierende funktionen ausschalten

  1. #11
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    09.04.2008
    Beiträge
    384
    Anzeige

    E-Bike
    Versuch erst mal die Fahr-Auftrage ohne Greifer Function Functionieren zu lassen. Einfach in haupt Schleife taskServo weglassen. Bleibt dan den RP6 stehen wen die Eingang von Sensor hoch ist ?
    So ja, dan hangt das ab von diese taskServo. Wahrscheinlich bleibt er dan in eine While Schleife ewig hangen.
    Functioniert diesen taskServo eigentlich zwei mal nach ein ander ? Sensor ist hoch, Greifer lauft, Sensor ist aus, Greifer steht. Sensor wieder hoch, Greifer lauft wieder.
    Bei SW Problemen muss men immer Schritt pro Schritt weiter gehen. Nicht zu fiel zusammen aendern. Moglich so programmieren das Functionen unabhangig voneinander laufen. Diese While Schleifen sind dan nicht der richtige Weg.

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

    Am Ende von task_TeilErkannt() wird z=0 gesetzt, das bedeutet für task_fahren() dann natürlich fahren:

    void task_fahren(void)
    {if(z==0)
    {
    moveAtSpeed(50,50);
    writeString_P("Fahren\n");}
    .....

    Das z=0 sollte wohl besser im else-Zweig sein und die 5 Schlafsekunden würde ich ersatzlos streichen weil er dann 5 Sekunden weiterdüst obwohl das hinderniss erkannt wurde? Fehlt hier nicht noch ein MoveAtSpeed():

    powerON();
    changeDirection(BWD);
    task_TeilErkannt();

    Vermutlich wäre es so richtiger:

    powerON();
    changeDirection(BWD);

    while(true)
    {task_servo();
    task_TeilErkannt();
    task_fahren();
    task_RP6System();
    }

    Gruß

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

  3. #13
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    37
    Beiträge
    220
    ich habe jetzt das ganze programm nochmal gründlich überarbeitet.
    das task_TeilErkannt(); habe ich jetzt im main teil in die while(true) schleife verschoben.


    Code:
    #include "RP6RobotBaseLib.h"
    
    uint8_t i;
    uint8_t a;
    uint8_t n;
    uint8_t p;
    uint8_t z;
    
    void task_teil_erkannt(void)
    {if(PINA & (1<<4))
    	{z=1;
    writeString_P("Teil erkannt\n");}
    
    if(z==1)
    	{startStopwatch1();}
    
    if(getStopwatch1()>3000)
    	{z=0;
    	setStopwatch1(0);}
    }
    
    
    
    
    void task_servo(void)
    {
    
    if(PINA & (1<<4)) // Greifer schließen 
    {
    while(i<52)
    {
    writeString_P("Greifer schließen\n");
    PORTC |=(1<<0);
    mSleep(1);
    PORTC &=~ (1<<0);
    mSleep(19);
    p=0;
    i++;}
    }
    
    
    if(i>50)	// Schwenkarm nach oben
    {
    while(a<52)
    {
    writeString_P("Schwenkarm nach oben\n");
    PORTC |=(1<<1); 
    mSleep(2);
    PORTC &=~ (1<<1);
    mSleep(18);
    i=0;
    a++;}
    }
    
    
    if(a>50) // Greifer öffnen                                      
    {
    while(n<40)
    {
    writeString_P("Greifer öffnen\n");
    PORTC |=(1<<0);
    mSleep(2);
    PORTC &=~ (1<<0);
    mSleep(18);
    setStopwatch1(0);
    a=0;
    n++;}
    
    }
    
    if(n>38) //Schwenkarm wieder nach unten
    {
    while(p<20)
    {
    writeString_P("Schwenkarm wieder nach unten\n");
    PORTC |=(1<<1);
    mSleep(1);
    PORTC &=~ (1<<1);
    mSleep(19);
    n=0;
    p++;}
    }
    
    }
    
    void task_fahren(void)
    {if(z==1)
    	{
    	moveAtSpeed(0,0);
    	writeString_P("Nicht Fahren\n");}
    else if(z==0)
    	{moveAtSpeed(50,50);
    	writeString_P("Fahren\n");}
    
    }
    
    
    int main(void)
    {
    initRobotBase();
    
    DDRC |=(1<<1);		//PORT 1 von Register C als Ausgang für Servo
    DDRC |= (1<<0);	//PORT 0 von Register C als Ausgang für Servo
    DDRA &=~ (1<<4);	//PORT 4 von Register A als Eingang für Reflexkoppler
    
    powerON(); 
    changeDirection(BWD);
    
    
    
    
    
    while(true)
    {task_servo();
    task_teil_erkannt();
    task_fahren();
    task_RP6System();
    }
    return 0;
    }












    aber das alte problem besteht immer noch.
    der roboter ignoriert den task_teil_erkannt() teil komplett.

    die textmeldung "teil erkannt wird nie" ausgegeben.

    nur die Servos bewegen sich korrekt.

    irgendwie wird das alles durch die servo schleifen blockiert.

    ich kann mir das nicht erklären.....

  4. #14
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hallo proevofreak,
    irgendwie wird das alles durch die servo schleifen blockiert.
    Ja, genau. Und auch noch auf 2 Arten:
    1. Die eigentliche Impulserzeugung und Impulswiederholung alle 20ms ist mit den Sleep-Befehlen voll blockierend.
    2. Du erzeugst die Bewegung des Greiferarms ebenfalls voll blockierend mit While-Schleifen.

    Lösung zu 1:
    In diesem Thread stehen Links zu vielen Möglichkeiten, die Impulserzeugung für Servos nicht vollständig blockierend zu machen:
    https://www.roboternetz.de/phpBB2/viewtopic.php?t=45790

    Lösung zu 2:
    Da die Bewegungen des Arms auch Zeit brauchen, würde ich sie nicht in Schleifen abarbeiten, sondern auch in einer Task laufen lassen. Das bedeutet, dass du die Bewegungen mit einer Stopwatch so steuerst, dass z.B. alle 40ms den Servos eine neue Position gegeben wird. Danach wird die Hauptschleife in Main jeweils wieder ausgeführt.

    Am Ende sieht deine Main dann so aus:
    while(true)
    {task_SERVO();
    task_teil_erkennen();
    task_teil_greifen();
    task_fahren();
    task_RP6System();
    }
    Wichtig ist, dass ALLE Tasks (auch die task_teil_greifen) nur so kurz wie möglich sind und die Kontrolle immer rasch wieder an die Hauptschleife abgeben. Das Verhalten der Tasks kannst du mit globalen Flags steuern: Wenn er gerade ein Teil greift, wird z.B. in der task_teil_greifen ein Flag auf true gesetzt, das in der task_fahren benutzt wird, um den RP6 zu stoppen.

    Viel Erfolg!

    Gruß Dirk

Seite 2 von 2 ErsteErste 12

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress