Forum: Mikrocontroller und Digitale Elektronik Delta- Mischer mittels AVR


von Andi K. (aykay90)


Angehängte Dateien:

Lesenswert?

Hallo zusammen!

Neulich habe ich mir einen kleinen Flieger mit einem Deltaleitwerk 
gebastert, der nun einen Delta- Mischer bekommen soll. Und genau den 
wollte ich mir selber machen mit nem AVR.
Das Prinzip vom Mischen der Kanläe verstehe ich ja auch das verrechnen 
(invertieren) geht wunderbar. Nur bei der Signalausgabe happert es ein 
wenig. Ich habe schon so einiges versucht, aber mein Oszi und ich können 
uns einfach nicht einigen.

Im Anhang ist das Bild des Oszi zu sehen, wobei blau das Signal des 
Empfängers darstellt und das Gelbe, das vom AVR erzeugte Signal ist.

Mit einer IF-THAN-ELSE- Schleife invertiere ich die Variabel A solange, 
bis das Signal am empfänger abfällt. Dabei habe ich in der Schleife eine 
Wartezeit von 1us, also habe ich am bei Mittelstellung (1.5ms) ca. 
1500us.
Die Durchlaufzeit bei 10MHz ist so gering, dass mich da die 
Signalverfälschung nicht weiter stört.
Die Variabel A wird nun auusgegeben, indem ich wieder eine warteschleife 
mache und dabei jedesmal um 1 runterzähle. Und genau da liegt das 
Problem. anstelle am Ausgang ein brauchbares Signal zu erhalten, habe 
ich ne Rechteckkurve von jeweils 5ns! Die gute Nachricht ist jedoch, 
dass sich meine Pulsvolge proportional zur Signalkurve des Empfängers 
verhält. (1:1)
Hier mein Code, ich weiss echt nicht, was da noch falsch ist.
Ich bin noch nicht fertig damit, ich möchte nur mal eine Pulszeit messen 
und sie Wieder ausgeben, das ist alles. dDas beimischen des Höhensignals 
kommt dann noch. Die Berechnung für das 2te Querrudersignal ist jedoch 
schon gemacht, das müsste soweit gehen.

Habt ihr eine Idee was man da machen kann?
Ich sage schon einmal DANKE!

Code:
$regfile = "m48def.dat"
$crystal = 10000000
$baud = 9600



'=============================== Servo einlesen

Config Pind.4 = Input
Config Pind.3 = Input

Servo1_h_in Alias Pind.4
Servo2_s_in Alias Pind.3
'=============================== Servo ausgeben

Config Pinc.1 = Output
Config Pinc.2 = Output

Servo1_out Alias Pinc.1
Servo2_out Alias Pinc.0
'===============================


Dim Servo1_h_in As Bit
Dim Servo2_s_in As Bit
Dim Servo1_out As Bit
Dim Servo2_out As Bit

Dim A As Integer
Dim B As Integer
Dim C As Integer
Dim D As Integer
Dim E As Integer

Dim U As Integer
Dim V As Integer
Dim W As Integer
Dim Z As Integer
Dim K As Integer
Dim Q As Integer
Dim X As Integer


Waitms 100


Main:
A = 0
B = 0
C = 0
D = 0
E = 0

Do

If Servo1_h_in = 1 Then
Goto Servo1
End If
Loop


Servo1:
Do
If Servo1_h_in = 0 Then
Goto Servo2
Else
Incr A
Waitus 1
Loop
End If

Servo2:
Do
If Servo2_s_in = 0 Then
Goto Ausgabe_quer
Else
Incr B
Waitus 1
Loop
End If

Ausgabe_quer:
C = A - 1500
D = C + 1
K = D * -1
E = K + 1500

Do
If A > 0 Then
Sbi  Pinc , 1
Decr A
Waitus 1
Loop
Else
cbi  Pinc , 1
Waitms 5
Goto Main
End If


'Ausgabe_quer_1:
'Do
'Set Servo2_out
'If E < 1 Then
'Else
'Reset Servo2_out
'Goto Main
'End If
'Decr E
'Waitus 1
'Loop



End

Grüsse

von Karl H. (kbuchegg)


Lesenswert?

Andreas Kuster schrieb:

> Habt ihr eine Idee was man da machen kann?

Rücke deinen Code ein!
1
Do
2
  If A > 0 Then
3
    Sbi  Pinc , 1
4
    Decr A
5
    Waitus 1
6
    Loop
7
  Else
8
    cbi  Pinc , 1
