PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Servosteuerung und STK500



raoul.m@gmx.ch
10.12.2006, 02:18
Hallo STK 500-Freaks

Könnt ihr mir einen Ansatz geben, wie ich (für den Anfang mal) einen Servo über ASM ansprechen kann? Reicht ein Servo aus dem Modellbauladen gegenüber? Wie muss ich den Servo auf dem STK verkabeln? Muss man einen Servo konstant bedienen (Loop) oder reicht eine Adressübergabe und der bleibt in dem definierten Winkel? Brauche ich zusätzliche Speisung oder kann das STK das liefern (auch in Hinblick auf später 4 Servos - Wenn nein, speise ich den Saft übers STK oder über einen externen Adapter)? Kann ich überhaupt einen Servo direkt am STK anschliessen oder braucht es was dazwischen? Wenn ja: eine Lochrasterplatine kann ich bestücken, wenn ich weiss, was wie drauf muss. Wenn nein: Puh, schwein gehabt! Bin Windoof-Entwickler und habe keine Ahnung von Volt, mA usw, geschweige denn von Schaltungen oder so. Aber ich werds hinkriegen - bin ein C64-Freak und mit dem hab ich ja auch schon einiges angestellt :-)

Für alle Anleitungen, Codebeispiele oder sonstigen Hinweise bin ich überdankbar und freue mich, meine Fortschritte in diesem Forum posten zu können.

Viele Grüsse
Raoul

JonnyP
10.12.2006, 10:32
Mit dem STK500 programmiert man microcontroller und testet daran hängende Schaltungen. Es ist kurz vor Weihnachten, daher sind Glaskugeln out. Wie sollen wir wissen, was du verbauen willst. Servos gibt es etliche. Wenn du hier Antworten haben möchtest, dann poste hier die Daten der Geräte, die du verwenden willst, dann kann man dir auch sagen ob du Interface Bausteine brauchst, oder nicht. Lieber eine Zahl zu viel als 2 zu wenig, denn wenn man jede Ziffer nachfragen muß, dann nervt das nicht nur, es dauert auch länger.

Manf
10.12.2006, 11:12
Hier haben wir eine kleine Darstellung über Servos, über die Controller steht im dem Bereich auch einiges.
Manfred

https://www.roboternetz.de/wissen/index.php/Servo

raoul.m@gmx.ch
10.12.2006, 23:00
Ich möchte nichts konkretes realisieren. Servos sind einfach interessanter als LEDs und das wäre für mich mein erstes kleines Elektronik-Projekt. Ich bitte um Verständnis für meine Unwissenheit.

@JonnyP: Ich wollte Dich auf keinen Fall nerven, nur habe ich noch keine Geräte, die ich anschliessen möchte. Das STK (mit AT90S8515-Controller) und meine Neugierde sind im Moment meine Ausgangslage. Vielleicht hast Du mir eine Empfehlung, was für ein Servo-Typ sich einfach und ohne sonstige Infrastruktur verwenden lassen würde?

@Manf: Danke für den Link, ich habe auch noch ein Code-Beispiel gefunden:

/* servo ist angeschlossen an PB0 */
sbi(PORTB, PB0); /* high */

/* eine gewisse zeit nichts tun,
* entweder ausrechnen oder experimentell ermitteln
*/
for(delay=0;delay<servo_value;delay++) {
asm("nop"); /* nichts tun */
}

cbi(PORTB,PB0); /* low */

Quelle: http://scriptkiller.de/avr_sharp_3d_scanner.php

Laienhaft schliesse ich daraus, dass ich ein Signal auf einem Portpin setzen, warten und wieder löschen muss. Die Wartezeit definiert den Winkel. Ich muss noch rausfinden, wie man Interrupts programmiert, aber wenn man den Code in einem simplen Loop wiederholen würde, müsste ich am Schluss vermutlich noch eine NOP-Schlaufe anhängen, welche 20ms wartet, um den 20ms-Intervall zu generieren? Nicht sehr fein, aber ist ja auch nur zum Verständnis.

Nochmals zur physischen Seite: Wie schliesse ich einen Servo auf dem STK an. Servos haben nach meinen neuesten Kenntnissen (danke Manf) 3 Anschlüsse (+5V/GND und den effektiven Signalanschluss (PWM)). Wo ich das Signal anschliessen muss, weiss ich jetzt: PortX/PinX (z.B. PORTB, PB0). Woher kriege ich die +5V? kann mir das STK das liefern? GND werd ich wohl noch irgendwo auf dem Board finden.

Danke für Eure unendliche Geduld und viele Grüsse, Raoul

izaseba
10.12.2006, 23:19
Woher kriege ich die +5V?

