PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Servo ansteuern mit dem Atmega88 - Basics.



Sand64
04.12.2009, 21:57
Hallo,
Ich habe seit 2 Wochen ein Mikrocontroller Lernpaket von FRanzis mit einem Atmega88. Ich versuche verzeifelt mit meinem PB0 ausgang einen Servo anzusteuern. Der Servo hat eine 4,5 Volt Spannung über ein Netzteil und das PWM signal gebe ich auf PB0 raus.
Es würde mir reichen wenn ich Ihn beim Programmstart in eine fest devinierte Position fahren kann. Aber so richtig werde ich aus der Hilfe oder anderen suchfunktionen nicht schlau. Deshalb hoffe ich hier mein neues zuhause finden zu können. Kann das so überhaup funktionieren oder benötige ich einen Timer ? kann mir jemand eine kleine hilfestellung geben ?

Der Servo läuft wenn ich ihn zurückstelle immer bis zum anschlag:

$crystal = 8000000
$regfile = "m88def.dat"
Config Servos = 1 , Servo1 = Portb.0 , Reload = 10
Config Portb = Output
Enable Interrupts


Do
Servo(1) = 90
Waitms 20

Loop
End

Besserwessi
04.12.2009, 22:29
Läuft der µC wirklich mit 8 MHz ?
Wenn man nichts anders einstellt, laufen die µCs mit 1 MHz.

Edblum
05.12.2009, 08:19
Moin,

Also Fusebits. Vielleicht läuft der Servo auch mit 1 Mhz? Eine interessante Frage, ich plane in meine Triebwagen auch 3 Servo's.

Weiterhin eine Bemerkung beim Programm:

Do
Servo(1) = 90
Waitms 20

Loop

Der Servo nimmt nur einen Wert an. Bitte den Programm ändern:

Do
Servo(1) = 90
Waitms 300
Servo(1) = 50 'oder ein andere Wert
Waitms 300


Loop

Dan wackelt der Servo hin und her.

Vielleicht ist nicht alles korrekt Deutsch. ;)

LG,

Ed

Sand64
05.12.2009, 09:04
Moin Moin,
Habe nochmal einen zweiten Servo getestet .. er läuft auch bis zum anschlag und fertig. Es muss irgendwie am Timing liegen .. wenn ich den Reload erhöhe läuft er auch zum anschlag aber langsam .. egal was in Servo(1) steht. Bei Servo 1 kann ich 30 oder 150 schreiben das ist egal .

Ich versuche mal vom Conrad lernkasten das Ozilloskop anzuschließen, hat noch jemand eine Idee ?

$crystal = 1000000 'Normal 8000000
$regfile = "m88def.dat"

Config Servos = 1 , Servo1 = Portb.0 , Reload = 10
Config Portb = Output
Enable Interrupts

Do
Servo(1) = 90
Waitms 300
Servo(1) = 50
Waitms 300
Loop
End

Besserwessi
05.12.2009, 12:49
Die Servofunktion solle auch mit einem anderen Takt funktionieren. Wichtig ist nur, dass der Takt oben im Programm auch richtig eingetragen ist.

Ein einfacher Test für die Taktfrequenz ist es ein LED blinken (z.B 1 mal pro sekunde) zu lassen. Wenn die Blinkfrequenz stimmt, sollte auch die Taktfrequenz stimmen.

Mit M88 läuft bei unveränderten Fuses der internen RC Oszillator (8 MHz) und er takt wird durch 8 geteilt. Der µC läuft also effektiv mit 1 MHz.
Den Teiler kann das Programm zur Laufzeit verändern, da muß man also nicht unbedingt die Fuses ändern.

Sand64
05.12.2009, 13:01
das mit de LED werde ich gleich mal austesten.
Kurz nochmal zum verständniss.

Servo(1) ist eine Variable die die mit Reload 10 alle 10 ms an den Servo geschickt wird ? das tut er in meiner schleife 300ms mit Servor 90 und 300ms mit 50 ? das ist vielleicht etwas schnell für den wächsel von 90 auf 50...
Achso Servo(1) ist natürlich ein Array.

