- Labornetzteil AliExpress         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 21

Thema: Mechanikanfänger braucht Tipps für den Einstieg am Bsp. Arm

  1. #11
    Benutzer Stammmitglied
    Registriert seit
    11.09.2007
    Ort
    Leipzig
    Alter
    43
    Beiträge
    31
    Anzeige

    Praxistest und DIY Projekte
    Zumindest bewegt er sich schonmal.
    Wenn er das nur alle Jubeljahre einmal richtig macht, würde ich mit meinem Halbwissen vermuten, er resetet den AVR (Spannungseinbruch)

    Hast du testweise mal versucht, den AVR und den Servo aus separaten Stromquellen zu versorgen?
    Oder einen größeren Kondensator an die Versorgungsspannung von Controller o. Servo?

    Edit:
    Zum Thema Gripper gibt es hier auch noch eine einfach zu realisierende Lösung http://www.robotstore.com/store/prod...d=267&catid=11
    ( darf man eigtl. auf kommerz. Seiten verlinken?)

  2. #12
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.08.2006
    Ort
    Budapest
    Alter
    36
    Beiträge
    563
    Beim C Code im RN-Wissen ist diese Zeile meiner Ansicht nach falsch:

    TIMSK|=(1<<TOIE2);

    es sollte nicht der OVF Interrupt enabled werden, sondern der Output Compare Match, also OCIE2.

  3. #13
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.07.2004
    Ort
    Südhessen
    Beiträge
    1.312
    Guten Morgen!

    >Hast du testweise mal versucht, den AVR und den Servo aus separaten Stromquellen zu versorgen?
    Ich habe die Spannungsquelle gewechselt, auf eine bessere. Bei jedem Schubs hat sich die Spannungs-Kontroll-LED kurz verdunkelt. Das macht sie immernoch, aber das bringt dem µC keinen Abbruch.

    >Oder einen größeren Kondensator an die Versorgungsspannung von Controller o. Servo?
    Hab ich auch gemacht, da hängen jetzt zusammen 570 µF. Das ändert aber nichts.

    Ich hab die Software gestern noch weiter bearbeitet, bis ich eine Art Drehung hinbekommen habe, die beweist, dass es möglich ist, und eigentlich nur an meiner Programmierung lag. Er geht ne Schleife durch, die eine PWM erzeugt, wobei der HIGH-Anteil sich verschiebt und wieder zurückgesetzt wird. Der Servo macht also etwa 9-11 merkbare Schritte mit einer Pause, dann dreht er sich blitzschnell zum Ausgang zurück und weiter gehts.
    Ich muss also wohl oder übel doch eine fertig-PWM, oder zumindest einen Timer/IRQ benutzen, da ich gemerkt hab, dass die Servos nur dann gut funktionieren, wenn die Zeiten einigermaßen stimmen.

    Hattest Du nicht gesagt, das Hartpapier lässt sich gut mit einer Laubsäge bearbeiten?
    Herrje, das wird'n Haufen Arbeit. Wie hast du Deine Schnitt so grade bekommen? Spannst Du das Hartpapier irgendwie ein?

    Grüße,
    Wulfi

    PS: @pongi: Danke für den Hinweis, ich hab die Routine vorerst aber eh selbst gebaut, da ich auf ASM setze. Und wenn ich einen Timer oder IRQ benutze, guck ich mir sowieso die Register einzeln an und stelle die Flags selbst zusammen

    Wie kriegt man eigentlich einen gescheiten Timerzyklus hin, damit ich auf 20ms komme?

  4. #14
    Benutzer Stammmitglied
    Registriert seit
    11.09.2007
    Ort
    Leipzig
    Alter
    43
    Beiträge
    31
    Zitat Zitat von thewulf00
    Hattest Du nicht gesagt, das Hartpapier lässt sich gut mit einer Laubsäge bearbeiten?
    Herrje, das wird'n Haufen Arbeit. Wie hast du Deine Schnitt so grade bekommen? Spannst Du das Hartpapier irgendwie ein?
    Gut, das war ein wenig geflunkert. Man bekommt nach ein paar Teilen nen Krampf in der "Festhaltehand"
    Ansonsten mit einer Hand festhalten, mit der anderen halbwegs gerade sägen. Dann jeweils zwei gegenüberliegende Teile in den Schraubstock spannen und mittels Feile den letzten Schliff geben.

    Ist ein wenig Arbeit, aber man sägt ja nun nicht jeden Tag 20 Teile aus. Umso befriedigender ist's dann, wenn mans geschafft hat

    Was den Timer angeht wäre ein Lösungsansatz:
    Timer/Prescaler so wählen, dass man eine möglichst feine Auflösung für die High-Anteile bekommt, dann in der ISR entsprechend nen Zähler laufen lassen und irgendwann den Port tooglen. Nach dem der High-Teil abgearbeitet ist, kann man ja ruhig etwas größer vorladen, so dass die Auflösung gröber wird und zählt dann in der ISR wieder für den Low-Anteil.

    Ob das Sinn macht, steht zur Diskussion. Man muss halt nicht so viel zählen, wenn man die Timezeit ja nach Low o. High anpasst.

  5. #15
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.07.2004
    Ort
    Südhessen
    Beiträge
    1.312
    Ja, so ähnlich mache ich das auch schon, nur ohne Timer. Die Timerauflösung bleibt dann wahrscheinlich. Aber das Problem ist, dass der Timer eine 2er-Potenz als Prescaler bekommt.
    Ist es möglich, eine 20ms-PWM von AVR erzeugen zu lassen?

    Ich halte das Hartpapier nicht fest, sondern presse es fest auf den Tisch, dann kann ich in Ruhe neben dem Tisch sägen und man bekommt keinen Krampf

  6. #16
    Benutzer Stammmitglied
    Registriert seit
    11.09.2007
    Ort
    Leipzig
    Alter
    43
    Beiträge
    31
    Mmh, die Frage verstehe ich nicht ganz.
    Meinst du, ob es möglich ist, einen Interrupt exakt aller 20ms auszulösen?

    Bei nem 12MHz AVR mit 8Bit Timer, würdest du bspw. einfach Prescaler 1024 einstellen und beim Start und jedem Interrupt immer 22 vorladen.
    Damit wird der IRQ aller 19.968ms aufgerufen. Mit einer Zählvariablen in der InterruptServiceRoutine kannst du dir ja dann dein PWM softwareseitig basteln.

    Oder reden wir von Hardware-PWM?
    Da sollte sich das ähnlich lösen lassen. Hab ich bloss noch nie ausprobiert. Einfach immer etwas entsprechend im Zähler vorladen, damit man die Periodenlänge exakt einstellen kann. Beim Hardware-PWM muss man vor dem vorladen jedoch noch die Interrupts sperren ( cli(); )und den Wert in High-Byte und Low-Byte teilen. Danach wieder enablen ( sei(); )

  7. #17
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.07.2004
    Ort
    Südhessen
    Beiträge
    1.312
    Ja, ich meinte Hardware-PWM. Also Register initialisieren, und einen High-Level übergeben, und er macht dann von selbst eine 1:20ms-PWM. Das wäre schön.

    Ich habe gestern mit C ein wenig herumgespielt (bin eigentlich ASM-Freak), und da hab ich dann die fertigen Funktionen _delay_us und _delay_ms genommen. Selbst damit war es noch schwer und die Schritte waren nicht sehr genau, denn ich habe es so programmiert, dass in jedem Schleifendurchlauf der aktuelle Stand per PWM übermittelt wird, und dann alle 100 Durchläufe der Stand verändert wird. Das klappt soweit ganz gut, bis auf zwei Tatsachen:

    - Den ersten Wert muss ich mit _delay_ms einstellen (us geht nicht über 786 hinaus) und da brauch ich dann Kommazahlen (z.B. 1.2 ms) und dann kommt die Fließkommaberechnung mit hinein und das Programm wird größer als alle meine ASM-Programme zusammen. (Es geht zwar noch rein, aber für eine Software-PWM für EINEN Servo, über 4% des 32K-Speichers... Und ja, ich habe Optimierung an.)
    - Bleibt er in einem Stand, wird jedesmal mit den Warteroutinen eine Warteberechnung durchgeführt, so dass er ETWA so lang wartet, wie angegeben, das merkt man, weil er in jedem Schritt um den Sollwert schwankt, d.h. er zittert, während er stehen sollte. Das geht so weit, dass die Katze auf den Tisch springt, um zu sehen, was da so quitscht.

    PS: Wie genau funktioniert das mit dem Vorladen der Interrupts/Timer?

  8. #18
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.08.2006
    Ort
    Budapest
    Alter
    36
    Beiträge
    563
    Im Code im RN-Wissen wirds so gemacht: der Timer wird mit einer Frequenz x betrieben, womit zB alle 1us ein der Zähler einen Schritt weitergeht. Der Compare Match Register wird so gestellt, dass CMPR*Periode = zB 0,01ms sind, also im unseren Fall wäre CMPR=100. Wenn der Wert im Zähler CMPR erreicht, wird ein Interrupt ausgelöst. Mit verschiedenen Frequenzeinstellungen und CMPR Werten kann man also genau ausrechnen, nach welcher Zeit ein Interrupt aktiviert wird.

    In der Interruptroutine werden die Interrupts gezählt, und mit einer Variable verglichen, die die Länge des High-Impulses bestimmt. Willst du 1,2ms, muss dieser Wert 100 sein. Wenn die Zählvariable zwischen 0 u. High-Impuls Länge liegt, wird ein Pin auf High gesetzt, ist es größer als die High-Impuls Länge, wird es auf 0 gesetzt. Willst Du eine Periodendauer von insgesamt 20ms, wird die Zählvariable im Interrupt auf 0 gesetzt, falls es 2000 überschreitet, und das ganze fängt von vorn an.

    Wars einigermassen vertsändlich?

    Noch etwas, damit ersparst du die floats, du brauchst nur einen uint16, und sonst nur uint8.

    MfG

    pongi

  9. #19
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.07.2004
    Ort
    Südhessen
    Beiträge
    1.312
    Jepp, danke Pongi.
    Ich habe dieses Beispiel als erstes benutzt, bevor ich auf delay_* umstieg, aber da das auf 10ms eingestellt war, habe ich dann die Interrupt-Zählung ausgeschaltet und die Interrupts selbst haben den timer_10ms dekrementiert. Da hats dann aber trotzdem noch gezittert.
    Und wenn ich einen Servo sehr "smooth", d.h. weich und geschmeidig, in beliebigen langsamen Geschwindigkeiten bewegen will, müssten doch eigentlich meine Schritte unendlich klein und die Zeit dazwischen auch unendlich klein werden, richtig?
    Weil bisher ist es ja so, dass ich viele Schritte mit kleinen Zeiträumen mache und er "springt" zu einem Schritt, wartet ne Miniweile und "springt" weiter, wenn ich das mit einem Roboterarm machen würde, dann würde das ganze Gestell pervers klappern und zittern, weil er ja sehr viele, sehr kleine, sehr ruckartige Bewegungen macht.
    Wie stellt man das ab?

  10. #20
    Benutzer Stammmitglied
    Registriert seit
    11.09.2007
    Ort
    Leipzig
    Alter
    43
    Beiträge
    31
    Mit dem vorladen funktioniert das prinzipiell, am Beispiel des 8Bit Timers erklärt, so:
    12MHz, 8Bit, Prescaler 1024 -> zählt von 0..255 und löst Interrupt aus. Für die 255 Ticks benötigt er insgesamt 21.8453ms. Lädst du nun jedoch bei jedem Interrupt gleich 22 vor, zählt er nur noch 233 Ticks, was 19.968ms dauert.

    Vorladen beim 8Bit Timer0:
    Code:
    ISR(TIMER0_OVF_vect)
    {
        /* preload counter */
        TCNT0 = 22; // toogle breakpoint here to verify correct timings
    
        /* code here */
    }
    Mit Timer1/2 im Hardware PWM sollte man da ähnliches basteln können. Eventuell gibt es da auch noch eine elegantere Möglichkeit, aber soweit hab ich mich nie mit PWM befasst.
    Hat bis jetzt immer ohne irgendwelche Verrenkungen geklappt (Meine Servos laufen auch ganz normal mit einer Periode von 21.7ms, die mir der PWM-Mode ausspuckt).

    Was du gerade mit delay() treibst kann ich nicht ganz nachvollziehen. Aber m.E. macht man es doch so, in einer Schleife 12 mal _delay_us(100) aufzurufen, um auf 1.2ms zu kommen. Wenn man denn delays nutzen will...

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

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

Solar Speicher und Akkus Tests