9
    Waitms 5
10
    Goto Main
11
  End If

Und jetzt schau mal, wo das schliessende Loop zum Do steht.
Sicher bin ich nicht, aber zumindest sieht es nicht vernünftig aus.
Was spricht gegen
1
  Sbi PinC, 1
2
3
  while A > 0
4
    Decr A
5
    Waitus 1
6
  wend
7
8
  cbi PinC, 1
9
  Waitms 5
10
  goto main

AUch wenn die Programmiersprache BASCOM heißt, solltest du dir trotzdem 
einen strukturierten Ansatz angewöhnen und auf goto quer durchs Gemüse 
verzichten. Es führt genau zu diesem schwer zu durchschauenden, 
unwartbaren Spaghetticodestil, der zu recht verpöhnt ist.

von Andi K. (aykay90)


Lesenswert?

Oke, danke!
Ja ich werde es mir angewöhnen ;-)
Also das Programm läuft noch immer nicht, jedoch sieht das Signal schon 
etwas anders aus.
Das gelbe Signal wechselt jetzt bei jeder fallenden Flange des blauen 
Signals, die eigene. Also "(blau=0/ gelb=0), (blau=1/ gelb=0), (blau=0/ 
gelb=1)"

von Andi K. (aykay90)


Angehängte Dateien:

Lesenswert?

...Hier noch das Bild dazu...

von Karl H. (kbuchegg)


Lesenswert?

Hier derselbe Müll
1
Do
2
If Servo1_h_in = 0 Then
3
Goto Servo2
4
Else
5
Incr A
6
Waitus 1
7
Loop
8
End If

Überarbeite deinen Code komplett.

Rücke ihn ein, sieh zu dass du die goto los wirst. In deinem Code kannst 
du fast alle goto mittels einem while erschlagen.

Ach was solls
1
...
2
3
Waitms 100
4
5
Do
6
  ' warte auf die steigende Flanke
7
  while Servo1_h_in = 0
8
  wend
9
10
  ' die Flanke ist da, jetzt die Laenge des 1 Pulses ausmessen
11
  A = 0
12
  while Servo1_h_in = 1
13
    Incr A
14
    Waitus 1
15
  wend
16
17
18
19
  ' den Ausgabepuls erzeugen
20
  ' dazu den Ausgabepin auf 1 ...
21
  Sbi PinC, 1
22
23
  ' ... und die Pulslänge absitzen ...
24
  while A > 0
25
    Decr A
26
    Waitus 1
27
  wend
28
29
  ' ... und den Ausgabepin wieder auf 0
30
  cbi PinC, 1
31
32
  ' dem Servo seine Pause goennen
33
  Waitms 5
34
35
  ' und ab zur naechsten Runde
36
Loop
37
End

Die Erwartung ist, dass der Ausgabepuls (gelb) genau dem Eingangspuls 
(blau) folgt. Wird blau kürzer, wird auch gelb kürzer und umgekehrt.
Passiert das?

von STK500-Besitzer (Gast)


Lesenswert?

>Ausgabe_quer:
>C = A - 1500
>D = C + 1
>K = D * -1
>E = K + 1500

Interessante Berechnung...

von bix (Gast)


Lesenswert?

Es gibt mehrere logische Fehler, z.B. in diesem Code:
1
Servo1:
2
Do
3
If Servo1_h_in = 0 Then
4
Goto Servo2
5
Else
6
Incr A
7
Waitus 1
8
Loop
9
End If

Man kann Strukturen verschachteln, z.B.
1
Do
2
  If .. Then
3
    ..
4
  Else
5
    ..
6
  Endif
7
Loop

Aber der Code von Servo1 sollte eigentlich eine eine Fehlermeldung des 
Compilers bringen:
1
Do
2
  If .. Then
3
  Else
4
5
  !! Hier fehlt das Endif
6
7
Loop
8
9
End If  !! Hier gehört es nicht hin
10
11
Außerdem sollte man nicht mit Goto aus einer Do..Loop Schleife springen.

von Andi K. (aykay90)


Lesenswert?