mal schauen , noch besteht das problem

Sand64
05.12.2009, 16:49
er läuft immer nur in eine richtung...

chw9999
05.12.2009, 21:29
Klingt vielleicht blöd, aber: Habe mal den gleichen Effekt gehabt - immer ist das Servo an den Anschlag gefahren. Und mind. eine viertel Stunde gesucht, bis ich die vertauschten Kabel bemerkt habe...

Cheers
Christoph

Sand64
05.12.2009, 22:36
Moin Christoph,
Die Lösung klang so gut!! aber leider oder zum glück ist der Stecker richtig montiert... komisch aber das seit dem kurzen versuche den Stecker falsch rum raufzustecken der Servo sich nun in beide richtungen bewegt...

Danke, mfg jonny

Willa
05.12.2009, 22:48
@Jonny: Läuft der Controller denn jetzt garantiert mit 8MHz? Hast du das mit der LED ausprobiert? Wie hast du das Servo ganz genau angeschlossen? Rot an + 5V, schwarz an das gleiche (!!!!) Ground wie dein Controller, Gelb/weiß an PIN B 0?

chw9999
06.12.2009, 10:12
Schade, dass es mit dem Umstecken nicht (so einfach) geklappt hat. Aber welches Programm hattest Du denn am laufen, als Du das Servo umgesteckt hattest? Dieses von Dir oben genannte?

Do
Servo(1) = 90
Waitms 300
Servo(1) = 50
Waitms 300
Loop
End

Dann würde es sich ja korrekterweise (etwas) hin- und herbewegen... :-)

Ich hatte mal was für den ATtiny25 geschrieben, vielleicht kannst Du ja was aus dem Code rauslösen und modifizieren - und probieren, ob es damit funktioniert.

http://www.jurmo.de/AVR/

Cheers
Christoph

Sauerbruch
06.12.2009, 15:34
Hallo Sand64,

der "Servo"-Befehl läuft erst ab Taktfrequenzen von mindestens (!) 8 MHz korrekt. Warum weiss ich auch nicht, hab´s aber mal bei 1 MHz probiert, und grotesk falsche Pulsweiten mit dem Oszi gemessen (die jedes Servo sofort an den Anschlag zwingen).

Wie Besserwessi ja schon vorgeschlagen hat, solltest Du als erstes checken, mit welchem Takt Dein µC läuft. Das stellt man nicht mit $Crystal ein, sondern mit den Fusebits. Die $Crystal-Angabe ist "nur" wichtig, damit der Compiler programmierte Zeiten (wie z.B. bei waitms XX) richtig berechnen kann. Läuft der Controller mit einer anderen Frequenz als bei $Crystal geschrieben, kommen falsche Zeiten raus - Und so kannst Du es auch checken:



$Crystal = 80000000
DDRX.Y = 1 'Port X.Y als Ausgang konfigurieren

Do
Toggle PortX.Y 'logischen Zustand von PortX.Y wechseln
waitms 500 '0,5 Sekunden Pause
Loop



Wenn Deine LED an PortX.Y mit 1 Hz blinkt, stimmen Taktfrequenz und $Crystal-Angabe überein.


Servo(1) ist eine Variable die die mit Reload 10 alle 10 ms an den Servo geschickt wird ?

Nicht ganz - der Befehl Servo generiert Rechteckimpulse und schickt sie automatisch alle 20ms raus. Die Länge der Impulse ist Servo(x) * Reload (in µS). Bei Reload = 10 und Servo(1) = 90 dauert der Impuls also 900µS, wobei Servos i.d.R Impulsbreiten zwischen 800 und 2200µS verarbeiten.

Wenn Du schon ein Oszi hast, schau Dir die Impulse doch mal an!

