So, ist ein bisschen später geworden, aber die Platine ist fertig und bestückt! Auf ihr befinden sich ein LM317 (SMD), 4 Wiederstande, 2 Kondensatoren, eine Wii Motion Plus und eine Nunchuk.
Ich kann beide Sensoren direkt hintereinander mittels I2C auslesen; beim WM+ bekomme ich akzeptable Werte (ich shifte die tatsächlichen Werte um 2 nach rechts, sprich ich teile durch 4), somit ist kein Drift mehr vorhanden (bzw. er ist normalweise schon so klein, dass er jetzt wegfällt). Hab zwar schon öfter gelesen, dass die WM+ ziemlich viel Drift hat, das kann ich jedoch nicht(!) bestätigen!
Leider verstehe ich den Nunchuk nicht so ganz... Einer der Werte (acc-z) steht für mich in keinem Verhältnis zu irgendeiner Bewegung der Platine?! ... Der Wert verändert sich zwar manchmal, aber ich wei0 nicht, wie genau ich die Platine bewegen muss, damit das passiert? Wo ist beim Nunchuk die Z-Achse?

Nun aber zu meiner eigentlichen Frage:
Wie kann ich die ACC-Daten mit den Gyros verrechnen? Irgendwo hab ich in letzer Zeit mal gelesen, dass man mit einem Kalman-Filter diese beiden Senoren kombinieren kann?! Hier im Forum gibt es ja bereits einen BASCOM-Code für einen Kalman, jedoch wei0 ich nicht, wo ich da die ACC-Werte einsetzen soll. Wäre toll, wenn mir das jemand erklären könnte?!
Hier mal mein momentaner Code:
Code:
$regfile = "m32def.dat"
$crystal = 16000000
$framesize = 150
$hwstack = 150
$swstack = 150


Declare Sub Pid_regulator()

Declare Sub Wmp_init()
Declare Sub Send_zero()
Declare Sub Read_wmp_data()
Declare Sub Set_wmp_offset()

Declare Sub Nunchuk_init()
Declare Sub Nunchuk_read()
Declare Sub Set_nunchuk_offset()

Declare Function Tastenabfrage() As Byte



Config Adc = Single , Prescaler = Auto
Start Adc

Config Pina.7 = Input
Porta.7 = 1


Dim Taste As Byte
Dim _direction As Byte
_direction = 1


$lib "I2C_TWI.LBX"
Config Scl = Portc.0
Config Sda = Portc.1
Config Twi = 100000
I2cinit


Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.5
Config Lcdbus = 4
Initlcd
Cursor Off
Cls

Locate 1 , 1
Lcd "*WM+ // NUNCHUK*"


Dim Nunchuk_buffer(6) As Byte
Dim Wmplus_buffer(6) As Byte


Dim Yaw As Word
Dim Yaw0 As Byte At Yaw + 1 Overlay
Dim Yaw1 As Byte At Yaw Overlay

Dim Roll As Word
Dim Roll0 As Byte At Roll + 1 Overlay
Dim Roll1 As Byte At Roll Overlay

Dim Pitch As Word
Dim Pitch0 As Byte At Pitch + 1 Overlay
Dim Pitch1 As Byte At Pitch Overlay

Dim _yawoffset As Long
Dim _rolloffset As Long
Dim _pitchoffset As Long

Dim _yawoffset_int As Integer
Dim _rolloffset_int As Integer
Dim _pitchoffset_int As Integer

Dim _yawnow As Integer
Dim _rollnow As Integer
Dim _pitchnow As Integer


Dim Acc_x As Byte
Dim Acc_y As Byte
Dim Acc_z As Byte

Dim Acc_x_now As Integer
Dim Acc_y_now As Integer
Dim Acc_z_now As Integer

Dim Acc_x_offset As Word
Dim Acc_y_offset As Word
Dim Acc_z_offset As Word

Dim Acc_x_offset_int As Integer
Dim Acc_y_offset_int As Integer
Dim Acc_z_offset_int As Integer

Dim Tmp As Byte
Dim I As Byte


Dim _yaw_kp_err As Integer
Dim _roll_kp_err As Integer
Dim _pitch_kp_err As Integer