Ich habe schon so viel am Code rumgebastelt, dass der hald so geendet 
ist...Die end ifs hatte ich alles auch mal anders...
Die Berechnung invertiert die gemessene Zeit und stellt diese umgekehrt 
proportional zur gemessenen Zeit dar -> Taschenrechner hervornehmen und 
mal mit ner Zahl versauchen. Das brauche ich später um das Querruder zu 
steuern. Das eine Servo verhält sich gleich zum Steuerknüppel und das 
Andere eben gertade umgekehrt proportional.
wie gesagt, der Code ist n bastel.
Aber funktionieren tut er Trotzdem noch nicht :( es ist genau das 
gleiche Bild wie dso_2.gif.
Was kann denn da noch falsch sein? wieso geht das mit der Ausgabe nicht?
Eigentlich müsste das gelbe Signal nach der Zeit in A wieder abfallen.

von Andi K. (aykay90)


Lesenswert?

Also das finde ich eigenartig. ich habe mal diesen Code laufen geladden:

$regfile = "m48def.dat"
$crystal = 10000000
$baud = 9600



'=============================== Servo einlesen

Config Pind.4 = Input
Config Pind.3 = Input

Servo1_h_in Alias Pind.4
Servo2_s_in Alias Pind.3
'=============================== Servo ausgeben

Config Pinc.1 = Output
Config Pinc.2 = Output

Servo1_out Alias Pinc.1
Servo2_out Alias Pinc.0
'===============================


Dim Servo1_h_in As Bit
Dim Servo2_s_in As Bit
Dim Servo1_out As Bit
Dim Servo2_out As Bit

Dim A As Integer
Dim B As Integer
Dim C As Integer
Dim D As Integer
Dim E As Integer

Dim U As Integer
Dim V As Integer
Dim W As Integer
Dim Z As Integer
Dim K As Integer
Dim Q As Integer
Dim X As Integer


Waitms 100

Do
Main:
B = 0
C = 0
D = 0
E = 0


  ' warte auf die steigende Flanke
  while Servo1_h_in = 0
  Wend



  ' die Flanke ist da, jetzt die Laenge des 1 Pulses ausmessen
  A = 0
  while Servo1_h_in = 1
    Incr A
    Waitus 1
  Wend



'Servo2:
'Do
'If Servo2_s_in = 0 Then
'Goto Ausgabe_quer
'Else
'Incr B
'Waitus 1
'Loop
'End If

Ausgabe_quer:
C = A - 1500
D = C + 1
K = D * -1
E = K + 1500

 ' den Ausgabepuls erzeugen
  ' dazu den Ausgabepin auf 1 ...
  Sbi PinC, 1

  ' ... und die Pulslänge absitzen ...
  'While A > 0
    'Decr A
    Waitus 1000
  'Wend

  ' ... und den Ausgabepin wieder auf 0
  cbi PinC, 1

  ' und ab zur naechsten Runde
Loop
End



Also im Prinzip nur den Ausgang ne ms lang gesetzt. doch das Signal war 
genau gleich, wie schon auf dem 2ten Bild.
auch wenn ich den Ausgang Setze und gleich wieder lösche (kein Wait 
dazwischen) bekomme ich das gleiche Bild.
Was heisst denn das? Ich bin verwirrt.
Was auch komisch ist, verändere ich Die Pulslänge am Sender, so passt 
sich die gelbe Linie an.

von Karl H. (kbuchegg)


Lesenswert?

Andreas Kuster schrieb:

> Was heisst denn das? Ich bin verwirrt.

Ist beim Brennen etwas schief gelaufen?

Brenn mal was drauf, was überhaupt nichts mit den Pusle zu tun hat :-)

von Andi K. (aykay90)


Lesenswert?

Jeah, es geht, ich musste aus dem "Sbi PinC,1" ein "Sbi PortC, 1" machen 
:) jetzt funzt es! Danke Für eure Hilfe, ich hoffe ich werde es noch 
ganz hinbekommen! ;-)

von Karl H. (kbuchegg)


Lesenswert?

Andreas Kuster schrieb:
> Jeah, es geht, ich musste aus dem "Sbi PinC,1" ein "Sbi PortC, 1" machen
> :)

Schäm.
Hab ich auch nicht gesehen sondern mitkopiert

Aber nachdem du sowieso ein paar schöne Alias hast, schlage ich vor, du 
machst gleich Nägel mit Köpfen und schreibst


   Servo1_out = 1

bzw

   Servo1_out = 0

dann passiert dir sowas nicht noch einmal.
(Und einfacher zu warten und zu ändern ist es ausserdem :-)

von Andi K. (aykay90)


Lesenswert?

Hehe, ja sowas kann ja mal vorkommen.
Ich hab die Variabeln auch so umbenannt zu Beginn, aber als es dann 
nicht gefunzt hat, hab ich als erstes die Variabeln geändert, weil ich 
so schonmal n Fehler ausschliessen konnte :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.