hunni
08.12.2009, 18:53
Habe zufällig gerade das gleiche Problem, dass das Servo einfach nur richtung anschlag läuft und dann nix. egal was ich mache. (Wollte die ganze Schaltung schon fast Richtung Mülltonne werfen).
Der Servo befehl läuft erst ab 8 MHZ?
Dann muss ich woll n externe Quarz anschließen, oder sehe ich das falsch :)
Hunni

Sauerbruch
08.12.2009, 19:19
Also, bevor Du zur Mülltonne gehst, sag Bescheid - dann schicke ich Dir meine Adresse per PN :-)

Ab wecher Taktfrequenz der Servo-Befehl genau funktioniert, weiß ich nicht 100% genau. Ich hab´s mir aber mal bei 1 und 2 MHz auf dem Oszi angesehen, und da kamen Impulsbreiten heraus, die so garnichts mehr mit dem erwarteten Wert zu tun hatten. 8 MHz ist glaube ich schon o.k., und die können viele Controller ja auch über den internen Oszillator generieren. Über die genaue minimale Taktfrequenz findest aber Du bestimmt was, wenn Du hier im Forum rumstöberst...

hunni
08.12.2009, 19:34
öhhh...... ich dachte immer die internen Oszilatoren können nich mehr als 1 MHZ!!!! ohhh man dann brauch ich ja gar nichts ändern.

Ich werd das gleich ma ausprobieren.
hunni

Besserwessi
08.12.2009, 21:03
Die internen Oszillatoren können auch mehr als 1 MHz. Bei den neueren Chips wie Mega88 sind wenigstens 8 MHz möglich, bzw. der Interne RC takt ist eigentlich immer 8 MHz und wird für NIedreigere Frequenzen geteilt. Voreingestellt ist ein Teiler von 8. Das kann aber sogar zur Laufzeit geändert werden.

Beim Tiny26 / Tuny461 usw. gehen sogar 16 MHz mit dem internen RC.

hunni
08.12.2009, 21:09
mhhh... kann ich das unter bascom einfach mit $crystal machen oder muss ich da i welche fusebits setzten? Habe bis dato immer nur mit 1 MHZ gearbeitet, bin mir jetzt nicht mehr sicher wie das geht.

hunni

chw9999
08.12.2009, 21:19
Für ATtiny25 (siehe Post oben) ein Zitat:


$crystal=8000000 ' externer Quarz oder interner Oszillator mit Vorteiler 1 (Fuse CKSEL0=0 CKSEL1=0 CKSEL2=1 CKSEL3=0 SUT0=0 SUT1=0) 0=programmiert, 1=nicht programmiert

' Hier noch 1 MHz
' Setzt CLKPR auf Vorteiler=1 -> Kein Vorteiler -> 8 MHz statt 1MHz
$ASM
Ldi R16 , &B10000000
Out CLKPR,R16
Ldi R16, &B00000000
Out CLKPR,R16
$END ASM
' ... und hier geht's mit 8 MHz weiter...




Cheers
Christoph

hunni
09.12.2009, 14:34
super cool man kann das einfach umschalten? genial =D>
Danke schön für eure schnelle Hilfe

hunni
11.12.2009, 18:19
bitte schön was ist daran falsch? ich habe versucht (ja ich habe noch nie assembler geproggt) den Assembler Code für einen Atmega8 umzuschreiben, anscheinend mache ich da etwas falsch. Könntet ihr bitte noch mal gucken.


$regfile "m8def.dat"
$crystal = 8000000
$baud = 300




$ASM

Ldi R16, &H0x0003 'Hier versuche ich den OSCCAL Register passenden
Out Osccal , R16 'zu bringen
$END ASM
' ... und hier geht's mit 8 MHz weiter...


Config Servos = 1 , Servo1 = Portb.4 , Reload = 10
Config Portb.4 = Output
Enable Interrupts

Do
Servo(1) = 70
Waitms 1000
Servo(1) = 100
Waitms 1000
Servo(1) = 50
Loop




Hunni

chw9999
11.12.2009, 19:20
Moin,

