PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bascom Funktionen Servo & I2cslave



!*sascha*!
08.01.2011, 14:05
Hi,


ich baue einen Hexapod und möchte 18 Servos ansteuern! Bascom kann aber nur 12! Jetzt wollte ich für jede Seite einen Atmega8 benutzen der je 9 Servos steuert! Dann können die IC´s saubere PWN Signale erzeugen :-) und die Positionen sollen über I2C gesetzt werden.


Im Atmega habe ich als 1. aus dem Bascom Beispiel die I2cslave getestet! geht

Dann den Servo Befehlt von Bascom! geht!

Aber beide Funktionen in einen Programm geht !nicht

Meine Frage!

Wie kann ich z.B. in "i2cslave.LBX" den Timer0 auf Timer1 ädern?


Vielleicht kennt ja jemand eine andere Lösung?



Zusatz:

Habe grad in der history.txt einen Eintrag gefunden!

1.11.7.8 NOTE : 30 - 6 - 2005

- CONFIG SERVO enhanced with selectable TIMER0 or TIMER1.


Dann habe ich getestet! geht aber nicht!

I2C geht aber ich bekomme kein Servo PWM




Config I2cslave = &H40 , Int = Int0 , Timer = Timer0
Config Servos = 1 , Servo1 = Portb.1 , Reload = 10 , Timer = Timer1

Gruß,
Sascha

PicNick
09.01.2011, 07:58
Ich studiere grad, wofür die Slave-Funktionen wohl überhaupt irgendeinen Timer brauchen ?

Richard
09.01.2011, 13:42
Hi,


ich baue einen Hexapod und möchte 18 Servos ansteuern! Bascom kann aber nur 12! Jetzt wollte ich für jede Seite einen Atmega8 benutzen der je 9 Servos steuert! Dann können die IC´s saubere PWN Signale erzeugen :-) und die Positionen sollen über I2C gesetzt werden.


Im Atmega habe ich als 1. aus dem Bascom Beispiel die I2cslave getestet! geht

Dann den Servo Befehlt von Bascom! geht!

Aber beide Funktionen in einen Programm geht !nicht

Meine Frage!

Wie kann ich z.B. in "i2cslave.LBX" den Timer0 auf Timer1 ädern?


Vielleicht kennt ja jemand eine andere Lösung?



Zusatz:

Habe grad in der history.txt einen Eintrag gefunden!

1.11.7.8 NOTE : 30 - 6 - 2005

- CONFIG SERVO enhanced with selectable TIMER0 or TIMER1.


Dann habe ich getestet! geht aber nicht!

I2C geht aber ich bekomme kein Servo PWM




Config I2cslave = &H40 , Int = Int0 , Timer = Timer0
Config Servos = 1 , Servo1 = Portb.1 , Reload = 10 , Timer = Timer1

Gruß,
Sascha

Schaust Du hier....
http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=87&products_id=198

Gruß Richard

!*sascha*!
09.01.2011, 14:57
Hi,

Ja danke den habe ich auch gefunden! Wenn es einfach nicht klappt, werde ich in den sauren Apfel beissen!

Ich habe eben noch den Ehrgeiz alles selber zu machen! Dann kann ich die Platinen selber erstellen und passen genau in den Hexapod!


Meine 2. Überlegung ist einfach die Module via UART an meinen Hauptcontroller zu verbinden!

Bin dankbar für alle Vorschläge :)

Danke....


Gruß,
Sascha

guenter1604
09.01.2011, 19:33
Hallo PicNick,

es wird daran liegen, daß Config i2cslave anscheinend nicht die Hardware-TWI nutzt. Da viele Chips die Hardware-TWI haben frage ich mich auch, was das soll. Dafür ein Drittel aller Timer und die Hälfte der Hardwareinterrupts zu verheizen ist unschön. Ich kapiere auch nicht warum Bascom um die I2C-Slaves so einen Spektakel macht und dafür extra Geld verlangt. Für einen Hardware-TWI Slave müssen doch nur ein paar Register gesetzt werden.

Gruß Günter

guenter1604
09.01.2011, 19:43
Hallo Sascha,

fündig wirst du im Atmel Datasheet des ATMega8 ab Seite 184.
Wenn du das Register TWCR als Slave Receiver setzt und im Register TWAR eine Adresse hinterlegst, kann der ATMega8 ganz unbehelligt arbeiten und wird erst per Interruptflag gestört, wenn auf dem I2C-Bus die eigene Adresse aufgerufen wird.

Günter

!*sascha*!
12.01.2011, 19:41
Hallo guenter,

danke für deinen Tipp!

Mein Ziel wird es 100% sein, die Module via I2C zu verbinden!

Als 1. Lösung habe ich einen Buss mit dem UART gebaut!

