Che Guevara
28.07.2011, 22:11
Hallo,
da ich jetzt einen Quadrocopter plane, will ich alle Teile von meinem Tri nochmal gut überarbeiten, aber im Groben und Ganzen so belassen (da ich von vornherein alles so gemacht habe, dass man mit wenigen Handgriffen das Ganze auf 4 Motoren einstellen kann). Jetzt stellt sich mir allerdings die Frage, ob es nicht besser wäre, die Kommunikation der beiden AVRs (ATMEGA328P - Master // ATTINY2313 - Slave), welche momentan über UART läuft, auf I2C umzustellen, da ich als Sensor eine Wii Motion Plus verwende und ich somit nur noch einen "Bus" hätte. Außerdem kann ich ja bei I2C nach der Übertragung das ERR-Flag überprüfen, ob die Daten erfolgreich gesendet wurden! (Ist in I2C eig. schon eine Checksumme o.ä. integriert??) Das würde bei UART nur durch eine Rückmeldung funktionieren, welche mir wieder Performance wegnimmt...
Allerdings stellt sich mir die Frage: Was ist den insgesamt (also Geschwindigkeit, Störanfälligkeit, Performance, etc...) besser? Als Levelconverter (5V <--> 3V3) verwende ich 2 Mosfets.
Ich persönlich würde eher zu UART tendieren, da diese auf meinem Tri mit momentan 1.000.000 baud läuft und somit mein Regelkreis mit ca. 500Hz läuft, das wird aber noch viel weiter optimiert! Es werden (kurz getestet, allerdings bis jetzt nur, wenn die Motoren aus waren) 1000 von 1000 Datenpaketen korrekt auf dem Slave (start-byte ; _bl(1-4) ; _crc) empfangen. Eine Datenübertragung dauert bei mir ca. 235µs. Ist das mit I2C (100kHz) zu erreichen? Hab da noch nie wirklich etwas gemacht, außer beim WM+. Deswegen kann ich auch nur mit 100kHz takten, da die I2C Schnittstelle des WM+ nur mit dieser Taktrate richtig funktioniert.... (BTW: Kennt jemand eine erfolgreich-getestete Bascom-Implementation des Passthrough-Modus mit WM+ und Nunchuk?? Habs bis jetzt nur selten in C gesehen, das hab ich aber nicht verstanden...)
Wäre nett, wenn ihr einfach mal ein paar Meinungen postet :)
Hier noch der Code (Master)
$regfile = "m328pdef.dat"
$crystal = 16000000
$framesize = 200
$hwstack = 200
$swstack = 200
$baud = 1000000 '115200
Open "COMC.3:19200,8,N,1" For Input As #1
Open "COMC.2:19200,8,N,1" For Output As #2
Declare Sub Init_system()
Declare Sub Filter_gyro_data()
Declare Sub Filter_rx_data()
Declare Sub Mixer()
Declare Sub Send_data()
Declare Sub Pid_regulator()
Declare Sub Wmp_init()
Declare Sub Send_zero()
Declare Sub Read_wmp_data()
Declare Sub Set_wmp_offset()
$lib "I2C_TWI.LBX"
Config Scl = Portc.5
Config Sda = Portc.4
Config Twi = 100000
I2cinit
Config Timer0 = Timer , Prescale = 256
On Timer0 Pausedetect
Enable Timer0
Config Int0 = Falling
On Int0 Measure
Enable Int0
Config Pind.2 = Input
Portd.2 = 0
Config Portd.4 = Output
Led Alias Portd.4
Led = 0
'####################################
'###########KONSTANTEN###############
'####################################
Const _maxchannel = 8
Const Start_byte = 127
Const _throttlechannel = 1
Const _rollchannel = 2
Const _pitchchannel = 3
Const _yawchannel = 4
Const _statechannel = 5
Const _datachannel = 6
Const _bl4offset = 0
Const _max_d_state = 3
'###################################
'###################################
'###################################
'###################################
'###########PID-PARAMETER###########
'###################################
Dim _yaw_kp As Single
Dim _roll_kp As Single
Dim _pitch_kp As Single
Dim _yaw_ki As Single
Dim _roll_ki As Single
Dim _pitch_ki As Single
Dim _yaw_kd As Single
Dim _roll_kd As Single
Dim _pitch_kd As Single
'#########PID-Werte############
'(
P : 0.675000008 : 1.049999949
I : 0.00139999 : 0.004399952
D:
')
'##############################
_yaw_kp = 1.5
_roll_kp = 0.675000008
_pitch_kp = 1.049999949
_yaw_ki = 0
_roll_ki = 0.00139999
_pitch_ki = 0.004399952
_yaw_kd = 0
_roll_kd = 0
_pitch_kd = 0.00079995
'###################################
'###################################
'###################################
'###################################
'###############TMP#################
'###################################
Dim _btm222_counter As Byte
Dim I As Byte
Dim Newvalsreceived As Bit
'###################################
'###################################
'###################################
'###################################
'#########RC-EMPFÄNGER##############
'###################################
Dim Bufferbyte As Byte
Dim Kanal(_maxchannel) As Word
Dim _lp_bandwidth As Byte
Dim _hkanal(_maxchannel) As Word
Dim _lkanal(_maxchannel) As Word
Dim _kanal_filter(_maxchannel) As Word
Dim Channel As Byte
Dim _bl(4) As Word
Dim _crc As Word
Dim _sbl(_maxchannel) As Integer
Dim _sbl_filter(_maxchannel) As Integer
'###################################
'###################################
'###################################
'###################################
'###########I2C-Inputs##############
'###################################
Dim Wmplus_buffer(6) As Byte
'###################################
'###################################
'###################################
'###################################
'#########GYRO######################
'###################################
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
'###################################
'###################################
'###################################
'##################################
'#########PID-REGLER###############
'##################################
Dim _d_state As Byte
Dim _yaw_kp_err As Single
Dim _roll_kp_err As Single
Dim _pitch_kp_err As Single
Dim _yaw_ki_err As Single
Dim _roll_ki_err As Single
Dim _pitch_ki_err As Single
Dim _yaw_ki_sum As Single
Dim _roll_ki_sum As Single
Dim _pitch_ki_sum As Single
Dim _yaw_kd_err_single As Single
Dim _roll_kd_err_single As Single
Dim _pitch_kd_err_single As Single
Dim _yaw_kd_err(_max_d_state) As Single
Dim _roll_kd_err(_max_d_state) As Single
Dim _pitch_kd_err(_max_d_state) As Single
Dim _yaw_kd_old(_max_d_state) As Single
Dim _roll_kd_old(_max_d_state) As Single
Dim _pitch_kd_old(_max_d_state) As Single
Dim _yaw_pid_int As Integer
Dim _roll_pid_int As Integer
Dim _pitch_pid_int As Integer
Dim _yaw_pid As Single
Dim _roll_pid As Single
Dim _pitch_pid As Single
Dim _yaw_err_int As Integer
Dim _roll_err_int As Integer
Dim _pitch_err_int As Integer
Dim _yaw_err As Single
Dim _roll_err As Single
Dim _pitch_err As Single
'#################################
'#################################
'#################################
Dim _yawstickvel As Integer
Dim _rollstickvel As Integer
Dim _pitchstickvel As Integer
Dim _sbl_old(_maxchannel) As Integer
Dim _x1 As Single
Dim _x2 As Single
Wait 2
Call Init_system()
Enable Interrupts
Do
Call Filter_rx_data() '580
Call Filter_gyro_data() '1900
Call Pid_regulator() '700
Call Mixer() '210
Call Send_data() '470
Loop
Sub Filter_gyro_data()
Call Read_wmp_data()
_yawnow = Yaw - _yawoffset_int
_rollnow = Roll - _rolloffset_int
_pitchnow = Pitch - _pitchoffset_int
End Sub
Sub Filter_rx_data()
If Newvalsreceived = 1 Then
Newvalsreceived = 0
If Kanal(_throttlechannel) >= 60 And Kanal(_throttlechannel) <= 140 Then
_sbl(_throttlechannel) = Kanal(_throttlechannel) - 100
_sbl(_throttlechannel) = _sbl(_throttlechannel) * 30
If _sbl(_throttlechannel) > 900 Then _sbl(_throttlechannel) = 900
If _sbl(_throttlechannel) < -1000 Then _sbl(_throttlechannel) = -1000
End If
For I = 2 To _maxchannel
If Kanal(i) >= 60 And Kanal(i) <= 140 Then
_sbl(i) = Kanal(i) - 100
If _sbl(i) > -2 And _sbl(i) < 2 Then _sbl(i) = 0
_sbl(i) = _sbl(i) * 25
End If
Next I
_sbl_filter(_throttlechannel) = _sbl_filter(_throttlechannel) + _sbl(_throttlechannel)
_sbl_filter(_throttlechannel) = _sbl_filter(_throttlechannel) / 2
_sbl(_throttlechannel) = _sbl_filter(_throttlechannel)
_sbl_filter(_rollchannel) = _sbl_filter(_rollchannel) + _sbl(_rollchannel)
_sbl_filter(_rollchannel) = _sbl_filter(_rollchannel) / 2
_sbl(_rollchannel) = _sbl_filter(_rollchannel)
_sbl_filter(_pitchchannel) = _sbl_filter(_pitchchannel) + _sbl(_pitchchannel)
_sbl_filter(_pitchchannel) = _sbl_filter(_pitchchannel) / 2
_sbl(_pitchchannel) = _sbl_filter(_pitchchannel)
_sbl_filter(_yawchannel) = _sbl_filter(_yawchannel) + _sbl(_yawchannel)
_sbl_filter(_yawchannel) = _sbl_filter(_yawchannel) / 2
_sbl(_yawchannel) = _sbl_filter(_yawchannel)
_sbl_filter(_statechannel) = _sbl_filter(_statechannel) * 19
_sbl_filter(_statechannel) = _sbl_filter(_statechannel) + _sbl(_statechannel)
_sbl_filter(_statechannel) = _sbl_filter(_statechannel) / 20
_sbl(_statechannel) = _sbl_filter(_statechannel)
_sbl_filter(_datachannel) = _sbl_filter(_datachannel) + _sbl(_datachannel)
_sbl_filter(_datachannel) = _sbl_filter(_datachannel) / 2
_sbl(_datachannel) = _sbl_filter(_datachannel)
If _sbl(_statechannel) < 200 Then
_sbl(_rollchannel) = _sbl(_rollchannel) / 5 '5
_sbl(_pitchchannel) = _sbl(_pitchchannel) / 5
Elseif _sbl(_statechannel) > 200 Then
_sbl(_rollchannel) = _sbl(_rollchannel) / 2 '3
_sbl(_pitchchannel) = _sbl(_pitchchannel) / 3
End If
_sbl(_yawchannel) = _sbl(_yawchannel) / 2
_rollstickvel = _sbl(_rollchannel) - _sbl_old(_rollchannel)
_rollstickvel = _rollstickvel / 10
_sbl_old(_rollchannel) = _sbl(_rollchannel)
_pitchstickvel = _sbl(_pitchchannel) - _sbl_old(_pitchchannel)
_pitchstickvel = _pitchstickvel / 10
_sbl_old(_pitchchannel) = _sbl(_pitchchannel)
'(
_kanal_filter(7) = _kanal_filter(7) * 3
_kanal_filter(7) = _kanal_filter(7) + Kanal(7)
Shift _kanal_filter(7) , Right , 2
Kanal(7) = _kanal_filter(7)
_kanal_filter(8) = _kanal_filter(8) * 3
_kanal_filter(8) = _kanal_filter(8) + Kanal(8)
Shift _kanal_filter(8) , Right , 2
Kanal(8) = _kanal_filter(8)
')
'(
'#########P-GAIN###########
_x1 = Kanal(7) - 100
_x1 = _x1 * 0.075
_x2 = Kanal(8) - 100
_x2 = _x2 * 0.075
_roll_kp = 0 + _x1
_pitch_kp = 0 + _x2
'#########I-GAIN###########
_x1 = Kanal(7) - 100
_x1 = _x1 * 0.0002
_x2 = Kanal(8) - 100
_x2 = _x2 * 0.0002
_roll_ki = 0.0 + _x1
_pitch_ki = 0.0 + _x2
'#########D-GAIN###########
_x1 = Kanal(7) - 100
_x1 = _x1 * 0.0002
_x2 = Kanal(8) - 100
_x2 = _x2 * 0.0002
_roll_kd = 0.0 + _x1
_pitch_kd = 0.0 + _x2
')
If _sbl(_pitchchannel) > 170 And _sbl(_yawchannel) > 200 And _sbl(_throttlechannel) < -950 And _sbl(_statechannel) < -200 Then
Call Set_wmp_offset()
Led = 0
If _sbl(_datachannel) > -200 Then
Print #2 , "OFFSET neu berechnet!"
End If
End If
End If
End Sub
Measure:
If Channel > 0 And Channel < 9 Then
Kanal(channel) = Timer0
End If
Timer0 = 6
Incr Channel
Return
Pausedetect:
If Channel <> 0 Then
Newvalsreceived = 1
End If
Channel = 0
Return
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
End Sub
Sub Set_wmp_offset()
_yawoffset = 0
_rolloffset = 0
_pitchoffset = 0
For I = 1 To 100
Waitms 5
Call Read_wmp_data()
_yawoffset = _yawoffset + Yaw
_rolloffset = _rolloffset + Roll
_pitchoffset = _pitchoffset + Pitch
Toggle Led
Next I
Led = 0
_yawoffset = _yawoffset / 100
_rolloffset = _rolloffset / 100
_pitchoffset = _pitchoffset / 100
_yawoffset_int = _yawoffset
_rolloffset_int = _rolloffset
_pitchoffset_int = _pitchoffset
End Sub
Sub Pid_regulator()
'##############FEHLER_BERECHNEN##########
'(
_yaw_err_int = _sbl(_yawchannel) - _yawnow
_yaw_err = _yaw_err_int
_roll_err_int = _sbl(_rollchannel) - _rollstickvel
_roll_err_int = _roll_err_int - _rollnow
_roll_err = _roll_err_int
_pitch_err_int = _sbl(_pitchchannel) - _pitchstickvel
_pitch_err_int = _pitch_err_int - _rollnow
_pitch_err = _pitch_err_int
')
_yaw_err_int = _sbl(_yawchannel) - _yawnow
_yaw_err = _yaw_err_int
_roll_err_int = _sbl(_rollchannel) - _rollnow
_roll_err = _roll_err_int
_pitch_err_int = _sbl(_pitchchannel) - _pitchnow
_pitch_err = _pitch_err_int
'##############PROPORTIONAL##############
_yaw_kp_err = _yaw_err * _yaw_kp
_roll_kp_err = _roll_err * _roll_kp
_pitch_kp_err = _pitch_err * _pitch_kp
'##############INTEGRAL##################
_yaw_ki_err = _yaw_err * _yaw_ki
_yaw_ki_sum = _yaw_ki_sum + _yaw_ki_err
_roll_ki_err = _roll_err * _roll_ki
_roll_ki_sum = _roll_ki_sum + _roll_ki_err
_pitch_ki_err = _pitch_err * _pitch_ki
_pitch_ki_sum = _pitch_ki_sum + _pitch_ki_err
'##############DIFFERENTIAL#############
Incr _d_state
If _d_state > _max_d_state Then _d_state = 1
_yaw_kd_err(_d_state) = _yaw_err * _yaw_kd
_yaw_kd_err(_d_state) = _yaw_kd_err(_d_state) - _yaw_kd_old(_d_state) 'evtl. anders herum!!!!!!!!!!
_yaw_kd_old(_d_state) = _yaw_kd_err(_d_state)
_roll_kd_err(_d_state) = _roll_err * _roll_kd
_roll_kd_err(_d_state) = _roll_kd_err(_d_state) - _roll_kd_old(_d_state) 'evtl. anders herum!!!!!!!!!!
_roll_kd_old(_d_state) = _roll_kd_err(_d_state)
_pitch_kd_err(_d_state) = _pitch_err * _pitch_kd
_pitch_kd_err(_d_state) = _pitch_kd_err(_d_state) - _pitch_kd_old(_d_state) 'evtl. anders herum!!!!!!!!!!
_pitch_kd_old(_d_state) = _pitch_kd_err(_d_state)
_yaw_kd_err_single = _yaw_kd_err(_d_state)
_roll_kd_err_single = _roll_kd_err(_d_state)
_pitch_kd_err_single = _pitch_kd_err(_d_state)
'##############AUFSUMMIEREN##############
_yaw_pid = _yaw_kp_err + _yaw_ki_sum
_yaw_pid = _yaw_pid + _yaw_kd_err_single
_yaw_pid_int = _yaw_pid
_roll_pid = _roll_kp_err + _roll_ki_sum
_roll_pid = _roll_pid + _roll_kd_err_single
_roll_pid_int = _roll_pid
_pitch_pid = _pitch_kp_err + _pitch_ki_sum
_pitch_pid = _pitch_pid + _pitch_kd_err_single
_pitch_pid_int = _pitch_pid
'###############WERTE_BEGRENZEN##########
If _yaw_pid_int < -1000 Then _yaw_pid_int = -1000
If _yaw_pid_int > 1000 Then _yaw_pid_int = 1000
If _roll_pid_int < -1000 Then _roll_pid_int = -1000
If _roll_pid_int > 1000 Then _roll_pid_int = 1000
If _pitch_pid_int < -1000 Then _pitch_pid_int = -1000
If _pitch_pid_int > 1000 Then _pitch_pid_int = 1000
End Sub
Sub Mixer()
_bl(1) = 62667 - _sbl(_throttlechannel)
_bl(2) = _bl(1)
_bl(3) = _bl(1)
_bl(4) = 62667
_bl(4) = _bl(4) + _bl4offset
If _sbl(_statechannel) > -200 Then
_bl(1) = _bl(1) + _pitch_pid_int
_bl(2) = _bl(2) - _roll_pid_int
_bl(3) = _bl(3) + _roll_pid_int
_pitch_pid_int = _pitch_pid_int / 2
_bl(2) = _bl(2) - _pitch_pid_int
_bl(3) = _bl(3) - _pitch_pid_int
_bl(4) = _bl(4) - _yaw_pid_int
Led = 1
Elseif _sbl(_statechannel) < -200 Then
_bl(1) = 63800
_bl(2) = 63800
_bl(3) = 63800
For I = 0 To _max_d_state
_yaw_kd_err(i) = 0
_yaw_kd_old(i) = 0
_roll_kd_err(i) = 0
_roll_kd_old(i) = 0
_pitch_kd_err(i) = 0
_pitch_kd_old(i) = 0
Next I
_yaw_kp_err = 0
_yaw_ki_sum = 0
_yaw_kd_err_single = 0
_yaw_ki_err = 0
_roll_kp_err = 0
_roll_ki_sum = 0
_roll_kd_err_single = 0
_roll_ki_err = 0
_pitch_kp_err = 0
_pitch_ki_sum = 0
_pitch_kd_err_single = 0
_pitch_ki_err = 0
_yaw_pid_int = 0
_roll_pid_int = 0
_pitch_pid_int = 0
_yaw_pid = 0
_roll_pid = 0
_pitch_pid = 0
Led = 0
End If
End Sub
Sub Send_data()
_crc = Crc16(_bl(1) , 4)
Printbin Start_byte
Incr _btm222_counter
If _btm222_counter = 20 Then
_btm222_counter = 0
If _sbl(_datachannel) > -200 Then
'Print #2 , _roll_kp ; ":" ; _pitch_kp
'Print #2 , _roll_ki ; ":" ; _pitch_ki
'Print #2 , _roll_kd ; ":" ; _pitch_kd
'Print #2 , _sbl(_throttlechannel) ; ":" ; _sbl(_rollchannel) ; ":" ; _sbl(_pitchchannel) ; ":" ; _sbl(_yawchannel) ; ":" ; _sbl(_statechannel) ; ":" ; _sbl(_datachannel)
End If
End If
Printbin _bl(1) ; _bl(2) ; _bl(3) ; _bl(4) ; _crc
End Sub
Sub Init_system()
_sbl_filter(_throttlechannel) = -1000
_sbl_filter(_rollchannel) = 0
_sbl_filter(_pitchchannel) = 0
_sbl_filter(_yawchannel) = 0
_sbl_filter(_statechannel) = -600
_sbl_filter(_datachannel) = -600
Reset Newvalsreceived
_yawnow = 0
_rollnow = 0
_pitchnow = 0
Call Wmp_init()
Wait 1
For I = 1 To 50
Call Read_wmp_data()
Next I
Wait 1
Call Set_wmp_offset()
For I = 1 To 5
Led = 1
Waitms 20
Led = 0
Waitms 100
Next I
End Sub
End
Slave:
$regfile = "attiny2313.dat"
$crystal = 16000000
$framesize = 30
$hwstack = 32
$swstack = 30
$baud = 1000000 '115200
Config Timer1 = Timer , Prescale = 8
Timer1 = 62535
On Timer1 Servoirq
Enable Timer1
Config Servos = 1 , Servo1 = Portd.5 , Reload = 10
Config Portd.2 = Output
Config Portd.3 = Output
Config Portd.4 = Output
Config Portd.5 = Output
Dim Kanal As Byte
Dim _servo(4) As Word
Dim _bl(4) As Word
Dim I As Word
Dim _crc As Word
Dim _start As Byte
'min: 63800, mitte: 62667.5 , max: 61535 --> 2265 Schritte
Const _servo_teiler = 20
Const Start_byte = 127
Const Min_servo = 63800
Const Max_servo = 61535
Const Diff_servo = Max_servo - Min_servo
For I = 1 To 3
_bl(i) = Min_servo
_servo(i) = _bl(i)
Next I
Servo(1) = 100
Enable Interrupts
Wait 3
Do
If Ischarwaiting() > 0 Then
Inputbin _start
If _start = Start_byte Then
Inputbin _bl(1) , _bl(2) , _bl(3) , _bl(4) , _crc
If _crc = Crc16(_bl(1) , 4) Then
For I = 1 To 4
If _bl(i) < Max_servo Then _bl(i) = Max_servo
If _bl(i) > Min_servo Then _bl(i) = Min_servo
_servo(i) = _bl(i)
Next I
_servo(4) = _servo(4) - 61535
_servo(4) = _servo(4) / _servo_teiler
Servo(1) = 50 + _servo(4)
End If
End If
End If
Loop
Servoirq:
If Kanal = 0 Then
If Portd.2 = 0 Then 'wenn port low
Timer1 = _servo(1) 'dann timer auf entsprechende verzögerung
Portd.2 = 1 'und port anschalten
Else 'das hier passiert erst bei dem darauf folgenden interrupt
Portd.2 = 0 'dann port wieder ausschalten
Incr Kanal 'und den nächsten kanal bearbeiten
End If
End If
If Kanal = 1 Then
If Portd.3 = 0 Then
Timer1 = _servo(2)
Portd.3 = 1
Else
Portd.3 = 0
Incr Kanal
End If
End If
If Kanal = 2 Then
If Portd.4 = 0 Then
Timer1 = _servo(3)
Portd.4 = 1
Else
Portd.4 = 0
Incr Kanal
End If
End If
If Kanal = 3 Then
Timer1 = 65535
Kanal = 0
End If
'(
If Kanal = 3 Then
If Portd.5 = 0 Then
Timer1 = _servo(4)
Portd.5 = 1
Else
Portd.5 = 0
Incr Kanal
End If
End If
If Kanal = 4 Then
Timer1 = 40000 '65535 | eine pause von ca. 12ms bis zum nächsten interrupt. Bei guten Servos oder Brushlessreglern kann man hier bis auf 65530 gehen ==> ansteuerfrequenz von ~ 200Hz
Kanal = 0
End If
')
Return
End
Vielen Dank & Gruß
Chris
EDIT: Kann man in Bascom überhaupt einen Slave (Hardware I2C) vernünftig konfigurieren? Also mit Interrupt usw... Oder denkt ihr, Uart ist einfacher?
da ich jetzt einen Quadrocopter plane, will ich alle Teile von meinem Tri nochmal gut überarbeiten, aber im Groben und Ganzen so belassen (da ich von vornherein alles so gemacht habe, dass man mit wenigen Handgriffen das Ganze auf 4 Motoren einstellen kann). Jetzt stellt sich mir allerdings die Frage, ob es nicht besser wäre, die Kommunikation der beiden AVRs (ATMEGA328P - Master // ATTINY2313 - Slave), welche momentan über UART läuft, auf I2C umzustellen, da ich als Sensor eine Wii Motion Plus verwende und ich somit nur noch einen "Bus" hätte. Außerdem kann ich ja bei I2C nach der Übertragung das ERR-Flag überprüfen, ob die Daten erfolgreich gesendet wurden! (Ist in I2C eig. schon eine Checksumme o.ä. integriert??) Das würde bei UART nur durch eine Rückmeldung funktionieren, welche mir wieder Performance wegnimmt...
Allerdings stellt sich mir die Frage: Was ist den insgesamt (also Geschwindigkeit, Störanfälligkeit, Performance, etc...) besser? Als Levelconverter (5V <--> 3V3) verwende ich 2 Mosfets.
Ich persönlich würde eher zu UART tendieren, da diese auf meinem Tri mit momentan 1.000.000 baud läuft und somit mein Regelkreis mit ca. 500Hz läuft, das wird aber noch viel weiter optimiert! Es werden (kurz getestet, allerdings bis jetzt nur, wenn die Motoren aus waren) 1000 von 1000 Datenpaketen korrekt auf dem Slave (start-byte ; _bl(1-4) ; _crc) empfangen. Eine Datenübertragung dauert bei mir ca. 235µs. Ist das mit I2C (100kHz) zu erreichen? Hab da noch nie wirklich etwas gemacht, außer beim WM+. Deswegen kann ich auch nur mit 100kHz takten, da die I2C Schnittstelle des WM+ nur mit dieser Taktrate richtig funktioniert.... (BTW: Kennt jemand eine erfolgreich-getestete Bascom-Implementation des Passthrough-Modus mit WM+ und Nunchuk?? Habs bis jetzt nur selten in C gesehen, das hab ich aber nicht verstanden...)
Wäre nett, wenn ihr einfach mal ein paar Meinungen postet :)
Hier noch der Code (Master)
$regfile = "m328pdef.dat"
$crystal = 16000000
$framesize = 200
$hwstack = 200
$swstack = 200
$baud = 1000000 '115200
Open "COMC.3:19200,8,N,1" For Input As #1
Open "COMC.2:19200,8,N,1" For Output As #2
Declare Sub Init_system()
Declare Sub Filter_gyro_data()
Declare Sub Filter_rx_data()
Declare Sub Mixer()
Declare Sub Send_data()
Declare Sub Pid_regulator()
Declare Sub Wmp_init()
Declare Sub Send_zero()
Declare Sub Read_wmp_data()
Declare Sub Set_wmp_offset()
$lib "I2C_TWI.LBX"
Config Scl = Portc.5
Config Sda = Portc.4
Config Twi = 100000
I2cinit
Config Timer0 = Timer , Prescale = 256
On Timer0 Pausedetect
Enable Timer0
Config Int0 = Falling
On Int0 Measure
Enable Int0
Config Pind.2 = Input
Portd.2 = 0
Config Portd.4 = Output
Led Alias Portd.4
Led = 0
'####################################
'###########KONSTANTEN###############
'####################################
Const _maxchannel = 8
Const Start_byte = 127
Const _throttlechannel = 1
Const _rollchannel = 2
Const _pitchchannel = 3
Const _yawchannel = 4
Const _statechannel = 5
Const _datachannel = 6
Const _bl4offset = 0
Const _max_d_state = 3
'###################################
'###################################
'###################################
'###################################
'###########PID-PARAMETER###########
'###################################
Dim _yaw_kp As Single
Dim _roll_kp As Single
Dim _pitch_kp As Single
Dim _yaw_ki As Single
Dim _roll_ki As Single
Dim _pitch_ki As Single
Dim _yaw_kd As Single
Dim _roll_kd As Single
Dim _pitch_kd As Single
'#########PID-Werte############
'(
P : 0.675000008 : 1.049999949
I : 0.00139999 : 0.004399952
D:
')
'##############################
_yaw_kp = 1.5
_roll_kp = 0.675000008
_pitch_kp = 1.049999949
_yaw_ki = 0
_roll_ki = 0.00139999
_pitch_ki = 0.004399952
_yaw_kd = 0
_roll_kd = 0
_pitch_kd = 0.00079995
'###################################
'###################################
'###################################
'###################################
'###############TMP#################
'###################################
Dim _btm222_counter As Byte
Dim I As Byte
Dim Newvalsreceived As Bit
'###################################
'###################################
'###################################
'###################################
'#########RC-EMPFÄNGER##############
'###################################
Dim Bufferbyte As Byte
Dim Kanal(_maxchannel) As Word
Dim _lp_bandwidth As Byte
Dim _hkanal(_maxchannel) As Word
Dim _lkanal(_maxchannel) As Word
Dim _kanal_filter(_maxchannel) As Word
Dim Channel As Byte
Dim _bl(4) As Word
Dim _crc As Word
Dim _sbl(_maxchannel) As Integer
Dim _sbl_filter(_maxchannel) As Integer
'###################################
'###################################
'###################################
'###################################
'###########I2C-Inputs##############
'###################################
Dim Wmplus_buffer(6) As Byte
'###################################
'###################################
'###################################
'###################################
'#########GYRO######################
'###################################
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
'###################################
'###################################
'###################################
'##################################
'#########PID-REGLER###############
'##################################
Dim _d_state As Byte
Dim _yaw_kp_err As Single
Dim _roll_kp_err As Single
Dim _pitch_kp_err As Single
Dim _yaw_ki_err As Single
Dim _roll_ki_err As Single
Dim _pitch_ki_err As Single
Dim _yaw_ki_sum As Single
Dim _roll_ki_sum As Single
Dim _pitch_ki_sum As Single
Dim _yaw_kd_err_single As Single
Dim _roll_kd_err_single As Single
Dim _pitch_kd_err_single As Single
Dim _yaw_kd_err(_max_d_state) As Single
Dim _roll_kd_err(_max_d_state) As Single
Dim _pitch_kd_err(_max_d_state) As Single
Dim _yaw_kd_old(_max_d_state) As Single
Dim _roll_kd_old(_max_d_state) As Single
Dim _pitch_kd_old(_max_d_state) As Single
Dim _yaw_pid_int As Integer
Dim _roll_pid_int As Integer
Dim _pitch_pid_int As Integer
Dim _yaw_pid As Single
Dim _roll_pid As Single
Dim _pitch_pid As Single
Dim _yaw_err_int As Integer
Dim _roll_err_int As Integer
Dim _pitch_err_int As Integer
Dim _yaw_err As Single
Dim _roll_err As Single
Dim _pitch_err As Single
'#################################
'#################################
'#################################
Dim _yawstickvel As Integer
Dim _rollstickvel As Integer
Dim _pitchstickvel As Integer
Dim _sbl_old(_maxchannel) As Integer
Dim _x1 As Single
Dim _x2 As Single
Wait 2
Call Init_system()
Enable Interrupts
Do
Call Filter_rx_data() '580
Call Filter_gyro_data() '1900
Call Pid_regulator() '700
Call Mixer() '210
Call Send_data() '470
Loop
Sub Filter_gyro_data()
Call Read_wmp_data()
_yawnow = Yaw - _yawoffset_int
_rollnow = Roll - _rolloffset_int
_pitchnow = Pitch - _pitchoffset_int
End Sub
Sub Filter_rx_data()
If Newvalsreceived = 1 Then
Newvalsreceived = 0
If Kanal(_throttlechannel) >= 60 And Kanal(_throttlechannel) <= 140 Then
_sbl(_throttlechannel) = Kanal(_throttlechannel) - 100
_sbl(_throttlechannel) = _sbl(_throttlechannel) * 30
If _sbl(_throttlechannel) > 900 Then _sbl(_throttlechannel) = 900
If _sbl(_throttlechannel) < -1000 Then _sbl(_throttlechannel) = -1000
End If
For I = 2 To _maxchannel
If Kanal(i) >= 60 And Kanal(i) <= 140 Then
_sbl(i) = Kanal(i) - 100
If _sbl(i) > -2 And _sbl(i) < 2 Then _sbl(i) = 0
_sbl(i) = _sbl(i) * 25
End If
Next I
_sbl_filter(_throttlechannel) = _sbl_filter(_throttlechannel) + _sbl(_throttlechannel)
_sbl_filter(_throttlechannel) = _sbl_filter(_throttlechannel) / 2
_sbl(_throttlechannel) = _sbl_filter(_throttlechannel)
_sbl_filter(_rollchannel) = _sbl_filter(_rollchannel) + _sbl(_rollchannel)
_sbl_filter(_rollchannel) = _sbl_filter(_rollchannel) / 2
_sbl(_rollchannel) = _sbl_filter(_rollchannel)
_sbl_filter(_pitchchannel) = _sbl_filter(_pitchchannel) + _sbl(_pitchchannel)
_sbl_filter(_pitchchannel) = _sbl_filter(_pitchchannel) / 2
_sbl(_pitchchannel) = _sbl_filter(_pitchchannel)
_sbl_filter(_yawchannel) = _sbl_filter(_yawchannel) + _sbl(_yawchannel)
_sbl_filter(_yawchannel) = _sbl_filter(_yawchannel) / 2
_sbl(_yawchannel) = _sbl_filter(_yawchannel)
_sbl_filter(_statechannel) = _sbl_filter(_statechannel) * 19
_sbl_filter(_statechannel) = _sbl_filter(_statechannel) + _sbl(_statechannel)
_sbl_filter(_statechannel) = _sbl_filter(_statechannel) / 20
_sbl(_statechannel) = _sbl_filter(_statechannel)
_sbl_filter(_datachannel) = _sbl_filter(_datachannel) + _sbl(_datachannel)
_sbl_filter(_datachannel) = _sbl_filter(_datachannel) / 2
_sbl(_datachannel) = _sbl_filter(_datachannel)
If _sbl(_statechannel) < 200 Then
_sbl(_rollchannel) = _sbl(_rollchannel) / 5 '5
_sbl(_pitchchannel) = _sbl(_pitchchannel) / 5
Elseif _sbl(_statechannel) > 200 Then
_sbl(_rollchannel) = _sbl(_rollchannel) / 2 '3
_sbl(_pitchchannel) = _sbl(_pitchchannel) / 3
End If
_sbl(_yawchannel) = _sbl(_yawchannel) / 2
_rollstickvel = _sbl(_rollchannel) - _sbl_old(_rollchannel)
_rollstickvel = _rollstickvel / 10
_sbl_old(_rollchannel) = _sbl(_rollchannel)
_pitchstickvel = _sbl(_pitchchannel) - _sbl_old(_pitchchannel)
_pitchstickvel = _pitchstickvel / 10
_sbl_old(_pitchchannel) = _sbl(_pitchchannel)
'(
_kanal_filter(7) = _kanal_filter(7) * 3
_kanal_filter(7) = _kanal_filter(7) + Kanal(7)
Shift _kanal_filter(7) , Right , 2
Kanal(7) = _kanal_filter(7)
_kanal_filter(8) = _kanal_filter(8) * 3
_kanal_filter(8) = _kanal_filter(8) + Kanal(8)
Shift _kanal_filter(8) , Right , 2
Kanal(8) = _kanal_filter(8)
')
'(
'#########P-GAIN###########
_x1 = Kanal(7) - 100
_x1 = _x1 * 0.075
_x2 = Kanal(8) - 100
_x2 = _x2 * 0.075
_roll_kp = 0 + _x1
_pitch_kp = 0 + _x2
'#########I-GAIN###########
_x1 = Kanal(7) - 100
_x1 = _x1 * 0.0002
_x2 = Kanal(8) - 100
_x2 = _x2 * 0.0002
_roll_ki = 0.0 + _x1
_pitch_ki = 0.0 + _x2
'#########D-GAIN###########
_x1 = Kanal(7) - 100
_x1 = _x1 * 0.0002
_x2 = Kanal(8) - 100
_x2 = _x2 * 0.0002
_roll_kd = 0.0 + _x1
_pitch_kd = 0.0 + _x2
')
If _sbl(_pitchchannel) > 170 And _sbl(_yawchannel) > 200 And _sbl(_throttlechannel) < -950 And _sbl(_statechannel) < -200 Then
Call Set_wmp_offset()
Led = 0
If _sbl(_datachannel) > -200 Then
Print #2 , "OFFSET neu berechnet!"
End If
End If
End If
End Sub
Measure:
If Channel > 0 And Channel < 9 Then
Kanal(channel) = Timer0
End If
Timer0 = 6
Incr Channel
Return
Pausedetect:
If Channel <> 0 Then
Newvalsreceived = 1
End If
Channel = 0
Return
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
End Sub
Sub Set_wmp_offset()
_yawoffset = 0
_rolloffset = 0
_pitchoffset = 0
For I = 1 To 100
Waitms 5
Call Read_wmp_data()
_yawoffset = _yawoffset + Yaw
_rolloffset = _rolloffset + Roll
_pitchoffset = _pitchoffset + Pitch
Toggle Led
Next I
Led = 0
_yawoffset = _yawoffset / 100
_rolloffset = _rolloffset / 100
_pitchoffset = _pitchoffset / 100
_yawoffset_int = _yawoffset
_rolloffset_int = _rolloffset
_pitchoffset_int = _pitchoffset
End Sub
Sub Pid_regulator()
'##############FEHLER_BERECHNEN##########
'(
_yaw_err_int = _sbl(_yawchannel) - _yawnow
_yaw_err = _yaw_err_int
_roll_err_int = _sbl(_rollchannel) - _rollstickvel
_roll_err_int = _roll_err_int - _rollnow
_roll_err = _roll_err_int
_pitch_err_int = _sbl(_pitchchannel) - _pitchstickvel
_pitch_err_int = _pitch_err_int - _rollnow
_pitch_err = _pitch_err_int
')
_yaw_err_int = _sbl(_yawchannel) - _yawnow
_yaw_err = _yaw_err_int
_roll_err_int = _sbl(_rollchannel) - _rollnow
_roll_err = _roll_err_int
_pitch_err_int = _sbl(_pitchchannel) - _pitchnow
_pitch_err = _pitch_err_int
'##############PROPORTIONAL##############
_yaw_kp_err = _yaw_err * _yaw_kp
_roll_kp_err = _roll_err * _roll_kp
_pitch_kp_err = _pitch_err * _pitch_kp
'##############INTEGRAL##################
_yaw_ki_err = _yaw_err * _yaw_ki
_yaw_ki_sum = _yaw_ki_sum + _yaw_ki_err
_roll_ki_err = _roll_err * _roll_ki
_roll_ki_sum = _roll_ki_sum + _roll_ki_err
_pitch_ki_err = _pitch_err * _pitch_ki
_pitch_ki_sum = _pitch_ki_sum + _pitch_ki_err
'##############DIFFERENTIAL#############
Incr _d_state
If _d_state > _max_d_state Then _d_state = 1
_yaw_kd_err(_d_state) = _yaw_err * _yaw_kd
_yaw_kd_err(_d_state) = _yaw_kd_err(_d_state) - _yaw_kd_old(_d_state) 'evtl. anders herum!!!!!!!!!!
_yaw_kd_old(_d_state) = _yaw_kd_err(_d_state)
_roll_kd_err(_d_state) = _roll_err * _roll_kd
_roll_kd_err(_d_state) = _roll_kd_err(_d_state) - _roll_kd_old(_d_state) 'evtl. anders herum!!!!!!!!!!
_roll_kd_old(_d_state) = _roll_kd_err(_d_state)
_pitch_kd_err(_d_state) = _pitch_err * _pitch_kd
_pitch_kd_err(_d_state) = _pitch_kd_err(_d_state) - _pitch_kd_old(_d_state) 'evtl. anders herum!!!!!!!!!!
_pitch_kd_old(_d_state) = _pitch_kd_err(_d_state)
_yaw_kd_err_single = _yaw_kd_err(_d_state)
_roll_kd_err_single = _roll_kd_err(_d_state)
_pitch_kd_err_single = _pitch_kd_err(_d_state)
'##############AUFSUMMIEREN##############
_yaw_pid = _yaw_kp_err + _yaw_ki_sum
_yaw_pid = _yaw_pid + _yaw_kd_err_single
_yaw_pid_int = _yaw_pid
_roll_pid = _roll_kp_err + _roll_ki_sum
_roll_pid = _roll_pid + _roll_kd_err_single
_roll_pid_int = _roll_pid
_pitch_pid = _pitch_kp_err + _pitch_ki_sum
_pitch_pid = _pitch_pid + _pitch_kd_err_single
_pitch_pid_int = _pitch_pid
'###############WERTE_BEGRENZEN##########
If _yaw_pid_int < -1000 Then _yaw_pid_int = -1000
If _yaw_pid_int > 1000 Then _yaw_pid_int = 1000
If _roll_pid_int < -1000 Then _roll_pid_int = -1000
If _roll_pid_int > 1000 Then _roll_pid_int = 1000
If _pitch_pid_int < -1000 Then _pitch_pid_int = -1000
If _pitch_pid_int > 1000 Then _pitch_pid_int = 1000
End Sub
Sub Mixer()
_bl(1) = 62667 - _sbl(_throttlechannel)
_bl(2) = _bl(1)
_bl(3) = _bl(1)
_bl(4) = 62667
_bl(4) = _bl(4) + _bl4offset
If _sbl(_statechannel) > -200 Then
_bl(1) = _bl(1) + _pitch_pid_int
_bl(2) = _bl(2) - _roll_pid_int
_bl(3) = _bl(3) + _roll_pid_int
_pitch_pid_int = _pitch_pid_int / 2
_bl(2) = _bl(2) - _pitch_pid_int
_bl(3) = _bl(3) - _pitch_pid_int
_bl(4) = _bl(4) - _yaw_pid_int
Led = 1
Elseif _sbl(_statechannel) < -200 Then
_bl(1) = 63800
_bl(2) = 63800
_bl(3) = 63800
For I = 0 To _max_d_state
_yaw_kd_err(i) = 0
_yaw_kd_old(i) = 0
_roll_kd_err(i) = 0
_roll_kd_old(i) = 0
_pitch_kd_err(i) = 0
_pitch_kd_old(i) = 0
Next I
_yaw_kp_err = 0
_yaw_ki_sum = 0
_yaw_kd_err_single = 0
_yaw_ki_err = 0
_roll_kp_err = 0
_roll_ki_sum = 0
_roll_kd_err_single = 0
_roll_ki_err = 0
_pitch_kp_err = 0
_pitch_ki_sum = 0
_pitch_kd_err_single = 0
_pitch_ki_err = 0
_yaw_pid_int = 0
_roll_pid_int = 0
_pitch_pid_int = 0
_yaw_pid = 0
_roll_pid = 0
_pitch_pid = 0
Led = 0
End If
End Sub
Sub Send_data()
_crc = Crc16(_bl(1) , 4)
Printbin Start_byte
Incr _btm222_counter
If _btm222_counter = 20 Then
_btm222_counter = 0
If _sbl(_datachannel) > -200 Then
'Print #2 , _roll_kp ; ":" ; _pitch_kp
'Print #2 , _roll_ki ; ":" ; _pitch_ki
'Print #2 , _roll_kd ; ":" ; _pitch_kd
'Print #2 , _sbl(_throttlechannel) ; ":" ; _sbl(_rollchannel) ; ":" ; _sbl(_pitchchannel) ; ":" ; _sbl(_yawchannel) ; ":" ; _sbl(_statechannel) ; ":" ; _sbl(_datachannel)
End If
End If
Printbin _bl(1) ; _bl(2) ; _bl(3) ; _bl(4) ; _crc
End Sub
Sub Init_system()
_sbl_filter(_throttlechannel) = -1000
_sbl_filter(_rollchannel) = 0
_sbl_filter(_pitchchannel) = 0
_sbl_filter(_yawchannel) = 0
_sbl_filter(_statechannel) = -600
_sbl_filter(_datachannel) = -600
Reset Newvalsreceived
_yawnow = 0
_rollnow = 0
_pitchnow = 0
Call Wmp_init()
Wait 1
For I = 1 To 50
Call Read_wmp_data()
Next I
Wait 1
Call Set_wmp_offset()
For I = 1 To 5
Led = 1
Waitms 20
Led = 0
Waitms 100
Next I
End Sub
End
Slave:
$regfile = "attiny2313.dat"
$crystal = 16000000
$framesize = 30
$hwstack = 32
$swstack = 30
$baud = 1000000 '115200
Config Timer1 = Timer , Prescale = 8
Timer1 = 62535
On Timer1 Servoirq
Enable Timer1
Config Servos = 1 , Servo1 = Portd.5 , Reload = 10
Config Portd.2 = Output
Config Portd.3 = Output
Config Portd.4 = Output
Config Portd.5 = Output
Dim Kanal As Byte
Dim _servo(4) As Word
Dim _bl(4) As Word
Dim I As Word
Dim _crc As Word
Dim _start As Byte
'min: 63800, mitte: 62667.5 , max: 61535 --> 2265 Schritte
Const _servo_teiler = 20
Const Start_byte = 127
Const Min_servo = 63800
Const Max_servo = 61535
Const Diff_servo = Max_servo - Min_servo
For I = 1 To 3
_bl(i) = Min_servo
_servo(i) = _bl(i)
Next I
Servo(1) = 100
Enable Interrupts
Wait 3
Do
If Ischarwaiting() > 0 Then
Inputbin _start
If _start = Start_byte Then
Inputbin _bl(1) , _bl(2) , _bl(3) , _bl(4) , _crc
If _crc = Crc16(_bl(1) , 4) Then
For I = 1 To 4
If _bl(i) < Max_servo Then _bl(i) = Max_servo
If _bl(i) > Min_servo Then _bl(i) = Min_servo
_servo(i) = _bl(i)
Next I
_servo(4) = _servo(4) - 61535
_servo(4) = _servo(4) / _servo_teiler
Servo(1) = 50 + _servo(4)
End If
End If
End If
Loop
Servoirq:
If Kanal = 0 Then
If Portd.2 = 0 Then 'wenn port low
Timer1 = _servo(1) 'dann timer auf entsprechende verzögerung
Portd.2 = 1 'und port anschalten
Else 'das hier passiert erst bei dem darauf folgenden interrupt
Portd.2 = 0 'dann port wieder ausschalten
Incr Kanal 'und den nächsten kanal bearbeiten
End If
End If
If Kanal = 1 Then
If Portd.3 = 0 Then
Timer1 = _servo(2)
Portd.3 = 1
Else
Portd.3 = 0
Incr Kanal
End If
End If
If Kanal = 2 Then
If Portd.4 = 0 Then
Timer1 = _servo(3)
Portd.4 = 1
Else
Portd.4 = 0
Incr Kanal
End If
End If
If Kanal = 3 Then
Timer1 = 65535
Kanal = 0
End If
'(
If Kanal = 3 Then
If Portd.5 = 0 Then
Timer1 = _servo(4)
Portd.5 = 1
Else
Portd.5 = 0
Incr Kanal
End If
End If
If Kanal = 4 Then
Timer1 = 40000 '65535 | eine pause von ca. 12ms bis zum nächsten interrupt. Bei guten Servos oder Brushlessreglern kann man hier bis auf 65530 gehen ==> ansteuerfrequenz von ~ 200Hz
Kanal = 0
End If
')
Return
End
Vielen Dank & Gruß
Chris
EDIT: Kann man in Bascom überhaupt einen Slave (Hardware I2C) vernünftig konfigurieren? Also mit Interrupt usw... Oder denkt ihr, Uart ist einfacher?