PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RC Summensignal Atmega8



Thalhammer
10.08.2011, 13:35
Hallo, ich habe folgendes Problem:
Ich möchte mit dem Atmega ein RC Summensignal generieren.
Die Auflösung sollte mindestens 200 Schritte sein.
Die wertvorgabe soll über rs232 vom pc kommen.
Kanalanzahl ist ja eigentlich egal, aber es müssen mindestens 4 sein.

So nun das, was es zu einem Problem macht:
Ich habe nur einen Myavr MKII zur verfügung, und der läuft nur mit 3,6468 MHz
Ich vermute mal, das das ziemlich kanpp wird oder ?
Ich hab mir schonmal von dem rntool dafür die zeiten für die timer ausrechnen lassen, sowie das beispiel im wiki angekuckt.
kann mir vieleicht einer einbeispiel geben wie ich das regeln kann ?
Hab nicht wirklich ahnung von BASCOM und microcontrollern, aber eine fertige lösung, die das summensignal ausspuckt hab ich nicht gefunden.
DAS RS232 Protokoll soll so aufgebaut sein:
#S als startmarkierung und dann die werte der einzelnen kanäle als bytes.

Ne fertiglösung wär mir am liebsten, aber das kann ich hier nicht erwarten oder ?

MFG Thalhammer

Arkon
10.08.2011, 13:59
Ne fertige Lösung habe ich jetzt nicht parat. Und ich weiß auch nicht ob mein erster Gedanke brauchbar ist oder total ineffizient aber ich probiere es trotzdem und lasse mich gerne korrigieren:

Ich würde einen Timer mit Compare-Interrupt initialisieren. den ersten Interrupt gleich bei 0 oder 1 auslösen lassen -> Pin auf High, den Wert für den ersten Kanal auf die Timerlaufzeit umrechnen und den Timer bei diesem Wert den nächsten Interrupt auslösen lassen. Bei diesem dann entsprechend den Pin auf Low und neuen Interruptwert festlegen. Das ganze Spiel dann so oft wiederholen lassen bis die gewünschte Anzahl an Kanälen entstanden ist.

Thalhammer
10.08.2011, 15:49
Also hab jetzt ein bischen mit den timerwerten gespielt und nach gerechnet.
bei dem 16 Bit timer und einem prescaler von 1 währe 0,1 ms ungefär ein timer wert von 369.
heist: um die werte die vom pc kommen(1 -200) in timer werte umzurechenen währe folgende gleichung nötig:
1 : pc_wert * 3690 = Timerwert für den impuls
oder irre ich mich da ?
heist um die zeit bis zum nächsten interupt einzustellen müsste ich doch nur den timer auf den maximalwert des timers minus diesen wert setzen oder ?
Ich hab noch nicht viel mit timern gearbeitet, von daher weis ich nicht wie genau man sowas realisieren kann.

Arkon
10.08.2011, 16:34
Dein Timer macht bei einem Prozessortakt von 3,6468 MHz und einem Prescaler von 1 entsprechend 3,6468*10^6 Schritte pro Sekunde. Bei einer Periodendauer von 20ms pro Kanal macht der Timer (3,6468*10^6)/50=72936 Schritte. Ein 16bit-Timer läuft bei 2^16-1=65535 (man fängt bei 0 an zu zählen) über. Du musst also einen Vorteiler wählen, damit dein Timer innerhalb von 20ms diesen Wert nicht überschreitet. (3,6468*10^6)/65535 = 55,6 also brauchst du einen Prescaler von 64.

Damit macht dein Timer in den 20ms Periodendauer, die ein RC-Kanal hat, (3.6468*10^6)/64 = 56981 Schritte. Ein Servosignal ist im Normalfall 1ms (Stellung ganz links) bis 2ms (Stellung ganz rechts) HIGH (man kann den Verfahrweg durch entsprechend kleinere bzw. größere Werte noch aufbohren, das müsstest du dann ausprobieren was du brauchst).

Wenn du den Verfahrweg jetzt noch in 200 Schritten auflösen möchtest unterteilst du die "High-Zeit" für jeden Kanal in 1ms/200Schritte = 0,005 ms/Schritt. Damit ergibt sich für jeden Schritt Auflösung eine Timerlaufzeit von rund 14,25 Schritten.

ACHTUNG: In meinen Ausführungen bitte nicht die Schritte, die der Timer macht mit den Schritten deiner Auflösung verwechseln/durcheinander bringen.

Thalhammer
10.08.2011, 17:07
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.

Arkon
11.08.2011, 08:30
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:


Prescale = 1
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.

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 unter
If Phase = 3 Then den Befehl Phase = 3. Da sollte bestimmt =4 stehen damit er in die letzen Phase springt.

Zudem sieht mir die ganze Interruptroutine nicht so aus, als würde es ein verlässliches Servosignal erzeugen.

Thalhammer
11.08.2011, 11:16
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

Thalhammer
11.08.2011, 15:02
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

Arkon
11.08.2011, 17:12
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.

Arkon
11.08.2011, 20:52
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

Sauerbruch
12.08.2011, 07:49
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:




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


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).

Diese Idee ist allerdings nicht getestet, noch nicht mal compiliert, weil ich hier gerade kein bascom habe. Aber vielleicht reicht ja die Idee schon...

Thalhammer
12.08.2011, 08:02
Ich hab jetzt deine Idee noch nicht genau durchgelesen, aber ich denke ich werde mir ein Quarz mit 8Mhz besorgen und die Lösung die ich oben verlinkt habe nutzen.
Edit: Könnte mir eventuell einer das Programm kompilen ?
Weil ich nur die Demo von Bascom habe ?

MFG Thalhammer

Rone
12.08.2011, 08:22
Hallo!

Was denn nun?

Die Servo-bas von oben belegt grade mal 12% vom Flash,
und die Soft von Mitchsoft liegt als Hex vor ????


MfG
Rone

Thalhammer
12.08.2011, 08:31
Ach ja stimmt hatte übersehen das die schon als Hex vorliegt.
;) Mein Fehler *duck*
So Problem erledigt, Es funktionierd wie es soll.
Muss mir nur bei gelegeheit noch ein externes Quarz mit 8Mhz besorgen, wobei wenn ich mir das so ansehe ist das signal doch recht stabil dafür das ich für sowas den internen Takt nehme :-)
So jetzt steht dem Flug nichts mehr im weg :-)
Ein XBEE Pro noch dazu und fertig.

MFG Thalhammer

Arkon
12.08.2011, 09:14
Was hast du denn vor? Soll das ne Drohne werden? Dann bitte ich um mehr Informationen!

Thalhammer
12.08.2011, 10:52
Soll werden ist relativ:
Ich hab schon seit längeren einen Mikrokopter als Quadro.
und denn wollte ich mal über Joystick steuern.
War mehr ne witz idee, und ich hätte auch nicht gedacht, das es so relativ einfach ist.
Naja dann ist mir eingefallen das ich ja noch mein MKII hab, und hab einfach mal auf gutglück hier gepostet.
naja Die PC Software schreib ich selbst und werd jetzt erstmal gucken.
Problem ist halt das ich momentan recht knapp bei kasse bin und 2x XBee Pro kosten halt doch fast 80 €
MFG Thalhammer

EDIT:
Jetzt schreib ich aber erstmal die Software, erst Konsole dann GUI für Unix und Windows, dann mal schauen ob ich mir die Xbee's hol.
Aber wenn du einen guten shop in Deutschland kennst wo ich die herkriege immer her damit.
Weil Reichelt und co haben alle nur diese 2mW module.
ich will aber die vollen 100, auch wenn ich sie nicht nutzen darf :-)