( 4 Byte pro Servo )
1. Byte Servo-Nr.
2. Byte Geschwindigkeit
3. Byte Servo Winkel(Position
4. CRC8 Check

Das protokoll will ich dann auch auf dem I2C machen.



Werde dann beide Schnittstellen einbauen.

!*sascha*!
12.01.2011, 23:05
Hi *,


Hardware TWI funktioniert :-)

Code gibt es wenn er fertig ist :-)

Mfg
Sascha

funkheld
18.01.2011, 18:45
brauchen wir nicht, es gibt dafür code wie sand am meer.....

!*sascha*!
21.01.2011, 23:04
Hallo *,

ich habe mal wieder ein kleines Problem!

Ich habe jetzt 2 controller (Atmega8) und 18 Servos angeschlossen.
Die Controller werden via USB 5V betrieben und die Servos über ein Labornetzteil!

Wenn ich jetzt die spannungsquellen einschalte egal in welcher Reihenfolge oder auch beides aus der Gleichen Quelle.

Laufen meine Servos alle Amok.

Der Atmega ist nicht im dauer reset! PWM liegt am PIN an!
Habe ich mit dem Scope geprüft...

Habe an jeden Controller 2x 1000µF

Wenn ich alle Servos abklemme und nach und nach anklemme geht alles nur alle gleich anschalten knallt!

Denke das Problem liegt im Bereich Stromversorgung...

Kann mir jemand helfen? Bin ja für alle Tipps offen!

@funkheld

Kennst du mehr als ich=? Ich habe kein Projekt gefunden, welches den Aufbau eines Servo-controller´s beschreibt und code + pc programm zum download anbietet!

Die Hardware wird dann in SMD aufgebaut, wenn ich weiß dass alles funktioniert....


Video:

http://www.youtube.com/watch?v=A8ek9rJrOpI


Bilder:

http://picasaweb.google.com/sascha.markward/MyHexapod#

http://lh4.ggpht.com/_enzObwK8Ov4/TTnnhDKCKgI/AAAAAAAAAOE/TckIBmopams/s1152/IMG_6527.JPG


http://lh4.ggpht.com/_enzObwK8Ov4/TTnnlICSZBI/AAAAAAAAAOQ/xR-WF6i2LSw/s1152/IMG_6544.JPG

http://lh4.ggpht.com/_enzObwK8Ov4/TTnnnuxYpoI/AAAAAAAAAOY/PfhmW-221GA/s1152/IMG_6550.JPG

Richard
22.01.2011, 00:39
18 Servos ziehen beim Einschalten eine menge Strom da können die Leiterbahnen schnell zu dünn sein. Versuche einmal fette Zuleitungen und einen fetten Elco für dessen Versorgung.

Oder einfach ....

http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=87&products_id=198

verwenden, die Teile sind getestet das spart eine Menge Arbeit = Zeit. :-)

Ich habe bisher nur zum Test mit einem Servo unter Bascom "gespielt" und das ging recht gut.

Gruß Richard

!*sascha*!
22.01.2011, 16:17
Hi,

danke für die Info!

Ich habe schon den Ehrgeiz das Modul selber zu bauen! Habe auch nicht den Platz die ganzen fertig Platinen in den Hexa zu bauen...

Hobby ist Hobby und da ist halt der Grund :-)

Kaufen kann ja jeder^^

Aber ich sehe grade mein Netzteil hat nur 1,5A!
Das wird bestimmt beim einschalten nicht reichen...

Wollte ja schon immer ein anderes bestellen..

http://www.reichelt.de/?;ACTION=3;LA=444;GROUP=D44;GROUPID=4155;ARTICLE=9 7832;START=0;SORT=artnr;OFFSET=500;SID=31qdtrfKwQA R8AABo5vsAa35ec51d21f04fc9b4d6dbd6580b17b8

Dani-Bruchflieger
24.01.2011, 18:34
Hallo Sascha,

interessantes Projekt!

Falls du interesse hast, ich habe vor einiger Zeit (als 2,4GHz Fernsteuerungen nur träumereien von ein paar Freaks im RC-Line-Forum waren) auch mal ein Programm für den Mega 8 geschrieben und dabei per Rs232 und XBee eine einfache Funkfernsteuerung für meine Modelle programmiert... Dabei hatte ich auch eine Routine für die Servos implementiert, mit der man sicher auch ohne großen Aufwand 18 Servos ansteuern könnte - hab aber in meinen Modellfliegern zwar noch nie mehr als 5 echte Servos anschließen müssen, darum keine Garantie auf 18 - aber 9 gehen auf jeden Fall... - kannst mich gern per PN kontaktieren. ;)

Andere Frage - die Holzteile hast du die gefräst oder in Handarbeit gefertigt? - Frästeile könnte ich bei Bedarf fertigen... PN .... ;)

!*sascha*!
24.01.2011, 23:36
Hi,