Dim _yaw_ki_err As Integer
Dim _roll_ki_err As Integer
Dim _pitch_ki_err As Integer

Dim _yaw_ki_sum As Integer
Dim _roll_ki_sum As Integer
Dim _pitch_ki_sum As Integer

Dim _yaw_kd_err As Integer
Dim _roll_kd_err As Integer
Dim _pitch_kd_err As Integer

Dim _yaw_kd_old As Integer
Dim _roll_kd_old As Integer
Dim _pitch_kd_old As Integer

Dim _yaw_pid As Integer
Dim _roll_pid As Integer
Dim _pitch_pid As Integer

Dim _yaw_err As Integer
Dim _roll_err As Integer
Dim _pitch_err As Integer



Dim _sbl(4) As Integer
_sbl(1) = 0
_sbl(2) = 0
_sbl(3) = 0
_sbl(4) = 0


Const _yaw_kp = 1000
Const _roll_kp = 1000
Const _pitch_kp = 1000

Const _yaw_ki = 100
Const _roll_ki = 100
Const _pitch_ki = 100

Const _yaw_kd = 100
Const _roll_kd = 100
Const _pitch_kd = 100


Dim _yaw_filter As Integer
Dim _yaw_filter_2 As Integer
Dim _roll_filter As Integer
Dim _roll_filter_2 As Integer
Dim _pitch_filter As Integer
Dim _pitch_filter_2 As Integer


'DEBUG!!!
Dim Min_yaw As Integer
Dim Max_yaw As Integer
Dim Min_roll As Integer
Dim Max_roll As Integer
Dim Min_pitch As Integer
Dim Max_pitch As Integer
'########



Call Nunchuk_init()
Call Wmp_init()
Call Set_wmp_offset()
Call Set_nunchuk_offset()
Cls



Do


 Call Read_wmp_data()
 Call Nunchuk_read()

 _yawnow = Yaw - _yawoffset_int
 _rollnow = Roll - _rolloffset_int
 _pitchnow = Pitch - _pitchoffset_int

 Acc_x_now = Acc_x - Acc_x_offset_int
 Acc_y_now = Acc_y - Acc_y_offset_int
 Acc_z_now = Acc_z - Acc_z_offset_int

 Call Pid_regulator()

 If _yaw_pid < Min_yaw Then Min_yaw = _yaw_pid
 If _yaw_pid > Max_yaw Then Max_yaw = _yaw_pid
 If _roll_pid < Min_roll Then Min_roll = _roll_pid
 If _roll_pid > Max_roll Then Max_roll = _roll_pid
 If _pitch_pid < Min_pitch Then Min_pitch = _pitch_pid
 If _pitch_pid > Max_pitch Then Max_pitch = _pitch_pid

 Taste = Tastenabfrage()
 If Taste <> 0 Then
  If Taste = 1 Then Decr _direction
  If Taste = 2 Then Incr _direction
  If _direction > 3 Then _direction = 1
  If _direction < 1 Then _direction = 3
 End If

 Cls
 Locate 1 , 1
 Lcd _yaw_pid ; " : " ; _roll_pid ; " : " ; _pitch_pid ; "  "

 Locate 2 , 1
 If _direction = 1 Then
  Lcd "YAW: " ; Min_yaw ; "/" ; Max_yaw ; "   "
 Elseif _direction = 2 Then
  Lcd "ROLL: " ; Min_roll ; "/" ; Max_roll ; "   "
 Elseif _direction = 3 Then
  Lcd "PITCH: " ; Min_pitch ; "/" ; Max_pitch ; "   "
 End If


'(
 Cls
 Locate 1 , 1
 Lcd _yawnow
 Locate 1 , 6
 Lcd ": " ; _rollnow
 Locate 1 , 11
 Lcd ": " ; _pitchnow ; "  "
 Locate 2 , 1
 Lcd Acc_x_now
 Locate 2 , 6
 Lcd ": " ; Acc_y_now
 Locate 2 , 11
 Lcd ": " ; Acc_z_now
 Waitms 100
')

Loop