Mit STK500 hast Du Dir was sehr gutes angeschafft, schau Dir die Platine doch genau an, Bei allen Pinheads hast Du ganz unten zwei Anschlüsse GND u. VTG wenn Du jetzt Dein VTarget auf 5V einstellst (AVR STUDIO) kannst Du da die 5V anzapfen...
Ich hatte problemlos 4 Servos gleichzeitig an STK500 angeschlossen, von da aus sehe ich da keine Probleme...
Dein Codebeispiel ist schon etwas älter sbi und cbi gibt es bei avr-gcc IMHO nicht mehr :-k dafür solltest Du C pur benutzen
PORTB |= (1<<PB0);
um den Pin HIGH zu schalten, und
PORTB &=~(1<<PB0);
um den LOW zu schalten,
seh Dich hier im Forum was um, Beispiele gibt es genug...

Gruß Sebastian

Manf
10.12.2006, 23:29
Als Einstiegs-Servo sind die "Conrad 5€ Servos" zu empfehlen. Sie arbeiten wie die meisten einfachen Modellbauservos und sind eben nicht sehr teuer.
Manfred

https://www.roboternetz.de/wissen/index.php/Bezugsquellen

JonnyP
11.12.2006, 19:53
@ raoul.m
Hallo mein Guter, du nervst mich nicht (ich würde dann nicht mehr antworten). Es sollte nur der Hinweis sein, gleich mit allen Fakten rüber zu kommen. Klapper hier mal das Forum ab und du weisst was ich meine. Es werden ein paar Insider Sätze ins Forum geworfen und manche Leute erwarten, das jeder erkennt, was sie bei sich auf dem Tisch liegen haben.

Izaseba und Manf haben schon alles wichtige gesagt.
Ein Tip vielleicht noch zu den Steckanschlüssen auf den STK500: Ich habe mir von Schrott-PC´s die LED-und Tasterkabel mit ihren Flachanschlüssen herausgeholt, die kann ich prima für Peripherie am STK verwenden.

raoul.m@gmx.ch
15.12.2006, 00:49
@Manf: Danke für Deine Empfehlung. Ich schloss daraus, dass das Servo keine speziellen Bedingungen erfüllen muss und habe mir das billigste Servo von einem Modellbauladen besorgt. Conrad wäre inkl. Versand nur unwesentlich günstiger gewesen.

@izaseba: Mit einem Satz alles erklärt :-) Danke sehr. Ich habe rot auf VTG, schwarz auf GND und gelb (Signal) auf PB0 gestöpselt und schön mit den Servokabeln verzwirbelt und mit Klebstreifen gesichert. Da hab ich sogar Einzel-Pin-Abnehmer mit passenden Kabeln und so gekauft, aber das Lötzinn vergessen (*schäm*).

Aber anyway - bin eh noch nicht so weit. Irgendwas an meinem Code funzt noch nicht so recht. Ich befinde mich im Moment im AVR-Simulator und habe ein Programm geschrieben, das den 'Funktionstest' vornehmen soll, nämlich schlicht und einfach das Servo in die mittlere Position stellen, sonst nichts. Also: Pin0 auf PortB einschalten (1.5ms warten), ausschalten (20ms warten) und von vorne. Das Timing hab ich aus der Servo-Seite von Manf.

Hier der Code:

;***** STK500 Servo in mittlere Position bringen
;************************************************* *********
.include "8515def.inc" ; Definitionen für AT90S8515
rjmp RESET ; Reset Handle
;************************************************* *********
.def temp =r16 ; Temporary register
RESET:
ser temp ; ???
out DDRB,temp ; Set PORTB to output
LOOP:
out PORTB,temp ; Update Port
sbi PORTB, PB0 ; Setze PortB, Pin0
rcall WAITPOS ; warte 1-2ms (Servo-Position)
cbi PORTB, PB0 ; Lösche PortB, Pin0
rcall WAITREP ; warte 20ms (Repetition-Periode)
rjmp LOOP ; usw usf

;************************************************* *********
; Subroutinen (später mal auf 4Mhz anpassen)
;************************************************* *********
WAITPOS:
ldi ZH, HIGH(1500) ; setze höheres Z-Byte
ldi ZL, LOW(1500) ; setze niedriges Z-Byte
LOOPPOS:
sbiw ZL, 1 ; decrementiere Z
brne LOOPPOS ; loop bis Z=0
ret ; und tschüss

WAITREP: ; dito WAITPOS
ldi ZH, HIGH(20000)
ldi ZL, LOW(20000)
LOOPREP:
sbiw ZL, 1
brne LOOPREP
ret


Wenn ich mit F10 durchsteppe, loopt das immer nur hier durch:
sbi PORTB, PB0 ; Setze PortB, Pin0
rcall WAITPOS ; warte 1-2ms (Servo-Position)
Zu
cbi PORTB, PB0 ; Lösche PortB, Pin0
usw. kommt er gar nie...hmmm

Was mache ich falsch?

Ach und ja: Ich weiss, dass das nicht die optimale Lösung ist (Polling und so) aber ich möchte den Weg vorerst mal in diese Richtung weiter beschreiten. Zuerst mal solls übersichtlich bleiben.

Herzlichen Dank für Eure Unterstützung und viele Grüsse
Raoul

