-         

Seite 1 von 5 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 46

Thema: "Vereinfachung" von radbruchs Servoansteuerung mög

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    15.12.2007
    Ort
    Salching
    Alter
    26
    Beiträge
    46

    "Vereinfachung" von radbruchs Servoansteuerung mög

    Anzeige

    hallo asurogemeinde,
    ich habe diesen http://www.roboternetz.de/phpBB2/viewtopic.php?t=29902
    tread von radbruch gelesen und finde die idee ziemlich genial

    Da ich an meinem asuro gerne einen greifer mit zwei Servos (fürs erste langt auch einer ) anbauen möchte, ich aber keine Fotodiode daheimhabe, wollte ich einfach mal fragen obs auch so gehen würde (siehe anhang) !??
    Wenn das ginge, welchen widerstand bräuchte ich dann, bzw. was müsste ich an der schaltung sonst noch ändern ??
    ich hab leider keine wirkliche ahnung von elektronic, deshalb bitte nicht wundern wenn die frage dem einen oder anderen profi ein bisschen anfängermässig erscheint !!

    Könnte man auf eine ähnliche weise evtl. auch eine ansteuerung für einen zweiten servo bauen (mit den beiden V+ pins von con1 und con2 an der basis des transistors ? ) ??

    also schon mal danke für die antworten

    mfg Felix


    P.S.: Warum kann man Bitmaps eigentlich nicht direkt anhängen ??????
    Angehängte Dateien Angehängte Dateien
    Wer Rechtschreibfehler findet, darf sie behalten !!

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

    Das war ja eine meiner Jugendsünden. Die galvanische Trennung entstand weil ich nicht auf dem asuro rumbruzeln wollte.

    Selbstverständlich kann man die Servos auch an das asuro-Bordnetz anschliesen und das Signal direkt von einem Pin abgreifen. Obwohl ich dabei gewöhnlich keine Schutzwiderstände in den Signalleitungen verwende können ca. 470-1k nicht schaden.

    CON1 ist dabei sehr ungünstig weil es ausgerechnet der Anschluss der IR-LED ist. An PB3 liegt möglicherweise immer der 36kHz-IR-Takt den man erst ausschalten müsste. Damit legt man dann aber auch das IR-Senden lahm. Zudem muss man beim Flashen das Servo trennen sonst zuckt es wild.

    Die Pins PC2+3 der Liniensensoren würden sich vielleicht besser eignen. Wenn dein geplanter Greiferasuro keiner Linie folgen soll könntest du die Fototransistoren (T9+10) auslöten und durch Buchsenleisten ersetzen. Dann kannst du wahlweise die Liniensensoren oder die Steuerleitungen der Servos anstöpseln. Mit gesockelter D11 wäre Platz für einen dritten Servo. (Mit WireWrap-Buchsen ist das der Umbau für das US-Modul/Snakevision) Eine weitere Möglichkeit wäre die Servos mit PD2/PB0 anzusteuern, das ist die StatusLED...

    Viel Spaß und Erfolg

    mic

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

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    15.12.2007
    Ort
    Salching
    Alter
    26
    Beiträge
    46
    hi danke für die schnelle antwort :-D

    ich hatte die linienfolgeteile nie eingelötet, sondern gleich buchsenleisten ( (kein wirewrap ) eingebaut (ich hab dann die bauteilebeinchen entsprechend gebogen und habab sie dann auf der oberseite eingesteckt) !
    funktioniert wunderbar :-D

    wenn ich dich richtig vertehe meinst du also ich bräuchte den transistor gar nicht ?
    wo soll dann der widerstand hin ? in die pwm leitung ?

    kann ich dann wenn ich die signalleitungen an PC 2 und PC 3 hänge also 2 Servos ansteuern ?

    Danke für den tipp mit der IR-Sendediode gottseidank hab ichs nicht so gebaut :-p
    Ich möchte nämlich deine IR-Hinderniserkennung (die mit dem spiegel ),
    die ebenfalls bestens funktioniert, zusammen mit dem greifer verwenden !

    Wie ist das dann eigentlich bei deiner lösung ?
    da erzeugst du das pwm signal doch auch über den frontled ausgang oder?
    ich dachte eigl mal gelesen zu haben dass man leds mit einer so schnellen frequenz gar nicht schalten kann ??!! *verwirrt bin *

    danke für die antworten
    mfg Felix
    Wer Rechtschreibfehler findet, darf sie behalten !!

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

    wenn ich dich richtig vertehe meinst du also ich bräuchte den transistor gar nicht?
    wo soll dann der widerstand hin ? in die pwm leitung ?
    Der Transistor ist nicht nötig. Der Widerstand soll in die Signalleitung und schützt den Kontrollerpin bei einem Kurzschluss in der Signalleitung. Der Wert sollte den Strom bei einem Kurzschluss auf <20mA begrenzen.

    kann ich dann wenn ich die signalleitungen an PC 2 und PC 3 hänge also 2 Servos ansteuern?
    Ja.

    da erzeugst du das pwm signal doch auch über den frontled ausgang oder?
    ich dachte eigl mal gelesen zu haben dass man leds mit einer so schnellen frequenz gar nicht schalten kann ??!!
    Die optische Ansteuerung mit Fototransistor funktioniert an allen LEDs. Das ist doch nicht schnell! Die IR-LED wird z.B. mit 36kHz angesteuert.

    btw: Du plenkst und ein Satzzeichen reicht !?!!

    Gruß

    mic

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

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    15.12.2007
    Ort
    Salching
    Alter
    26
    Beiträge
    46
    hi,
    danke für deine hilfreichen antworten!

    ich werde mir das jetzt dann gleich mal aufbauen und hoffe dass das dann funktioniert

    nur zu meinem verständnis: ein PWM signal besteht doch immer aus 1-2ms strom und anschließend 10-20ms pause sehe ich das richtig?
    des wären dann max. ca. 90Hz und da dachte ich halt da es ja heißt, dass ne LED ca. 5 sekunden braucht um richtig an bzw. aus zu sein dass des viel zu schnell wär ?!
    vieleicht könntest du mir das mal erklären

    Plenke ich etz immer noch ? (danke für den hinweis)
    mfg Felix
    Wer Rechtschreibfehler findet, darf sie behalten !!

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

    ein PWM signal besteht doch immer aus 1-2ms strom und anschließend 10-20ms pause sehe ich das richtig?
    Fast richtig. Alle 20ms ein Impuls von 1-2ms Dauer wäre richtiger. Es dürfen auch mehr oder weniger als 20ms sein, grössere Werte machen das Servo meist träger.

    des wären dann max. ca. 90Hz und da dachte ich halt da es ja heißt, dass ne LED ca. 5 sekunden braucht um richtig an bzw. aus zu sein
    Bei 1 Sek. (1000ms) durch 20ms pro Impuls komme ich auf genau 50Hz. Diesen Takt schaffen sogar noch Glühlampen -> Stroboskopeffekt bei Plattenspielern mit Strichmarkierungen zur Geschwindigkeitseinstellung.

    Die Zeit die eine LED braucht um volle Helligkeit zu erlangen oder wieder ganz dunkel zu sein kann man möglicherweise im Datenblatt der jeweiligen LED finden. Die maximalen Frequenzen liegen vermutlich im 3-stelligen kHz-Bereich! (z.B. sendet eine normale rote 3mm-LED ohne Probleme Daten mit 36kHz-Trägerfrequenz)

    Gruß

    mic

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

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    15.12.2007
    Ort
    Salching
    Alter
    26
    Beiträge
    46
    ok vielen dank,
    man lernt ja nie aus :-D
    eine frage hätte ich aber noch:
    wie müsste so ungefähr der code aussehn z.B. um beide Servos ganz nach links/rechts zu schwenken?

    ich habe etz nämlich mal die schaltung gebaut
    so wie du sagtest mit je signalleitung einem 470 Ohm wiederstand + und - parallel an OUT + und OUT - und die signalleitungen an PC 2 und PC3.

    da ich bisher nur mit den funktionen aus der lib gearbeitet hab es dafür etz aber keine gibt fäll mir des a bissl schwer

    wär also nett wenn mir da jemand auf die sprünge helfen könnte !

    ABER: schreibt mir bitte keine fertigen programme ich will ja schliesslich was dabei lernen :-P

    vielen dank nochmal an alle die sich so mit mir abmühen, vor allem dir natürlich radbruch !

    mfg Felix
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken pb090127.jpg   pb090126.jpg  
    Wer Rechtschreibfehler findet, darf sie behalten !!

  8. #8
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.782
    Blog-Einträge
    8
    wie müsste so ungefähr der code aussehn z.B. um beide Servos ganz nach links/rechts zu schwenken?
    Es gibt einige unterschiedliche Konzepte zur Servoansteuerung. Ich versuche mal die gebräuchlichsten zu erklären (soweit ich es selbst kapiert habe) Grundsätzlich muss man zwischen blockierend und nicht blockierend unterscheiden.

    Bei blockierender Ansteuerung kann der Kontroller während der Impulserzeugung keine anderen Tätigkeiten ausführen, selbst Interrupts sollten gesperrt sein um ein Zittern der Servos zu unterdrücken. Diese Art der Ansteuerung ist einfach umzusetzen und hat wenig Seiteneffekte. Die Impuls-und Pausenlängen erzeugt man dabei z.B. mit Zählschleifen. Oder wie im folgenden Beispiel für den asuro (für die BackLEDs!) mit Sleep():
    Code:
    #include "asuro.h"
    
    unsigned char i, servo_stellzeit;
    
    void servo(unsigned char winkel){
    unsigned int count=0;
    do{
    	count++;
    	BackLED(ON,OFF);
    	FrontLED(ON);
    	Sleep(winkel);
    	BackLED(OFF,ON);
    	FrontLED(OFF);
    	Sleep(255); Sleep(255); Sleep(255);
    }while (count<servo_stellzeit);
    }
    
    int main(void) {
    
    Init();
    StatusLED(OFF);
    do{
    servo_stellzeit=35;
    servo(51);
    servo(90);
    servo(51);
    servo(15);
    servo_stellzeit=2;
    for (i=15; i<88; i+=2) servo(i);
    for (i=90; i>17; i-=2) servo(i);
    }while (1);
    return 0;
    }
    (Ich weiß, oben schreibe ich möglichst ohne Interrupts, aber weil's mit Sleep() so einfach und überschaubar funktioniert wollte ich das auch mal zeigen.)

    Anstelle der BackLED()-Funktionen muss man die Ausgänge der gewählten Pins selbst ansteuern. Es müssen zuerst die Pins auf Ausgang geschaltet werden. Dazu schreibt man in das entsprechende Datenrichtungsregister eine 1, am Beispiel von PC2/3 könnte das so aussehen:

    DDRC |= 0b00001100; // Die Zählung beginnt mit PC0 ganz rechts!

    Das |= ändert nur die beiden in der Maske gesetzten Bits. Bei = würden zusätzlich alle anderen Pins auf Eingang geschaltet werden. Nun kann man mit

    PORTC |= 0b00000100; // den Pin PC2 high (5V, 1, ein, aktiv...) schalten

    oder mit

    PORTC &= ~0b00000100; // wieder ausschalten.

    Die Tilde ~ negiert die angegebene Maske (Einerkomplement), das &= löscht nur die Bits die in der negierten Maske den Wert 0 haben.

    /*Nur für Interessierte:

    Alternative mit shift-Operatoren

    Wie man den Wert der Maske angibt ist übrigens völlig egal und jeder kann die Form wählen die ihm am besten zusagt. Bei den Portzugriffen sorgen shift-Operatoren für besseren Überblick:

    PORTC |= (1<<PC3); // setzt z.B. den Ausgang PC3.

    Dazu muss man wissen, dass PC3 ein #define ist und vom Präprozessor (vor dem Kopilieren) durch 3 ersetzt wird(->io.h). Und so funktionert es: Die 1 wird in der Maske ganz rechts eingetragen (0b00000001) und anschliessend um die Anzahl der Stellen in <<PC3 nach links verschoben. Das Ergebniss ist also 0b00001000. Wenn man nun noch mehrere Pins zusammenfasst wird es richtig übersichtlich:

    PORTC &= ~((1<<PC3) | (1<<PC2));
    */

    Bei der Ansteuerung der Servos muss man noch beachten, dass ein Servo nicht schlagartig auf einer neuen Postion steht wenn man die Impulslänge ändert. Vielmehr braucht es abhängig von der Größe der Positionsänderung eine gewisse Zeit während der man die Impulse wiederholen muss. Das erledigt im meinem Beispielprogramm oben die Variable stellzeit.

    Noch kurz ein Ausblick auf nichtblockierende Ansteuerungen:

    - Eine Interruptserviceroutine wird regelmässig über einen Timerinterrupt aufgerufen. Schöne Werte ergeben sich dabei wenn man die ISR alle 100µs aufrufen läßt, denn wenn man in dieser ISR eine Variable hochzählt vergeht dann genau 1 ms bis der Zähler 100 erreicht, 20ms erreicht man dann nach 2000 Aufrufen. Damit wäre dann auch eine Impuls/Pause-Periode beendet und man kann von vorne beginnen indem man den Zähler wieder mit 0 läd. Diese Methode ist auch im RN-Wiki (Servos) beschrieben. Mit der Anzahl der Servos steigt allerdings der Rechenaufwand beim Vergleich der einzelnen Servopositionen mit dem aktuellen Stand der Zählvariablen. Außerdem werden durch den gleichzeitigen Start der Impulse alle Servos gleichzeitig gestartet was hohe Einschaltsummenströme erzeugt. Dies kann man zwar durch eine pfiffige Programmierung der ISR umgehen, aber dadurch steigt der Rechenaufwand noch mehr.

    - Eine weitere, deutlich resourcenschonendere Methode (die ich selbst noch nicht versucht habe): Die Signalleitung des Servos wird eingeschaltet und ein Timer wird so konfiguriert und gestartet dass er (einmalig!) nach der gewünschten Impulslänge eine ISR aufruft. In der ISR wird der Ausgang wieder ausgeschaltet und der Timer dann so umkonfiguriert dass nach ca. 20ms ein zweiter Interrupt ausgelöst wird. Dann wieder Ausgang setzen und Timer auf Impulslänge konfigurieren uswusw. Das funktioniert natürlich auch mit mehreren Servos die dann auch schön nacheinander starten weil die Impulse nacheinander erzeugt werden. Wenn bei mehreren Servos alle Impulse an die Servos gesendet wurden wird die zu 20ms fehlende Zeit mit einem Dummyservo vertrödelt. Ächz.

    Gruß

    mic

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

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    15.12.2007
    Ort
    Salching
    Alter
    26
    Beiträge
    46
    hallo,
    das war jetzt mal sehr viel neues auf einmal!
    ich versuche das, was ich glaube zu verstehen, mal zusammenzufassen
    wenn ich also einen der beiden Servos benutzten möchte schalte ich mit

    DDRC |= 0b00001100; pinns pc2 und pc3 an

    dann setze ich ihn auf high und schalte den servo ein mit

    PORTC |= 0b00000100; bei PC 2 und PORTC |= 0b00001000; bei PC 3

    oder ich mach beides in einem schritt : PORTC |=((1<<PC3)|(1<<PC2));
    // beide Servos an und auf high - richtig ?

    wenn ichs wieder ausschalten will ersetze ich einfach das |= durch &=~
    oder?

    Das war allerdings erstmal alles, was ich glaube wirklich verstanden zu habe :-P

    wie mach ich das jetzt genau mit der for-schleife und dem COUNTER??
    und was ist eine "Interruptserviceroutine" und ein "Timerinterrupt"?

    mit solchen sachen hab ich bisher noch nicht gearbeitet, kenn mich da also kein bisschen aus!

    mfg Felix
    Wer Rechtschreibfehler findet, darf sie behalten !!

  10. #10
    Erfahrener Benutzer Roboter Genie Avatar von pinsel120866
    Registriert seit
    18.12.2007
    Ort
    Hohenems
    Alter
    51
    Beiträge
    847
    Hallo,

    es müsste doch auch möglich sein beide Servos auf einen PIN zu nehmen nachdem beide Servos gleichzeitig Synchrone Bewegungen ausführen, oder liege ich da falsch?

Seite 1 von 5 123 ... LetzteLetzte

Berechtigungen

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