Sub Nunchuk_init()
    I2cstart
    I2cwbyte &HA4
    I2cwbyte &H40
    I2cwbyte &H00 .
    I2cstop
End Sub

Sub Nunchuk_read()
   I2cstart
   I2cwbyte &HA4
   I2cwbyte &H00
   I2cstop
   Waitms 1
   Nunchuk_buffer(1) = 0
   I2creceive &HA5 , Nunchuk_buffer(1) , 0 , 6
   Acc_x = Nunchuk_buffer(3) Eor &H17
   Acc_x = Acc_x + &H17
   Acc_y = Nunchuk_buffer(4) Eor &H17
   Acc_y = Acc_y + &H17
   Acc_z = Nunchuk_buffer(5) Eor &H17
   Acc_z = Acc_z + &H17
End Sub

Sub Set_nunchuk_offset()
   Acc_x_offset = 0
   Acc_y_offset = 0
   Acc_z_offset = 0
   For I = 1 To 100
      Call Nunchuk_read()
      Acc_x_offset = Acc_x_offset + Acc_x
      Acc_y_offset = Acc_y_offset + Acc_y
      Acc_z_offset = Acc_z_offset + Acc_z
   Next I
   Acc_x_offset = Acc_x_offset / 100
   Acc_y_offset = Acc_y_offset / 100
   Acc_z_offset = Acc_z_offset / 100
   Acc_x_offset_int = Acc_x_offset
   Acc_y_offset_int = Acc_y_offset
   Acc_z_offset_int = Acc_z_offset
End Sub


Sub Wmp_init()
   I2cstart
   I2cwbyte &HA6
   I2cwbyte &HFE
   I2cwbyte &H04
   I2cstop
End Sub

Sub Send_zero()
   I2cstart
   I2cwbyte &HA4
   I2cwbyte &H00
   I2cstop
End Sub

Sub Read_wmp_data()
   Gosub Send_zero
   I2creceive &HA4 , Wmplus_buffer(1) , 0 , 6
   Yaw1 = Wmplus_buffer(1)
   Roll1 = Wmplus_buffer(2)
   Pitch1 = Wmplus_buffer(3)
   Shift Wmplus_buffer(4) , Right , 2 : Yaw0 = Wmplus_buffer(4)
   Shift Wmplus_buffer(5) , Right , 2 : Roll0 = Wmplus_buffer(5)
   Shift Wmplus_buffer(6) , Right , 2 : Pitch0 = Wmplus_buffer(6)
   Shift Yaw , Right , 2
   Shift Roll , Right , 2
   Shift Pitch , Right , 2

   'IIR-Filter
   'filter_wert = filter_wert * s + wert * (1.0-s)

    _yaw_filter = _yaw_filter * 4
    _yaw_filter = _yaw_filter / 10
    _yaw_filter_2 = Yaw * 6
    _yaw_filter_2 = _yaw_filter_2 / 10
    _yaw_filter = _yaw_filter + _yaw_filter_2
    Yaw = _yaw_filter

    _roll_filter = _roll_filter * 4
    _roll_filter = _roll_filter / 10
    _roll_filter_2 = Roll * 6
    _roll_filter_2 = _roll_filter_2 / 10
    _roll_filter = _roll_filter + _roll_filter_2
    Roll = _roll_filter

    _pitch_filter = _pitch_filter * 4
    _pitch_filter = _pitch_filter / 10
    _pitch_filter_2 = Pitch * 6
    _pitch_filter_2 = _pitch_filter_2 / 10
    _pitch_filter = _pitch_filter + _pitch_filter_2
    Pitch = _pitch_filter

End Sub

Sub Set_wmp_offset()
   _yawoffset = 0
   _rolloffset = 0
   _pitchoffset = 0
   For I = 1 To 100
      Call Read_wmp_data()
      _yawoffset = _yawoffset + Yaw
      _rolloffset = _rolloffset + Roll
      _pitchoffset = _pitchoffset + Pitch
   Next I
   _yawoffset = _yawoffset / 100
   _rolloffset = _rolloffset / 100
   _pitchoffset = _pitchoffset / 100
   _yawoffset_int = _yawoffset + 10
   _rolloffset_int = _rolloffset + 10
   _pitchoffset_int = _pitchoffset + 10
