Hi zusammen
Ich arbeite an einem Roboterprojekt und bin sitze auf einem Problem
fest.
Der Roboter wird mit Servos gesteuert.
Ich lasse das Programm die Winkel, die die Servos haben müssen,
berechnen und danach in eine Pulswelle umwandeln.
Es stellt sich nun das Problem, dass sich eine Variable "selbsständig
macht", das heisst, sie ändert sich einfach.
Folgender Code: (er wurde etwas beschnitten um ihn übersichtlicher zu
machen.
1 | $regfile = "m32def.dat"
|
2 | $crystal = 16000000
|
3 | $baud = 19200
|
4 | $hwstack = 64
|
5 | $swstack = 64
|
6 | $framesize = 64
|
7 | Declare Function Angletopwm(byval Angle As Single , Byval Servonr As Integer) As Word
|
8 | Declare Sub Pwmrechner(byval X As Single , Byval Y As Single)
|
9 | Declare Sub Gotoposition
|
10 | Declare Sub Closeopen
|
11 | Dim Clse As Bit
|
12 | Clse = 0
|
13 | Dim Pi As Single
|
14 | Pi = 3.14159265358979
|
15 | Dim Pidiv As Single
|
16 | Config Portb = Output
|
17 | Portb.0 = 0
|
18 | Portb.1 = 0
|
19 | Portb.2 = 0
|
20 | Portb.3 = 0
|
21 | Dim Servopos(4) As Word
|
22 | Dim Servoapos(4) As Word
|
23 | Servoapos(1) = 62535
|
24 | Servoapos(2) = 62535
|
25 | Servoapos(3) = 62535
|
26 | Servopos(4) = 61335
|
27 | Dim Servodpos(3) As Integer
|
28 | Dim Servod1pos(3) As Integer
|
29 | Dim Servostatus(3) As Byte
|
30 | Dim Servostpsize(3) As Integer
|
31 | Servostpsize(1) = 0
|
32 | Servostpsize(2) = 0
|
33 | Servostpsize(3) = 0
|
34 | Dim Steps As Integer
|
35 | Dim Channel As Byte
|
36 | Channel = 0
|
37 | Dim Chnl As Byte
|
38 | Config Timer1 = Timer , Prescale = 8 'Servotimer
|
39 | Enable Timer1
|
40 | Timer1 = 62535
|
41 | On Timer1 Servoirq
|
42 | Enable Interrupts
|
43 |
|
44 | 'Hauptprogramm
|
45 |
|
46 | Call Pwmrechner(40 , 5)
|
47 | Call Gotoposition
|
48 | Do
|
49 | Loop
|
50 | End
|
51 |
|
52 | Sub Pwmrechner(byval X As Single , Byval Y As Single)
|
53 | Local A As Single
|
54 | A = 25.5
|
55 | Local B As Single
|
56 | Local I As Single
|
57 | I = 26.5
|
58 | Local C As Single
|
59 | Local D As Single
|
60 | D = 5.5
|
61 | Local F As Single
|
62 | Local Alpha As Single
|
63 | Local Beta As Single
|
64 | Local Gamma As Single
|
65 | Local Rt As Single
|
66 | Rt = 0.5
|
67 | Local Phi As Single
|
68 | Local Delta As Single
|
69 | .
|
70 | .
|
71 | .
|
72 | .
|
73 | Alpha = Asin(alpha) 'Berechnung von Alpha
|
74 | Gamma = Pidiv - Alpha 'Prov Berechnung von Gamma Gamma = Winkel an Basis
|
75 | Alpha = 2 * Alpha 'Verdoppelung von Alpha(gleischschenkliges Dreieck), endgültige Berechnung in Rad
|
76 | Phi = Atn(phi) 'Berechnung von Phi
|
77 | Delta = Pidiv - Phi 'vorlage zur endg. Berechnung von Gamma
|
78 | Beta = Gamma + Delta 'prov. Berechnung von Beta Beta = Winkel an schaufel
|
79 | Print "Beta:";Beta
|
80 | Beta = Pi - Beta 'endgültige Berechnung von Beta in Rad
|
81 | Waitms 1
|
82 | Print "Beta:";Beta
|
83 | If I < Y Then 'Endgültige Berechnung von Gamma in Rad
|
84 | Phi = Pi - Phi
|
85 | End If
|
86 | Pidiv = Pi / 8
|
87 | Gamma = Phi + Gamma
|
88 | Gamma = Gamma + Pidiv
|
89 | Gamma = Pi - Gamma
|
90 | Print "Alpha:" ; Alpha 'Siehe Punkt 1
|
91 | Print "Beta:" ; Beta
|
92 | Print "Gamma:" ; Gamma
|
93 | Servopos(1) = Angletopwm(gamma , 1)
|
94 | Servopos(2) = Angletopwm(alpha , 2)
|
95 | Servopos(3) = Angletopwm(beta , 3)
|
96 | Return
|
97 | End Sub
|
98 |
|
99 | Sub Closeopen
|
100 | If Clse = 0 Then
|
101 | Servopos(4) = 62000
|
102 | Clse = 1
|
103 | Else
|
104 | Servopos(4) = 61335
|
105 | Clse = 0
|
106 | End If
|
107 | End Sub
|
108 |
|
109 | Sub Gotoposition
|
110 | .
|
111 | .
|
112 | .
|
113 | .
|
114 | .
|
115 | End Sub
|
116 |
|
117 |
|
118 | Function Angletopwm(byval Angle As Single , Byval Servonr As Integer) As Word
|
119 | Local Af As Single
|
120 | Local Bf As Single
|
121 | Local Res As Word
|
122 | Print Angle 'Punkt 2
|
123 | If Servonr = 1 Then 'erster Servo
|
124 | If Angle <= 1.0472 Then
|
125 | Af = -1558.7441
|
126 | Bf = 3275.471
|
127 | End If
|
128 | If Angle > 1.0472 And Angle <= 1.37881 Then
|
129 | Af = -897.5444
|
130 | Bf = 2568.8925
|
131 | End If
|
132 | If Angle > 1.0472 And Angle <= 1.37881 Then
|
133 | Af = -897.5444
|
134 | Bf = 2568.8925
|
135 | End If
|
136 | If Angle > 1.37881 And Angle <= 1.44862 Then
|
137 | Af = -1575.7055
|
138 | Bf = 3505.5985
|
139 | End If
|
140 | If Angle > 1.44862 Then
|
141 | Af = -736.6181
|
142 | Bf = 2290.08
|
143 | End If
|
144 | End If
|
145 | If Servonr = 2 Then
|
146 | Af = -1884 / Pi '2. Servo
|
147 | Bf = 2911
|
148 | End If
|
149 | If Servonr = 3 Then '3. Servo
|
150 | Af = 1810 / Pi
|
151 | Bf = 202
|
152 | End If
|
153 | Print "Af:" ; Af
|
154 | Print "Bf:" ; Bf
|
155 | Print "Angle:" ; Angle
|
156 | Af = Af * Angle 'y = ax+b
|
157 | Res = Af + Bf
|
158 | Print "Res:" ; Res
|
159 | Res = 2 * Res
|
160 | Angletopwm = 65536 - Res
|
161 | Print Angletopwm
|
162 | Return
|
163 | End Function
|
164 |
|
165 |
|
166 |
|
167 | 'Servosignale
|
168 | Servoirq:
|
169 | If Channel = 0 Then
|
170 | If Portb.0 = 0 Then
|
171 | Timer1 = 62535
|
172 | Portb.0 = 1
|
173 | Servoapos(1) = Servoapos(1) + Servostpsize(1)
|
174 | If Servoapos(1) = Servopos(1) Then
|
175 | Servostpsize(1) = 0
|
176 | End If
|
177 | Print Servoapos(1)
|
178 | Else
|
179 | Portb.0 = 0
|
180 | Incr Channel
|
181 | End If
|
182 | End If
|
183 | If Channel = 1 Then
|
184 | If Portb.1 = 0 Then
|
185 | Timer1 = 63535
|
186 | Portb.1 = 1
|
187 | Servoapos(2) = Servoapos(2) + Servostpsize(2)
|
188 | If Servoapos(2) = Servopos(2) Then
|
189 | Servostpsize(2) = 0
|
190 | End If
|
191 | Print Servoapos(2)
|
192 | Else
|
193 | Portb.1 = 0
|
194 | Incr Channel
|
195 | End If
|
196 | End If
|
197 | If Channel = 2 Then
|
198 | If Portb.1 = 0 Then
|
199 | Timer1 = 62535
|
200 | Portb.1 = 1
|
201 | Servoapos(3) = Servoapos(3) + Servostpsize(3)
|
202 | If Servoapos(3) = Servopos(3) Then
|
203 | Servostpsize(3) = 0
|
204 | End If
|
205 | Print Servoapos(3)
|
206 | Else
|
207 | Portb.1 = 0
|
208 | Incr Channel
|
209 | End If
|
210 | End If
|
211 | If Channel = 3 Then
|
212 | If Portb.1 = 0 Then
|
213 | Timer1 = Servopos(4)
|
214 | Portb.1 = 1
|
215 | Else
|
216 | Portb.1 = 0
|
217 | Incr Channel
|
218 | End If
|
219 | End If
|
220 | If Channel = 4 Then
|
221 | Timer1 = 40000
|
222 | Channel = 0
|
223 | End If
|
224 | Return
|
225 | End
|
Bei Punkt 1 wird folgendes Ausgegeben
Alpha:1.844886299
Beta:1.935949561
Gamma:1.08703446
Bei Punkt 2 ergibt der Simulator folgende Werte:
Alpha: 0.500121708
Beta: -0.0
Gamma: *1.08703446*
Das sonderbare ist, wenn ich beim Funktionsaufruf die Plätze vertausche,
dass dann immer das erste stimmt und die Anderen nicht, und dass Af und
Bf dann -0.0 sind, was sehr sonderbar ist, denn sonst sind sie korrekt.
Falls ihr weitere infos braucht einfach melden
Danke für eure Hilfe
Silvan