Also ich hab mal meinen code angehangen.
nur irgendwie funktionierd der nicht
Der servo macht nicht, und der Controller giebt komischerweise auch nichts über den RS232 aus.
Also ich hab mal meinen code angehangen.
nur irgendwie funktionierd der nicht
Der servo macht nicht, und der Controller giebt komischerweise auch nichts über den RS232 aus.
Wie gesagt habe ich von Bascom keine Ahnung. Da du aber fleißig kommentierst und man sich ja ein paar Sachen ableiten kann versuch ich mal etwas zu dem Code beizutragen:
Wie oben berechnet musst du den Prescaler auf mindestens 64 setzen, da der Timer sonst zu schnell arbeitet und überläuft bevor die 20ms Periodendauer vom RC-Signal rum ist. Außerdem weiß ich nicht, ob du in Bascom den Interrupt definieren musst. Ein Timer kann wie gesagt bei verschiedenen Einflüssen einen Interrupt. Wir benötigen den "Clear Timer on Compare match" (CTC) wobei man einstellen kann, ob beim treffen des eingestellten Wertes (Compare-Wert) der Timer genullt werden oder weiter laufen soll. Bei meiner Idee müsste der Timer weiterlaufen.Prescale = 1
In deiner Interruptroutine steht der Befehl Timer1=64428. Ich gehe mal davon aus, dass du damit versucht den neuen Wert festzulegen, bei dem der Timer einen Interrupt auslöst. Einen solchen Befehl finde ich aber nicht während der Initialisierung. Dem Tmer würde also ein Wert fehlen bei welchem er den ersten Interrupt auslöst.
Ausserdem hast du unterden Befehl Phase = 3. Da sollte bestimmt =4 stehen damit er in die letzen Phase springt.If Phase = 3 Then
Zudem sieht mir die ganze Interruptroutine nicht so aus, als würde es ein verlässliches Servosignal erzeugen.
Geändert von Arkon (11.08.2011 um 07:46 Uhr)
Alles ist möglich. Unmögliches dauert nur etwas länger!
Nein du denkst falsch, ich will ja das der timer überläuft, den dann wird die rutine ausgeführt,
Der Befehl Timer1=64482 oder wie auch immer sorgt dafür, das der timer schon eher überläuft.
Der Code den ich angehangen habe ist nur für 1 servo,
in Phase 1 wird der timer so vorgladen, dass 0,3ms Pause entstehen, ind Phase 2 so, das die zeit, die das Servosignal braucht entsteht, und in Phase 3 wieder 0,3ms pause.
in Phase 4 wird dann der Start geschrieben.
Daraus das du dich mit Bascom nicht auskennst schliese ich mal, das du C programmierst.
Wie würdest du es denn dort lösen ?
Schlieslich Programmiere ich auf dem PC auch C++.
MFG Thalhammer
So, ich hab jetzt bischen weiter gesucht, und das:
http://www.mitchsoft.de/Modelbau/PPM-Encoder/index.html
sowie das gefunden:
http://www.ulrichradig.de/home/index.php/avr/avr_-_rc
Das erste würde sogar eine Steuerung über RS232 zulassen, Problem: die arbeiten alle mit 8Mhz, was die sache enorm vereinfacht.
Nur die hab ich leider nicht.
MFG Thalhammer
Was mir grade einfällt: Kann der Atmega kein PWM-Signal erzeugen? Also ich meine mal ein Programm geflasht zu haben, bei dem ich nur die Periodendauer und die HIGH-Zeit definieren musste. Damit habe ich ein einzelnes Servo angesteuert. Das kann man bestimmt anpassen um ein Summensignal zu erzeugen. Ich muss grade mal einkaufen und gucke dann ob ich was entsprechendes finde.
Alles ist möglich. Unmögliches dauert nur etwas länger!
http://www.mikrocontroller.net/topic/177721
Ist zwar C-Code aber damit hast du zumindest einen Ansatz.
Timer1 kann intern ein PWM-Signal erzeugen. In dem Beitrag geht es darum ein Servo anzusteuern. Ich weiß nicht wie du das Summensignal weiterverwenden möchtest. Servos sind, was die Periodendauer angeht, sehr kulant. Wenn du das PWM jetzt mit einer Periodendauer von 5ms (20ms/4Kanäle) initialisierst und nach jedem HIGH-Pegel das OCR1A-Register mit dem neuen Wert für den jeweiligen Kanal beschreibst hast du dein Summensignal.
OCR1A
Alles ist möglich. Unmögliches dauert nur etwas länger!
Also ich habe im Datenblatt mal gelesen, dass der erste Impuls möglicherweise verfälscht sein kann, wenn man das OCR-Register im "laufenden Betrieb" ändert. Für die meisten PWM-Anwendungen mag der erste Impuls nicht besonders wichtig sein - aber hier wäre das natürlich fatal.
Was hältst Du von folgendem Ansatz:
Im Rest der Hauptschleife kannst Du Dich dann darum kümmern, dass die Werte Impuls(1) bis Impuls(4) per RS232 aktualisiert werden. Sie bestimmen, wie lange Timer1 bis zu seinem nächsten Überlauf braucht, und somit die Dauer der High-Impulse. Logischerweise berechnen sie sich so: Impuls = 65535 - (3686400 * Impulslänge in Sekunden).Code:Dim Impuls(4) as Word 'Ist ein Array aus 4 Word-Variablen Dim Index as Byte 'Zum Durchzählen von Impuls(1) bis Impuls(4) Dim Flag as Bit 'Zeigt Timer1-Interrupt an Config PORTX.Y = Output 'Ausgangs-Pin On Timer1 Timer1_ISR Enable Timer1 Enable Interrupts Do ... ... If Flag = 1 then Flag = 0 If PORTX.Y = 1 then PORTX.Y = 0 Timer1 = Timer1 + 64429 'Nächster Überlauf in 0,3 ms Else PORTX.Y = 1 If Index = 4 then Index = 1 Else Index = Index + 1 Timer1 = Timer1 + Impuls(Index) End if End if ... ... Loop On Timer1_ISR: Flag=1 Return
Diese Idee ist allerdings nicht getestet, noch nicht mal compiliert, weil ich hier gerade kein Bascom habe. Aber vielleicht reicht ja die Idee schon...
Lesezeichen