Forum: FPGA, VHDL & Co. Ansteuerung eines Servos via FPGA


von photon (Gast)


Lesenswert?

Hallo liebe mikrocontroller-Mitglieder,

ich beschäftige mich seit einiger Zeit mit FPGA's bzw. der 
Hardwarebeschreibungssprache VHDL und habe noch nicht all zu viele 
Erfahrungen auf dem Gebiet sammeln können.
Bei der Umsetzung könnte ich ein paar Tipps von Euch erfahrenden Usern 
gebrauchen. Nun möchte ich aus Übungsgründen gerne einen kleinen 
Modellbauservo mittels einem FPGA ansteuern.

Zur Theorie:

Die Winkeleinstellung des Servos wird mittels der Pulsweitenmodulation 
geregelt. Alle 20 ms (50 Hz) wird ein Impuls zwischen 1er und 2 ms 
gesendet, wobei die Mittelstellung bei einer Pulsbreite von 1.5 ms 
liegt. Maximale Winkelausrichtung bei Pb von 1er ms zu der einen Seite 
und 2 ms zu der anderen Seite.

Mein FPGA Board, an dem ich diese Umsetzung realisieren möchte, taktet 
mit 50 Mhz. Um eine Frequenz von 50 Hz, bzw. eine Periodendauer von 20 
ms zu erhalten, muss ich die 50 MHz. mit dem Faktor 10^6 teilen.

Ein 50 Hz Signal habe ich bereits realisieren können, indem ich einen 
Zähler gebaut habe, der bei jeder aktiven Taktflanke von 0 bis 499999 
hochzählt und den Zähler jeweils um 1 inkrementiert und den Ausgangswert 
nach dem gesamten Zählzyklus 'not' alter Ausgangswert verknüpft. Somit 
oszilliert mein Signal 10 ms High, 10 ms Low .... usw.

Jetzt habe ich oft in Foren gelesen, dass man die Ansteuerung des Servos 
mit z.B. 8 bit quantisiert. Also Werte von 0 - 255.
Meine Frage: Beziehen sich die 8 bit auf den gesamten Zeitraum von 20 ms 
oder auf den Zeitraum der Pulsweite, also maximal 10% der Periodendauer, 
auf 2 ms?

Bei dem gesamten Zeitraum würde das doch bedeuten, dass bei angenommener 
Pulsbreite von 2 ms (was ja 10 % von 20 ms beträgt), dann 256*0.1 = 25.6 
Werte, also 25 mögliche Servoeinstell-werte zur Verfügung stehen?


Wie müsste ich jetzt weiter vorgehen? Ich habe mir folgendes gedacht:

Meinen 50 Hz Zähler benötige ich nur, um jeweils den Begin meines 
Impulses zu detektieren. Dann würde ich einen weiteren Zähler benötigen, 
der dann für maximal 2 ms den Takt auf 'High' hält und die restliche 
Zeit, maximal 18 ms, auf 'Low'.
Für das erste würde mir schon reichen, wenn ich den Stellwinkel im 
Quellcode vorgebe, ohne zusätzliche Eingänge vom Fpga. Dazu würde ich 
dann später übergehen.

Kann mir jemand sagen, ob ich mit dieser Sichtweise ersteinmal richtig 
liege?

Vielen Dank,

photon

von Klaus F. (kfalser)


Lesenswert?

photon schrieb:
> Meine Frage: Beziehen sich die 8 bit auf den gesamten Zeitraum von 20 ms
> oder auf den Zeitraum der Pulsweite, also maximal 10% der Periodendauer,
> auf 2 ms?

Eigentlich sind es ja 1 ms.
Nach dem Start ist der Puls 1 ms immer high, und dann je nach 8 Bit Wert 
weitere 0 bis 1 ms.
127 wäre dann die mittelstellung von 1,5 ms.

So würde jedenfalls ich es machen.

von Chris (Gast)


Lesenswert?

Die Widerholrate der Servos liegt zwischen 13mS und 25mS .
Schau dir das mal an, http://www.fpga4fun.com/RCServos.html

von Thomas T. (knibbel)


Lesenswert?

Klaus Falser schrieb:
> Nach dem Start ist der Puls 1 ms immer high, und dann je nach 8 Bit Wert
> weitere 0 bis 1 ms.
> 127 wäre dann die mittelstellung von 1,5 ms.

Wenn man sich jetzt einen Zähler baut, welcher alle 4 Mikrosekunden 
inkrementiert, dann hat man bei dem Wert 255 1,02 ms zusammen. Würde mal 
sagen das wäre ausreichend genau.

Also:

* Einen Puls alle 20 ms als "Startsignal" generieren.
* Einen weiteren Puls alle 4 us als "Zeitsignal" generieren.

* Deinen 8-Bit Stellwert zu 256 addieren (ein 9. gesetztes Bit 
voranstellen)
  (das wird nachher das 1 ms Vorab-High)

* Bei "Startsignal" einen Zähler auf Null setzen und Ausgang auf High 
legen.

* Zähler mit dem "Zeitsignal" inkrementieren

* Sobald Zähler den korrigierten Stellwert erreicht hat, den Ausgang auf 
Low legen.

* Zähler zählt bis 511 und bleibt dann da stehen.


Das ist so aus'm Kopf heraus runtergeschrieben, sollte aber 
funktionieren...

Gruß,
Thomas

PS: Man könnte den Zähler auch so breit machen, dass er alle 20 ms 
überläuft, dann würde die ganze Sache noch etwas einfacher werden.

von Thomas T. (knibbel)


Lesenswert?

Neue Idee:

Du nimmst einen 12 Bit breiten Zähler, den du alle 4 us inkrementierst. 
Dieser läuft jetzt alle 16,384 ms über. Damit hast du schon automatisch 
deine Wiederholrate.

Wenn der Zähler 3846 ist, dann setzt du den Ausgang auf High. Das ist 
genau 1 Millisekunde, bevor der Zähler überläuft.

Jetzt brauchst du nur noch deinen Stellwert mit dem Zählerstand 
vergleichen und bei Gleichheit den Ausgang auf Low legen.

Gruß,
Thomas

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.