PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Suche Hilfe bei Messung Summensignal an Modellflugempfänger



Salvador
01.06.2008, 12:27
Hi,

ich komm' nicht mehr weiter bei folgendem Problem:

An einem Modellflugempfänger wird das Summensignal abgegriffen (siehe Bild):

http://gallery.mikrokopter.de/main.php?g2_view=core.DownloadItem&g2_itemId=1289&g2_serialNumber=2

Nun benötige ich den Wert der ersten vier Impulse (= Kanäle)

Und nach einigen Versuchen hab' ich folgendes Programm geschrieben:


$baud = 9600
$crystal = 16000000
$regfile "m32def.dat"

Config Portc.2 = Output
Vorne Alias Portc.2
Config Portc.1 = Output
Hinten Alias Portc.1
Config Portc.0 = Output
Links Alias Portc.0
Config Portd.7 = Output
Rechts Alias Portd.7



Config Timer0 = Timer , Prescale = 1024 'konfiguriere Timer0
Enable Timer0
Stop Timer0



Config Int0 = Rising 'configuriere Int0 Auf Low Level
Enable Interrupts 'einschalten der Interrupts
Enable Int0 'einschalten Von Interrupt Int0
On Int0 Summensignalmessung 'springe Zu einstellen_von _int0



Dim Pitch As Byte
Dim Gier As Byte
Dim Roll As Byte
Dim Nick As Byte
Dim Messung As Bit
Dim Kanal As Byte
Dim Zaehler As Byte


Do

Links = 1
Links = 0



Loop


Summensignalmessung:
Rechts = 1



If Messung = 0 And Kanal = 0 And Timer0 < 50 Then
Stop Timer0
Tcnt0 = 0
Start Timer0
End If

If Messung = 0 And Kanal = 0 And Timer0 > 50 Then
Stop Timer0
Tcnt0 = 0
Start Timer0
Messung = 1
Incr Kanal
End If

If Messung = 1 And Kanal = 1 Then
Stop Timer0
Timer0 = Pitch
Tcnt0 = 0
Start Timer0
Incr Kanal
End If

If Messung = 1 And Kanal = 2 Then
Stop Timer0
Timer0 = Gier
Tcnt0 = 0
Start Timer0
Incr Kanal
End If

If Messung = 1 And Kanal = 3 Then
Stop Timer0
Timer0 = Roll
Tcnt0 = 0
Start Timer0
Incr Kanal
End If

If Messung = 1 And Kanal = 4 Then
Stop Timer0
Timer0 = Nick
Tcnt0 = 0
Start Timer0
Messung = 0
Kanal = 0
End If

Incr Zaehler
If Zaehler = 250 Then
Print Pitch
Print Gier
Print Roll
Print Nick
Zaehler = 0
End If

Rechts = 0

Return


End

Sorry für die nicht vorhandenen Kommentare, aber ich schreib' die immer erst am Schluss rein :-k

Die Ausgänge sind die Servoimpulsausgänge für die vier Regler, die später angesteuert werden (daher kann Timer1 nicht verwendet werden)

Was ich in dem Programm versucht habe: Summensignal ist am Interrupt- Pin0 angeschlossen (Pind.2 glaub ich), bei einer steigenden Flanke geht der MC in ein Unterprogramm, in dem je nach gesetztem KanalByte und Messungsbit der Zähler gestartet oder gestoppt wird. Wenn das Kanalbyte zwischen 1 und 4 ist werden entsprechende Variablen mit dem Wert des Timers überschrieben, sie Stellen also die Position der Knüppel am Sender dar.

Nur das Problem an der Sache: Angefangen hab ich mit einem Prescaler von 1024, wollte sehen wie hoch der Zähler denn kommt. Aber beim Befehl "print" kam nur 0 raus. Laut meinen Berechnungen müsste der Timer aber bei einer Impulsdauer von 2ms bis knapp über 30 zählen. Als ich direkt den Timerwert ausgelesen hab' kamen dann 36 bei "roll" raus, aber der Wert änderte sich nicht bei verändern der Impulsdauer (also wenn man den Knüppel am Sender bewegt).

Bei einem Versuch, einen 1 Sekundentakt herzustellen fiel mir auf dass der berechnete Wert garnicht stimmte. Vll. auch ein Programmfehler von mir.

Ich wäre euch sehr dankbar wenn ihr mir beim Thema Timer weiterhelfen würdet, komme auch mit den Infos aus dem RN-Wissen nicht weiter. Hab mich bis jetzt noch nicht allzu sehr damit beschäftigt.

for_ro
01.06.2008, 13:11
Im Moment habe ich keine Zeit, daher nur ein kurzer Hinweis:
Du speicherst mit

Timer0 = Gier

den Wert von Gier in den Timer counter. Ich denke, du willst das doch wohl eher umgekehrt machen, also mit

Gier = Timer0

den Wert des Timers in der Variablen speichern.

Gruß

Rolf