ich habe auf dem ATtiny25 auch noch kein Assembler geproggt, gut geklaut ist aber halb programmiert (;-)). Nur, wie kommst Du auf, dass es auf dem ATmega8 so "einfach" sei wie auf dem tiny?

Wenn Du nach "CLKPR" im Tiny-Doc suchst, findest Du "prescaler".
Wenn Du nach "CLKPR" im ATmega8-Doc suchst, findest Du nix.

Mit "prescaler" in der Suche beim ATm8 nur den "Counter" und den "Watchdog".

Beim Tiny hast Du einen 8MHz internen Oszillator, der normalerweise durch den Teiler auf 1 MHz clock (der Prozessor "fühlt" nur 1 MHz) reduziert wird. Beim ATmega8 kannst Du keinen Teiler per Soft einstellen, ergo auch nicht die gefühlte Geschwindigkeit des Prozessors (korrigiere man mich bitte, falls ich hier Mist erzähle).

Zum Setzen auf 8MHz nimmt man beim ATmega8 am besten die Fuse bits, siehe besonders CKSEL (suche "CKSEL3..0") und CKOPT.

Das OSCCAL, das Du ansprichst, ist das "Calibration Byte", mit dem Du die Frequenz etwas hin- und herschieben kannst (ggf. zum -> Kalibieren), aber kein Teiler im Sinne wie beim Tiny.

Aber hier ein Beispiel für OSCCAL: So kann man den internen Prozessortakt etwas (!) entschleunigen (oder beschleunigen, mit OSCCAL=255). Obacht: Serielle Kommunikation und EEPROM-Zugriff gehen dann eventuell nicht mehr...


dim OSCCALval as Byte ' für den Originalwert...
OSCCALval=OSCCAL ' OSCCAL merken zum zurückschreiben

OSCCAL=0 ' Es ruhiger angehen lassen, es ist eh' dunkel (nix passiert...)
' hier langsamer (ca. 50%)
' . . .
OSCCAL=OSCCALval ' Originalwert
' hier wieder "normal"


Cheers
Christoph

Besserwessi
11.12.2009, 21:38
Beim Mega8 geht es wirklichnur über die Fuse des Takt auf 8 MHz zu bringen. Beim Mega88 geht es dagen auch ähnlich wie beim Tiny24 über den Teiler. Der Mega8 ist noch einer der alten Chips ohne Teiler.

hunni
11.12.2009, 21:41
mhhh, wie müssen den dann die fuses stehen, ich meine ich habe das darüber auch schon probiert, nur i wie wollte das nicht so wie ich das gerne hätte, damit meine ich, dass gar nichts mehr funktionierte.
oder MUSS ich da einen externen Quarz nehmen um die frequenz zu erreichen?

Besserwessi
11.12.2009, 22:02
Beim mega 8 kreigt man ca. 8 MHz auch mit den Fuses. Gerade bei BASCOM sollte es noch reativ vreständlich sein wie man die Fuses ändern muß, um auf 8 MHz takt vom internen RC kommen. Einfach mal die Fuses auslesen und dann beim Auswahlfenster den passenden takt auswählen.

Robotniks
18.12.2009, 09:37
Hallo,

wie hast du das Servo angeschlossen.
Masse muss mit der Boardmasse gleich sein!
Die Versorgung des Servos muss seperat sein, aber
die Masse (GND) muss am Servo und am Board angelegt werden!


Du kannst es testweise auch in einer Do Loop und mit Pulsout versuchen.


Grüße

hunni
18.12.2009, 17:39
ich habs mitleerweile schon gefunden, hoffe ich, woran es liegt

chw9999
18.12.2009, 21:34
Oh, bitte lass uns teilhaben an Deiner Erkenntnis, und nicht dumm sterben...

Ist es was peinliches oder warum schreibst Du's nicht?


Cheers
Christoph

hunni
19.12.2009, 12:10
ach so, nee ich habe halt alles mit einem MHZ gemacht, naja und wie gesagt läuft der Servobefehl erst ab 8 MHZ.
Naja und deswegen kam da nur Müll raus