End Sub

Sub Pid_regulator()
 _yaw_err = _sbl(4) / 1
 _yaw_err = _yaw_err - _yawnow

 _roll_err = _sbl(3) / 5
 _roll_err = _roll_err - _rollnow

 _pitch_err = _sbl(2) / 5
 _pitch_err = _pitch_err - _pitchnow


 _yaw_kp_err = _yaw_kp_err * _yaw_kp
 _yaw_kp_err = _yaw_err / 10

 _roll_kp_err = _roll_kp_err * _roll_kp
 _roll_kp_err = _roll_err / 10

 _pitch_kp_err = _pitch_kp_err * _pitch_kp
 _pitch_kp_err = _pitch_err / 10


 _yaw_ki_err = _yaw_ki_err * _yaw_ki
 _yaw_ki_err = _yaw_err / 50
 _yaw_ki_sum = _yaw_ki_sum + _yaw_ki_err

 _roll_ki_err = _roll_ki_err * _roll_ki
 _roll_ki_err = _roll_err / 50
 _roll_ki_sum = _roll_ki_sum + _roll_ki_err

 _pitch_ki_err = _pitch_ki_err * _pitch_ki
 _pitch_ki_err = _pitch_err / 50
 _pitch_ki_sum = _pitch_ki_sum + _pitch_ki_err


 _yaw_kd_err = _yaw_kd_err * _yaw_kd
 _yaw_kd_err = _yaw_err / 50
 _yaw_kd_err = _yaw_kd_old - _yaw_kd_err
 _yaw_kd_old = _yaw_kd_old

 _roll_kd_err = _roll_kd_err * _roll_kd
 _roll_kd_err = _roll_err / 50
 _roll_kd_err = _roll_kd_old - _roll_kd_err
 _roll_kd_old = _roll_kd_old

 _pitch_kd_err = _pitch_kd_err * _pitch_kd
 _pitch_kd_err = _pitch_err / 50
 _pitch_kd_err = _pitch_kd_old - _pitch_kd_err
 _pitch_kd_old = _pitch_kd_old


 _yaw_pid = _yaw_kp_err + _yaw_ki_sum
 _yaw_pid = _yaw_pid + _yaw_kd_err

 _roll_pid = _roll_kp_err + _roll_ki_sum
 _roll_pid = _roll_pid + _roll_kd_err

 _pitch_pid = _pitch_kp_err + _pitch_ki_sum
 _pitch_pid = _pitch_pid + _pitch_kd_err


 If _yaw_pid < -1000 Then _yaw_pid = -1000
 If _yaw_pid > 1000 Then _yaw_pid = 1000
 If _roll_pid < -1000 Then _roll_pid = -1000
 If _roll_pid > 1000 Then _roll_pid = 1000
 If _pitch_pid < -1000 Then _pitch_pid = -1000
 If _pitch_pid > 1000 Then _pitch_pid = 1000
End Sub

Function Tastenabfrage() As Byte
Local Ws As Word
   Tastenabfrage = 0
   Start Adc
   Ws = Getadc(7)
   If Ws < 500 Then
      Select Case Ws
         Case 400 To 450
            Tastenabfrage = 1
         Case 330 To 380
            Tastenabfrage = 2
         Case 260 To 305
            Tastenabfrage = 3
         Case 180 To 220
            Tastenabfrage = 4
         Case 90 To 130
            Tastenabfrage = 5
      End Select
   End If
   Waitms 100
End Function

End
Wenn jemand ein Video vom Display sehen möchte, kann ichs schnell filmen! Die WM+ liegt seit ca. 30 Min neben mir und es gab noch keinen einzigen (!!!) "Ausbrecher". Ich denke, das genügt vollkommen zum fliegen?!
ABER:
Durch meine Division durch 4 verliere ich an Auflösung, d.h. ich muss auch die Werte für kp, ki, kd extrem hochschrauben... Denkt ihr, das ist ok oder würdet ihr das anders lösen?

Viele Fragen auf einmal, ich hoffe auf zahlreiche Antworten
Gruß
Chris