Salvador
01.06.2008, 13:23
ups. das stimmt 8-[ werds nacher mal testen

Salvador
01.06.2008, 14:40
So, jetzt gibt der MC immer folgendes aus

Bei Prescaler 1:

41
36
36
36


41 ist Pitch,dann kommt Gier, Roll und Nick.

Ändern tut sich nix. Die Impulslängen verändern sich aber beim Bewegen der Knüppel.

Und bei Prescaler 1024 kommt entweder nullen oder ab und zu auch mal ne 1 :-k

for_ro
01.06.2008, 14:55
So wie du das aufgesetzt hast, würde ich denken, dass du immer die Zeit von einer steigenden Flanke zur nächsten misst. Die ist aber doch bestimmt konstant, nur das Verhältnis von high zu low ändert sich.
Entweder du änderst den Interrupt ab
Config Int0 = Change
dann bekommst du bei jedem Wechsel von high auf low und umgekehrt einen Interrupt (musst du deinen Code natürlich anpassen!) oder du fragst beim Incr befehl ab, ob der entsprechende Eingang (z.B. Gier) noch auf high ist.

Gruß

Rolf

Salvador
01.06.2008, 15:28
Du hast es richtig erkannt, dass ich von flanke zu flanke messe. Aber auf meinem Oszi verändert sich jeweils nur der Impuls, d.h. die ganze darauffolgende Impulsreihe verschiebt sich etwas!

Ich werde das mit "Change" trotzdem mal probieren.. Und vor allem nochmal nachmessen. Machst mich grad unsicher 8-[

Salvador
01.06.2008, 16:56
$baud = 9600
$crystal = 16000000
$regfile "m32def.dat"

Config Portc.2 = Output
Vorne Alias Portc.2
Config Portc.1 = Output
Hinten Alias Portc.1
Config Portc.0 = Output
Links Alias Portc.0
Config Portd.7 = Output
Rechts Alias Portd.7



Config Timer0 = Timer , Prescale = 256 'konfiguriere Timer0 auf 16mikrosekunden pro takt
On Timer0 Pausenerkennung
Enable Timer0 '125 takte für 2millisekunden

Stop Timer0
Timer0 = 200



Config Int0 = Change 'configuriere Int0 Auf Wechsel
Enable Interrupts 'einschalten der Interrupts
Enable Int0 'einschalten Von Interrupt Int0
On Int0 Summensignalmessung 'springe Zu Summensignalmessung



Dim Pitch As Byte
Dim Gier As Byte
Dim Roll As Byte
Dim Nick As Byte
Dim Messung As Bit
Dim Anfang As Bit
Dim Kanal As Byte



Do

Links = 1
Links = 0

Waitms 1000

Print Pitch
Print Gier
Print Roll
Print Nick

Loop


Summensignalmessung:

If Messung = 0 And Kanal = 0 And Anfang = 1 Then
Start Timer0
Messung = 1
Anfang = 0
Incr Kanal
End If

If Messung = 0 And Kanal > 0 And Anfang = 0 Then
Start Timer0
Messung = 1
Incr Kanal
End If

If Messung = 1 And Kanal = 1 Then
Stop Timer0
Pitch = Timer0
Timer0 = 200
Messung = 0
End If

If Messung = 1 And Kanal = 2 Then
Stop Timer0
Gier = Timer0
Timer0 = 200
Messung = 0
End If

If Messung = 1 And Kanal = 3 Then
Stop Timer0
Roll = Timer0
Timer0 = 200
Messung = 0
End If

If Messung = 1 And Kanal = 4 Then
Stop Timer0
Nick = Timer0
Timer0 = 200
Messung = 0
End If



Return


Pausenerkennung:

Stop Timer0
Timer0 = 200
Anfang = 1
Print ; "pause"
Return

End

Und immernoch: Nur Nullen. Aber(!) wie man sieht ist am Schluss im Unterprogramm Pausenerkennung ein Printbefehl drin, d.h. normal müsste ich sehen wenn der Timer in den Überlauf geht (wie gewollt, damit die Pausenzeit mit mehr als 2ms erkannt wird). Am Anfang war der Startwert des Zählers 100, da müsste der Timer nur in der Pause in den Überlauf gehen. Bei 200 müsste er immer in den Überlauf gehen - tut er aber nie! Wo könnte das Problem sein?


Braucht man evtl. nen speziellen Datentyp für die Variablen (Pitch usw.) ?

Übrigens verändert sich mit Sicherheit nur die Impulsdauer, nicht das Tastverhältnis. Ich hab im Programm, das ich am Anfang gezeigt hab mal die gemessene Pausenzeit anzeigen lassen - die verändert sich wenn man die Knüppel von Endanschlag nach Min. Anschlag bewegt!

for_ro
01.06.2008, 19:23
Bei einem Versuch, einen 1 Sekundentakt herzustellen fiel mir auf dass der berechnete Wert garnicht stimmte. Vll. auch ein Programmfehler von mir.
Dies musst du unbedingt überprüfen, sonst stimmen alle Zeiten nicht.
Check mal die Fuse Clkdiv8 (oder so ähnlich).


Bei 200 müsste er immer in den Überlauf gehen - tut er aber nie! Wo könnte das Problem sein?

Wenn der Timer0 bei 200 anfängt zu zählen und deine Werte immer 36 und 41 sind, dann muss er schon übergelaufen sein.
Ich habe heute Abend noch etwas Zeit und wenn sich bis dahin niemand anderes gemeldet habe, dann schreibe ich dir deinen Code mal so um, wie ich es machen würde.

Gruß

Rolf

Michael
01.06.2008, 21:21
Hallo Salvador,

natürlich steckt die Impulslänge zwischen 2 steigenden Flanken,
Config Int0 = Rising war richtig.

Bei 16 Mhz Taktfrequenz und einem Prescaler von 256 läuft der Timer mit 62500 Hz. Also nach gut 4ms ist ein Überlauf zu erwarten.
Der Wert für einen Impuls von 1,5ms sollte um 93 liegen.

Kannst du nachprüfen, ob der Interrupt überhaupt angesprungen wird? Du kannst ja z.B. eine LED anschalten lassen.

Nach dem Einsprung in den Interrupt würde ich (nach dem Sichern) Timer0 löschen. Dann läuft er wieder von 0 losfür die nächste Messung.
Ein Stoppen des Timers ist nicht erforderlich und für die Genauigkeit der Messung nicht hilfreich.
Im Überlauf-Interrupt löschst du einfach die Kanal-Variable. Dort kannst du auch ein Flag setzen, welches im Hauptprogramm nach dem seriellem Senden dieses wieder löscht.
So hast du die Werte einmal pro Impulstelegramm gesendet.
Bedenke aber, daß bei 9600 Baud ein Zeichen ungefähr 1 Millisekunde dauert. Bei deinen 4 Werten mit je 5 Zeichen sind das schon 20ms!
Dazu kommt noch das Wörtchen "pause" welches nochmal 7ms braucht.

Gruß, Michael

Salvador
03.06.2008, 19:39
Ich hab im Programm beim Anfang des Interrupts den Ausgang "Rechts" auf 1 gesetzt, am Ende wieder auf 0 - somit konnte ich mit dem Oszi messen, dass der verdammt schnell bzw. oft in den Interrupt geht. Es ist also eher ein Problem des Timers / der Variablenübertragung... Ich mach erstmal ein paar Versuche mit dem Timer, damit ich weis wie der sich zu verhalten hat im Normalfall ^^

Sorry, dass ich so lange nicht geantwortet hab, aber durch die Arbeit hab ich unter der Woche kaum Zeit.

Salvador
03.06.2008, 21:29
Tja, wer hätte es gedacht: Erst habe ich einige Versuche mit dem Timer gemacht, um richtig zu verstehen wie er funktioniert, dann ein Programm geschrieben und siehe da - es funktioniert !!


$baud = 9600
$crystal = 16000000
$regfile "m32def.dat"

Config Portc.2 = Output
Vorne Alias Portc.2
Config Portc.1 = Output
Hinten Alias Portc.1
Config Portc.0 = Output
Links Alias Portc.0
Config Portd.7 = Output
Rechts Alias Portd.7



Config Timer0 = Timer , Prescale = 256 'konfiguriere Timer0 auf 16mikrosekunden pro takt, überlauf bei ca. 4ms
Enable Timer0
On Timer0 Pausenerkennung




Config Int0 = Falling 'configuriere Int0 fallende Flanke
Enable Interrupts 'einschalten der Interrupts
Enable Int0 'einschalten Von Interrupt Int0
On Int0 Summensignalmessung 'springe Zum Interrupt von Timer0



Dim Pitch As Byte
Dim Gier As Byte
Dim Roll As Byte
Dim Nick As Byte
Dim Uebertragewert As Byte
Dim Kanal As Byte
Dim Zaehler As Byte



Do

Links = 1 'Zwei befehle, damit der Controller beschäftigt ist
Links = 0 'normal steht hier das normale Programm



Loop


Summensignalmessung:

Uebertragewert = Timer0
Timer0 = 0

If Kanal = 1 Then
Pitch = Uebertragewert
End If

If Kanal = 2 Then
Gier = Uebertragewert
End If

If Kanal = 3 Then
Roll = Uebertragewert
End If

If Kanal = 4 Then
Nick = Uebertragewert
End If


Incr Kanal


Return


Pausenerkennung: 'wenn der Zähler überläuft sind mehr als 4ms vergangen, also muss es eine Pause sein...

Kanal = 0

Incr Zaehler

If Zaehler = 100 Then
Zaehler = 0
Print Pitch ; "p"
Print Gier
Print Roll
Print Nick ; "n"
End If

Return



End

Weiter gehts dann wieder in meinem Thread "4C":

https://www.roboternetz.de/phpBB2/viewtopic.php?t=40365&start=0

Danke für euren Beistand =D>