izaseba
15.12.2006, 01:03
Abend,
sieht ja garnicht so schlecht aus...
nur wo setzt Du den Stackpointer ?
Schau mal hier rein (http://www.izaseba.roboterbastler.de/index.php?popup=Tutorial&section=Lektion8), ich denke an dem Fehlendem Stackpointer dürfte es liegen :-k

Gute Nacht

Gruß Sebastian

JonnyP
15.12.2006, 17:32
Ich denke du solltest bei "Reset" erst mal den Stack initialisieren, sonst gibt es kein ret.
; STACK initialisieren
ldi temp, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse
out SPL, temp
ldi temp, HIGH(RAMEND) ; HIGH-Byte der obersten RAM-Adresse
out SPH, temp

raoul.m@gmx.ch
16.12.2006, 03:23
@izaseba: jahaaa!!! In jedem Anfänger-Manual oben links auf der ersten Seite :-) Ich hab mich auch an Deinem Beispiel orientiert: http://www.izaseba.roboterbastler.de/index.php?popup=Tutorial&section=Lektion8 Das stammt doch von Dir, oder? Vielen Dank!

@JonnyP: brauch ich das HIGH-Byte für mein simples Vorhaben?

Wie auch immer - hey Leute, die Erde ist rund und es funktioniert!!! Ich hab mir jetzt sogar Lötzinn organisiert und die Käbelchen an meine Pin-Abnehmer gelötet. Aber mal im Ernst. Diese Abnehmer, die ich da habe, die sind ja wohl ein Witz... Die haben schön die Aussparung, damit ich sie auf den Platinenpin aufstöpseln kann, aber am anderen Ende kommt wieder ein Pin raus. Meine Güte, ich musste meine Frau zu Hilfe holen, damit sie mit der einen Hand das Kabel hält und mit der anderen die Zange mit dem eingeklemmten Pin-Abnehmer, damit ich einerseits das Lötzinn halten und andererseits den Quatsch zusammenlöten konnte. Da gibts doch sicher optimalere Lösungen...

Aber mal zurück zum Code (kann ich den mit HTML-Code formatieren?):

<pre>
;***** STK500 Servo in mittlere Position bringen
;************************************************* *********
.include "8515def.inc" ; Definitionen für AT90S8515
rjmp RESET ; Reset Handle
;************************************************* *********
.def temp =r16 ; Temporary register
.def stack = r17 ; stack

RESET:
; ser temp ; auskommentiert, versteh ich nicht
ldi stack, HIGH(RAMEND)
out SPH, stack
sbi DDRB,PB0 ; Set PORTB to output
LOOP:
; out PORTB,temp ; Update Port, auskommentiert, versteh ich auch nicht
sbi PORTB, PB0 ; Setze PortB, Pin0
rcall WAITPOS ; warte 1-2ms (Servo-Position)
cbi PORTB, PB0 ; Lösche PortB, Pin0
rcall WAITREP ; warte 20ms (Repetition-Periode)
rjmp LOOP ; usw usf

;************************************************* *********
; Subroutinen (später mal auf 4Mhz anpassen)
;************************************************* *********
WAITPOS:
ldi ZH, HIGH(1500) ; setze höheres Z-Byte
ldi ZL, LOW(1500) ; setze niedriges Z-Byte
LOOPPOS:
sbiw ZL, 1 ; decrementiere Z
brne LOOPPOS ; loop bis Z=0
ret ; und tschüss

WAITREP: ; dito WAITPOS
ldi ZH, HIGH(65535)
ldi ZL, LOW(65535)
LOOPREP:
sbiw ZL, 1
brne LOOPREP
ret
</pre>

Der Servo akzeptiert, wenn ich mit einem 65535-Intervall daherkomme (Eigentlich akzeptiert er alle Werte, ich könnte sogar 100 eingeben). Als Steuersignal akzeptiert er 1000 (links), 1500 (mitte), 2000 (rechts) wie im Beschieb steht, auf das mich Manf aufmerksam gemacht hat. Die Limits gehen sogar von etwa 750 - 2400 (hab das noch nicht bis in die Nachkommastellen getestet). Bei 1000/2000 geht er nicht ganz nach links/rechts. Aber das ist ein Detail.

Ursprünglich hatte ich mit meinem simplen Gemüt erwartet, dass ich den Wert vervierfachen muss, weil ich ja mit 4Mhz daherkomme. Ich denke inzwischen aber, dass ich die Cycles innerhalb der Warteschlaufe auch berücksichtigen muss:
SBIW: 2 + BRNE: 1 + RET ? (4 devices with 16-bit PC ), was auch immer das für RET heissen mag. Angenommen RET braucht 1 Cycle, käme ich exakt auf 4, was wiederum bedeutet, dass ein Loop 4 Takte verbrennt. Das führt dazu, dass ich meine Millisekunden eben gerade NICHT vervierfachen muss, weil mein Loop bereits schon 4 Takte braucht.

Gehen meine Gedanken in etwa in die richtige Richtung oder sehe ich das komplett falsch?

Mein nächstes Vorhaben wird sein, die Taster miteinzubeziehen. Mal schauen, ob ich das hinkriege.

Auf alle Fälle vielen Dank für Eure bisherige Unterstützung - ohne Euch hätte ich das niemals so schnell hinbekommen.