ich habe keine Pläne im Internet gefunden und so alles selber gezeichnet.
Die Teile habe ich dann alle mit einer Laubsäge ausgeschnitten :-)

Der Körper muss jetzt wohl noch min. 2-3 cm größer werden...

Für die 2. Version werde ich mal ganz lieb bei mir auf der Arbeit nachfragen, ob ich die Teile mit dem Laster Plotter/Cuter schneiden kann.

Das Teil kann Holz und Acrylglas schneiden oder Metall gravieren.

Der Roboter hat jetzt ein Gewicht von 1200g viel mehr als ich dachte!

Dein Projekt hört sich gut an :-)

Du hast also eine 2.4GHz Funkt Verbindung zum PC geschaffen?


Oh ich muss schlafen^^ Bis später

Ich werde mein Projekt dann auf meiner Webseite Dokumentieren Datenplätter, Zeichnungen und Code usw...

Dani-Bruchflieger
25.01.2011, 16:54
Hi

nicht ganz - Modellflieger steuert man ja nicht mit dem PC... ;)
Habe eine alte Fernsteuerung genommen, alles rausgeschmissen und eine neue Elektronik eingebaut, die die Steuerknüppel einliest und diese Werte an dem Prozessor im Modell sendet, der damit die Servos für die Ruder steuert...
Übertragung war auf 256 Schritte / Servoweg reduziert und wurde dann im Empfänger mit möglichen 1024 Schritten / Servoweg ausgegeben - so war Trimmung etc dann etwas feiner abgestuft.

Leider liegt der ganze Kram nun in der Ecke, da ich im vergangenen Sommer dort eine Fehlfunktion im Sender hatte, und noch keine Zeit da mal nach der Ursache zu suchen. Außerdem hab ich jetzt ja auch 1 gekaufte 2,4GHz Fernsteuerung, die ausgezeichnet funktioniert und auch diverse einstellbare Mischerfunktionen hat, an deren Programmierung in meiner eigenen Steuerung ich total gescheitert war...

Wie gesagt - eine PN und ich schick dir mal den Bascom-Code, mit dem du dann nur noch 1 Prozessor für die 18 Servos brauchst - wird nur 1 * 16 Bit Timer benötigt dafür.

Edith: für 18 Servos hab ich die Routine jetzt umgeschrieben - aber dafür wird dann der Mega 16 benötigt - Da du ja eh auf SMD gehen willst, ist das ja kein Problem, denn da ist er ja nur minimalst größer als der M8.
RS232 und I2C-Pins bleiben dabei auch noch frei benutzbar.

$regfile = "m16def.dat"
$crystal = 8000000


Config Porta = Output 'alle Pins voll belegt
Config Portc = Output 'Pin 0 und 1 bleiben frei belegbar (I2C Bus)
Config Portd = Output 'Pin 0 und 1 bleiben frei belegbar (RS232) ebenso Pin 6 und 7 sind noch frei


Config Timer1 = Timer , Prescale = 8
Start Timer1
On Timer1 _timer1
Enable Timer1
Enable Interrupts


Dim Aktservo As Byte 'Aktuelles Servo (ISR)
Dim _aktservo As Byte 'Aktuelles Portpin für Servo (ISR)
Dim Sk(18) As Word 'Servowertearray
Dim Tempw(18) As Word 'temporären-Array mit den Werten für die 18 Servokanäle aus deinem Programm.
Dim A As Byte


'*init der Vars*
Aktservo = 1



'***Hauptschleife***
Do

For A = 1 To 18 'hier wird dem Servokanal (SK) der Wert übergeben
Sk(a) = Tempw(a) 'mögliche Werte sind von 0 bis 1024; 512 ist Mitte
Next

Loop





'*Interruptroutinen*
_timer1:
If Aktservo < 9 Then 'Servo 1-8
_aktservo = Aktservo - 1 'Pindefinition berechnen
Porta._aktservo = 0 'dann Pin ausschalten
Elseif Aktservo < 15 Then 'Servo 9-14
_aktservo = Aktservo - 7 'Pindefinition berechnen
Portc._aktservo = 0 'dann Pin ausschalten
Else 'Servo 15-18
_aktservo = Aktservo - 13 'Pindefinition berechnen
Portd._aktservo = 0 'dann Pin ausschalten
End If
Incr Aktservo 'aktuelles Servo um 1 erhöhen
If Aktservo = 19 Then 'Wenn alle 18 Servos durch sind
Aktservo = 1 'aktuelles Servo auf 1 zurücksetzen
End If
If Aktservo < 9 Then 'Servo 1-8
_aktservo = Aktservo - 1 'neue Pindefinition berechnen
Porta._aktservo = 1 'neues Pin anschalten
Elseif Aktservo < 15 Then 'Servo 9-14
_aktservo = Aktservo - 7 'neue Pindefinition berechnen
Portc._aktservo = 1 'neues Pin anschalten
Else 'Servo 15-18
_aktservo = Aktservo - 13 'neue Pindefinition berechnen
Portd._aktservo = 1 'neues Pin anschalten
End If
Timer1 = Sk(aktservo) + 63523 'Timer laden mit neuem Wert
Return

