Ein Blick ins Datenblatt wird noch mehr Features als meine Beispiele hier zeigen. Auch sind die eingestellten Werte eher als grober Startwert zu sehen, z.b. ist der Oszillator nicht der genaueste, ich benötige z.b. den Vorteiler von 133 um auf 50 Hz zu kommen um mein Servo hat auch einen wesentlich grösseren Verstellbereich als 2ms. Man kann den IC aber auch mit maximal 50MHz externem Signal genauer und/oder schneller machen.
Manche Servos funktionieren auch mit 100Hz wiederholrate ohne Probleme, dann hat man meinen Verstellbereich nochmals verdoppelt und erreicht noch mehr Auflösung bzw. Genauigkeit. Dem besseren Verständnis wegen bleiben meine Beispiele bei den standard Signalen.
Zuerst muss man dem IC den zur Ausgangsfrequenz passenden Vorteiler/Prescaler einstellen, standardmäßig läuft er sonst auf 200Hz Ausgangsfrequenz. Möglich sind werte von 24 bis 1625Hz. Leider lässt sich die Frequenz nur einstellen wenn der Interne 25MHz Oszillator im Sleep Mode (also aus) ist. Das automatische Hochzählen der I2C Adressen ist auch nicht automatisch eingeschaltet, das wird gleich mit erledigt, ansonsten müsste man jede Adresse einzeln anwählen anstatt aufeinanderfolgende Adressen einfach nacheinander schreiben zu können:
Alles anzeigen
Der PCA9685 hat einen internen 25MHz Oszillator, die Ausgangsfrequenz berechnet sich nach dem Vorteiler und der Auflösung von 12Bit: =( 25000000/(4096*50)-1 für 50Hz welche die Servos benötigen also einen Vorteiler von 121.
Jetzt muss noch eingestellt werden welche Art von Last am IC hängt, er kann nämlich FETs direkt schalten sowie auch LEDs bis 20mA pro Kanal direkt Versorgen. In diesem Fall stellen wir Servo ein:
servo1.jpg
Ausgangsfrequenz und Ausgangscharakteristik können leider nur global pro IC eingestellt werden. Das bedeutet alle Ausgänge laufen mit der gleichen Frequenz und theoretisch nur LEDs oder nur Servos. Wenn man die ein und ausschaltpunkte neu anpasst läuft das Servo aber auch mit einem Pullup unter der LED Einstellung, in dieser Einstellung ist das Signal ja invertiert und das Servo würde in den mechanischen Anschlag fahren.
Ein Servo Signal ist zwischen 1ms und 2 ms lang und kommt mit 50 Hz (20ms Wiederholung), ein durchlauf (signalperiode) des PCA9685 hat 12 Bit bzw. 4095 Takte. 1 Millisekunde sind also knapp 205 Takte womit das Servosignal zwischen 205 und 410 Takten für mix/max liegt.
pic2.jpg
Der PCA hat zwei Schaltpunkte pro Kanal, den Einschaltpunkt und Ausschaltpunkt.
pic1.jpg
Beide werden durch eine Word-Variable gesetzt, zuerst wird das niedrigwertigere Byte übertragen, dann das höherwertige jedes Punktes. Im Beispiel hier wird bei Zählerstand 0 eingeschaltet und bei 205 wieder ausgeschaltet und somit ein 1ms Signal erzeugt. Auch werden in diesem Beispiel hier werden gleichzeitigallen 16 Kanäle mit den gleichen Werten eingestellt:
Alles anzeigen
Sieht dann so aus:
2nd.jpg
Wenn man alle Kanäle gleichzeitig ein oder ausschalten will kann man statt den 4 Bytes für ON und OFF auch einfach das 5te Bit aus dem höheren Byte schreiben:
Das vorherige Beispiel hat den nachteil das alle Signale zur gleichen Zeit beginnen, für die Stromversorgung ist so etwas eine sehr hohe Belastung. Besser wäre es wenn man das Signal an jeden Kanal etwas zeitverzögert ausgibt:
Alles anzeigen
Dadurch das man Start und Stopp Punkte pro Kanal setzen kann ist ein Versatz ohne Probleme möglich. Im vorherigen Beispiel fährt das Servo langsam hin und her. Das Signal vom zweiten Kanal wird um ca 1,2ms später (wert 255) ausgegeben.
3rd.jpg
Zur Erreichung einer Position muss man die Signalwerte aber nicht wie eben gezeigt hochzählen, das Servo vergleicht ja selber Soll-wert vom Signal und Ist-Stellung und fährt dann automatisch in die Soll- Position.
Das vom mir eingesetzte Modul:
PCA9685.jpg
Alle Adresseingänge liegen per Default auf logisch null somit ist der
PCA9685 unter der schreibdresse Hex 80 zu erreichen. Spannungsversorgung
der Servo Stiftleisten über PIN „V+“ oder die Schraubklemme. Spannungsversorgung vom PCA über PIN „VCC“.
Alle Ausgänge sind über 220Ohm Widerstände herausgeführt. SDA und SCL haben 10K Pullups.
Im Gegensatz zum ähnlichen Modulen wurde an diesem hier die Verpolschutzschaltung an „V+“ eingespart.
Manche Servos funktionieren auch mit 100Hz wiederholrate ohne Probleme, dann hat man meinen Verstellbereich nochmals verdoppelt und erreicht noch mehr Auflösung bzw. Genauigkeit. Dem besseren Verständnis wegen bleiben meine Beispiele bei den standard Signalen.
Zuerst muss man dem IC den zur Ausgangsfrequenz passenden Vorteiler/Prescaler einstellen, standardmäßig läuft er sonst auf 200Hz Ausgangsfrequenz. Möglich sind werte von 24 bis 1625Hz. Leider lässt sich die Frequenz nur einstellen wenn der Interne 25MHz Oszillator im Sleep Mode (also aus) ist. Das automatische Hochzählen der I2C Adressen ist auch nicht automatisch eingeschaltet, das wird gleich mit erledigt, ansonsten müsste man jede Adresse einzeln anwählen anstatt aufeinanderfolgende Adressen einfach nacheinander schreiben zu können:
Quellcode
- 'Prescalerregister setzen, dafür muss das Oszillator bit5 von Mode 1ausgeschaltet sein sein
- 'Auto increment der Adressregister ist per default aus, einschalten mit bit6 vom Mode 1
- I2cstart
- I2cwbyte adressPCA9685_write
- I2cwbyte &H00
- I2cwbyte &B0011_0000 '&H21, auto increment on, sleep mode on
- I2cstop
- 'Servo signal 20MS=50Hz, impulslänge 1-2ms, verstellbereich min/max demnach 205 schritte;bereich min/max= 205-410
- I2cstart
- I2cwbyte adressPCA9685_write
- I2cwbyte &B1111_1110 '&HFE = set to PRE_SCALE register
- I2cwbyte &B0111_1001 '50 hz Osc_CLK=( 25000000/(4096*50)-1 = 121) set prescale, sleep mode must be 1 to set scaler
- I2cstop
- I2cstart
- I2cwbyte adressPCA9685_write
- I2cwbyte &H00
- I2cwbyte &B0010_0000 'auto increment on, sleep mode off
- I2cstop
Der PCA9685 hat einen internen 25MHz Oszillator, die Ausgangsfrequenz berechnet sich nach dem Vorteiler und der Auflösung von 12Bit: =( 25000000/(4096*50)-1 für 50Hz welche die Servos benötigen also einen Vorteiler von 121.
Jetzt muss noch eingestellt werden welche Art von Last am IC hängt, er kann nämlich FETs direkt schalten sowie auch LEDs bis 20mA pro Kanal direkt Versorgen. In diesem Fall stellen wir Servo ein:
Ausgangsfrequenz und Ausgangscharakteristik können leider nur global pro IC eingestellt werden. Das bedeutet alle Ausgänge laufen mit der gleichen Frequenz und theoretisch nur LEDs oder nur Servos. Wenn man die ein und ausschaltpunkte neu anpasst läuft das Servo aber auch mit einem Pullup unter der LED Einstellung, in dieser Einstellung ist das Signal ja invertiert und das Servo würde in den mechanischen Anschlag fahren.
Ein Servo Signal ist zwischen 1ms und 2 ms lang und kommt mit 50 Hz (20ms Wiederholung), ein durchlauf (signalperiode) des PCA9685 hat 12 Bit bzw. 4095 Takte. 1 Millisekunde sind also knapp 205 Takte womit das Servosignal zwischen 205 und 410 Takten für mix/max liegt.
pic2.jpg
Der PCA hat zwei Schaltpunkte pro Kanal, den Einschaltpunkt und Ausschaltpunkt.
pic1.jpg
Beide werden durch eine Word-Variable gesetzt, zuerst wird das niedrigwertigere Byte übertragen, dann das höherwertige jedes Punktes. Im Beispiel hier wird bei Zählerstand 0 eingeschaltet und bei 205 wieder ausgeschaltet und somit ein 1ms Signal erzeugt. Auch werden in diesem Beispiel hier werden gleichzeitigallen 16 Kanäle mit den gleichen Werten eingestellt:
Quellcode
- 'Alle 16 kanäle gleichzeitig ansprechen ab adresse FA servo minimalwert
- PCFword_on =0
- PCFword_off= 205 'beginn des signals immer bei 0
- I2cstart
- I2cwbyte adressPCA9685_write
- I2cwbyte &HFA
- I2cwbyte LOW(PCFword_on)
- I2cwbyte High(PCFword_on)
- I2cwbyte LOW(PCFword_off)
- I2cwbyte High(PCFword_off)
- I2cstop
- wait 5
- 'Alle 16 kanäle gleichzeitig ansprechen ab adresse FA servo maximalwert
- PCFword_on =0
- PCFword_off= 410 'beginn des signals immer bei 0
- I2cstart
- I2cwbyte adressPCA9685_write
- I2cwbyte &HFA
- I2cwbyte LOW(PCFword_on)
- I2cwbyte High(PCFword_on)
- I2cwbyte LOW(PCFword_off)
- I2cwbyte High(PCFword_off)
- I2cstop
- Wait 5
2nd.jpg
Wenn man alle Kanäle gleichzeitig ein oder ausschalten will kann man statt den 4 Bytes für ON und OFF auch einfach das 5te Bit aus dem höheren Byte schreiben:
Das vorherige Beispiel hat den nachteil das alle Signale zur gleichen Zeit beginnen, für die Stromversorgung ist so etwas eine sehr hohe Belastung. Besser wäre es wenn man das Signal an jeden Kanal etwas zeitverzögert ausgibt:
Quellcode
- 'default werte damit Servo nicht in Anschlag fährt
- PCFword_on=0
- PCFword_off= 307
- do
- PCFword_on_add = PCFword_on + 255
- PCFword_off_add = PCFword_off + 255
- 'Ausgänge einzeln ansprechen, Ausgang 0:
- I2cstart
- I2cwbyte adressPCA9685_write
- I2cwbyte Aus0
- I2cwbyte LOW(PCFword_on)
- I2cwbyte HIGH(PCFword_on)
- I2cwbyte Low(PCFword_off)
- I2cwbyte High(PCFword_off)
- I2cstop
- 'Ausgänge einzeln ansprechen, Ausgang 1:
- I2cstart
- I2cwbyte adressPCA9685_write
- I2cwbyte AUS1
- I2cwbyte LOW(PCFword_on_add)
- I2cwbyte High(PCFword_on_add)
- I2cwbyte Low(PCFword_off_add)
- I2cwbyte High(PCFword_off_add)
- I2cstop
- ' Ausgänge kontinuierlich schreiben Ausgang 2-3:
- I2cstart
- I2cwbyte adressPCA9685_write
- I2cwbyte AUS2
- I2cwbyte LOW(PCFword_on)
- I2cwbyte HIGH(PCFword_on)
- I2cwbyte Low(PCFword_off)
- I2cwbyte High(PCFword_off)
- I2cwbyte LOW(PCFword_on_add) 'Hier beginnt Speicherbereich Ausgang 3
- I2cwbyte High(PCFword_on_add)
- I2cwbyte Low(PCFword_off_add)
- I2cwbyte High(PCFword_off_add)
- I2cstop
- 'Hochzählen bis zum maximum, Wenn erreicht zählrichtung umkehren
- if direction = 0 then
- incr PCFword_off
- if PCFword_off = 440 then direction = 1
- end if
- 'Runterzählen bis zum minimum, wenn erreicht zählrichtung umkehren
- if direction = 1 then
- decr PCFword_off
- if PCFword_off = 209 then direction = 0
- end if
- waitms 500
- loop
3rd.jpg
Zur Erreichung einer Position muss man die Signalwerte aber nicht wie eben gezeigt hochzählen, das Servo vergleicht ja selber Soll-wert vom Signal und Ist-Stellung und fährt dann automatisch in die Soll- Position.
Das vom mir eingesetzte Modul:
PCA9685.jpg
Alle Adresseingänge liegen per Default auf logisch null somit ist der
PCA9685 unter der schreibdresse Hex 80 zu erreichen. Spannungsversorgung
der Servo Stiftleisten über PIN „V+“ oder die Schraubklemme. Spannungsversorgung vom PCA über PIN „VCC“.
Alle Ausgänge sind über 220Ohm Widerstände herausgeführt. SDA und SCL haben 10K Pullups.
Im Gegensatz zum ähnlichen Modulen wurde an diesem hier die Verpolschutzschaltung an „V+“ eingespart.
5.743 mal gelesen