Für alle anderen hier der Code mit 5 Servos und 7 "Dummykanälen" als Word Variable:

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


Config Portb = Output

Config Timer1 = Timer , Prescale = 8
Start Timer1
On Timer1 _timer1
Enable Timer1
Enable Interrupts


Dim Aktservo As Byte 'Aktuelles Servo (ISR)
Dim _aktservo As Byte 'Aktuelles Portpin für Servo (ISR)
Dim Servo As Word 'Dummy für verarbeitung der 7 Dummyservokanäle für die Pausenzeit
Dim Sk(12) As Word 'Servowertearray
Dim Tempw(5) As Word 'temporären-Array mit den Werten für die 5 Servokanäle aus deinem Programm.
Dim A As Byte



'*init der Vars*
Aktservo = 1
_aktservo = 0
For A = 6 To 12 'Dummykanäle der Pausenzeit auf 0 setzen
Sk(a) = 0
Next



'***Hauptschleife***
Do

For A = 1 To 5 'hier wird dem Servokanal (SK) der Wert übergeben
Sk(a) = Tempw(a) 'Werte sind von 0 bis 1024 wenn ich mich jetzt nicht total irre...
Next 'ich glaube aber, daß ich nur bis 1020 übergeben habe

Loop





'*Interruptroutinen*
_timer1:
If Aktservo < 6 Then 'aktuelles Servo <6 ist noch der pin vom letzten einschalten... (wenn ausgaben an pins sollen)
Portb._aktservo = 0 'dann Pin ausschalten
Incr Aktservo 'aktuelles servo um 1 erhöhen
Else 'wenn keine Pins mehr ( Pausenzeit ab servo 6)
Servo._aktservo = 0 'Dann bit im Variable Servo ausschalten
Incr Aktservo 'aktuelles servo um 1 erhöhen
If Aktservo = 13 Then 'Wenn bei durchlauf 13 sind
Aktservo = 1 'Aktuelles Servo Auf 1 Setzen
End If
End If
_aktservo = Aktservo - 1 'da mit Portpin 0 anfangen - diese Variable eins niedriger
If Aktservo < 6 Then 'Wenn im Bereich der Pins arbeiten
Portb._aktservo = 1 'neues Pin anschalten
Else 'ansonsten
Servo._aktservo = 1 'Bit in Dummyvariable anschalten
End If
Timer1 = Sk(aktservo) + 63523 'Timer laden mit neuem Wert
Return

!*sascha*!
26.01.2011, 17:28
Hi Dani-Bruchflieger,

wuha :-)

Habe grad leider keine Zeit, aber am WE werde ich mal alles genau angucken...

Danke für deinen Code!


Gruß,
Sascha

Dani-Bruchflieger
26.01.2011, 21:45
Hi,

Prinzip ist ganz einfach:
im Interrupt vom Timer ist die erste Handlung ein Pin, an dem ein Servo angeschlossen ist ausschalten, den Zähler erhöhen und den nächsten Pin einschalten, Timer mit Vorgabe laden und fertig.
Wenn Zeit für den Pin abgelaufen, dann wird die ISR wieder aufgerufen, der Pin abgeschaltet und der nächste Pin eingeschaltet. und so weiter...
Das, was die Sache nur etwas kompliziert macht ist, daß man pro Port ja maximal 8 Pins ansprechen kann und dann eben auf nächsten Port wechseln muß - aber es sollte so funktionieren - jedenfalls hat mir Bascom keinen Fehler beim Compilieren angezeigt.

Übrigens: Wenn du einen RC-Empfänger mit dem Oszi an den Servopins misst - die machen das genauso.....

Wichtig ist nur, daß man die Zeiten für die Impulslänge genau einhält und die Pausen nicht zu lang aber auch nicht zu kurz hat.
Normal sind glaub ich von Impulszeit = 1...2ms und Gesamte Periodendauer 20ms - Periodendauer kann aber auch auf 10ms gesenkt werden (dann sind die Servos schneller) oder auch verlängert werden - in diesem Code ist die Periodendauer davon abhängig, wie lang die Impulszeiten der 18 Servos sind - minimal 18ms und maximal 36ms wird sich aber irgendwo dazwischen einpendeln...

Wenn man noch einen oder 2 weitere 16 Bit Timer frei hätte, könnte man da natürlich auch Parrallel arbeiten lassen - wobei man dann auch verdammt aufs Timing achten müsste, damit sich nichts verknotet, wenn 2 Timer gleichzeitig ihren Interrupt aufrufen wollen...