(→Software) |
(→Software) |
||
| Zeile 29: | Zeile 29: | ||
Siehe Link oben zum Rutscherle 2 [http://www.rn-wissen.de/index.php/Rutscherle_-_selbstbalancierender_Elektroroller]. | Siehe Link oben zum Rutscherle 2 [http://www.rn-wissen.de/index.php/Rutscherle_-_selbstbalancierender_Elektroroller]. | ||
| − | |||
| − | + | <pre>Motorcontroller | |
'******************Listrik01 Motorsteuerung, Version 01 ********************** | '******************Listrik01 Motorsteuerung, Version 01 ********************** | ||
| Zeile 1.082: | Zeile 1.081: | ||
Portd.6 = 1 'C- | Portd.6 = 1 'C- | ||
End Sub | End Sub | ||
| + | </pre> | ||
| − | Hauptsteuerung: | + | <pre>Hauptsteuerung: |
'( ******************Listrik01 Hauptsteuerung, Version 01 ****************** | '( ******************Listrik01 Hauptsteuerung, Version 01 ****************** | ||
| Zeile 3.592: | Zeile 3.592: | ||
Enable Interrupts | Enable Interrupts | ||
End Sub | End Sub | ||
| + | </pre> | ||
| − | Display3000: | + | <pre>Display3000: |
'****************Listrik01 LCD Display Steuerung Version 01 ***************** | '****************Listrik01 LCD Display Steuerung Version 01 ***************** | ||
Version vom 8. Februar 2013, 10:08 Uhr
Dieser Artikel ist noch in Bearbeitung.
Inhaltsverzeichnis
Listrik01 - Ein selbstbalancierendes Elektroeinrad
Beim Listrik01 handelt es sich um einen selbstbalancierenden Elektroroller. Die Elektronik basiert auf den Veröffentlichungen des Rutscherle 2 [1]. Die Schaltung wurde verändert um I2C Gyro und Accelerometer anschließen zu können. Die Listing wurden außerdem umfangreicher kommentiert.
Antrieb
Der Prototyp fährt mit einem 24V / 500W Gleichstrommotor. Das Gefährt ist allerdings extrem koflastig, deshalb baue ich es um auf einen 48V/1000W BLDC Motor. Vom Hersteller in China direkt importiert. Das Bild oben zeigt den GS-Prototyp. Bei der BLDC Variante werden Batterie, Steuerung und Motor in die Felge integriert. Dies sorgt für einen niedrigen Schwerkunkt. Habe mir ein 18" Motorrad Hinterrad besorgt in das alles integriert wird.
Die Sensorik wurde um 3 weitere Hallsensoren erweitert um einen Trigger je 60 Grad elektrisch zu bekommen. Die Geschwindigkeit ist auf 20km/h begrenzt.
Akkus
Der Gleichstrom Prototyp fährt mit 2 Bleiakkus mit 12V/7AH in Reihe geschaltet. Sie sind für Motoren und Elektronik. Die Entscheidung für Bleiakkus wurde bewusst getroffen. Bei einem Prototyp sind Ergebnisse wichtiger als Eleganz.
Der BLDC Prototyp fährt mit 4 Bleiakkus mit 12V/7AH in Reihe geschaltet. Sie sind für Motoren und Elektronik.
Elektronik
Motorregler mit Atmega 168A sowie eine Hauptsteuerung mit einem Atmega 644PA. Ein Display von Display3000 als Tacho (und Datenlogger). Siehe Stückliste.
Software
Die Software ist in Bascom geschrieben. Zeitkritische Teile in Assembler. Siehe Link oben zum Rutscherle 2 [2].
Motorcontroller
'******************Listrik01 Motorsteuerung, Version 01 **********************
'Es gibt keine Stromregelung, sondern eine Lageregelung im Hauptcontroller
'LED1 blinkt mit gültigem seriellen Telegramm
'LED2 blinkt wenn Zwangskommutierung
'LED2 dauerlicht wenn serielle Verbindung fehlt, d.h. Not Halt
'LED1 und LED2 blinken abwechselnd mit 1Hz für 3 Sekunden während CPU Anlauf
'LED1 und LED2 blinken mit 2Hz wenn Hallstecker nicht gesteckt ist.
' Ausserdem antwortet der Controller jetzt nicht auf Telegramme.
'LockBit, FuseBit , FuseBitHigh , FuseBitExtended
'$prog &HFF , &HF9 , &HDF , &HF6 'Fusebits 168A CPU
'Use AMTEL Studio / Fuses Menu instead to set fusebits
'BOOTSZ = 1024W_1C00
'BOOTRST = unchecked
'RSTDISBL = unchecked
'DWEN = unchecked
'SPIEN = checked
'WDTON = unchecked
'EESAVE = unchecked
'BODLEVEL = unchecked
'CKDIV8 = unchecked
'CKOUT = unchecked
'SUT_CKSEL = EXTFSXTAL_1KCK_14CK_4MS1
$regfile = "m168def.dat" 'ATMEGA168A CPU
$crystal = 11059200
$baud = 57600
$hwstack = 32
$swstack = 20
$framesize = 40
Const _pcicr = &B00000101 'Bit0 = PCIE0 = Port B0..B7
'Bit2 = PCIE2 = Port D0..D7
Const Numhall = 3 '<<<<<<<<<< TEST, Normalerweise = 4
Const Pclink = 1 '<<<<<<<<<< TEST, Normalerweise = 0, Sie Delphi
Declare Sub Setspeed
Declare Sub Pwm_start
Declare Sub Pwm_stop
Config Portb.0 = Input 'Hall_D
Config Portb.1 = Output 'B-
Config Portb.2 = Output 'B+
Config Portb.3 = Output 'A-(MOSI)
Config Portb.4 = Output 'LED2 (MISO)
Config Portb.5 = Input 'SCK
' PortB.6 XTAL
' PortB.7 XTAL
Config Portc.0 = Input 'UBatterie
Config Portc.1 = Input 'I-Ist
Config Portc.2 = Input 'Kühlkörper Temperatur
Config Portc.3 = Output 'LED1
Config Portc.4 = Output 'Lüfter
Config Portc.5 = Input 'Adress Jumper
' PortC.6 Reset
' PortC.7 nicht rausgeführt
' PortD.0 RxD
' PortD.1 TxD
Config Portd.2 = Input 'Hall_C
Config Portd.3 = Output 'A+
Config Portd.4 = Input 'Hall_B
Config Portd.5 = Output 'C+
Config Portd.6 = Output 'C-
Config Portd.7 = Input 'Hall_A
Hall_a Alias Pind.7
Hall_b Alias Pind.4
Hall_c Alias Pind.2
Hall_d Alias Pinb.0
Led1 Alias Portc.3
Led2 Alias Portb.4
Fan Alias Portc.4
Adrjumper Alias Pinc.5
'A-Werte stellen die Rotorposition in Abhängigkeit der Halleingänge dar
'Siehe Exceltabelle "Rotorposition Array A().xls"
Dim A(15) As Byte At $100
'S-Werte stellen die aktuelle Soll PWM-Breite dar
Dim S(12) As Byte At $10f
'0 = Vorwärts, 1 = Links, 2 = Leerlauf, 3 =
Dim Richtung(255) As Byte At $11b
'IstRichtung-Werte stellen den 0..2, siehe Zeile oberhalb
Dim Istrichtung As Integer At $21a
'Ticks-Werte stellen die Anzahl verbrauchter Ticks während eine Do..Loop dar
Dim Ticks As Integer At $221
'Anzahl Kommutierungen zwischen seriellen Telegrammen
Dim Uzu As Integer 'Netzspannung
Dim M1 As Byte At Uzu + 0 Overlay
Dim M2 As Byte At Uzu + 1 Overlay
Dim Izu As Integer 'Motorstrom
Dim M3 As Byte At Izu + 0 Overlay
Dim M4 As Byte At Izu + 1 Overlay
Dim Ausgabeticks As Integer 'Anzahl Ticks für ein Do ... Loop
Dim M5 As Byte At Ausgabeticks + 0 Overlay
Dim M6 As Byte At Ausgabeticks + 1 Overlay
Dim Temperatur As Integer 'Kühlkörpertemperatur
Dim M7 As Byte At Temperatur + 0 Overlay
Dim M8 As Byte At Temperatur + 1 Overlay
Dim Drehzahl As Integer 'Drehzahl
Dim M9 As Byte At Drehzahl + 0 Overlay
Dim M10 As Byte At Drehzahl + 1 Overlay
Dim Kalibrierwert As Integer
Dim Kal(2) As Byte At Kalibrierwert + 0 Overlay
Dim Sinus(12) As Byte
Dim Motorposition As Byte
Dim Altrichtung As Integer
Dim Aposition As Byte
Dim Zposition As Byte
Dim Zwangskommutieren As Byte
Dim Temp As Word
Dim Motoradresse As Byte
Dim Vwinkel As Byte
Dim Rwinkel As Byte
Dim N As Byte
Dim Notaus As Byte
Dim Loopcount As Word
Dim Sollrichtung As Byte
Dim Altsollrichtung As Byte
Dim Sollspeed As Byte
Dim Altsollspeed As Byte
Dim Bdummy As Byte
Dim Intbdummy As Byte
Dim Intidummy As Integer
Dim Sdummy As Single
Dim Idummy1 As Integer
Dim Idummy2 As Integer
Dim Uw As Word
Dim Iw As Word
Dim Uwsum As Long
Dim Iwsum As Long
Dim Wcount As Long
Dim Fancount As Long
Dim Uoffset As Single
Dim Ufaktor As Single
Dim Ioffset As Single
Dim Ifaktor As Single
Dim Empfpuffer(6) As Byte 'Empfangspuffer
Dim Ta As Byte
Dim Tb As Byte
Dim Tc As Byte
Dim Fehler As Byte
Dim Errorword As Word
Dim Errorword1 As Byte At Errorword + 0 Overlay
Dim Errorword2 As Byte At Errorword + 1 Overlay
'Integer bzw. Word (2Byte) = %
'Single (4Byte) = !
'Double (8Byte) = #
'Long (4Byte) = & ==> 32Bit Integer
'Byte (1Byte) = ohne Zusatz
$eeprom 'wird nicht benutzt
U_offset:
Data 0.0! 'Single
U_faktor:
Data 1.0! 'Single
I_offset:
Data 0.0! 'Single
I_faktor:
Data 1.0! 'Single
V_winkel:
Data 0 'Byte
R_winkel:
Data 0 'Byte
Sinus_12: 'Sinus mit 4 Hallgebern
Data 0 , 0 , 33 , 66 , 100 , 100 , 100 , 100 , 66 , 33 , 0 , 0
Sinus_6: 'Sinus mit 3 Hallgebern
Data 0 , 33 , 66 , 100 , 66 , 33
$data
Sollspeed = 0
Pwm_stop 'Erstmal alles auschalten
For N = 1 To 15
A(n) = 0
Next
'Variablen für die Richtungserkennung vorbelegen
'Diese Variante frisst zwar viel Arbeitsspeicher, ist aber sehr schnell
For N = 1 To 255
Richtung(n) = 2
Next
If Adrjumper = 0 Then 'Rechter Motor
Motoradresse = 82
#if Numhall = 3 'Anzahl Hallsensoren
A(5) = 1
A(1) = 2
A(3) = 3
A(2) = 4
A(6) = 5
A(4) = 6
#else
A(12) = 12
A(4) = 11
A(6) = 10
A(14) = 9
A(10) = 8
A(2) = 7
A(3) = 6
A(11) = 5
A(9) = 4
A(1) = 3
A(5) = 2
A(13) = 1
#endif
Richtung(21) = 3
Richtung(93) = 3
Richtung(220) = 3
Richtung(196) = 3
Richtung(70) = 3
Richtung(110) = 3
Richtung(234) = 3
Richtung(162) = 3
Richtung(35) = 3
Richtung(59) = 3
Richtung(185) = 3
Richtung(145) = 3
Richtung(81) = 1
Richtung(25) = 1
Richtung(155) = 1
Richtung(179) = 1
Richtung(50) = 1
Richtung(42) = 1
Richtung(174) = 1
Richtung(230) = 1
Richtung(100) = 1
Richtung(76) = 1
Richtung(205) = 1
Richtung(213) = 1
Else
Motoradresse = 76 'Linker Motor
#if Numhall = 3 'Anzahl Hallsensoren
A(3) = 1
A(1) = 2
A(5) = 3
A(4) = 4
A(6) = 5
A(2) = 6
#else
A(11) = 1
A(3) = 2
A(1) = 3
A(9) = 4
A(13) = 5
A(5) = 6
A(4) = 7
A(12) = 8
A(14) = 9
A(6) = 10
A(2) = 11
A(10) = 12
#endif
Richtung(236) = 3
Richtung(196) = 3
Richtung(69) = 3
Richtung(93) = 3
Richtung(217) = 3
Richtung(145) = 3
Richtung(19) = 3
Richtung(59) = 3
Richtung(186) = 3
Richtung(162) = 3
Richtung(38) = 3
Richtung(110) = 3
Richtung(42) = 1
Richtung(171) = 1
Richtung(179) = 1
Richtung(49) = 1
Richtung(25) = 1
Richtung(157) = 1
Richtung(213) = 1
Richtung(84) = 1
Richtung(76) = 1
Richtung(206) = 1
Richtung(230) = 1
Richtung(98) = 1
End If
'AD-Wandler einstellen
Config Adc = Single , Prescaler = Auto , Reference = Off
Start Adc
'<Test Hallsensoren>
Fehler = 1
Fan = 1
While Fehler = 1
Fehler = 0
Motorposition = 0
Motorposition.0 = Hall_a
Motorposition.1 = Hall_b
Motorposition.2 = Hall_c
#if Numhall = 3 'Anzahl Hallsensoren
Motorposition.3 = 0
#else
Motorposition.3 = Hall_d
#endif
If Motorposition = 0 Then Fehler = 1 'Stecker nicht gesteckt
If Motorposition > 0 Then
'Das währe eine Motorposition die es nicht gibt
If A(motorposition) = 0 Then Fehler = 1
End If
If Fehler = 1 Then
Toggle Led1
Toggle Led2
Waitms 250 '==> 2Hz
End If
Wend
'</Test Hallsensoren>
On Timer2 Update_pwm Nosave
'Pin-Change Interrupt einstellen: (Hall Impulse)
Pcmsk2 = &B10010100 'Hall A, B, C
Pcmsk1 = &B00000000
Pcmsk0 = &B00000001 'Hall D
Pcicr = _pcicr
'Wenn sich das Hallsignal ändert, wird kommutiert
On Pcint2 Kommutieren Nosave
On Pcint0 Kommutieren Nosave
'EEPROM mit dem Programm Motorcontroller_EEPROM.bas vorbesetzen
' Datenreihenfolge dort ist ab Byte(1):
' U_offset, U_faktor, I_offset, I_faktor im Single Format
' Voreilwinkel, Nacheilwinkel im Byte Format
'Sinuskurve 12 Werte im Byte Format für 4 Hall Sensoren
'Sinuskurve 6 Werte im Byte Format für 3 Hall Sensoren
'Readeeprom Uoffset , 1
Uoffset = 0
'Readeeprom Ufaktor , 5
Ufaktor = 5.37109375 'Siehe Hardwarezeichnung für Berechnung
'Readeeprom Ioffset , 9
Ioffset = 512 '2,5V
'Readeeprom Ifaktor , 13
Ifaktor = 7.8125 'Siehe Hardwarezeichnung für Berechnung
'Voreilwinkel:
'Readeeprom Vwinkel , 17
Vwinkel = 0
'Readeeprom Rwinkel , 18
Rwinkel = 0
If Ufaktor = 0 Then Ufaktor = 1.0
If Ifaktor = 0 Then Ifaktor = 1.0
'Angepasste Sinuskurve aus dem EEprom laden
#if Numhall = 3 'Anzahl Hallsensoren
' For N = 1 To 6
' Bdummy = N + 30
' Readeeprom Sinus(n) , Bdummy
' Next
Sinus(1) = 0
Sinus(2) = 33
Sinus(3) = 66
Sinus(4) = 100
Sinus(5) = 66
Sinus(6) = 33
#else 'Anzahl Hallsensoren = 4
' For N = 1 To 12
' Bdummy = N + 18
' Readeeprom Sinus(n) , Bdummy
' Next
Sinus(1) = 0
Sinus(2) = 0
Sinus(3) = 33
Sinus(4) = 66
Sinus(5) = 100
Sinus(6) = 100
Sinus(7) = 100
Sinus(8) = 100
Sinus(9) = 66
Sinus(10) = 33
Sinus(11) = 0
Sinus(12) = 0
#endif
Fan = 1 'Lüfter kurz einschalten damit die Lager nicht fest werden
For N = 1 To 3 '3 sekunden
Led1 = 1
Led2 = 0
Waitms 500
Toggle Led1
Toggle Led2
Waitms 500
Next
Led2 = 0
Fan = 0
On Urxc Datenempfang Nosave
Enable Urxc 'serielles UART. No parity, 1 stop bit, 8 data bits
Enable Interrupts
Do
Led1 = 0
'<Messen>
Uw = Getadc(0) + 14 'Versorgungsspannung. Siehe Hardwarezeichnung
Uwsum = Uwsum + Uw
Iw = Getadc(1) 'Gesamtstrom
Iwsum = Iwsum + Iw
Incr Wcount
'Kühkörpertemperatur in counts. Siehe Datenblätter\10K_NTC_Kennlinie.odt
Temp = Getadc(2)
'</Messen>
'<Serielle Telegramme abarbeiten>
' Empfpuffer(1) Empfpuffer(2) Empfpuffer(3) Empfpuffer(4) Empfpuffer(5) Empfpuffer(6)
' <CR> Contr.Adresse Richtung PWM Checksum <CR>
If Empfpuffer(1) = 13 Then 'Das letzte im Ring verschobene empfangene CR
If Empfpuffer(6) = 13 Then
Led1 = 1
If Empfpuffer(2) = Motoradresse Then '"R" oder "L"
Disable Urxc
'BCC für Empfangsmessage berechnen
!lds R24,{Empfpuffer(2)} 'Adresse. Load Direct from data space @address xxx
!LDs R25,{Empfpuffer(3)} 'Richtung.Load Direct from data space @address xxx
!add R24,R25
!LDs R25,{Empfpuffer(4)} 'PWM. Load Direct from data space @address xxx
!add R24,R25
!STS {Bdummy},R24 'Write Rxx to address loaction
If Bdummy = Empfpuffer(5) Then 'Die Prüfsumme stimmt
'Kommutieren deaktivieren, weil sonst die Ticks während dem Zugriff
'geändert werden könnten
Pcicr = &B00000000
Ausgabeticks = Ticks
Ticks = 0
Pcicr = _pcicr
'BCC für Sendemessage berechnen
!lds R24,{M1} 'Load Direct from data space @address xxx into Rxx
!LDs R25,{M2} 'Load Direct from data space @address xxx into Rxx
!add R24,R25 'Add Rxx + Ryy, Result in Rxx
!LDs R25,{M3} 'Load Direct from data space @address xxx into Rxx
!add R24,R25 'Add Rxx + Ryy, Result in Rxx
!LDs R25,{M4} 'Load Direct from data space @address xxx into Rxx
!add R24,R25 'Add Rxx + Ryy, Result in Rxx
!LDs R25,{M5} 'Load Direct from data space @address xxx into Rxx
!add R24,R25 'Add Rxx + Ryy, Result in Rxx
!LDs R25,{M6} 'Load Direct from data space @address xxx into Rxx
!add R24,R25 'Add Rxx + Ryy, Result in Rxx
!STS {Bdummy},R24 'Write Rxx to address loaction
'Antwort am UART ausgeben
'M1/M2=Spg M3/M4=Strom M5/M6=Loop Ticks Bdummy=Checksum
'Print M1 ; M2 ; M3 ; M4 ; M5 ; M6 ; Bdummy ; 13
'in Assembler geht das so...
!LdS R24,{M1} 'Load Direct from data space @address xxx into Rxx
!STS udr,R24 'Write Rxx to address loaction
Warten1:
!LDS R24,UCSR0A 'Load Direct from data space @address xxx into Rxx
!BST R24,5 'Store bit x of Rxx in T Flag
!Brtc warten1
!LDS R24,{M2} 'Load Direct from data space @address xxx into Rxx
!STS udr,R24 'Write Rxx to address loaction
Warten2:
!LDS R24,UCSR0A 'Load Direct from data space @address xxx into Rxx
!BST R24,5 'Store bit x of Rxx in T Flag
!Brtc warten2
!lds R24,{M3} 'Load Direct from data space @address xxx into Rxx
!STS udr,R24 'Write Rxx to address loaction
Warten3:
!LDS R24,UCSR0A 'Load Direct from data space @address xxx into Rxx
!BST R24,5 'Store bit x of Rxx in T Flag
!Brtc warten3
!LDS R24,{M4} 'Load Direct from data space @address xxx into Rxx
!STS udr,R24 'Write Rxx to address loaction
Warten4:
!LDS R24,UCSR0A 'Load Direct from data space @address xxx into Rxx
!BST R24,5 'Store bit x of Rxx in T Flag
!Brtc warten4
!LDS R24,{M5} 'Load Direct from data space @address xxx into Rxx
!STS udr,R24 'Write Rxx to address loaction
Warten5:
!LDS R24,UCSR0A 'Load Direct from data space @address xxx into Rxx
!BST R24,5 'Store bit x of Rxx in T Flag
!Brtc warten5
!LDS R24,{M6} 'Load Direct from data space @address xxx into Rxx
!STS udr,R24 'Write Rxx to address loaction
Warten6:
!LDS R24,UCSR0A 'Load Direct from data space @address xxx into Rxx
!BST R24,5 'Store bit x of Rxx in T Flag
!Brtc warten6
!LDS R24,{bdummy}
!STS udr,R24 'Write Rxx to address loaction
Warten7:
!LDS R24,UCSR0A 'Load Direct from data space @address xxx into Rxx
!BST R24,5 'Store bit x of Rxx in T Flag
!Brtc warten7
!LDi R24,13
!STS udr,R24 'Write Rxx to address loaction
Warten8:
!LDS R24,UCSR0A 'Load Direct from data space @address xxx into Rxx
!BST R24,5 'Store bit x of Rxx in T Flag
!Brtc warten8
If Empfpuffer(3) < 3 Then 'Richtung
Notaus = 0
Loopcount = 0
Sollrichtung = Empfpuffer(3) 'Richtung
Sollspeed = Empfpuffer(4) 'PWM Breite
If Sollrichtung = 2 Then
Sollrichtung = 1
Notaus = 1
Loopcount = 250
Sollspeed = 0
End If
Setspeed
'<Messwerte berechnen>
'Messwerte werden hier berechnet, weil genau jetzt 1/100s Zeit ist.
'Spannung berechnen
Sdummy = Uwsum / Wcount
Sdummy = Sdummy - Uoffset
Sdummy = Sdummy * Ufaktor
Uzu = Int(sdummy)
Uwsum = 0
'Strom berechnen
Sdummy = Iwsum / Wcount
Sdummy = Sdummy - Ioffset
Sdummy = Sdummy * Ifaktor
Izu = Int(sdummy)
Iwsum = 0
Wcount = 0
'</Messwerte berechnen>
Else 'wird nie erreicht weil weder Hauptsteuerung noch Display diese
'Werte senden
Select Case Empfpuffer(3)
Case 3 'Sinus(1) empfangen
Sinus(1) = Empfpuffer(4)
Writeeeprom Sinus(1) , 17
Case 4 'Sinus(2) empfangen
Sinus(2) = Empfpuffer(4)
Writeeeprom Sinus(2) , 18
Case 5 'Sinus(3) empfangen
Sinus(3) = Empfpuffer(4)
Writeeeprom Sinus(3) , 19
Case 6 'Sinus(4) empfangen
Sinus(4) = Empfpuffer(4)
Writeeeprom Sinus(4) , 20
Case 7 'Sinus(5) empfangen
Sinus(5) = Empfpuffer(4)
Writeeeprom Sinus(5) , 21
Case 8 'Sinus(6) empfangen
Sinus(6) = Empfpuffer(4)
Writeeeprom Sinus(6) , 22
Case 9 'Sinus(7) empfangen
Sinus(7) = Empfpuffer(4)
Writeeeprom Sinus(7) , 23
Case 10 'Sinus(8) empfangen
Sinus(8) = Empfpuffer(4)
Writeeeprom Sinus(8) , 24
Case 11 'Sinus(9) empfangen
Sinus(9) = Empfpuffer(4)
Writeeeprom Sinus(9) , 25
Case 12 'Sinus(10) empfangen
Sinus(10) = Empfpuffer(4)
Writeeeprom Sinus(10) , 26
Case 13 'Sinus(11) empfangen
Sinus(11) = Empfpuffer(4)
Writeeeprom Sinus(11) , 27
Case 14 'Sinus(12) empfangen
Sinus(12) = Empfpuffer(4)
Writeeeprom Sinus(12) , 28
Case 15 'Spannung Kalibrieren (Byte 1)
Kal(1) = Empfpuffer(4)
Case 16 'Spannung Kalibrieren (Byte 2)
Kal(2) = Empfpuffer(4)
Sdummy = Uwsum / Wcount
Ufaktor = Kalibrierwert / Sdummy
Writeeeprom Ufaktor , 5
Uoffset = 0 'Schaltungsbedingt
Writeeeprom Uoffset , 1
Case 17 'Strom Kalibrieren (Byte 1)
Kal(1) = Empfpuffer(4)
Case 18 'Strom Kalibrieren Byte (2)
Kal(2) = Empfpuffer(4)
Sdummy = Iwsum / Wcount
If Kalibrierwert = 0 Then 'Das ist der Offset
Ioffset = Sdummy + 1
Writeeeprom Ioffset , 9
Else 'Jetzt den Faktor berechnen
Sdummy = Sdummy - Ioffset
Ifaktor = Kalibrierwert / Sdummy
Writeeeprom Ifaktor , 13
End If
Case 19
Vwinkel = Empfpuffer(4)
Writeeeprom Vwinkel , 29
Case 20
Rwinkel = Empfpuffer(4)
Writeeeprom Rwinkel , 30
End Select
End If
!LDI R24,0
!sTS {Empfpuffer(1)},R24 'Write Rxx to address loaction
!sTS {Empfpuffer(2)},R24 'Write Rxx to address loaction
!sTS {Empfpuffer(3)},R24 'Write Rxx to address loaction
!sTS {Empfpuffer(4)},R24 'Write Rxx to address loaction
!sTS {Empfpuffer(5)},R24 'Write Rxx to address loaction
End If
Enable Urxc
End If
End If
End If
'</Serielle Telegramme abarbeiten>
'Lüfter einschalten wenn Temperatur > 57 GradC
'Lüfter ausschalten wenn Temperatur < 45 GradC
If Temp < 350 Then
Fan = 1
Fancount = 120000 'Nachlaufzeit, Zykluszeit 1/100 Sekunde = 150 Sekunden
Else
If Temp > 532 Then
If Fancount = 0 Then 'Nachlaufzeit beendet
Fan = 0
End If
End If
End If
If Fancount > 0 Then Decr Fancount
'Notaus mit Freilauf wenn keine Nachricht von Seriell
If Loopcount < 50 Then 'Das sind schätzungsweise 0.1s
Notaus = 0
Incr Loopcount
Else
Notaus = 1
Sollspeed = 0
Setspeed
End If
Loop
Kommutieren:
!push R10 'Rxx sichern
!PUSH R11 'Rxx sichern
!PUSH R16 'Rxx sichern
!PUSH R17 'Rxx sichern
!PUSH R20 'Rxx sichern
!PUSH R21 'Rxx sichern
!PUSH R24 'Rxx sichern
!PUSH R26 'Rxx sichern
!PUSH R27 'Rxx sichern
!IN R24,sreg
!PUSH R24
!clr R16 'Clear Rxx
#if Numhall = 3
!andi R17,&B01110111 'Clear Hall-D Bits
#else
!lds R17, $0023 'Port B input pins address. Hall D
!BST R17,0 'Store bit x of Rxx in T Flag. Hall D-Bit
!BLD R16,3 'Copy T Flag in the SREG (Status Register) to Bit x in Rxx
#endif
!LDS R17, $0029 'Port D input pins address. Hall A,B,C
!BST R17,2 'Store bit x of Rxx in T Flag. Hall C-Bit
!bld R16,2 'Copy T Flag in the SREG (Status Register) to Bit x in Rxx
!BST R17,4 'Store bit x of Rxx in T Flag. Hall B-Bit
!bld R16,1 'Copy T Flag in the SREG (Status Register) to Bit x in Rxx
!BST R17,7 'Store bit x of Rxx in T Flag. Hall A-Bit
!bld R16,0 'Copy T Flag in the SREG (Status Register) to Bit x in Rxx
'R16 hat nun 0000DCBA Hall Signale
!lds R17,{aposition} 'Load Direct from data space @address xxx
!Swap R17 'R17 hat nun DCBA0000 Hall Signale
!andi R17,&B11110000 'Bit-And of Rxx with a constant value. Die 4 Bit sind Hall A...D
'R17 hat nun nur noch die oberen 4 Bit
!add R17,R16 'Rxx + Ryy. Ergebnis in Rxx
!STS {aposition},R17 'Write Rxx to address loaction
!CLR R17
!LDI R26,$FF 'Startadresse von A() - 1
!LDI R27,$00
!ADD R26,R16
!ADC R27,R17
!LD R24,X 'Load Direct from address xxx
!LDS R16,{Sollrichtung} 'Load Direct from data space @address xxx
!CPI R16,0
!BREQ Sollrichtungnull 'Branch out if equal
!Jmp Sollrichtungnichtnull
Sollrichtungnull:
!LDS R20,{Vwinkel} 'Load Direct from data space @address xxx
!Add R24,R20
!JMP Richtunggesetzt
Sollrichtungnichtnull:
!LDS R20,{Rwinkel}
!Add R24,R20
Richtunggesetzt:
#if Numhall = 3
!CPI R24,$07 'Compare Rxx with constant 6 + 1 Sinusschritte
#else
!CPI R24,$0D 'Compare Rxx with constant 12 + 1 Sinusschritte
#endif
!BRCC Istgroesser13_1
!JMP Istkleiner13_1
Istgroesser13_1:
#if Numhall = 3
!SUBI R24,$06 'Subtract constant from Rxx, result in Rxx. 6 Sinusschritte
#else
!SUBI R24,$0C 'Subtract constant from Rxx, result in Rxx. 12 Sinusschritte
#endif
Istkleiner13_1:
!CLR R20
!Ldi R26,$0E 'Startadresse von S() - 1
!LDI R27,$01 'Startadresse von S() - 1
!ADD R26,R24
!ADC R27,R20
!LD R16,X 'Load Direct from address xxx
!STS {Ta},R16 'Write Rxx to address loaction
!subi R24,$fc
#if Numhall = 3
!CPI R24,$07 'Compare Rxx with constant 6 + 1 Sinusschritte
#else
!CPI R24,$0D 'Compare Rxx with constant 12 + 1 Sinusschritte
#endif
!BRCC Istgroesser13_2
!JMP Istkleiner13_2
Istgroesser13_2:
#if Numhall = 3
!SUBI R24,$06 'Subtract constant from Rxx, result in Rxx. 6 Sinusschritte
#else
!SUBI R24,$0C 'Subtract constant from Rxx, result in Rxx. 12 Sinusschritte
#endif
Istkleiner13_2:
!CLR R20
!Ldi R26,$0E 'Startadresse von S() - 1
!LDI R27,$01 'Startadresse von S() - 1
!ADD R26,R24
!ADC R27,R20
!LD R16,X 'Load Direct from address xxx
!STS {Tc},R16 'Write Rxx to address loaction
!subi R24,$fc
#if Numhall = 3
!CPI R24,$07 'Compare Rxx with constant 6 + 1 Sinusschritte
#else
!CPI R24,$0D 'Compare Rxx with constant 12 + 1 Sinusschritte
#endif
!BRCC Istgroesser13_3
!JMP Istkleiner13_3
Istgroesser13_3:
#if Numhall = 3
!SUBI R24,$06 'Subtract constant from Rxx, result in Rxx. 6 Sinusschritte
#else
!SUBI R24,$0C 'Subtract constant from Rxx, result in Rxx. 12 Sinusschritte
#endif
Istkleiner13_3:
!CLR R20
!Ldi R26,$0E 'Startadresse von S() - 1
!LDI R27,$01 'Startadresse von S() - 1
!ADD R26,R24
!ADC R27,R20
!LD R16,X 'Load Direct from address xxx
!STS {Tb},R16 'Write Rxx to address loaction
!lds R10,{aposition}
!CLR R11 'Clear Rxx
!LDI R26,$1A 'Startadresse von Richtung() - 1
!LDI R27,$01 'Startadresse von Richtung() - 1
!ADD R26,R10 'move Ptr by {aposition} innnerhalb Richtung()
!ADC R27,R11 'Add Zero
!LD R16,X+ 'Load Rxx with data from address in X Register(R26, R27) and increment Ptr
'R16 hat Inhalt von Richtung(X+)
!CLR R17 'Clear Rxx
!LDI R20,$02 '2 Byte
!LDI R21,$00
!Sub R16 , R20 'Werte von einander abziehen
!SBC R17,R21 'Werte von einander abziehen
!LDI R26,$1A 'Startadresse von IstRichtung()
!LDI R27,$02 'Startadresse von IstRichtung()
!ST X+,R16 'Store Rxx in address in X + 1 Register
!ST X,R17
!LDI R26,$41 'Startadresse von Ticks()
!LDI R27,$02 'Startadresse von Ticks()
!LD R16,X+ 'Load Rxx with data from address in X Register
!LD R17,X
!LDI R26,$1A 'Startadresse von IstRichtung()
!LDI R27,$02 'Startadresse von IstRichtung()
!LD R20,X+ 'Load Rxx with data from address in X Register
!LD R21,X
!ADD R16,R20
!ADC R17,R21
!LDI R26,$41 'Startadresse von Ticks()
!LDI R27,$02 'Startadresse von Ticks()
!ST X+,R16 'Store Rxx in address in X + 1 Register
!ST X,R17
!LDS R24,timsk2
!ORI R24,$01
!STS timsk2,R24 'Write Rxx to address loaction
!POP R24
!Out Sreg , R24
!POP R27 'Rxx wieder herstellen
!POP R26'Rxx wieder herstellen
!POP R24'Rxx wieder herstellen
!POP R21 'Rxx wieder herstellen
!POP R20 'Rxx wieder herstellen
!POP R17'Rxx wieder herstellen
!POP R16 'Rxx wieder herstellen
!POP R11 'Rxx wieder herstellen
!POP R10 'Rxx wieder herstellen
Return
Update_pwm:
'Ta, Tb und Tc sind die Amplituden der 3 Phasen
!PUSH R24
!IN R24,sreg
!PUSH R24
!lds R24,{Ta}
!STS ocr2a,R24 'Write Rxx to address loaction
!STS ocr2b,R24
!LDS R24,{Tb}
!STS ocr1al,R24 'Write Rxx to address loaction
!STS ocr1bl,R24
!lds R24,{Tc}
!Out Ocr0a , R24
!Out Ocr0b , R24
!LDS R24,timsk2
!ANDI R24,$FE
!STS timsk2,R24 'Write Rxx to address loaction
!POP R24 'Rxx wieder herstellen
!Out Sreg , R24
!POP R24 'Rxx wieder herstellen
Return
Datenempfang:
'Die empfangenen Zeichen im nach links laufenden Umlauf in Empfpuffer(1)..Empfpuffer(6) geschrieben
'Dadurch wir sichergestellt, dass das Startzeichen (CR) irgendwann in EP0 steht
!PUSH R24 'Rxx sichern
!IN R24, SREG 'Statusregistr sichern
!PUSH R24
'Zeichen im Puffer nach links schieben
!LDS R24,{Empfpuffer(2)} 'Load Direct from data space @address xxx
!STS {Empfpuffer(1)},R24 'Write Rxx to address loaction
!LDS R24,{Empfpuffer(3)} 'Load Direct from data space @address xxx
!STS {Empfpuffer(2)},R24 'Write Rxx to address loaction
!LDS R24,{Empfpuffer(4)} 'Load Direct from data space @address xxx
!STS {Empfpuffer(3)},R24 'Write Rxx to address loaction
!LDS R24,{Empfpuffer(5)} 'Load Direct from data space @address xxx
!STS {Empfpuffer(4)},R24 'Write Rxx to address loaction
!LDS R24,{Empfpuffer(6)} 'Load Direct from data space @address xxx
!STS {Empfpuffer(5)},R24 'Write Rxx to address loaction
'neues Zeichen einlesen
!IN R24,UDR 'Load an I/O Location to Rxx
!STs {Empfpuffer(6)},R24 'Write Rxx to address loaction
!POP R24 'Rxx wieder herstellen
!Out Sreg , R24 'Statusregister wieder herstellen
!POP R24 'Rxx wieder herstellen
Return
Sub Setspeed
If Notaus = 1 Then
Pwm_stop
Sollspeed = 0
For N = 1 To 12
S(n) = 0
Next
Else
#if Numhall = 3 'Anzahl Hallsensoren
For N = 1 To 6
Idummy1 = Sollspeed * Sinus(n)
Idummy1 = Idummy1 / 100
S(n) = Idummy1
Next
#else
For N = 1 To 12
Idummy1 = Sollspeed * Sinus(n)
Idummy1 = Idummy1 / 100
S(n) = Idummy1
Next
#endif
If Tccr0a = 0 Then Pwm_start 'Wenn die PWM aus ist
'<Zwangskommutieren??>
Zwangskommutieren = 0
If Sollrichtung <> Altsollrichtung Then Zwangskommutieren = 1
If Sollspeed <> Altsollspeed Then Zwangskommutieren = 1
If Zwangskommutieren = 1 Then
Pcicr = &B00000000 'Den eigentlichen Kommutierinterrupt abschalten
!clr R16 'Clear Register 16
!lds R17, $0023 'Load Direct from data space @address xxx
!BST R17,0 'Store bit x of Rxx in T Flag
!BLD R16,3 'Copy T Flag in the SREG (Status Register) to Bit x in Rxx
!LDS R17, $0029 'Load Direct from data space @address xxx
!BST R17,2 'Store bit x of Rxx in T Flag
!bld R16,2 'Copy T Flag in the SREG (Status Register) to Bit x in Rxx
!BST R17,4 'Store bit x of Rxx in T Flag
!bld R16,1 'Copy T Flag in the SREG (Status Register) to Bit x in Rxx
!BST R17,7 'Store bit x of Rxx in T Flag
!bld R16,0 'Copy T Flag in the SREG (Status Register) to Bit x in Rxx
!lds R17,{aposition} 'Load Direct from data space @address xxx
!Swap R17 'Swap high and low nibbles in Rxx. aposition is now in the upper nibble
!andi R17,&B11110000 'Logical AND Rxx and a constant, Result in Rxx. Clear lower nibble
!add R17,R16 'Add Rxx + Ryy, Result in Rxx
!STS {aposition},R17 'Write Rxx to address loaction
!CLR R17 'Clear Rxx
!LDI R26,$FF 'Startadresse von A() - 1
!LDI R27,$00 'Startadresse von A() - 1
!ADD R26,R16 'Add Rxx + Ryy without carry, Result in Rxx
!ADC R27,R17 'Add Rxx + Ryy with carry, Result in Rxx
!LD R24,X 'Load Indirect Rxx with address in X Register
!LDS R16,{Sollrichtung} 'Load Direct from data space @address xxx
!CPI R16,0 'Compare Rxx with constant
!BREQ Sollrichtungnullz 'Branch if Equal
!Jmp Sollrichtungnichtnullz 'Relative Jump
Sollrichtungnullz:
!LDS R20,{Vwinkel} 'Load Direct from data space @address xxx
!Add R24,R20 'Add Rxx + Ryy, Result in Rxx
!JMP Richtunggesetztz
Sollrichtungnichtnullz:
!LDS R20,{Rwinkel} 'Load Direct from data space @address xxx
!Add R24,R20 'Add Rxx + Ryy without carry, Result in Rxx
Richtunggesetztz:
#if Numhall = 3
!CPI R24,$07 'Compare Rxx with constant 6 + 1 Sinusschritte
#else
!CPI R24,$0D 'Compare Rxx with constant 12 + 1 Sinusschritte
#endif
!BRCC Istgroesser13_1z 'Branch if Carry Cleared
!JMP Istkleiner13_1z 'Relative Jump
Istgroesser13_1z:
#if Numhall = 3
!SUBI R24,$06 'Subtract constant from Rxx, result in Rxx. 6 Sinusschritte
#else
!SUBI R24,$0C 'Subtract constant from Rxx, result in Rxx. 12 Sinusschritte
#endif
Istkleiner13_1z:
!CLR R20 'Clear Rxx
!Ldi R26,$0E 'Startadresse von S() - 1
!LDI R27,$01 'Startadresse von S() - 1
!ADD R26,R24 'Add Rxx + Ryy without carry, Result in Rxx
!ADC R27,R20 'Add Rxx + Ryy with carry, Result in Rxx
!LD R16,X 'Load Rxx with data from address in X Register
!STS {Ta},R16 'Write Rxx to address loaction
!subi R24,$fc 'Subtract constant from Rxx, result in Rxx
#if Numhall = 3
!CPI R24,$07 'Compare Rxx with constant 6 + 1 Sinusschritte
#else
!CPI R24,$0D 'Compare Rxx with constant 12 + 1 Sinusschritte
#endif
!BRCC Istgroesser13_2z 'Branch if Carry Cleared
!JMP Istkleiner13_2z 'Relative Jump
Istgroesser13_2z:
#if Numhall = 3
!SUBI R24,$06 'Subtract constant from Rxx, result in Rxx. 6 Sinusschritte
#else
!SUBI R24,$0C 'Subtract constant from Rxx, result in Rxx. 12 Sinusschritte
#endif
Istkleiner13_2z:
!CLR R20 'Clear Rxx
!Ldi R26,$1a 'Startadresse von S() - 1
!LDI R27,$01 'Startadresse von S() - 1
!ADD R26,R24 'Add Rxx + Ryy without carry, Result in Rxx
!ADC R27,R20 'Add Rxx + Ryy with carry, Result in Rxx
!LD R16,X 'Load Rxx with data from address in X Register
!STS {Tc},R16 'Write Rxx to address loaction
!subi R24,$fc 'Subtract constant from Rxx, result in Rxx
#if Numhall = 3
!CPI R24,$07 'Compare Rxx with constant 6 + 1 Sinusschritte
#else
!CPI R24,$0D 'Compare Rxx with constant 12 + 1 Sinusschritte
#endif
!BRCC Istgroesser13_3z 'Branch if Carry Cleared
!JMP Istkleiner13_3z 'Relative Jump
Istgroesser13_3z:
#if Numhall = 3
!SUBI R24,$06 'Subtract constant from Rxx, result in Rxx. 6 Sinusschritte
#else
!SUBI R24,$0C 'Subtract constant from Rxx, result in Rxx. 12 Sinusschritte
#endif
Istkleiner13_3z:
!CLR R20 'Clear Rxx
!Ldi R26,$1a 'Startadresse von S() - 1
!LDI R27,$01 'Startadresse von S() - 1
!ADD R26,R24 'Add Rxx + Ryy without carry , Result in Rxx
!ADC R27,R20 'Add Rxx + Ryy with carry, Result in Rxx
!LD R16,X 'Load Rxx with data from address in X Register
!STS {Tb},R16 'Write Rxx to address loaction
Pcicr = _pcicr 'Den eigentlichen Kommutierinterrupt einschalten
Timsk2.toie2 = 1 'Timer2 Overflow Interrupt aktivieren
Toggle Led2
End If
'</Zwangskommutieren>
End If
Altsollrichtung = Sollrichtung
Altsollspeed = Sollspeed
End Sub
Sub Pwm_start
Disable Interrupts 'Damit die Timer auch wirklich synchron laufen
Tccr0a = 161 'Timer Counter Control Register A
Tccr0b = 1 'Timer Counter Control Register B
Ocr0a = 0 'Set output compare Ctr 0, Register A, continuously compared with TCNT0
Ocr0b = 0 'Set output compare Ctr 0, Register B, continuously compared with TCNT0
Tccr1a = 161 'Timer Counter Control Register 1A
Tccr1b = 1 'Timer Counter Control Register 1B
Ocr1ah = 0 'Output A compare value in H and L Bytes
Ocr1al = 0
Ocr1bh = 0 'Output B compare value in H and L Bytes
Ocr1bl = 0
Tccr2a = 161 'Timer Counter Control Register 2A
Tccr2b = 1 'Timer Counter Control Register 2B
Ocr2a = 0 'Set output compare Ctr 2, Register A, continuously compared with TCNT0
Ocr2b = 0 'Set output compare Ctr 2, Register B, continuously compared with TCNT0
Tcnt0 = 0 'Timer Startwert
Tcnt1 = 6 'Timer Startwert, Wert anders damit sie alle synchron laufen
Tcnt2 = 9 'Timer Startwert, Wert anders damit sie alle synchron laufen
Enable Interrupts
End Sub
Sub Pwm_stop
Tccr0a = 0 'Timer Counter Control Register A
Tccr0b = 0 'Timer Counter Control Register B
Ocr0a = 0 'Set output compare Ctr 0, Register A, continuously compared with TCNT0
Ocr0b = 0 'Set output compare Ctr 0, Register B, continuously compared with TCNT0
Tccr1a = 0 'Timer Counter Control Register 1A
Tccr1b = 0 'Timer Counter Control Register 1B
Ocr1ah = 0 'Output A compare value in H and L Bytes
Ocr1al = 0
Ocr1bh = 0 'Output B compare value in H and L Bytes
Ocr1bl = 0
Tccr2a = 0 'Timer Counter Control Register 2A
Tccr2b = 0 'Timer Counter Control Register 2B
Ocr2a = 0 'Set output compare Ctr 2, Register A, continuously compared with TCNT0
Ocr2b = 0 'Set output compare Ctr 2, Register B, continuously compared with TCNT0
'alle Phasen Aus
Portd.3 = 0 'A+
Portb.3 = 1 'A-
Portb.2 = 0 'B+
Portb.1 = 1 'B-
Portd.5 = 0 'C+
Portd.6 = 1 'C-
End Sub
Hauptsteuerung:
'( ******************Listrik01 Hauptsteuerung, Version 01 ******************
1. LED1 blinkt mit 1 Hz wenn alles OK
2. LED1 und LED2 blinken mit 5Hz wenn I2c-Bus gestört ist
3. LED1 und LED2 blinken mit bis zu 10Hz wenn U-Batt zu klein ist. Frequenz hängt
von der Anzahl Interrups ab, die während der Wartezeit auflaufen, z.B. von COM
4. Lade-LEDs
- blinken mit 4Hz wenn Gyro nicht auf Null ist
- blinken mit 5Hz wenn Reset button gedrückt wird und Gyrosignale groß sind
- machen Lichtorgel wenn Kopplung zum Motorcontroler gestört ist. Siehe Punkt 6
5. Gyro wird nur zur Initialisierung benutzt. Fahrzeug muss still stehen beim START
6. Kommunikation zum Motorcontroller ist gestört (Timeout) wenn der Hallstecker
am Motorcontroller nicht steckt sind! Dadurch antwortet der Motorcontroller dem
Hauptcontroller nicht. Er sendet z.B. keine Spannungsinfo an den Hauptcontroller.
Dadurch macht Dieser ständig einen Restart. Viele Werte werden dann nicht zum
Dashboard übertragen!
LockBit, FuseBit , FuseBitHigh , FuseBitExtended
$prog &HFF , &HE7 , &HD9 , &HFF 'Fusebits für Atmega644PA 20MHz
Use AMTEL Studio / Fuses Menu instead to set fusebits
BODLEVEL = disabled
OCDEN = Disabled
JTAGEN = Disabled
SPIEN = Checked
WDTON = Disabled
EESAVE = Disabled
BOOTSZ = 4096W_7000
BOOTRST = Disabled
CKDIV8 = Disabled
CKOUT = Disabled
SUT_CKSEL = FSOSZ_16KCK_4MS1_XOSC_FASTPWR
')
$regfile = "m644def.dat" 'ATMEGA644PA CPU
$lib "i2c_twi.lbx"
$framesize = 64
$swstack = 64
$hwstack = 64
$crystal = 20000000
$baud = 57600 'No parity, 1 stop bit, 8 data bits
Declare Sub Onresetbtn
Declare Sub Logtext(byval Adresse As Word , Text As String )
Declare Sub Akkugrenzen
Declare Sub Unfalldatenschreiber
Declare Sub Betriebsdatenschreiber
Declare Sub Flashled(byval Which As Byte , Byval Dauer_ms As Byte)
Declare Sub Resetdata
' Porta.0 = ADC
' Porta.1 = ADC
Config Porta.2 = Input 'not used
Config Porta.3 = Input 'not used
Config Porta.4 = Input 'not used
Config Porta.5 = Input 'not used
Config Porta.6 = Input 'not used
Config Porta.7 = Input 'not used
'Pull up Widerstände der unbenutzten Eingänge einschalten
Porta = 1
Config Portb.0 = Input 'not used
Config Portb.1 = Output 'Gyro Self Test
Config Portb.2 = Output 'Gyro Reset
Config Portb.3 = Output 'Led 2
Config Portb.4 = Output 'LED 1
' PORTB.5 'MOSI
' PORTB.6 'MISO
' PORTB.7 'SCK
Config Scl = Portc.0
Config Sda = Portc.1
Config Portc.2 = Input 'Fussschalter 1
Config Portc.3 = Input 'Fussschalter 2
Config Portc.4 = Input 'not used
Config Portc.5 = Input 'not used
Config Portc.6 = Input 'not used
Config Portc.7 = Output 'Beeper
'Pull up Widerstände der Eingänge Ein/Ausschalten
Portc.2 = 0
Portc.3 = 0
Portc.4 = 1
Portc.5 = 1
Portc.6 = 1
' PORTD.0 = 'RXD
' PORTD.1 = 'TXD
Config Portd.2 = Input 'Reset Button vom Akku-Display
Config Portd.3 = Output 'Batterieanzeige
Config Portd.4 = Output 'Batterieanzeige
Config Portd.5 = Output 'Batterieanzeige
Config Portd.6 = Output 'Batterieanzeige
Config Portd.7 = Output 'Batterieanzeige
'Pull up Widerstände einschalten
Portd.2 = 1
Led1 Alias Portb.4
Led2 Alias Portb.3
Led3 Alias Portd.4 'Batterieladezustandsanzeige 0..20%
Led4 Alias Portd.5 'Batterieladezustandsanzeige 21..40%
Led5 Alias Portd.6 'Batterieladezustandsanzeige 41..60%
Led6 Alias Portd.3 'Batterieladezustandsanzeige 61..80%
Led7 Alias Portd.7 'Batterieladezustandsanzeige 81..100%
Beeper Alias Portc.7
Resetbtn Alias Pind.2
'Sensortest gibt es bei I2C Gyro nicht
'Sensor_aus Alias Portb.2 '1=Aus 0=Ein
'Sensor_test Alias Portb.1 '1=Self-Test. 0=Normalbetrieb
Config Debounce = 100 '[mS] when the config statement is not used a
' default of 25mS will be used
'******************************Gyro über I2C ********************************
'##### 7 - Bit Adresses Gyro ########
Const Who_am_i = &H0F 'auch V2
Const Ctrl_reg1 = &H20 'auch V2
Const Ctrl_reg2 = &H21 'auch V2
Const Ctrl_reg3 = &H22 'auch V2
Const Ctrl_reg4 = &H23 'auch V2
Const Ctrl_reg5 = &H24 'auch V2
Const Out_temp = &H26 'auch V2
Const Status_reg = &H27 'auch V2
Const Out_x_l = &H28 'auch V2
Const Out_x_h = &H29 'auch V2
Const Out_y_l = &H2A 'auch V2
Const Out_y_h = &H2B 'auch V2
Const Out_z_l = &H2C 'auch V2
Const Out_z_h = &H2D 'auch V2
'##### 7-Bit Adresses Accelerometer ########
Const Ctrl_reg1_a = &H20 'auch V2
Const Ctrl_reg2_a = &H21 'auch V2
Const Ctrl_reg3_a = &H22 'auch V2
Const Ctrl_reg4_a = &H23 'auch V2
Const Ctrl_reg5_a = &H24 'auch V2
Const Status_reg_a = &H27 'auch V2
Const Out_x_l_a = &H28 'auch V2
Const Out_x_h_a = &H29 'auch V2
Const Out_y_l_a = &H2A 'auch V2
Const Out_y_h_a = &H2B 'auch V2
Const Out_z_l_a = &H2C 'auch V2
Const Out_z_h_a = &H2D 'auch V2
'##### 7-Bit Adresses Magnetometer ########
'Const Cra_reg_m = &H00 'auch V2
'Const Crb_reg_m = &H01 'auch V2
'Const Mr_reg_m = &H02 'auch V2
'Const Out_x_h_m = &H03 'auch V2
'Immer *2 weil Adresse bei Bit1 beginnt. Bit 0 ist für Read/Write
Const Gyroadress_w = 210 '=105*2, =107d*2 bei V2. Gyro slave adress for write
Const Gyroadress_r = 211 '=(105*2) + 1, =107d*2 bei V2. Gyro slave adress for write
Const Accadress_w = 48 '=24*2, auch bei V2 Accelerometer slave adress for write
Const Accadress_r = 49 '=(24*2) + 1, auch bei V2 Accelerometer slave adress for write
'Const Magadress_w = 60 '=30*2, auch bei V2 Magnetometer slave adress for write
'Const Magadress_r = 61 '=(30*2) + 1, auch bei V2 Magnetometer slave adress for write
'--------------------------------------------------------------------
'>>>>>>>>>>>>>>>> DEFAULT WERTE <<<<<<<<<<<<<<<<<<
Const Fussschalterschwelle = 750 'ADC Wert
'Konstanten für die Geschwindigkeits und Streckenmessung
Const Kom_pro_u = 276 '276*Kommutieren für eine Umdrehung.
Const Radumpfang = 139 'RaduMPFang in Zentimeter
'Maximalwert bis zu dem die Abweichung in y aufaddiert wird
Const Max_mit_acc_nick_s = 1024
Const Min_mit_acc_nick_s = -1024
Const Max_lenk = 128
Const Min_lenk = -128
'Konstanten für die Leistungsbegrenzung, Geschwindigkeitsbegrenzung
'Maximalleistung
Const Maxpwm = 255
Const Minpwm = -255
'PWM ab der automatisch gebremst wird um blos nie an die Grenze zu kommen
Const Spwm = 128
Const Spwmr = -128
'Offsetwerte für die Mittellage
Const Offset_roll = 67700
Const Offset_nick = 65400
Const O_roll_u = 66200
Const O_roll_o = 69200
Const O_nick_u = 63900
Const O_nick_o = 66900
Const O_nick_oo = 67700
Const Vmax = 120 '12kmh Vmax Vorwärts in km/h*10
Const Vmaxr = -120 '-12Kmh Vmax Rückwärts in km/h*10
Const Systemvoltage = 14 '14, 24, 36, 48V
'Konstanten für die Akkus
#if Systemvoltage = 14 'Nur zum Test mit Netzteil
Const Akkuleer = 1300
Const Akkufastleer = 1330
#endif
#if Systemvoltage = 24
'24V, 12V pro Akku * 2 Akku
Const Akkuleer = 2400
Const Akkufastleer = 2500
#endif
#if Systemvoltage = 36
'36V, 12V pro Akku * 3 Akku
Const Akkuleer = 3600
Const Akkufastleer = 3750
#endif
#if Systemvoltage = 48
'48V, 12V pro Akku * 4 Akku
Const Akkuleer = 4800
Const Akkufastleer = 4950
#endif
'Konstanten für die Signalaufbereitung
Const Gyro_anz = 10 'war 10000
Const Acc_anz = 5 'Anzahl der Messungen zur Mittelwertbildung
Const Gyro_faktor = 1 'war 91
'****************************************************************************
Dim Ugemessen As Long 'Batteriespannung in V*100, kommt vom Motorcontr.
Dim Igemessen As Long 'Gesamter Motorstrom in mA, kommt vom Motorcontr.
Dim U As Integer
Dim I As Integer At U + 2
Dim K As Integer At U + 4
Dim Checksumme As Byte At U + 6
Dim Ende As Byte At U + 7
Dim Motormeldung(8) As Byte At U + 0 Overlay
Dim M1 As Byte At U + 0 Overlay
Dim M2 As Byte At U + 1 Overlay
Dim M3 As Byte At I + 0 Overlay
Dim M4 As Byte At I + 1 Overlay
Dim M5 As Byte At K + 0 Overlay
Dim M6 As Byte At K + 1 Overlay
Dim M7 As Byte At Checksumme Overlay
Dim M8 As Byte At Ende Overlay
'Variablen für die Telegramme an die Motorregler
Dim Checksum_rechts As Byte
Dim Checksum_links As Byte
Dim Richtung_rechts As Byte
Dim Richtung_links As Byte
Dim Pwm_rechts As Byte
Dim Pwm_links As Byte
Dim Zeiger_meldung As Byte
Dim Ta As Byte 'Interruptdauer. Wenn lang, dann ist der Zählwert nahe 255
Dim U_links As Integer 'Motorspannung linker Motor
Dim U_rechts As Integer 'Motorspannung rechter Motor
Dim I_links As Integer 'Motorstrom linker Motor
Dim I_rechts As Integer 'Motorstrom rechter Motor
Dim K_links As Integer 'Anzahl Kommutierungen linker Motor
Dim K_rechts As Integer 'Anzahl Kommutierungen rechter Motor
Dim B(5) As Byte
Dim Kilometer As Word
Dim Kilometermeldung(2) As Byte At Kilometer Overlay
Dim Akkustand As Integer
Dim Akkumeldung(2) As Byte At Akkustand Overlay
Dim Kmh As Integer
Dim Kmhmeldung(2) As Byte At Kmh Overlay
Dim Meter As Integer
Dim Metermeldung(2) As Byte At Meter Overlay
Dim Di As Single 'Distanz pro Kommutieren
Dim Kmhfaktor As Single
Dim Zentimeter As Single
Dim Strecke As Single 'Gefahrene Strecke während 1/100s
Dim Kx As Single 'Anzahl Kommutierungen für Streckenberechnung
Dim Kv As Single 'Anzahl Kommutierungen für Geschw.Berechnung
Dim Vbrems As Long 'Bremse bei Überlast oder zu hoher Geschw.
Dim Lbrems As Long
Dim Brems As Long
Dim P_faktor As Single
Dim Pf1 As Byte At P_faktor + 0 Overlay
Dim Pf2 As Byte At P_faktor + 1 Overlay
Dim Pf3 As Byte At P_faktor + 2 Overlay
Dim Pf4 As Byte At P_faktor + 3 Overlay
Dim I_faktor As Single
Dim If1 As Byte At I_faktor + 0 Overlay
Dim If2 As Byte At I_faktor + 1 Overlay
Dim If3 As Byte At I_faktor + 2 Overlay
Dim If4 As Byte At I_faktor + 3 Overlay
Dim D_faktor As Single
Dim Df1 As Byte At D_faktor + 0 Overlay
Dim Df2 As Byte At D_faktor + 1 Overlay
Dim Df3 As Byte At D_faktor + 2 Overlay
Dim Df4 As Byte At D_faktor + 3 Overlay
Dim Gyro_nick As Integer 'war word
Dim Gyro_nick1 As Byte At Gyro_nick + 0 Overlay
Dim Gyro_nick2 As Byte At Gyro_nick + 1 Overlay
Dim Gyro_roll As Integer 'war word
Dim Gyro_roll1 As Byte At Gyro_roll + 0 Overlay
Dim Gyro_roll2 As Byte At Gyro_roll + 1 Overlay
Dim Gyro_gier As Integer 'war word
Dim Gyro_gier1 As Byte At Gyro_gier + 0 Overlay
Dim Gyro_gier2 As Byte At Gyro_gier + 1 Overlay
Dim Gyro_roll_alt As Integer 'war word
Dim Gyro_nick_alt As Integer 'war word
Dim Acc_nick As Long
Dim Acc_nick1 As Byte At Acc_nick + 0 Overlay
Dim Acc_nick2 As Byte At Acc_nick + 1 Overlay
Dim Accnick As Integer
Dim Accnick_l As Byte At Accnick + 0 Overlay
Dim Accnick_h As Byte At Accnick + 1 Overlay
Dim Acc_roll As Long
Dim Acc_roll1 As Byte At Acc_roll + 0 Overlay
Dim Acc_roll2 As Byte At Acc_roll + 1 Overlay
Dim Accroll As Integer
Dim Accroll_l As Byte At Accroll + 0 Overlay
Dim Accroll_h As Byte At Accroll + 1 Overlay
Dim Acc_gier As Long
Dim Acc_gier1 As Byte At Acc_gier + 0 Overlay
Dim Acc_gier2 As Byte At Acc_gier + 1 Overlay
Dim Accgier As Integer
Dim Accgier_l As Byte At Accgier + 0 Overlay
Dim Accgier_h As Byte At Accgier + 1 Overlay
Dim Sum_acc_roll As Long
Dim Sum_acc_nick As Long
Dim Sum_gyro_roll As Long
Dim Sum_gyro_nick As Long
Dim Korr_acc_roll As Long
Dim Korr_acc_nick As Long
'Long ==> Long Integer
Dim Mit_acc_nick_s As Long 'Summierter Neigung vorwärts Mittelwert
Dim Mit_gyro_roll As Long
Dim Mit_gyro_nick As Long
Dim Sig_gyro_roll As Long
Dim Sig_gyro_nick As Long
Dim Stellwert As Single
Dim Stellwert1 As Byte At Stellwert + 0 Overlay
Dim Stellwert2 As Byte At Stellwert + 1 Overlay
Dim Stellwert3 As Byte At Stellwert + 2 Overlay
Dim Stellwert4 As Byte At Stellwert + 3 Overlay
Dim Mrg As Single
Dim Mrg1 As Byte At Mrg + 0 Overlay
Dim Mrg2 As Byte At Mrg + 1 Overlay
Dim Mrg3 As Byte At Mrg + 2 Overlay
Dim Mrg4 As Byte At Mrg + 3 Overlay
Dim Mra As Single
Dim Mra1 As Byte At Mra + 0 Overlay
Dim Mra2 As Byte At Mra + 1 Overlay
Dim Mra3 As Byte At Mra + 2 Overlay
Dim Mra4 As Byte At Mra + 3 Overlay
Dim Kksum As Single
Dim Kksum1 As Byte At Kksum + 0 Overlay
Dim Kksum2 As Byte At Kksum + 1 Overlay
Dim Kksum3 As Byte At Kksum + 2 Overlay
Dim Kksum4 As Byte At Kksum + 3 Overlay
Dim Gyronick As Long
Dim Gyronick1 As Byte At Gyronick + 0 Overlay
Dim Gyronick2 As Byte At Gyronick + 1 Overlay
Dim Gyronick3 As Byte At Gyronick + 2 Overlay
Dim Gyronick4 As Byte At Gyronick + 3 Overlay
Dim Mp_faktor As Single
Dim Mpf1 As Byte At Mp_faktor + 0 Overlay
Dim Mpf2 As Byte At Mp_faktor + 1 Overlay
Dim Mpf3 As Byte At Mp_faktor + 2 Overlay
Dim Mpf4 As Byte At Mp_faktor + 3 Overlay
Dim Mv_faktor As Single
Dim Mvf1 As Byte At Mv_faktor + 0 Overlay
Dim Mvf2 As Byte At Mv_faktor + 1 Overlay
Dim Mvf3 As Byte At Mv_faktor + 2 Overlay
Dim Mvf4 As Byte At Mv_faktor + 3 Overlay
Dim Mpl_faktor As Single
Dim Mplf1 As Byte At Mpl_faktor + 0 Overlay
Dim Mplf2 As Byte At Mpl_faktor + 1 Overlay
Dim Mplf3 As Byte At Mpl_faktor + 2 Overlay
Dim Mplf4 As Byte At Mpl_faktor + 3 Overlay
Dim Mvl_faktor As Single
Dim Mvlf1 As Byte At Mvl_faktor + 0 Overlay
Dim Mvlf2 As Byte At Mvl_faktor + 1 Overlay
Dim Mvlf3 As Byte At Mvl_faktor + 2 Overlay
Dim Mvlf4 As Byte At Mvl_faktor + 3 Overlay
Dim P_tacho As Single
Dim Tachomeldung(30) As Byte At P_tacho Overlay
Dim T1 As Byte At P_tacho + 0 Overlay
Dim T2 As Byte At P_tacho + 1 Overlay
Dim T3 As Byte At P_tacho + 2 Overlay
Dim T4 As Byte At P_tacho + 3 Overlay
Dim T5 As Byte At P_tacho + 4 Overlay
Dim T6 As Byte At P_tacho + 5 Overlay
Dim T7 As Byte At P_tacho + 6 Overlay
Dim T8 As Byte At P_tacho + 7 Overlay
Dim I_tacho As Single At P_tacho + 4 Overlay
Dim T9 As Byte At P_tacho + 8 Overlay
Dim T10 As Byte At P_tacho + 9 Overlay
Dim T11 As Byte At P_tacho + 10 Overlay
Dim T12 As Byte At P_tacho + 11 Overlay
Dim D_tacho As Single At P_tacho + 8 Overlay
Dim T13 As Byte At P_tacho + 12 Overlay
Dim T14 As Byte At P_tacho + 13 Overlay
Dim T15 As Byte At P_tacho + 14 Overlay
Dim T16 As Byte At P_tacho + 15 Overlay
Dim Mp_tacho As Single At P_tacho + 12 Overlay
Dim T17 As Byte At P_tacho + 16 Overlay
Dim T18 As Byte At P_tacho + 17 Overlay
Dim T19 As Byte At P_tacho + 18 Overlay
Dim T20 As Byte At P_tacho + 19 Overlay
Dim Mv_tacho As Single At P_tacho + 16 Overlay
Dim T21 As Byte At P_tacho + 20 Overlay
Dim T22 As Byte At P_tacho + 21 Overlay
Dim T23 As Byte At P_tacho + 22 Overlay
Dim T24 As Byte At P_tacho + 23 Overlay
Dim Mpl_tacho As Single At P_tacho + 20 Overlay
Dim T25 As Byte At P_tacho + 24 Overlay
Dim T26 As Byte At P_tacho + 25 Overlay
Dim T27 As Byte At P_tacho + 26 Overlay
Dim T28 As Byte At P_tacho + 27 Overlay
Dim Mvl_tacho As Single At P_tacho + 24 Overlay
Dim T29 As Byte At P_tacho + 28 Overlay
Dim T30 As Byte At P_tacho + 29 Overlay
Dim Tdummy As Integer At P_tacho + 28 Overlay
Dim Wwert As Word
Dim Wwert1 As Byte At Wwert + 0 Overlay
Dim Wwert2 As Byte At Wwert + 1 Overlay
Dim Gyro_gier_alt As Integer 'war word
Dim Sum_gyro_gier As Long
Dim Mit_gyro_gier As Long
Dim Sig_gyro_gier As Long
Dim Werteneu As Byte
Dim Mit_acc_roll As Long 'Neigungsmittelwert seitwärts
Dim Mit_acc_roll1 As Byte At Mit_acc_roll + 0 Overlay
Dim Mit_acc_roll2 As Byte At Mit_acc_roll + 1 Overlay
Dim Mit_acc_roll3 As Byte At Mit_acc_roll + 2 Overlay
Dim Mit_acc_roll4 As Byte At Mit_acc_roll + 3 Overlay
Dim Mit_acc_nick As Long 'Neigungsmittelwert vorwärts
Dim Mit_acc_nick1 As Byte At Mit_acc_nick + 0 Overlay
Dim Mit_acc_nick2 As Byte At Mit_acc_nick + 1 Overlay
Dim Mit_acc_nick3 As Byte At Mit_acc_nick + 2 Overlay
Dim Mit_acc_nick4 As Byte At Mit_acc_nick + 3 Overlay
Dim Null_roll As Long
Dim Null_roll1 As Byte At Null_roll + 0 Overlay
Dim Null_roll2 As Byte At Null_roll + 1 Overlay
Dim Null_roll3 As Byte At Null_roll + 2 Overlay
Dim Null_roll4 As Byte At Null_roll + 3 Overlay
Dim Null_nick As Long
Dim Null_nick1 As Byte At Null_nick + 0 Overlay
Dim Null_nick2 As Byte At Null_nick + 1 Overlay
Dim Null_nick3 As Byte At Null_nick + 2 Overlay
Dim Null_nick4 As Byte At Null_nick + 3 Overlay
Dim Mit_regelzeit_ges As Single
Dim Lagefehler As Long
'Die Zeit in 1/100s die benötigt wird bis die Nullage erreicht ist
Dim Regelzeit As Word
Dim Regelzeitmax As Word
Dim Mit_acc_roll_max As Long
Dim Mit_acc_nick_max As Long
Dim Mit_acc_roll_min As Long
Dim Mit_acc_nick_min As Long
Dim Pwm_gesamt As Single
Dim Pwm_rechts_max As Byte
Dim Pwm_links_max As Byte
Dim Intcount As Byte
Dim K_diff As Single
Dim K_sum As Single
Dim K_diff_min As Single
Dim K_diff_max As Single
Dim Pwm_lenk_rechts As Integer
Dim Pwm_lenk_links As Integer
Dim Lenkvorgabe As Single
Dim Mp_anpassung As Single
Dim Mv_anpassung As Single
Dim Mpl_anpassung As Single
Dim Mvl_anpassung As Single
Dim K_sum_anpassung As Single
Dim Wdummy1 As Word
Dim Ldummyi As Long
Dim Ldummy1 As Long
Dim Ldummy2 As Long
Dim Bdummy1 As Byte
Dim Idummy1 As Integer
Dim Sdummy1 As Single
Dim Antriebaus As Byte
Dim Notaus As Byte
Dim Sensor_ok As Byte 'Zeigt an ob die Mittelwerte der Gyros stabil stehen
Dim Sensor_ok_count As Byte
Dim Ltest As Byte
Dim Imin As Long 'Kleinster gemessener Motorstrom (größte Rückspeisung)
Dim Imax As Long 'größter gemessener Motorstrom
Dim Summe_as_entladen As Long
Dim Summe_mah_entladen As Long
Dim Summe_as_laden As Long
Dim Summe_mah_laden As Long
Dim Akkukap As Long 'Akkukapazität 0...100 %
Dim Akku1 As Long '80% Grenze
Dim Akku2 As Long '60% Grenze
Dim Akku3 As Long '40% Grenze
Dim Akku4 As Long '20% Grenze
Dim Akku5 As Long '0% Grenze
Dim Erzeugt As Long 'Erzeugte Ladung in mA-Stunden
Dim Verbraucht As Long 'Verbrauchte Ladung in mA-Stunden
'Single Variablen um die Prozente rechnen zu können
Dim Akkuinhalt As Single 'wie AkkuKap
Dim Akkuverbrauch As Single
Dim Akkuprozent As Single
Dim Bzeit As Long 'Beruhigungszeit von Gyro und Accelerometer
Dim Bstate As Byte 'Status der Beruhigungszeit von Gyro und Accelerometer
Dim Frei As Byte 'hat es etwas mit Gyro und Acc zu tun?
Dim Timeout As Byte
Dim S_err As Byte 'Serielle Schnittstellen Error
Dim Seriell_err_links As Word 'COM error links
Dim Seriell_err_rechts As Word 'COM error rechts
Dim Tamax As Byte 'Maximalwert von Ta
Dim Fusscount As Word 'Fusschalter nicht betätigt ==> zeitverzögerung
Dim Blinkcount As Byte 'verschiedene Blinkraten
Dim Lenkerstellung As Single
Dim Lenkstellwert As Single
Dim Lenkfehler As Single
'Texte für den Unfalldatenschreiber (als Text im eeprom)
Dim Utext As String * 32
Dim Ugrund As String * 32 'Auslösegrund
Dim Text As String * 16 'Allg. Ttext
Dim Min_v As Integer 'Minimalwert der Geschwindigkeit
Dim Max_v As Integer 'Maximalwert der Geschwindigkeit
Dim Tachocount As Byte 'Schleifenzähler um Werte an Display zu schicken
Dim Fussschalter As Byte 'Die beiden Fussschalter
Dim Adc0 As Word 'Analogwert Fussschalter 1
Dim Adc1 As Word 'Analogwert Fussschalter 2
Dim Slaveadress As Byte 'Adress of the I2C slave to read or write
Dim Subadress As Byte 'the I2C register to read or write
Dim Databyte As Byte 'I2C Byte to read or write
Dim Resetbtndone As Byte
Dim Nummotors As Byte '1 oder 2
Dim Errorword As Word 'See Delphi Dashboard.prj
Dim Errorword1 As Byte At Errorword + 0 Overlay
Dim Errorword2 As Byte At Errorword + 1 Overlay
Led1 = 0
Led2 = 0
Led3 = 1
Led4 = 1
Led5 = 1
Led6 = 1
Led7 = 1
'***************** Check! *********************
Nummotors = 1
'***************** Check! *********************
'Ein paar feste Werte vorab berechnen:
Di = Radumpfang / Kom_pro_u
'Eigentlich 3.6 aber bei der Mittelwertbildung entsteht der 4-Fache Wert,
'darum 9, und es ergibt sich automateisch V in 0.1km/h
'Unbenutzte Pins auf Masse legen
Kmhfaktor = Di * 9
'Sensorboard Schalten
'Sensor_aus = 0
'Sensor_test = 0
Config Adc = Single , Prescaler = Auto , Reference = Internal_2.56 'Avcc
'Start Adc not required because ADC will start immediately after Config ADC
'Inititialise I2C-Bus
I2cinit
Config Twi = 200000 ' wanted clock frequency in Hertz
'will set TWBR and TWSR
'Twbr = 12 'bit rate register
'Twsr = 0 'pre scaler bits
'TWI gleich einschalten, das macht Bascom ansonsten erst beim I2CStart !
Twcr = &B00000100
Gosub Init_gyro
Gosub Init_acc
'Wartezeit bis die Motorregler soweit sind
Readeeprom Max_v , $2f0
Readeeprom Min_v , $2f2
Readeeprom Summe_as_entladen , $300 'Entnommene Wh und Ws aus EEPROM lesen
Led3 = 0
Waitms 150
Readeeprom Summe_mah_entladen , $310
Led4 = 0
Waitms 150
Readeeprom Summe_as_laden , $320
Led5 = 0
Waitms 150
Readeeprom Summe_mah_laden , $330
Led6 = 0
Waitms 150
Readeeprom Akkukap , $340
Led7 = 0
Waitms 150
Readeeprom Kilometer , $350
Readeeprom Meter , $360
Readeeprom Zentimeter , $370
'<Faktoren für den PID-Regler einlesen>
P_faktor = 0.0033 'Readeeprom P_faktor , $380
I_faktor = 0.00006 'Readeeprom I_faktor , $384
D_faktor = 0.08 'Readeeprom D_faktor , $388
Mp_faktor = 0.006 'Readeeprom Mp_faktor , $38c
Mv_faktor = 0 'Readeeprom Mv_faktor , $390
Mpl_faktor = 0 'Readeeprom Mpl_faktor , $394
Mvl_faktor = 0 'Readeeprom Mvl_faktor , $398
'Sinnvolle Werte vorbelegen
If P_faktor < 0 Or P_faktor > 1 Then P_faktor = 0.0033
If I_faktor < 0 Or I_faktor > 1 Then I_faktor = 0.00006
If D_faktor < 0 Or D_faktor > 1 Then D_faktor = 0.08
If Mp_faktor < 0 Or Mp_faktor > 1 Then Mp_faktor = 0.006
If Mv_faktor < 0 Or Mv_faktor > 1 Then Mv_faktor = 0
If Mpl_faktor < 0 Or Mpl_faktor > 1 Then Mpl_faktor = 0
If Mvl_faktor < 0 Or Mvl_faktor > 1 Then Mvl_faktor = 0
'</Faktoren für den PID-Regler einlesen>
If Kilometer = $ffff Then 'Kommt bei frischem EEPROM vor
Zentimeter = 0
Meter = 0
Kilometer = 0
Min_v = 0
Max_v = 0
End If
'Bei Fehlerhaften Werten aus dem EEPROM einfach 10000mAh als Vorgabe
If Akkukap <= 0 Then Akkukap = 10000
#if Systemvoltage = 14 'Nur zum Test mit Netzteil
If Akkukap > 32000 Then Akkukap = 100
#endif
#if Systemvoltage = 24
If Akkukap > 32000 Then Akkukap = 100
#endif
#if Systemvoltage = 36
If Akkukap > 32000 Then Akkukap = 100
#endif
#if Systemvoltage = 48
If Akkukap > 32000 Then Akkukap = 100
#endif
Call Akkugrenzen
Fusscount = 0
Notaus = 0
Readeeprom Max_v , $2f0
Readeeprom Min_v , $2f4
Config Watchdog = 128 'mSec
'Maximalwerte für Datenschreiber/Notauserkennung auf 0 setzen
Regelzeit = 0
Regelzeitmax = 0
Mit_acc_nick_max = 0
Mit_acc_roll_max = 0
Pwm_rechts_max = 0
Pwm_links_max = 0
K_diff_min = 0
K_diff_max = 0
Richtung_links = 2 'Leerlauf
Richtung_rechts = 2 'Leerlauf
Pwm_links = 0
Pwm_rechts = 0
Pwm_gesamt = 0
Mit_acc_nick_s = 0
Lenkerstellung = 0
K_rechts = 0
K_links = 0
Seriell_err_links = 0
Seriell_err_rechts = 0
'Vrbelegen um zu sehen ob es einen Notaus ohne Grund gibt
Ugrund = "----------------"
Disable Interrupts
'Timer wird vorgeladen um die gewünschte Zykluszeit nach
'Timerüberlauf zu erreichen
'Nachteil: Timer Count ist nicht exakt gleich der Zykluszeit
On Timer0 Regel_interrupt
Config Timer0 = Timer , Prescale = 1024 ' (1/20MHz) * 1024 = 51,2uS pro Tick
Enable Timer0
Antriebaus = 1 'Beim Start ist immer alles aus
Enable Interrupts
Waitms 100
'< Sicherheitstest. CPU will Reset if one of these conditions are met
Start Watchdog 'nach 128mS wird CPU Reset ausgelöst
If Resetbtn = 0 Then Wait 10
If Antriebaus = 0 Then Wait 10
'If Ugemessen < 1000 Then Wait 10 '10V
'If Ugemessen > 5500 Then Wait 10 '55V
Stop Watchdog
'< Sicherheitstest
'Prüfung ob Akku gerade geladen:
#if Systemvoltage = 14
'Sensoren ausschalten wenn am Ladegerät oder zu Testzwecken
'If Ugemessen < 2200 Then
' Sensor_aus = 1
'Else
' Sensor_aus = 0
'End If
Errorword.0 = 1
While Ugemessen < 1100 'Unterspannung oder am Ladegerät
Call Flashled(0 , 50)
Wend
If Ugemessen > 1520 Then 'Akku ist ganzgeladen
#endif
#if Systemvoltage = 24
'Sensoren ausschalten wenn am Ladegerät oder zu Testzwecken
'If Ugemessen < 2200 Then
' Sensor_aus = 1
'Else
' Sensor_aus = 0
'End If
Errorword.1 = 1
While Ugemessen < 2200 'Unterspannung oder am Ladegerät
Call Flashled(0 , 50)
Wend
If Ugemessen > 2650 Then 'Akku ist ganzgeladen
#endif
#if Systemvoltage = 36
'Sensoren ausschalten wenn am Ladegerät oder zu Testzwecken
'If Ugemessen < 3300 Then
' Sensor_aus = 1
'Else
' Sensor_aus = 0
'End If
Errorword.2 = 1
While Ugemessen < 3300 'Unterspannung oder am Ladegerät
Call Flashled(0 , 50)
Wend
If Ugemessen > 4350 Then 'Akku ist ganzgeladen
#endif
#if Systemvoltage = 48
'Sensoren ausschalten wenn am Ladegerät oder zu Testzwecken
'If Ugemessen < 2400 Then
' Sensor_aus = 1
'Else
' Sensor_aus = 0
'End If
Errorword.3 = 1
While Ugemessen < 4300 'Unterspannung oder am Ladegerät
Call Flashled(0 , 50)
Wend
If Ugemessen > 5280 Then 'Akku ist ganzgeladen
#endif
'Interruts abschalten damit die folgenden Zeilen nicht gerade jetzt vom
'Interrupt unterbrochen werden.
Disable Interrupts
Waitms 50
Summe_as_entladen = 0
Summe_mah_entladen = 0
Summe_as_laden = 0
Summe_mah_laden = 0
Enable Interrupts
End If
Led3 = 0
Led4 = 0
Led5 = 0
Led6 = 0
Led7 = 0
Goto Jp
'Summen_vorbelegen:
Do
Errorword.4 = 1
' Acc_roll = Acc_roll * 100
' Acc_nick = Acc_nick * 100
'Sum_gyro_roll = Gyro_roll * Gyro_anz
'Sum_gyro_nick = Gyro_nick * Gyro_anz
'Sum_gyro_gier = Gyro_gier * Gyro_anz
Gyro_roll_alt = Gyro_roll
Gyro_nick_alt = Gyro_nick
Gyro_gier_alt = Gyro_gier
Mit_gyro_roll = Gyro_roll
Mit_gyro_nick = Gyro_nick
Mit_gyro_gier = Gyro_gier
Sum_acc_roll = Acc_roll * Acc_anz
Sum_acc_nick = Acc_nick * Acc_anz
Waitms 200
Toggle Led5
Toggle Led6
Waitms 200
Toggle Led5
Toggle Led6
Loop Until Sig_gyro_nick >= -3 And Sig_gyro_nick <= 3 And Sig_gyro_roll >= -3 And Sig_gyro_roll <= 3 And Sig_gyro_gier >= -3 And Sig_gyro_gier <= 3
Errorword.4 = 0
Jp:
Call Resetdata 'and Enable Interrupt
Resetbtndone = 0
Do
Errorword.5 = 1
'<Sicherheitstest Sensoren>
If Antriebaus = 1 Then
If Intcount <> Ltest Then
Ltest = Intcount
Sensor_ok = 0
If Sensor_ok_count > 0 Then Decr Sensor_ok_count
'1. Es darf keine nennenswerte Drehbewegung erkannt werden!
If Sig_gyro_nick < -3 Then Sensor_ok_count = 50
If Sig_gyro_nick > 3 Then Sensor_ok_count = 50
If Sig_gyro_roll < -3 Then Sensor_ok_count = 50
If Sig_gyro_roll > 3 Then Sensor_ok_count = 50
'Nach mehrfachen Drehungen könnte der Mittelwert etwas
'verschoben sein. Darum hier 12
If Sig_gyro_gier < -15 Then Sensor_ok_count = 50
If Sig_gyro_gier > 15 Then Sensor_ok_count = 50
'2. Die Werte dürfen nicht verrauscht sein
Ldummy2 = Mit_acc_nick + 500
If Acc_nick > Ldummy2 Then Sensor_ok_count = 50
Ldummy2 = Mit_acc_nick - 500
If Acc_nick < Ldummy2 Then Sensor_ok_count = 50
Ldummy2 = Mit_acc_roll + 500
If Acc_roll > Ldummy2 Then Sensor_ok_count = 50
Ldummy2 = Mit_acc_roll - 500
If Acc_roll < Ldummy2 Then Sensor_ok_count = 50
'3. Die Werte müssen ungefähr in einer legalen Nullage sein.
If Null_roll < O_roll_u Then Sensor_ok_count = 50
If Null_roll > O_roll_o Then Sensor_ok_count = 50
If Null_nick < O_nick_u Then Sensor_ok_count = 50
If Null_nick > O_nick_o Then Sensor_ok_count = 50
'Bedingungen während 50 Messungen (0.5s) eingehalten
If Sensor_ok_count = 0 Then Sensor_ok = 1
End If
Else
Sensor_ok = 0
End If
'</Sicherheitstest Sensoren>
'<Batterieanzeige>
'alles unter 36V Leerlaufspannung ist LEER
If Ugemessen > Akkufastleer Then
If Verbraucht > Akkukap Then
'Einfach mal annehmen daß noch mehr als angezeigt im Akku ist
Akkukap = Verbraucht + 1
Call Akkugrenzen
End If
End If
If Antriebaus = 1 Then
Errorword.6 = 1
Else
Errorword.6 = 0
End If
If Notaus = 1 Then
Errorword.7 = 1
Else
Errorword.7 = 0
End If
'Blinken wenn Gyros nicht bereit
If Antriebaus = 1 Then
If Ugemessen > Akkuleer Then
If Verbraucht > Akkukap Then
'annehmen dass noch mehr als angezeigt im Akku ist
Akkukap = Verbraucht + 20
Call Akkugrenzen
End If
End If
If Sensor_ok = 1 Then
If Verbraucht < Akku1 Then Led7 = 0 Else Led7 = 1
If Verbraucht < Akku2 Then Led6 = 0 Else Led6 = 1
If Verbraucht < Akku3 Then Led5 = 0 Else Led5 = 1
If Verbraucht < Akku4 Then Led4 = 0 Else Led4 = 1
If Verbraucht < Akku5 Then Led3 = 0 Else Led3 = 1
Else
If Frei = 1 Then 'ca. 2 Hz
Blinkcount = Intcount
If Blinkcount > 50 Then Blinkcount = Blinkcount - 50
Else
Blinkcount = Intcount / 2
End If
If Blinkcount > 40 Then 'ca. 1 Hz
If Verbraucht < Akku1 Then Led7 = 0 Else Led7 = 1
If Verbraucht < Akku2 Then Led6 = 0 Else Led6 = 1
If Verbraucht < Akku3 Then Led5 = 0 Else Led5 = 1
If Verbraucht < Akku4 Then Led4 = 0 Else Led4 = 1
If Verbraucht < Akku5 Then Led3 = 0 Else Led3 = 1
Else
Led7 = 1
Led6 = 1
Led5 = 1
Led4 = 1
Led3 = 1
End If
End If
Else
Errorword.6 = 0
If Verbraucht < Akku1 Then Led7 = 0 Else Led7 = 1
If Verbraucht < Akku2 Then Led6 = 0 Else Led6 = 1
If Verbraucht < Akku3 Then Led5 = 0 Else Led5 = 1
If Verbraucht < Akku4 Then Led4 = 0 Else Led4 = 1
If Verbraucht < Akku5 Then Led3 = 0 Else Led3 = 1
End If
'</Batterieanzeige>
'< Maximalwerte Für Betriebsdatenschreiber>
If Igemessen < Imin Then Imin = Igemessen 'Nur zur Information
If Igemessen > Imax Then Imax = Igemessen 'Nur zur Information
If Regelzeit > Regelzeitmax Then Regelzeitmax = Regelzeit
If Mit_acc_nick > Mit_acc_nick_max Then Mit_acc_nick_max = Mit_acc_nick
If Mit_acc_roll > Mit_acc_roll_max Then Mit_acc_roll_max = Mit_acc_roll
If Mit_acc_nick < Mit_acc_nick_min Then Mit_acc_nick_min = Mit_acc_nick
If Mit_acc_roll < Mit_acc_roll_min Then Mit_acc_roll_min = Mit_acc_roll
If Pwm_links > Pwm_links_max Then Pwm_links_max = Pwm_links
If Pwm_rechts > Pwm_rechts_max Then Pwm_rechts_max = Pwm_rechts
If K_diff > K_diff_max Then K_diff_max = K_diff
If K_diff < K_diff_min Then K_diff_min = K_diff
If Ta > Tamax Then Tamax = Ta
'</Maximalwerte für Betriebsdatenschreiber>
'Debounce macht dasselbe, allerdings stockt der Programmfluss
Debounce Resetbtn , 0 , Onresetbtn , Sub
Goto Skipit
If Resetbtndone = 0 Then
If Resetbtn = 0 Then
Resetbtndone = 1
Call Onresetbtn
Resetbtndone = 2
Else
End If
Else
If Resetbtndone = 2 Then Resetbtndone = 0
End If
Skipit:
If Intcount > 80 Then Led1 = 1 Else Led1 = 0 'Sekundenblinken
'Daran lässt sich leicht erkennen ob noch alles normal läuft.
Loop
End
'**********************************************************************
'Ab hier Subroutinen und Interrupts
'**********************************************************************
Sub Akkugrenzen
'Grenzwerte für die Akku-LEDs berechnen
Ldummy1 = Akkukap / 5
Akku1 = Ldummy1
Akku2 = 2 * Ldummy1
Akku3 = 3 * Ldummy1
Akku4 = 4 * Ldummy1
Akku5 = 5 * Ldummy1
End Sub
Sub Unfalldatenschreiber
Waitms 10
Utext = Str(regelzeit)
Utext = "Rz=" + Utext
Logtext 0 , Utext
Utext = Str(mit_acc_nick_max)
Utext = "Nick max=" + Utext
Logtext $10 , Utext
Utext = Str(mit_acc_nick)
Utext = "Nick=" + Utext
Logtext $20 , Utext
Utext = Str(mit_acc_nick_min)
Utext = "Nick min=" + Utext
Logtext $30 , Utext
Utext = Str(mit_acc_roll_max)
Utext = "Roll max=" + Utext
Logtext $40 , Utext
Utext = Str(mit_acc_roll)
Utext = "Roll=" + Utext
Logtext $50 , Utext
Utext = Str(mit_acc_roll_min)
Utext = "Roll min=" + Utext
Logtext $60 , Utext
Utext = Str(pwm_rechts)
Utext = "PWM re=" + Utext
Logtext $70 , Utext
Utext = Str(pwm_links)
Utext = "PWM li=" + Utext
Logtext $80 , Utext
Utext = Str(u_rechts)
Utext = "U re=" + Utext
Logtext $90 , Utext
Utext = Str(u_links)
Utext = "U li=" + Utext
Logtext $a0 , Utext
Utext = Str(ta)
Utext = "Ta=" + Utext
Logtext $b0 , Utext
Utext = Str(seriell_err_links)
Utext = Utext + "|"
Utext = Utext + Str(seriell_err_rechts)
Utext = "S =" + Utext
Logtext $c0 , Utext
Utext = Ugrund
Logtext $d0 , Utext
End Sub
Sub Betriebsdatenschreiber
'Ob die Wartezeiten beim EEprom schreiben nötig sind ist nicht sicher.
'Mit den Wartezeiten treten aber keine Fehler bei den Werten mehr auf.
'Möglich, daß dies auch durch eine andere Änderung bewirkt wurde.
Writeeeprom Max_v , $2f0
Writeeeprom Min_v , $2f2
Zentimeter = Int(zentimeter) 'Keine Millimeter schreiben
Writeeeprom Summe_as_entladen , $300
Writeeeprom Summe_mah_entladen , $310
Writeeeprom Summe_as_laden , $320
Writeeeprom Summe_mah_laden , $330
Writeeeprom Akkukap , $340
Writeeeprom Kilometer , $350
Writeeeprom Meter , $360
Writeeeprom Zentimeter , $370
If Werteneu = 1 Then 'Nur wenn das Einstellklavier gesteckt ist.
Writeeeprom P_faktor , $380
Writeeeprom I_faktor , $384
Writeeeprom D_faktor , $388
Writeeeprom Mp_faktor , $38c
Writeeeprom Mv_faktor , $390
Writeeeprom Mpl_faktor , $394
Writeeeprom Mvl_faktor , $398
Werteneu = 0
End If
Utext = Str(pwm_rechts_max)
Utext = "PWM r max=" + Utext
Logtext $e0 , Utext
Utext = Str(pwm_links_max)
Utext = "PWM l max=" + Utext
Logtext $f0 , Utext
Utext = Str(ugemessen)
Utext = "U=" + Utext
Logtext $100 , Utext
Utext = Str(imin)
Utext = "Imin=" + Utext
Logtext $110 , Utext
Utext = Str(imax)
Utext = "Imax=" + Utext
Logtext $120 , Utext
Utext = Str(summe_mah_entladen)
Utext = "-mAh" + Utext
Logtext $130 , Utext
Utext = Str(summe_mah_laden)
Utext = "+mAh=" + Utext
Logtext $140 , Utext
Utext = Str(verbraucht)
Utext = " =" + Utext
Logtext $150 , Utext
Utext = Str(akkukap)
Utext = "Kap=" + Utext
Logtext $160 , Utext
Utext = Str(kilometer)
Utext = "Km=" + Utext
Logtext $170 , Utext
Utext = Str(meter)
Utext = "M=" + Utext
Logtext $180 , Utext
Utext = Str(zentimeter)
Utext = "cm=" + Utext
Logtext $190 , Utext
Utext = Str(regelzeitmax)
Utext = "Rz Max=" + Utext
Logtext $1a0 , Utext
Utext = Str(null_roll)
Utext = "Null_R=" + Utext
Logtext $1b0 , Utext
Utext = Str(null_nick)
Utext = "null_N=" + Utext
Logtext $1c0 , Utext
Utext = Str(p_faktor)
Utext = "P=" + Utext
Logtext $1d0 , Utext
Utext = Str(i_faktor)
Utext = "I=" + Utext
Logtext $1e0 , Utext
Utext = Str(d_faktor)
Utext = "D=" + Utext
Logtext $1f0 , Utext
Utext = Str(mp_faktor)
Utext = "M=" + Utext
Logtext $200 , Utext
Utext = Str(k_diff_min)
Utext = "K min=" + Utext
Logtext $210 , Utext
Utext = Str(k_diff_max)
Utext = "K max=" + Utext
Logtext $220 , Utext
Utext = Str(seriell_err_links)
Utext = "S l=" + Utext
Logtext $230 , Utext
Utext = Str(seriell_err_rechts)
Utext = "S r=" + Utext
Logtext $240 , Utext
Utext = Str(tamax)
Utext = "Ta_Max=" + Utext
Logtext $250 , Utext
Utext = Str(max_v)
Utext = "V_Max=" + Utext
Logtext $260 , Utext
Utext = Str(min_v)
Utext = "V_Min=" + Utext
Logtext $270 , Utext
End Sub
Sub Onresetbtn
If Antriebaus = 1 Then
'alles unter 36V Leerlaufspannung ist LEER
If Ugemessen > Akkuleer Then
If Sensor_ok = 1 Then 'Prüfen ob Gyros noch driften
'Interupts abschalten damit Fusscount nicht gerade jetzt
'decrementiert wird
Call Resetdata
Else
If Null_nick > O_nick_o And Null_nick < O_nick_oo Then
If Bzeit = 500 Then
Bstate = 1
Bzeit = 0
Else
If Bstate = 1 Then
If Bzeit < 50 Then
Disable Interrupts
Utext = " "
Logtext $00 , Utext
Logtext $10 , Utext
Logtext $20 , Utext
Logtext $30 , Utext
Logtext $40 , Utext
Logtext $50 , Utext
Logtext $60 , Utext
Logtext $70 , Utext
Logtext $80 , Utext
Logtext $90 , Utext
Logtext $a0 , Utext
Logtext $b0 , Utext
Logtext $c0 , Utext
Logtext $d0 , Utext
Logtext $e0 , Utext
Logtext $f0 , Utext
Logtext $100 , Utext
Logtext $110 , Utext
Logtext $120 , Utext
Logtext $130 , Utext
Logtext $140 , Utext
Logtext $150 , Utext
Logtext $160 , Utext
Logtext $170 , Utext
Logtext $180 , Utext
Logtext $190 , Utext
Logtext $1a0 , Utext
Logtext $1b0 , Utext
Logtext $1c0 , Utext
Logtext $1d0 , Utext
Logtext $1e0 , Utext
Logtext $1f0 , Utext
Logtext $200 , Utext
Logtext $210 , Utext
Logtext $220 , Utext
Logtext $230 , Utext
Logtext $240 , Utext
Logtext $250 , Utext
Logtext $260 , Utext
Summe_as_entladen = 0
Summe_mah_entladen = 0
Summe_as_laden = 0
Summe_mah_laden = 0
Writeeeprom Summe_as_entladen , $300
Writeeeprom Summe_mah_entladen , $310
Writeeeprom Summe_as_laden , $320
Writeeeprom Summe_mah_laden , $330
Frei = 0
For Bzeit = 1 To 10
Led3 = 1
Led4 = 1
Led5 = 1
Led6 = 1
Led7 = 1
Waitms 100
Led3 = 0
Led4 = 0
Led5 = 0
Led6 = 0
Led7 = 0
Waitms 100
Next
Bzeit = 500
Enable Interrupts
Waitms 100
End If
If Bzeit > 250 And Bzeit < 350 Then
Frei = 1
Bzeit = 500
Else
Frei = 0
Bzeit = 500
End If
End If
End If
Else
Frei = 0
Bzeit = 500
End If
End If
Else
If Verbraucht < Akkukap Then 'Akku ist laut Spannung leer!
'Einfach mal annehmen daß zuviel entnommen wurde
Akkukap = Verbraucht * 0.95
Akkugrenzen
End If
'Disable Interrupts
'Betriebsdatenschreiber
'Enable Interrupts
End If
Else
Antriebaus = 1
Waitms 100
Frei = 0
'Disable Interrupts
'Betriebsdatenschreiber
'Enable Interrupts
End If
End Sub
Sub Logtext(adresse , Text)
If Len(text) > 16 Then Text = Mid(text , 1 , 16)
While Len(text) < 16
Text = Text + " "
Wend
Writeeeprom Text , Adresse
End Sub
Regel_interrupt:
'*****************************************************************************
'Eigentlich ist das kein typischer Interrupt. Der Interrupt wird hier nur
'verwendet um der Regelung einen 100Hz Takt zu geben.
'Andere Timer Interrupts werden für diese Zeit blockiert
'*****************************************************************************
'Timer zählt ab diesem Wert aufwärts bis 256 und macht dann einen Interrupt
'==> je höher die Startzahl, umso kürzer das Intervall
' 20 MHz / 1024 (Prescaler) = 15,625 KHz / 256 = 61Hz
' (61/100) * 256 = 156
' 256 - 156 = 100 Der Timer selbst braucht auch etwas Zeit, d.h. 100 ist tatsächlich 61
Timer0 = 61
Bdummy1 = Udr
Gosub Readfussschalter
Gosub Read_gyro
Gosub Read_acc
'Acc_roll = Acc_roll '*100, war früher -512...+512 jetzt -30000...+30000
'Acc_nick = Acc_nick '*100, war früher -512...+512 jetzt -30000...+30000
'<Mittellage ausgleichen>
'Die Offsetwerte werden langsam an eine früher ermittelte Waagerechte
'Position angeglichen.
Null_roll = Null_roll * 99
Null_nick = Null_nick * 99
Null_roll = Null_roll + Offset_roll 'Mittellage
Null_nick = Null_nick + Offset_nick 'Mittellage
Null_roll = Null_roll / 100
Null_nick = Null_nick / 100
'</Mittellage ausgleichen>
'Offsetwerte der Beschleunigungssensoren sofort abziehen
'Diese werden nicht laufend ermittelt
'Acc_roll = Acc_roll - Null_roll
'Acc_nick = Acc_nick - Null_nick
'<Geschwindikgeitsbegrenzung>
'Bei Der Geschwindigkeitsbegrenzung Wird die Nullage Der Plattform Verändert.
'Beim Vorwärtsbremsen wird nach hinten geneigt, beim Rückwärtsbremsen nach vorne.
Vbrems = 0
Lbrems = 0
If Frei = 0 Then
If Kmh > Vmax Then Vbrems = Vmax - Kmh
If Kmh < Vmaxr Then Vbrems = Vmaxr - Kmh
End If
'Lastabhängige Bremse
'Es muss immer genug Reserve sein um noch zu Bremsen oder zu Balancieren
Ldummyi = Int(pwm_gesamt)
If Ldummyi > Spwm Then Lbrems = Spwm - Ldummyi
If Ldummyi < Spwmr Then Lbrems = Spwmr - Ldummyi
Brems = Lbrems + Vbrems
Brems = Brems * 50
'Nicht zu heftig Bremsen
If Brems < -2000 Then Brems = -2000
If Brems > 2000 Then Brems = 2000
Acc_nick = Acc_nick + Brems
'</Geschwindikgeitsbegrenzung>
'<Signalaufbereitung der Sensorsignale>
K_diff = K_rechts - K_links
K_sum = K_sum * 0.84
K_sum = K_sum + K_diff
'Gleitender Mittelwert der Gyros berechnen um damit den Offset bei
'Stillstand zu haben. Dieser ist leider Temperaturabhängig.
'Sum_gyro_gier = Sum_gyro_gier - Mit_gyro_gier
'Sum_gyro_gier = Sum_gyro_gier + Gyro_gier
'Mit_gyro_gier = Sum_gyro_gier / Gyro_anz
Sig_gyro_gier = Gyro_gier '- Mit_gyro_gier 'Polarität
'Sum_gyro_roll = Sum_gyro_roll - Mit_gyro_roll
'Sum_gyro_roll = Sum_gyro_roll + Gyro_roll
'Mit_gyro_roll = Sum_gyro_roll / Gyro_anz
Sig_gyro_roll = Gyro_roll '- Mit_gyro_roll 'Polarität
'Korr_acc_roll = Sig_gyro_roll * Gyro_faktor
Sum_acc_roll = Sum_acc_roll - Mit_acc_roll
Sum_acc_roll = Sum_acc_roll + Acc_roll
'Sum_acc_roll = Sum_acc_roll + Korr_acc_roll 'Gyrowert hinzu
'Mittelwert bilden
Mit_acc_roll = Sum_acc_roll / Acc_anz
Mit_acc_roll = Sum_acc_roll
'*************************************************************************
'Das soll ausgleichen, daß die Gyros bei gekippten Sensoren eine Drehung
'um die falsche Achse registrieren.
'Sdummy1 = Mit_acc_roll * Sig_gyro_gier
'Die Sensorplatine muss dazu absolut Waagerecht montiert sein.
'Sdummy1 = Sdummy1 / 20000
'Lagefehler = Int(sdummy1)
'Das soll den Fehler ausgleichen, der durch die geänderte Lage des
'Gyros auftritt.
'Gyro_nick = Gyro_nick + Lagefehler
'************************************************************************
Sum_gyro_nick = Sum_gyro_nick - Mit_gyro_nick
Sum_gyro_nick = Sum_gyro_nick + Gyro_nick
Mit_gyro_nick = Sum_gyro_nick / Gyro_anz
Sig_gyro_nick = Gyro_nick - Mit_gyro_nick
'Gyro = Beschleunigung
'Accelerometer = Neigung
'Korr_acc_nick = Sig_gyro_nick * Gyro_faktor
Sum_acc_nick = Sum_acc_nick - Mit_acc_nick
Sum_acc_nick = Sum_acc_nick + Acc_nick
'Sum_acc_nick = Sum_acc_nick - Korr_acc_nick 'Gyrowert hinzu
Mit_acc_nick = Sum_acc_nick / Acc_anz
'</Signalaufbereitung der Sensorsignale>
'<PID-Regler>
Stellwert = 0
'< P-Anteil>
Sdummy1 = Mit_acc_nick
Sdummy1 = Sdummy1 * P_faktor
Stellwert = Stellwert - Sdummy1
'<I-Anteil>
Mit_acc_nick_s = Mit_acc_nick_s + Mit_acc_nick
'Überlauf/unsinnige Werte verhindern
If Mit_acc_nick_s > Max_mit_acc_nick_s Then
Mit_acc_nick_s = Max_mit_acc_nick_s
End If
If Mit_acc_nick_s < Min_mit_acc_nick_s Then
Mit_acc_nick_s = Min_mit_acc_nick_s
End If
Sdummy1 = Mit_acc_nick_s
Sdummy1 = Sdummy1 * I_faktor
Stellwert = Stellwert - Sdummy1
'<D-Anteil>
Sdummy1 = Sig_gyro_nick
Sdummy1 = Sdummy1 * D_faktor
'Stellwert ==> Stromsollwert
Stellwert = Stellwert + Sdummy1
'<Anpassungsfaktoren berechnen>
K_sum_anpassung = K_rechts + K_links
K_sum_anpassung = Abs(k_sum_anpassung)
Mp_anpassung = Pwm_gesamt * Mp_faktor
Mp_anpassung = Abs(mp_anpassung)
Mp_anpassung = Mp_anpassung + 0.95
Mv_anpassung = K_sum_anpassung * Mv_faktor
Mv_anpassung = Abs(mv_anpassung)
Mv_anpassung = Mv_anpassung + 1
Mpl_anpassung = Pwm_gesamt * Mpl_faktor
Mpl_anpassung = Abs(mpl_anpassung)
Mpl_anpassung = Mpl_anpassung + 1
Mvl_anpassung = K_sum_anpassung * Mvl_faktor
Mvl_anpassung = Abs(mvl_anpassung)
Mvl_anpassung = Mvl_anpassung + 1
'</Anpassungsfaktoren berechnen>
'<Verstärkte Regelung bei hoher Leistung>
Stellwert = Stellwert * Mp_anpassung
Stellwert = Stellwert * Mv_anpassung
'<Verstärkte Regelung bei hoher Leistung>
'<Abgeschwächte Regelung im Stand>
If K_sum_anpassung < 8 Then Stellwert = Stellwert * 0.8
If K_sum_anpassung < 6 Then Stellwert = Stellwert * 0.8
If K_sum_anpassung < 4 Then Stellwert = Stellwert * 0.8
'</Abgeschwächte Regelung in Stand>
Pwm_gesamt = Pwm_gesamt + Stellwert
'</PID-Regler>
'<Bremsvibrator einmischen>
'Der Bremsvibrator signalisiert dem Fahrer, daß wegen irgend einem
'Grenzwert gebremst wird. Das kann V-Max oder P-Max sein.
If Brems <> 0 Then
Bdummy1 = Intcount / 2
Bdummy1 = Bdummy1 Mod 2
If Bdummy1 = 0 Then
Pwm_gesamt = Pwm_gesamt + 5
Else
Pwm_gesamt = Pwm_gesamt - 5
End If
End If
'<Bremsvibrator einmischen>
'<Lenkung>
Lenkvorgabe = Mit_acc_roll / 80
Sdummy1 = Abs(lenkvorgabe)
If Sdummy1 <= 6 Then
Sdummy1 = Sdummy1 / 12
Lenkerstellung = Lenkvorgabe * Sdummy1
Else
If Lenkvorgabe < 0 Then
Lenkerstellung = Lenkvorgabe + 3
Else
Lenkerstellung = Lenkvorgabe - 3
End If
End If
'Lenkfehler berechnen und zum Stellwert hinzu.
Sdummy1 = Sig_gyro_gier
Sdummy1 = Sdummy1 / 5
Lenkfehler = Lenkerstellung - Sdummy1
Lenkfehler = Lenkfehler * Mpl_anpassung
Lenkfehler = Lenkfehler * Mvl_anpassung
Lenkstellwert = Lenkerstellung + Lenkfehler
If Lenkstellwert > Max_lenk Then Lenkstellwert = Max_lenk
If Lenkstellwert < Min_lenk Then Lenkstellwert = Min_lenk
Pwm_lenk_links = Pwm_gesamt + Lenkstellwert
Pwm_lenk_rechts = Pwm_gesamt - Lenkstellwert
If Pwm_lenk_links > 0 Then Richtung_links = 1 Else Richtung_links = 0
If Pwm_lenk_rechts > 0 Then Richtung_rechts = 1 Else Richtung_rechts = 0
Pwm_lenk_links = Abs(pwm_lenk_links)
Pwm_lenk_rechts = Abs(pwm_lenk_rechts)
If Pwm_lenk_links > Maxpwm Then Pwm_lenk_links = Maxpwm
If Pwm_lenk_rechts > Maxpwm Then Pwm_lenk_rechts = Maxpwm
If Pwm_lenk_links < Minpwm Then Pwm_lenk_links = Minpwm
If Pwm_lenk_rechts < Minpwm Then Pwm_lenk_rechts = Minpwm
Pwm_links = Pwm_lenk_links
Pwm_rechts = Pwm_lenk_rechts
'</Lenkung>
If Antriebaus = 1 Then
If Notaus = 1 Then
'Unfalldatenschreiber: *************************************************
'Dauert zwar Lange, macht aber nix. Bei Notaus muss nix geregelt werden.
' call Unfalldatenschreiber
' call Betriebsdatenschreiber
Notaus = 0
'***********************************************************************
End If
'Auf 0 setzen was sonst geregelt wird
Richtung_links = 2 'Leerlauf
Richtung_rechts = 2 'Leerlauf
Pwm_links = 0
Pwm_rechts = 0
Pwm_gesamt = 0
Mit_acc_nick_s = 0
Lenkerstellung = 0
K_rechts = 0
K_links = 0
'Waagerechte Positoion setzen wenn Zustand Antriebaus:
Wdummy1 = Acc_roll
Null_roll = Wdummy1 * 100
Wdummy1 = Acc_nick
Null_nick = Wdummy1 * 100
'Mittelwert der Beschleunigungssensoren auf aktuellen Wert stellen
'Der Mittelwert braucht sonst zu lange bis er sich eingeregelt hat
Sum_acc_roll = Acc_roll * Acc_anz
Sum_acc_nick = Acc_nick * Acc_anz
If Intcount = 0 Then T30 = 1 'Regelparameter vom Tacho anfordern
If Intcount = 50 Then T30 = 1 'Regelparameter vom Tacho anfordern
End If
'******************************************************************************
If T30 = 1 Then 'Regelparameter vom Tacho anfordern
K_links = 0
K_rechts = 0
Zeiger_meldung = 1
Bdummy1 = Udr
T30 = 0 'Damit keine alte Rückmeldung ausgewertet wird
Timeout = Timer0
Timeout = Timeout + 100
'Anforderung an Display senden
Print Chr(255) ; Chr(0) ; Chr(0) ; Chr(255) ; Chr(13)
While Zeiger_meldung < 31
If Ucsr0a.rxc0 = 1 Then 'Warten bis ein Byte eingetroffen ist
Tachomeldung(zeiger_meldung) = Udr
Incr Zeiger_meldung
Timeout = Timer0
Timeout = Timeout + 20
End If
If Timer0 > Timeout Then
T30 = 0
Exit While 'Timeout
End If
Wend
If T30 = 13 Then 'Jetzt BCC berechnen
!lds R24,{t1}
!LDs R25,{t2}
!add R24,R25
!LDs R25,{t3}
!add R24,R25
!LDs R25,{t4}
!add R24,R25
!LDs R25,{t5}
!add R24,R25
!LDs R25,{t6}
!add R24,R25
!LDs R25,{t7}
!add R24,R25
!LDs R25,{t8}
!add R24,R25
!LDs R25,{t9}
!add R24,R25
!LDs R25,{t10}
!add R24,R25
!LDs R25,{t11}
!add R24,R25
!LDs R25,{t12}
!add R24,R25
!LDs R25,{t13}
!add R24,R25
!LDs R25,{t14}
!add R24,R25
!LDs R25,{t15}
!add R24,R25
!LDs R25,{t16}
!add R24,R25
!LDs R25,{t17}
!add R24,R25
!LDs R25,{t18}
!add R24,R25
!LDs R25,{t19}
!add R24,R25
!LDs R25,{t20}
!add R24,R25
!LDs R25,{t21}
!add R24,R25
!LDs R25,{t22}
!add R24,R25
!LDs R25,{t23}
!add R24,R25
!LDs R25,{t24}
!add R24,R25
!LDs R25,{t25}
!add R24,R25
!LDs R25,{t26}
!add R24,R25
!LDs R25,{t27}
!add R24,R25
!LDs R25,{t28}
!add R24,R25
!STS {Bdummy1},R24
If Bdummy1 = T29 Then
P_faktor = P_tacho
I_faktor = I_tacho
D_faktor = D_tacho
Mp_faktor = Mp_tacho
Mv_faktor = Mv_tacho
Mpl_faktor = Mpl_tacho
Mvl_faktor = Mvl_tacho
Werteneu = 1
End If
End If
Else
'Errechnete Geschwindigkeiten an Motoren Senden:
'Rechter Motor:
If Nummotors = 2 Then
Checksum_rechts = 82
Checksum_rechts = Checksum_rechts + Richtung_rechts
Checksum_rechts = Checksum_rechts + Pwm_rechts
'Geschwindigkeit an Motorregler senden
Bdummy1 = Udr 'Puffer leeren
'Print Chr(82); Chr(richtung_rechts); Chr(pwm_rechts); Chr(checksum_rechts); Chr(13);
'In Assembler geht das so:
!Ldi R24 , 82
!STS udr,R24
Warten1:
!LDS R24,UCSR0A
!BST R24,5
!Brtc warten1
!LDS R24,{Richtung_rechts}
!STS udr,R24
Warten2:
!LDS R24,UCSR0A
!BST R24,5
!Brtc warten2
!lds R24,{Pwm_rechts} 'PWM Wert
!STS udr,R24
Warten3:
!LDS R24,UCSR0A
!BST R24,5
!Brtc warten3
!LDS R24,{Checksum_rechts}
!STS udr,R24
Warten4:
!LDS R24,UCSR0A
!BST R24,5
!Brtc warten4
!LDI R24,13
!STS udr,R24
Warten5:
!LDS R24,UCSR0A
!BST R24,5
!Brtc warten5
Motormeldung(8) = 0 'Damit keine alte Rückmeldung ausgewertet wird
'Vom Motorcontroller lesen
Timeout = Timer0
Zeiger_meldung = 1
'80 Ticks * 51,2uS pro Tick = 4mS Wartezeit auf Antwort
'COM benötigt ca. 1,5mS für 9 Byte
Errorword.8 = 0
Timeout = Timeout + 80
While Zeiger_meldung < 9
If Ucsr0a.rxc0 = 1 Then 'Warten bis ein Byte eingetroffen ist
Motormeldung(zeiger_meldung) = Udr
Incr Zeiger_meldung
End If
If Timer0 > Timeout Then
Ende = 0
Errorword.8 = 1
Exit While 'Timeout
End If
Wend
!lds R24,{M1}
!LDs R25,{M2}
!ADD R24,R25
!LDs R25,{M3}
!ADD R24,R25
!LDs R25,{M4}
!ADD R24,R25
!LDs R25,{M5}
!ADD R24,R25
!LDs R25,{M6}
!ADD R24,R25
!STS {Bdummy1},R24
If Bdummy1 <> Checksumme Then Ende = 0
If Ende = 13 Then
U_rechts = U
I_rechts = I
K_rechts = K
Else
Incr Seriell_err_rechts
S_err = 1
End If
End If
'Linker Motor:
Checksum_links = 76 'Adresse
Checksum_links = Checksum_links + Richtung_links
Checksum_links = Checksum_links + Pwm_links
Zeiger_meldung = 1
Bdummy1 = Udr 'Puffer leeren
'Print Chr(76); Chr(richtung_links); Chr(pwm_links); Chr(checksum_links); Chr(13);
'>>>>>>>>>>>> Message an Motorcontroller senden <<<<<<<<<<<<<<
'In Assembler geht das so:
!Ldi R24 , 76 'Adresse
!STS udr,R24
Warten6:
!LDS R24,UCSR0A
!BST R24,5
!Brtc warten6
!LDS R24,{Richtung_links}
!STS udr,R24
Warten7:
!LDS R24,UCSR0A
!BST R24,5
!Brtc warten7
!lds R24,{Pwm_links}
!STS udr,R24
Warten8:
!LDS R24,UCSR0A
!BST R24,5
!Brtc warten8
!LDS R24,{Checksum_links}
!STS udr,R24
Warten9:
!LDS R24,UCSR0A
!BST R24,5
!Brtc warten9
!LDI R24,13
!STS udr,R24
Warten10:
!LDS R24,UCSR0A
!BST R24,5
!Brtc warten10
Motormeldung(8) = 0 'Damit keine alte Rückmeldung ausgewertet wird
Timeout = Timer0
Timeout = Timeout + 80 'Wartezeit auf Antwort
'>>>>>>>>>>>> Message vom Motorcontroller empfangen <<<<<<<<<<<<<<
While Zeiger_meldung < 9
If Ucsr0a.rxc0 = 1 Then 'Warten bis ein Byte eingetroffen ist
Motormeldung(zeiger_meldung) = Udr
Incr Zeiger_meldung
End If
If Timer0 > Timeout Then
Ende = 0
Errorword.8 = 1
Exit While 'Timeout
End If
Wend
!lds R24,{M1}
!LDs R25,{M2}
!ADD R24,R25
!LDs R25,{M3}
!ADD R24,R25
!LDs R25,{M4}
!ADD R24,R25
!LDs R25,{M5}
!ADD R24,R25
!LDs R25,{M6}
!ADD R24,R25
!STS {Bdummy1},R24
If Bdummy1 <> Checksumme Then Ende = 0
If Ende = 13 Then
U_links = U
I_links = I
K_links = K
Else
Incr Seriell_err_links
S_err = 1
End If
If S_err = 1 Then 'Sicherheitshalber, damit der Lenkausgleich nicht überreagiert.
K_links = 0
K_rechts = 0
S_err = 0
End If
End If
If Antriebaus = 0 Then
'<Not-Aus Kriterien ermitteln>
If Mit_acc_nick > -300 Then If Mit_acc_nick < 300 Then Regelzeit = 0
Incr Regelzeit
'</Not-Aus Kriterien ermitteln>
'<Not-Aus Kriterien abprüfen>
If Regelzeit > 250 Then 'Wenn nach 2,5s waagerechte Lage nicht erreicht
Notaus = 1
Antriebaus = 1
Ugrund = Str(regelzeit)
Ugrund = "*Rz " + Ugrund
End If
Ldummyi = 4000 + Brems
If Mit_acc_nick > Ldummyi Then 'zu weit nach hinten gekippt
Notaus = 1
Antriebaus = 1
Ugrund = Str(mit_acc_nick)
Ugrund = "*Nick " + Ugrund
End If
Ldummyi = -4000 + Brems
If Mit_acc_nick < Ldummyi Then 'zu weit nach vorn gekippt
Notaus = 1
Antriebaus = 1
Ugrund = Str(mit_acc_nick)
Ugrund = "*Nick " + Ugrund
End If
If Mit_acc_roll > 5000 Then 'Lenker zu weit nach rechts
Notaus = 1
Antriebaus = 1
Ugrund = Str(mit_acc_roll)
Ugrund = "*Roll " + Ugrund
End If
If Mit_acc_roll < -5000 Then 'Lenker zu weit nach links
Notaus = 1
Antriebaus = 1
Ugrund = Str(mit_acc_roll)
Ugrund = "*Roll " + Ugrund
End If
If K_diff > 10 Then 'Plattform rotiert zu schnell
Notaus = 1
Antriebaus = 1
Ugrund = Str(k_diff)
Ugrund = "*Gier " + Ugrund
End If
If K_diff < -10 Then 'Plattform rotiert zu schnell
Notaus = 1
Antriebaus = 1
Ugrund = Str(k_diff)
Ugrund = "*Gier " + Ugrund
End If
'</Not-Aus Kriterien abprüfen>
Else
If Fusscount > 0 Then Antriebaus = 0
End If
'<Akkuspannung berechnen>
If Nummotors = 2 Then
Ugemessen = U_links + U_rechts
Shift Ugemessen , Right , 1 , Signed 'Div by 2 weil 2 Motoren
Else
Ugemessen = U_links
End If
'</Akkuspannung berechnen>
'<Gesamtstrom berechnen>
If Nummotors = 2 Then
Igemessen = I_links + I_rechts
Else
Igemessen = I_links
End If
'</Gesamtstrom berechnen>
'<verbrauchte Amperestunden berechnen>
If Igemessen > 0 Then
Summe_as_entladen = Summe_as_entladen + Igemessen 'Verbrauchte
End If
If Igemessen < 0 Then
Summe_as_laden = Summe_as_laden - Igemessen 'Rückgespeiste
End If
'mAh aus den Amperestunden rausholen um Überläufe zu verhindern
'Die 360000 setzen sich zusammen aus:
'Igemessen in mA -> Faktor 1
'100 Messungen pro Sekunde -> mal 100
'1 mAh = 60 Sekunden * 60 mAsekunden -> 3600
'360000 = 1 * 100 * 3600
If Summe_as_entladen > 360000 Then
Incr Summe_mah_entladen
Summe_as_entladen = Summe_as_entladen - 360000
End If
If Summe_as_laden > 360000 Then 'Das kann passieren wenns den Berg runter geht
Incr Summe_mah_laden
Summe_as_laden = Summe_as_laden - 360000
End If
Erzeugt = Summe_mah_laden
Verbraucht = Summe_mah_entladen
Erzeugt = Erzeugt * 0.7 'Das ist der Akku-Wirkungsgrad 0.7 (0.85) bezogen auf den Stom
Verbraucht = Verbraucht - Erzeugt
Akkuinhalt = Akkukap
Akkuverbrauch = Verbraucht
Akkuprozent = Akkuverbrauch / Akkuinhalt
Akkuprozent = Akkuprozent * 1000
Akkuprozent = Int(akkuprozent)
Akkustand = Akkuprozent
'</verbrauchte As berechnen>
'<Strecke berechnen>
Kx = K_links + K_rechts
Kx = Kx / 2
Strecke = Kx * Di
Zentimeter = Zentimeter + Strecke
If Zentimeter >= 100 Then
Incr Meter
Zentimeter = Zentimeter - 100
End If
If Zentimeter < 0 Then
Decr Meter
Zentimeter = Zentimeter + 100
End If
If Meter >= 1000 Then
Incr Kilometer
Meter = Meter - 1000
End If
If Meter < 0 Then
Decr Kilometer
Meter = Meter + 1000
End If
'</Strecke berechnen>
'<Geschwindigkeit berechnen>
Kv = Kv + Kx
Kmh = Kv * Kmhfaktor
Kv = Kv * 0.75 'Bei Änderung auch den kmhfaktor neu berechnen
If Kmh > Max_v Then Max_v = Kmh
If Kmh < Min_v Then Min_v = Kmh
'</Geschwindigkeit berechnen>
If Bzeit < 500 Then Incr Bzeit
Incr Intcount
'******************************************************************************
'ADiverse Werte werden an den Tacho geschickt. Manche für die Funktion
'des Tachos, andere um die Steuerung zu optimieren.
'******************************************************************************
Incr Tachocount
Select Case Tachocount
Case 0
B(1) = 40 'Error Word
B(2) = Errorword1
B(3) = Errorword2
B(5) = 1
Case 1
B(1) = 1 'U
U = Ugemessen
B(2) = Motormeldung(1)
B(3) = Motormeldung(2)
B(5) = 1
Case 2
B(1) = 2 'I
I = Igemessen / 10
B(2) = Motormeldung(3)
B(3) = Motormeldung(4)
B(5) = 1
Case 3
B(1) = 3 'Km/h
B(2) = Kmhmeldung(1)
B(3) = Kmhmeldung(2)
B(5) = 1
Case 4
B(1) = 5 'Akkuprozente
B(2) = Akkumeldung(1)
B(3) = Akkumeldung(2)
B(5) = 1
Case 5
B(1) = 7 'Meter
B(2) = Metermeldung(1)
B(3) = Metermeldung(2)
B(5) = 1
Case 6
B(1) = 6 'Kilometer
B(2) = Kilometermeldung(1)
B(3) = Kilometermeldung(2)
B(5) = 1
Case 7
If Antriebaus = 0 Then
B(1) = 8 'Low
B(2) = Mit_acc_roll1
B(3) = Mit_acc_roll2
B(5) = 1
Else
B(1) = 12 'Low
B(2) = Null_roll1
B(3) = Null_roll2
B(5) = 1
End If
Case 8
If Antriebaus = 0 Then
B(1) = 9 'High
B(2) = Mit_acc_roll3
B(3) = Mit_acc_roll4
B(5) = 1
Else
B(1) = 13 'High
B(2) = Null_roll3
B(3) = Null_roll4
B(5) = 1
End If
Case 9
B(1) = 4 'Status
B(2) = Antriebaus
B(3) = Ta
B(5) = 1
Case 10
If Antriebaus = 0 Then
B(1) = 10 'acc_Nick
B(2) = Mit_acc_nick1
B(3) = Mit_acc_nick2
B(5) = 1
Else
B(1) = 14
B(2) = Null_nick1
B(3) = Null_nick2
B(5) = 1
End If
Case 11 'Nick und Roll
If Antriebaus = 0 Then
B(1) = 11 'acc_Nick
B(2) = Mit_acc_nick3
B(3) = Mit_acc_nick4
B(5) = 1
Else
B(1) = 15
B(2) = Null_nick3
B(3) = Null_nick4
B(5) = 1
End If
Case 12
B(1) = 16 'Stellwert
B(2) = Stellwert1
B(3) = Stellwert2
B(5) = 1
Case 13
B(1) = 17 'Stellwert
B(2) = Stellwert3
B(3) = Stellwert4
B(5) = 1
Case 14
Gyronick = Sig_gyro_nick
B(1) = 18 'Gyro Nick_l
B(2) = Gyronick1
B(3) = Gyronick2
B(5) = 1
Case 15
B(1) = 19 'Gyro Nick_h
B(2) = Gyronick3
B(3) = Gyronick4
B(5) = 1
Case 16
Kksum = K_sum
B(1) = 20 '??_l
B(2) = Kksum1
B(3) = Kksum2
B(5) = 1
Case 17
B(1) = 21 '??_h
B(2) = Kksum3
B(3) = Kksum4
B(5) = 1
If Antriebaus = 0 Then Tachocount = 255 'Gleich zu 0 überlaufen lassen
Case 18
B(1) = 22
B(2) = Pf1
B(3) = Pf2
B(5) = 1
Case 19
B(1) = 23
B(2) = Pf3
B(3) = Pf4
B(5) = 1
Case 20
B(1) = 24
B(2) = If1
B(3) = If2
B(5) = 1
Case 21
B(1) = 25
B(2) = If3
B(3) = If4
B(5) = 1
Case 22
B(1) = 26
B(2) = Df1
B(3) = Df2
B(5) = 1
Case 23
B(1) = 27
B(2) = Df3
B(3) = Df4
B(5) = 1
Case 24
B(1) = 28
B(2) = Mpf1
B(3) = Mpf2
B(5) = 1
Case 25
B(1) = 29
B(2) = Mpf3
B(3) = Mpf4
B(5) = 1
Case 26
B(1) = 30
B(2) = Mvf1
B(3) = Mvf2
B(5) = 1
Case 27
B(1) = 31
B(2) = Mvf3
B(3) = Mvf4
B(5) = 1
Case 28
B(1) = 32
B(2) = Mplf1
B(3) = Mplf2
B(5) = 1
Case 29
B(1) = 33
B(2) = Mplf3
B(3) = Mplf4
B(5) = 1
Case 30
B(1) = 34
B(2) = Mvlf1
B(3) = Mvlf2
B(5) = 1
Case 31
B(1) = 35
B(2) = Mvlf3
B(3) = Mvlf4
B(5) = 1
Case 32
B(1) = 36 'Port Status
B(2) = Portc
B(3) = Porta
B(5) = 1
Case 33
B(1) = 37 'Fussschalter 1
Wwert = Adc0 'Word
B(2) = Wwert1
B(3) = Wwert2
B(5) = 1
Case 34
B(1) = 38 'Fussschalter 2
Wwert = Adc1 'Word
B(2) = Wwert1
B(3) = Wwert2
B(5) = 1
Case 35
B(1) = 39 'Fussschalter gesamt
B(2) = Fussschalter
B(3) = 0
B(5) = 1
Tachocount = 255
Case Else
B(5) = 0 'Nichts ausgeben
End Select
If Intcount = 99 Then Intcount = 255
If B(5) = 1 Then
'Checksumme berechnen
B(4) = B(1)
B(4) = B(4) + B(2)
B(4) = B(4) + B(3)
'Print Chr(b(1)) ; Chr(b(2)) ; Chr(b(3)) ; Chr(b(4)) ; Chr(13);
'Print geht so in Assembler:
!LDS R24,{B(1)} 'Adresse von b(1)
!STS udr,R24
Warten11:
!LDS R24,UCSR0A
!BST R24,5
!Brtc warten11
!LDS R24,{B(2)} 'Adresse von b(2)
!STS udr,R24
Warten12:
!LDS R24,UCSR0A
!BST R24,5
!Brtc warten12
!lds R24,{B(3)} 'Adresse von B(3)
!STS udr,R24
Warten13:
!LDS R24,UCSR0A
!BST R24,5
!Brtc warten13
!LDS R24,{B(4)} 'Adresse von B(4)
!STS udr,R24
Warten14:
!LDS R24,UCSR0A
!BST R24,5
!Brtc warten14
!LDI R24,13 'CR
!STS udr,R24
Warten15:
!LDS R24,UCSR0A
!BST R24,5
!Brtc warten15
Ta = Timer0 'Um festzustellen ob der Interrupt zu lange dauert
'Wenn Ja, ist der Zählwert nahe 255
End If
Return
Sub Flashled(byval Which As Byte , Byval Dauer_ms As Byte)
Dim Done As Byte
Dim Waitstarttime As Byte
Dim Xx As Byte
Select Case Which
Case 0 'Both
Led1 = 1
Led2 = 1
Waitms Dauer_ms
Led1 = 0
Led2 = 0
Waitms Dauer_ms
Case 1 'LED1
Led1 = 1
Waitms Dauer_ms
Led1 = 0
Waitms Dauer_ms
Case 2 'LED2
Led2 = 1
Waitms Dauer_ms
Led2 = 0
Waitms Dauer_ms
End Select
End Sub
Readfussschalter:
Adc0 = Getadc(0)
If Adc0 > Fussschalterschwelle Then
Fussschalter.0 = 1
Else
Fussschalter.0 = 0
End If
Adc1 = Getadc(1)
If Adc1 > Fussschalterschwelle Then
Fussschalter.1 = 1
Else
Fussschalter.1 = 0
End If
If Fussschalter = 0 Then 'Max 0.5 Sekunden ohne Fussschalter
If Fusscount > 0 Then Decr Fusscount
Else
Fusscount = 50 'alles OK
End If
If Fusscount = 0 Then
If Antriebaus = 0 Then
Antriebaus = 1
Waitms 100 'Damit der Regel_interrupt auch was davon mitbekommt
'Disable Interrupts
'Betriebsdatenschreiber
'Enable Interrupts
End If
End If
Return
Read_gyro: 'Beschleunigung
I2cstart
I2cwbyte Gyroadress_w
'Start address for Read
I2cwbyte &B10101000 'Out_x_l AND &B10000000
I2cstart
I2cwbyte Gyroadress_r
'I2crbyte Temperatur , Ack
'I2crbyte Status , Ack
I2crbyte Gyro_roll1 , Ack
I2crbyte Gyro_roll2 , Ack
I2crbyte Gyro_nick1 , Ack
I2crbyte Gyro_nick2 , Ack
I2crbyte Gyro_gier1 , Ack
I2crbyte Gyro_gier2 , Nack
I2cstop
Return
Read_acc: 'Neigung
I2cstart
I2cwbyte Accadress_w
'Start address for Read
I2cwbyte &B10101000 'Out_x_l_a AND &B10000000
I2cstart
I2cwbyte Accadress_r
'I2crbyte Status_a , Ack
I2crbyte Accroll_l , Ack
I2crbyte Accroll_h , Ack
Acc_roll = Accroll
Acc_roll = Acc_roll / 2 'Divisor = Empfindlichkeit
I2crbyte Accnick_l , Ack
I2crbyte Accnick_h , Ack
Acc_nick = Accnick
Acc_nick = Acc_nick / 10 'Divisor = Empfindlichkeit
I2crbyte Accgier_l , Ack
I2crbyte Accgier_h , Nack
Acc_gier = Accgier
Acc_gier = Acc_gier / 10 'Divisor = Empfindlichkeit
I2cstop
Return
'Get_mag_data:
' Slaveadress = Magadress
' Subadress = Out_x_h_m
' Gosub Read_6_mag
' Xmag = Dataarray(1)
' Shift Xmag , Left , 8
' Xmag = Xmag + Dataarray(2)
' Ymag = Dataarray(3)
' Shift Ymag , Left , 8
' Ymag = Ymag + Dataarray(4)
' Zmag = Dataarray(5)
' Shift Zmag , Left , 8
' Zmag = Zmag + Dataarray(6)
' Xmag = Xmag - Xmagoff
' Ymag = Ymag - Ymagoff
'Return
Init_gyro:
'refer to MiniMu9 L3G4200D_Gyro.pdf, page 29
Slaveadress = Gyroadress_w
Subadress = Ctrl_reg1
'01 ==> 200Hz
' 11 ==> Bandwidth = 70
' 0 ==> Power Down Mode
' 1 ==> Z-Axis enable
' 1 ==> Y-Axis enable
' 1 ==> X-Axis enable
Databyte = &B00001111 'Enable x, y, z and turn off power down
I2cstart
I2cwbyte Slaveadress
I2cwbyte Subadress
I2cwbyte Databyte
I2cstop
Subadress = Ctrl_reg2
Databyte = &B0010_1001 'adjust/use the HPF
I2cstart
I2cwbyte Slaveadress
I2cwbyte Subadress
I2cwbyte Databyte
I2cstop
Subadress = Ctrl_reg3
Databyte = &B0000_1000
I2cstart
I2cwbyte Slaveadress
I2cwbyte Subadress
I2cwbyte Databyte
I2cstop
Subadress = Ctrl_reg4
'1 ==> Block Data Update
' 0 ==> BLE
' 00 ==> 250 dps
' 0 ==> not used
' 00 ==> Self Test 0=Normal Mode
' 0 ==> SIM 0=4-wire interface
Databyte = &B10000000
I2cstart
I2cwbyte Slaveadress
I2cwbyte Subadress
I2cwbyte Databyte
I2cstop
Subadress = Ctrl_reg5
Databyte = &B0000_0000 'high-pass filtering of outputs
I2cstart
I2cwbyte Slaveadress
I2cwbyte Subadress
I2cwbyte Databyte
I2cstop
Return
Init_acc:
Slaveadress = Accadress_w
Subadress = Ctrl_reg1_a
'001 ==> Normal Mode
' 01 ==> 100Hz, Bandwith=74
' 1 ==> Z-Axis enable
' 1 ==> Y-Axis enable
' 1 ==> X-Axis enable
Databyte = &B00101111
I2cstart
I2cwbyte Slaveadress
I2cwbyte Subadress
I2cwbyte Databyte
I2cstop
Slaveadress = Accadress_w
Subadress = Ctrl_reg4_a
'1 ==> Continuous, update when finished
' 0 ==> BLE
' 00 ==> FSE = 2g
' 0 ==> Self Test Sign
' 0 ==> not used
' 0 ==> Self Test Enable
' 0 ==> not used
Databyte = &B10000000 'Block Data Update, LSB low, Scale +-2g
I2cstart
I2cwbyte Slaveadress
I2cwbyte Subadress
I2cwbyte Databyte
I2cstop
Return
'Init_mag:
' Slaveadress = Magadress
' Subadress = Cra_reg_m
' Databyte = &B00011000 '75Hz Output
' I2cstart
' I2cwbyte Slaveadress
' I2cwbyte Subadress
' I2cwbyte Databyte
' I2cstop
' Slaveadress = Magadress
' Subadress = Crb_reg_m
' Databyte = &B01000000 'range +-1.9Gauss
' I2cstart
' I2cwbyte Slaveadress
' I2cwbyte Subadress
' I2cwbyte Databyte
' I2cstop
' Slaveadress = Magadress
' Subadress = Mr_reg_m
' Databyte = &B00000000 'continious mode
' I2cstart
' I2cwbyte Slaveadress
' I2cwbyte Subadress
' I2cwbyte Databyte
' I2cstop
'Return
Sub Resetdata
Disable Interrupts
Regelzeit = 0
Regelzeitmax = 0
Mit_acc_nick_max = 0
Mit_acc_roll_max = 0
Mit_acc_nick_min = 0
Mit_acc_roll_min = 0
Pwm_rechts_max = 0
Pwm_links_max = 0
Seriell_err_rechts = 0
Seriell_err_links = 0
K_diff_min = 0
K_diff_max = 0
Antriebaus = 0
Fusscount = 50 '0,5 Sekunden
Enable Interrupts
End Sub
Display3000:
'****************Listrik01 LCD Display Steuerung Version 01 *****************
$hwstack = 256
$swstack = 256
$framesize = 64
$regfile = "m2561def.dat"
$crystal = 16000000 'microcontroller crystal frequency
$baud1 = 57600
'(start block comment
---------------------
| |
| --------------- |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | Port D.0 = Tageskilometerzähler Reset
| | | |
| | | |
| | --------------| | Display:
| | 1| 2| |3| | 1 = Zyklusdauer (0..255)
| --------------- | 2 = Motorleistung links
| | 3 = Motorleistung rechts
| |
| O1 O2 |
| O5 | Schalter:
| | 1: PinD.7 Zeile abwärts
| O7 O8 | 2: PinD.4 Zeile aufwärts
| | 3: PinE.5 Blättern
| O6 | 4: PinE.7 SD-Karte aktivieren
| O3 O4 | 5: PinG.0 Werte übernehmen
| | 6: PinG.3 Taste defekt
| | 7: PinG.1 Zahl kleiner
| | 8: PinD.5 Zahl größer
| | 9: Cpu Reset
| |
| |
| O9 |
---------------------
')end block comment
'####################### LCD-Routines ######################################
'Definition of used ports and pull up resistors.
'We are using Port B for the SPI-communication to the LCD Display.
Ddra = &B00000000 'switch all 8 Ports of Port A to input (0),
'Pin (PA.0 - PA.7)
Porta = &B11111111 'All port pins have individually selectable pull-up
'resistors. Here we enable these pull-up-resisitors,
'so these Pins are always at logical 1
'You Need To Pull These Pins Against Ground(gnd)
'Select Port B as to an output port (data output to the display)
Ddrb = &B01110110 'DDR = Data direction register; Port B1, B2, B4, B5, B6
'switched to output (1) as needed by the display
Portb = &B10001001 'the other ports of Port B are inputs with
'switched on pull up resistors
Ddrc = &B00000000 'switch all Ports of Port C to input
Portc = &B11111111 'all pull-up-Resistors turned on
Ddrd = &B00000000 'switchall Ports of Port D to input
Portd = &B11110011 'almost all pull-up-Resistors turned on
Ddre = &B10000000 'E7=Output (SD card activate), all other Input
Porte = &B11111111 'all pull-up-Resistors turned on
Ddrf = &B00000000 'switch all Ports of Port F to input
Portf = &B11111111 'all pull-up-Resistors turned on
Ddrg = &B00000000 'switch all Ports of Port G to input
Portg = &B11111111 'all pull-up-Resistors turned on
'#############################################################################
Declare Sub Activate_display_bus
Declare Sub Activate_sd_bus()
Declare Sub Minmax()
Declare Function Trimtext(t As String) As String * 22
Declare Sub Drawpagestatics
Const Titel = "Tacho 0.1 "
Dim Ep0 As Byte At $0201
Dim Ep1 As Byte At $0202
Dim Ep2 As Byte At $0203
Dim Ep3 As Byte At $0204
Dim Ep4 As Byte At $0205
Dim Ep5 As Byte At $0206
Dim Iwert As Integer At $0203 Overlay
Dim Wwert As Integer At $0203 Overlay
Dim Index As Byte At $202 Overlay
Dim Maccx As Long At $0207
Dim Maccx1 As Byte At $0207 Overlay
Dim Maccx2 As Byte At $0208 Overlay
Dim Maccx3 As Byte At $0209 Overlay
Dim Maccx4 As Byte At $020a Overlay
Dim Maccy As Long At $020b
Dim Maccy1 As Byte At $020b Overlay
Dim Maccy2 As Byte At $020c Overlay
Dim Maccy3 As Byte At $020d Overlay
Dim Maccy4 As Byte At $020e Overlay
Dim Nullx As Long At $020f
Dim Nullx1 As Byte At $020f Overlay
Dim Nullx2 As Byte At $0210 Overlay
Dim Nullx3 As Byte At $0211 Overlay
Dim Nullx4 As Byte At $0212 Overlay
Dim Nully As Long At $0213
Dim Nully1 As Byte At $0213 Overlay
Dim Nully2 As Byte At $0214 Overlay
Dim Nully3 As Byte At $0215 Overlay
Dim Nully4 As Byte At $0216 Overlay
Dim Sw As Single At $00217
Dim Sw1 As Byte At $0217 Overlay
Dim Sw2 As Byte At $0218 Overlay
Dim Sw3 As Byte At $0219 Overlay
Dim Sw4 As Byte At $021a Overlay
Dim Gyronick As Long At $0021b
Dim Gyronick1 As Byte At $021b Overlay
Dim Gyronick2 As Byte At $021c Overlay
Dim Gyronick3 As Byte At $021d Overlay
Dim Gyronick4 As Byte At $021e Overlay
Dim Kksum As Single At $0021f
Dim Kksum1 As Byte At $021f Overlay
Dim Kksum2 As Byte At $0220 Overlay
Dim Kksum3 As Byte At $0221 Overlay
Dim Kksum4 As Byte At $0222 Overlay
Dim P_faktor As Single At $0223
Dim P_f1 As Byte At $0223 Overlay
Dim P_f2 As Byte At $0224 Overlay
Dim P_f3 As Byte At $0225 Overlay
Dim P_f4 As Byte At $0226 Overlay
Dim I_faktor As Single At $0227
Dim I_f1 As Byte At $0227 Overlay
Dim I_f2 As Byte At $0228 Overlay
Dim I_f3 As Byte At $0229 Overlay
Dim I_f4 As Byte At $022a Overlay
Dim D_faktor As Single At $022b
Dim D_f1 As Byte At $022b Overlay
Dim D_f2 As Byte At $022c Overlay
Dim D_f3 As Byte At $022d Overlay
Dim D_f4 As Byte At $022e Overlay
Dim Mp_faktor As Single At $022f
Dim Mp_f1 As Byte At $022f Overlay
Dim Mp_f2 As Byte At $0230 Overlay
Dim Mp_f3 As Byte At $0231 Overlay
Dim Mp_f4 As Byte At $0232 Overlay
Dim Mv_faktor As Single At $0233
Dim Mv_f1 As Byte At $0233 Overlay
Dim Mv_f2 As Byte At $0234 Overlay
Dim Mv_f3 As Byte At $0235 Overlay
Dim Mv_f4 As Byte At $0236 Overlay
Dim Mpl_faktor As Single At $0237
Dim Mpl_f1 As Byte At $0237 Overlay
Dim Mpl_f2 As Byte At $0238 Overlay
Dim Mpl_f3 As Byte At $0239 Overlay
Dim Mpl_f4 As Byte At $023a Overlay
Dim Mvl_faktor As Single At $023b
Dim Mvl_f1 As Byte At $023b Overlay
Dim Mvl_f2 As Byte At $023c Overlay
Dim Mvl_f3 As Byte At $023d Overlay
Dim Mvl_f4 As Byte At $023e Overlay
Dim Pfaktor As Long
Dim Ifaktor As Long
Dim Dfaktor As Long
Dim Mpfaktor As Long
Dim Mvfaktor As Long
Dim Mplfaktor As Long
Dim Mvlfaktor As Long
Dim Stellwert As Single
Dim Gyro_nick As Long
Dim Null_y As Long
Dim Null_x As Long
Dim Mit_acc_y As Long
Dim Mit_acc_x As Long
Dim K_sum As Single
Dim K_summax As Single
Dim K_summin As Single
Dim Bdummy As Byte
Dim Singdummy As Single
Dim Wdummy As Word
Dim Ldummy As Long
Dim Idummy As Integer
Dim Kilometer As Word
Dim Meter As Integer
Dim Akkuprozente As Integer
Dim Kmh As Integer
Dim Kmhmax As Integer
Dim Kmhmin As Integer
Dim I As Integer
Dim Imax As Integer
Dim Imin As Integer
Dim U As Integer
Dim Umax As Integer
Dim Umin As Integer
Dim Ml As Integer
Dim Mlmax As Integer
Dim Mrmax As Integer
Dim Mr As Integer
Dim Mlmin As Integer
Dim Mrmin As Integer
Dim Modus As Byte
Dim Editzeile As Byte
Dim Utext As String * 22
Dim Itext As String * 22
Dim Ltext As String * 22
Dim L1 As Byte
Dim L2 As Byte
Dim L3 As Byte
Dim Text As String * 22
Dim Farbe As Word
Dim X1 As Byte
Dim Y1 As Byte
Dim X2 As Byte
Dim Y2 As Byte
Dim Startkilometer As Single
Dim Ta As Byte
Dim Tamax As Byte
Dim Antriebaus As Byte
Dim Xoffset As Long
Dim Yoffset As Long
Dim Ya As Byte
Dim Xa As Byte
'Dim Lname As Long
'Dim Dateiname As String * 12
'Dim Dateilaenge As Long
'Dim Dateiaktuell As Byte
Dim Gbdriveerror As Byte
Dim Ulog As Single
Dim Ilog As Single
Dim Kmhlog As Single
Dim Kmlog As Single
Dim Akkuprozentelog As Single
Dim Loopcount As Word
Dim Aloopcount As Word
Dim Logtext As String * 255
Dim Zeit As String * 8
Dim Sichern As Byte
Dim Transferok As Byte
Dim Hexstr As String * 2
Dim Hauptstportc As Byte
Dim Hauptstporta As Byte
Dim Ad0 As Word 'AD value 0...1024
Dim Ad1 As Word 'AD value 0...1024
Dim Fussschalter As Byte 'Bit0 und Bit1
Dim Dummybyte As Byte
Config Clock = User
Config Date = Dmy , Separator = .
'No Need To Call Here Because Init21_display3000.bas Has Already Done This
Call Activate_display_bus
$include "Y:\Programme\Tools\BASCOM-AVR\Display 3000\Displaymodul\Bascom Programme\für Include\Init21_display3000.bas"
'If Porte.7 = 0 Then Activate_sd_bus
'Gbdriveerror = Driveinit() 'Init MMC/SD Card
'If Gbdriveerror = 0 Then
' Include AVR-DOS Configuration and library
' $include "Y:\Programme\Tools\BASCOM-AVR\Display 3000\SD Speicherkartenmodul P001\Bascom Basic\Config_AVR-DOS.BAS"
' Bdummy = Initfilesystem(1) ' Partition 1
' Ldummy = Disksize()
' Ldummy = Ldummy / 1024
' Utext = Str(ldummy)
' Utext = "Size: " + Utext
' Utext = Utext + " mb"
' Ldummy = Diskfree()
' Ldummy = Ldummy / 1024
' Itext = Str(ldummy)
' Itext = "Free: " + Itext
' Itext = Itext + " mb"
' If Porte.7 = 1 Then call Activate_display_bus
' gosub Lcd_cls
' call Lcd_print(Titel , 0 , 0 , 1 , 1 , 1 , Yellow , Blue)
' call Lcd_print ("SD-Karte init" , 0 , 18 , 1 , 1 , 1 , Black , White)
' call Lcd_print (Utext , 0 , 27 , 1 , 1 , 1 , Black , White)
' Lcd_print Itext , 0 , 36 , 1 , 1 , 1 , Black , White
' Wait 7
' Else
' If Porte.7 = 1 Then call Activate_display_bus
' Ltext = Str(gbdriveerror)
' Ltext = "Fehler: " + Ltext
' gosub Lcd_cls
' call Lcd_print (Titel , 0 , 0 , 1 , 1 , 1 , Yellow , Blue)
' call Lcd_print ("SD-Karte init" , 0 , 18 , 1 , 1 , 1 , Black , White)
' call Lcd_print (Ltext , 0 , 27 , 1 , 1 , 1 , Black , White)
' Wait 7
' End If
Readeeprom Startkilometer , 1
Readeeprom Xoffset , 5
Readeeprom Yoffset , 9
'Einige Werte vorbelegen um fehlerhafte Grafik zu vermeiden wenn keine
'serielle Verbindung besteht
Xa = 74
Ya = 130
Antriebaus = 1
Null_x = Xoffset
Null_y = Yoffset
'If Porte.7 = 1 Then call Activate_display_bus
Orientation = Portrait180 'landscape mode
Graphics_mode = 65k_uncompressed 'select the needed color mode, here 65.536 colors
Call Lcd_cls
Call Drawpagestatics
Config Timer2 = Timer , Prescale = 128
Assr.exclk = 0
Assr.as2 = 1
On Timer2 Tick
Enable Timer2
Start Timer2
On Urxc1 Datenempfang
Enable Urxc1
Enable Interrupts
Minmax
Do
If Pine.5 = 0 Then
While Pine.5 = 0 : Wend 'Debounce Button
Incr Modus
If Gbdriveerror <> 0 Then 'Logging nicht zulassen wenn DriveError
If Modus > 5 Then
Modus = 0
end if
end If
If Modus <> 4 Then'nur berechnen wenn die Werte nicht editiert werden
Singdummy = P_faktor * 10000
Singdummy = Round(Singdummy)
Pfaktor = Singdummy
Singdummy = I_faktor * 1000000
Singdummy = Round(Singdummy)
Ifaktor = Singdummy
Singdummy = D_faktor * 1000
Singdummy = Round(Singdummy)
Dfaktor = Singdummy
Singdummy = Mp_faktor * 10000
Singdummy = Round(Singdummy)
Mpfaktor = Singdummy
Singdummy = Mv_faktor * 1000
Singdummy = Round(Singdummy)
Mvfaktor = Singdummy
Singdummy = Mpl_faktor * 10000
Singdummy = Round(Singdummy)
Mplfaktor = Singdummy
Singdummy = Mvl_faktor * 1000
Singdummy = Round(Singdummy)
Mvlfaktor = Singdummy
End If
If Modus > 5 Then Modus = 0
'If Porte.7 = 1 Then call Activate_display_bus
Call Lcd_cls
Call Drawpagestatics
End If
If Modus <> 5 Then 'Nur wenn nicht geloggt wird
If U <> 0 Then 'Nur wenn auch schon eine Spannung übertragen wurde
If Ta <> 0 Then
Idummy = U 'Nur wenn auch schon ein Ta übertragen wurde
If Idummy > Umax Then Umax = Idummy
If Idummy < Umin Then Umin = Idummy
Idummy = I
If Idummy > Imax Then Imax = Idummy
If Idummy < Imin Then Imin = Idummy
Idummy = Kmh
If Idummy > Kmhmax Then Kmhmax = Idummy
If Idummy < Kmhmin Then Kmhmin = Idummy
Bdummy = Ta
If Bdummy > Tamax Then Tamax = Bdummy
Idummy = Ml
If Idummy > Mlmax Then Mlmax = Idummy
If Idummy < Mlmin Then Mlmin = Idummy
Idummy = Mr
If Idummy > Mrmax Then Mrmax = Idummy
If Idummy < Mrmin Then Mrmin = Idummy
End If
End If
End If
Select Case Modus
Case 0
'If Dateiaktuell = 1 Then
' If Porte.7 = 0 Then Activate_sd_bus
' Close #2
' Dateiaktuell = 0
'End If
'If Porte.7 = 1 Then call Activate_display_bus 'Standard Anzeige
If Pind.0 = 0 Then
Waitms 3
If Pind.0 = 0 Then
While Pind.0 = 0 : Wend
Singdummy = Meter / 1000
Singdummy = Singdummy + Kilometer
Startkilometer = Singdummy
Writeeeprom Startkilometer , 1
End If
End If
'Spannung und Strom
Singdummy = U / 100
Utext = Fusing(singdummy , "#.#")
Utext = Utext + "V"
Utext = " " + Utext
Singdummy = I / 100
Itext = Fusing(singdummy , "#.#")
Itext = Itext + "A "
L1 = Len(utext)
L2 = Len(itext)
L1 = L1 + L2
L2 = 22 - L1
Ltext = String(l2 , 32)
Text = Utext + Ltext
Text = Text + Itext
Lcd_print Text , 0 , 75 , 1 , 1 , 1 , Black , White
'Akku in Prozent
Singdummy = Akkuprozente / 10
Singdummy = 100 - Singdummy
Text = Fusing(singdummy , "#.#" )
Text = " " + Text + "% "
If Singdummy > 66 Then
Farbe = Green
Elseif Singdummy > 33 Then
Farbe = Yellow
Else
Farbe = Red
End If
Singdummy = Singdummy * 1.14 '124 - 8 - 1 - 1 = 114 / 100% = 1.14
X2 = Singdummy 'Type cast
X2 = X2 + 10 '10 wegen der "100 - Sdummy" weiter oben
Lcd_box X2 , 85 , 123 , 94 , White 'Hintergrund löschen
Lcd_box 9 , 85 , X2 , 94 , Farbe 'Balken zeichnen
'Text mittig platzieren
L1 = Len(text)
L1 = L1 * 5
L1 = L1 / 2
X1 = 66 - L1
Lcd_print Text , X1 , 98 , 1 , 1 , 1 , Black , White 'unterm Balken
'km/h
Singdummy = Kmh / 10
Text = Fusing(Singdummy , "#.#")
Text = Text + "km/h "
Text = " " + Text
L1 = Len(text)
Text = Text + " "
L1 = L1 * 4
X1 = 66 - L1
Lcd_print Text , X1 , 12 , 2 , 1 , 2 , Black , White
'km
Singdummy = Meter / 1000
Singdummy = Singdummy + Kilometer
Text = Fusing(Singdummy , "#.#")
Text = Text + "km "
Text = " " + Text
L1 = Len(text)
L1 = L1 * 5
L1 = L1 / 2
X1 = 66 - L1
Lcd_print Text , X1 , 46 , 1 , 1 , 1 , Black , White
'Tageskilometerzähler
Singdummy = Singdummy - Startkilometer
Text = Fusing(Singdummy , "#.###")
Text = Text + "km "
Text = " " + Text
L1 = Len(text)
L1 = L1 * 5
L1 = L1 / 2
X1 = 66 - L1
Lcd_print Text , X1 , 60 , 1 , 1 , 1 , Black , White
If Antriebaus = 1 Then
Text = "AUS"
Else
Text = "RUN"
End If
'Text mittig platzieren
L1 = Len(text)
L1 = L1 * 5 'Schriftlänge in Pixel, jedes Zeichen = 5 Pixel
L1 = L1 / 2 'Halbe schriftlänge
X1 = 74 - L1 'Text mittig
Lcd_print Text , X1 , 148 , 1 , 1 , 1 , Black , White
'>>>>>>>>>>>> Fusszeile im Display >>>>>>>>>>>>
' 01234567891111111111222
' 0123456789012
' xxx xxx xxx
'PmotLinks Ta PmotRechts
' L1 L2 L3
Text = String(22 , 32) 'Fill with spaces
Utext = Str(ml) 'Pmot_links (Integer)
L1 = Len(utext)
Mid(text , 0 , L1) = Utext 'insert Ml
Utext = Str(ta) 'Ticks (Byte)
L2 = Len(utext)
Mid(text , 10 , L2) = Utext 'insert Ta
Utext = Str(mr) 'Pmot_rechts (Integer)
L3 = Len(utext)
X1 = 23 - L3 'Starting position of Mr
Mid(text , X1 , L3) = Utext 'insert Mr
'L2 = X1 + L3
'L1 = 22 - L2
'Utext = String(l1 , 32)
'Mid(text , L2 , L1) = Utext 'insert final spaces
Lcd_print Text , 0 , 168 , 1 , 1 , 1 , White , Black
'>>>>>>>>>>>> Fusszeile im Display >>>>>>>>>>>>
If Antriebaus = 1 Then
Singdummy = Null_x
Singdummy = Singdummy - Xoffset
Singdummy = Singdummy / 50
If Singdummy > 49 Then Singdummy = 49
If Singdummy < -49 Then Singdummy = -49
Singdummy = Singdummy + 74
X1 = Int(Singdummy)
Lcd_draw Xa , 126 , Xa , 134 , 0 , White
Lcd_draw X1 , 126 , X1 , 134 , 0 , Black
Xa = X1
Singdummy = Null_y
Singdummy = Singdummy - Yoffset
Singdummy = Singdummy / 50
If Singdummy > 29 Then Singdummy = 29
If Singdummy < -29 Then Singdummy = -29
Singdummy = Singdummy + 130
Y1 = Int(Singdummy)
Lcd_draw 9 , Ya , 18 , Ya , 0 , White
Lcd_draw 9 , Y1 , 18 , Y1 , 0 , Black
Ya = Y1
Else
'Horizontaler Balken
Singdummy = Mit_acc_x
Singdummy = Singdummy / 50
If Singdummy > 49 Then Singdummy = 49
If Singdummy < -49 Then Singdummy = -49
Singdummy = Singdummy + 74
X1 = Int(Singdummy)
Lcd_draw Xa , 126 , Xa , 134 , 0 , White
Lcd_draw X1 , 126 , X1 , 134 , 0 , Black
Xa = X1
'Vertikaler Balken
Singdummy = Mit_acc_y
Singdummy = Singdummy / 50
If Singdummy > 29 Then Singdummy = 29
If Singdummy < -29 Then Singdummy = -29
Singdummy = Singdummy + 130
Y1 = Int(Singdummy)
Lcd_draw 9 , Ya , 18 , Ya , 0 , White
Lcd_draw 9 , Y1 , 18 , Y1 , 0 , Black
Ya = Y1
End If
Case 1 'Details
'If Dateiaktuell = 1 Then
' If Porte.7 = 0 Then Activate_sd_bus
' Close #2
' Dateiaktuell = 0
'End If
'If Porte.7 = 1 Then call Activate_display_bus
If Pind.0 = 0 Then
Waitms 3
If Pind.0 = 0 Then
While Pind.0 = 0 : Wend
If Antriebaus = 1 Then
Yoffset = Null_y
Xoffset = Null_x
Writeeeprom Xoffset , 5
Writeeeprom Yoffset , 9
End If
End If
End If
Singdummy = U / 100
Text = Fusing(Singdummy , "#.#")
Text = " U= " + Text
Text = Text + "V"
Text = Trimtext(text)
Lcd_print Text , 0 , 9 , 1 , 1 , 1 , Black , White
Singdummy = I / 100
Text = Fusing(Singdummy , "#.#")
Text = " I= " + Text
Text = Text + "A"
Text = Trimtext(text)
Lcd_print Text , 0 , 18 , 1 , 1 , 1 , Black , White
Singdummy = Kmh / 10
Text = Fusing(Singdummy , "#.#")
Text = " V= " + Text
Text = Text + "km/h"
Text = Trimtext(text)
Lcd_print Text , 0 , 27 , 1 , 1 , 1 , Black , White
Singdummy = Meter / 1000
Singdummy = Singdummy + Kilometer
Text = Fusing(Singdummy , "#.###")
Text = " S= " + Text
Text = Text + "km "
Text = Trimtext(text)
Lcd_print Text , 0 , 36 , 1 , 1 , 1 , Black , White
Singdummy = Ml
Text = Str(ml )
Text = " Pl= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 45 , 1 , 1 , 1 , Black , White
Singdummy = Mr
Text = Str(mr )
Text = " Pr= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 54 , 1 , 1 , 1 , Black , White
Singdummy = Akkuprozente / 10
Singdummy = 100 - Singdummy
Text = Fusing(Singdummy , "#.#")
Text = "Akku= " + Text
Text = Text + "%"
Text = Trimtext(text)
Lcd_print Text , 0 , 63 , 1 , 1 , 1 , Black , White
Text = Str(mit_acc_x)
Text = "Roll= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 72 , 1 , 1 , 1 , Black , White
Text = Str(mit_acc_y )
Text = "Nick= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 81 , 1 , 1 , 1 , Black , White
Text = Str(null_x )
Text = " R0= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 90 , 1 , 1 , 1 , Black , White
Text = Str(null_y )
Text = " N0= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 99 , 1 , 1 , 1 , Black , White
Text = Fusing(stellwert , "#.###")
Text = " SW= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 108 , 1 , 1 , 1 , Black , White
Text = Str(gyro_nick )
Text = " GN= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 117 , 1 , 1 , 1 , Black , White
Text = Str(ta )
Text = " TA= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 126 , 1 , 1 , 1 , Black , White
Text = Str(k_sum)
Text = "Ksum= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 135 , 1 , 1 , 1 , Black , White
Case 2 'Min/Max
'If Dateiaktuell = 1 Then
' If Porte.7 = 0 Then Activate_sd_bus
' Close #2
' Dateiaktuell = 0
'End If
'If Porte.7 = 1 Then call Activate_display_bus
If Pind.0 = 0 Then
Waitms 3
If Pind.0 = 0 Then
While Pind.0 = 0 : Wend
Minmax 'Min-Maxwerte auf 0 setzen
End If
End If
Singdummy = Umin / 100
Text = Fusing(Singdummy , "#.#")
Text = " Umin= " + Text
Text = Text + "V"
Text = Trimtext(text)
Lcd_print Text , 0 , 9 , 1 , 1 , 1 , Black , White
Singdummy = Umax / 100
Text = Fusing(Singdummy , "#.#")
Text = " Umax= " + Text
Text = Text + "V"
Text = Trimtext(text)
Lcd_print Text , 0 , 18 , 1 , 1 , 1 , Black , White
'**************************************************
Singdummy = Imin / 100
Text = Fusing(Singdummy , "#.#")
Text = " Imin= " + Text
Text = Text + "A"
Text = Trimtext(text)
Lcd_print Text , 0 , 27 , 1 , 1 , 1 , Black , White
Singdummy = Imax / 100
Text = Fusing(Singdummy , "#.#")
Text = " Imax= " + Text
Text = Text + "A"
Text = Trimtext(text)
Lcd_print Text , 0 , 36 , 1 , 1 , 1 , Black , White
'**************************************************
Singdummy = Kmhmin / 10
Text = Fusing(Singdummy , "#.#")
Text = " Vmin= " + Text
Text = Text + "km/h"
Text = Trimtext(text)
Lcd_print Text , 0 , 45 , 1 , 1 , 1 , Black , White
Singdummy = Kmhmax / 10
Text = Fusing(Singdummy , "#.#")
Text = " Vmax= " + Text
Text = Text + "km/h"
Text = Trimtext(text)
Lcd_print Text , 0 , 54 , 1 , 1 , 1 , Black , White
'**************************************************
Text = Str(mlmin )
Text = " Plmin= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 63 , 1 , 1 , 1 , Black , White
Text = Str(mlmax )
Text = " Plmax= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 72 , 1 , 1 , 1 , Black , White
'**************************************************
Text = Str(mlmin )
Text = " Prmin= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 81 , 1 , 1 , 1 , Black , White
Text = Str(mrmax )
Text = " Prmax= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 90 , 1 , 1 , 1 , Black , White
'**************************************************
Text = Str(tamax )
Text = " TAmax= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 99 , 1 , 1 , 1 , Black , White
'**************************************************
Text = Bin(hauptstportc)
Text = " HauptSt_C= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 108 , 1 , 1 , 1 , Black , White
'**************************************************
Text = Bin(hauptstporta)
Text = " HauptSt_A= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 118 , 1 , 1 , 1 , Black , White
'**************************************************
Text = Str(ad0)
Text = " AD(0)= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 127 , 1 , 1 , 1 , Black , White
'**************************************************
Text = Str(ad1)
Text = " AD(1)= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 136 , 1 , 1 , 1 , Black , White
'**************************************************
Dummybyte = Fussschalter And &H1
If Dummybyte > 0 Then
Text = "1"
Else
Text = "0"
End If
Text = " Fuss1= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 145 , 1 , 1 , 1 , Black , White
'**************************************************
Dummybyte = Fussschalter And &H2
If Dummybyte > 0 Then
Text = "1"
Else
Text = "0"
End If
Text = " Fuss2= " + Text
Text = Trimtext(text)
Lcd_print Text , 0 , 153 , 1 , 1 , 1 , Black , White
Case 3 'Werte editieren
'If Dateiaktuell = 1 Then
' If Porte.7 = 0 Then Activate_sd_bus
' Close #2
' Dateiaktuell = 0
'End If
'If Porte.7 = 1 Then call Activate_display_bus
If Pind.7 = 0 Then 'Zeile abwärts
Waitms 3
If Pind.7 = 0 Then
While Pind.7 = 0 : Wend
If Editzeile > 1 Then Decr Editzeile : End If
End If
If Pind.4 = 0 Then 'Zeile aufwärts
Waitms 3
If Pind.4 = 0 Then
While Pind.4 = 0 : Wend
If Editzeile < 7 Then Incr Editzeile : End If
End If
If Ping.1 = 0 Then 'Zahl dekrementieren
Waitms 3
If Ping.1 = 0 Then
While Ping.1 = 0 : Wend
Select Case Editzeile
Case 1
Decr Pfaktor
Case 2
Decr Ifaktor
Case 3
Decr Dfaktor
Case 4
Decr Mpfaktor
Case 5
Decr Mvfaktor
Case 6
Decr Mplfaktor
Case 7
Decr Mvlfaktor
End Select
End If
End If
If Pind.5 = 0 Then 'Zahl inkrementieren
Waitms 3
If Pind.5 = 0 Then
While Pind.5 = 0 : Wend
Select Case Editzeile
Case 1
Incr Pfaktor
Case 2
Incr Ifaktor
Case 3
Incr Dfaktor
Case 4
Incr Mpfaktor
Case 5
Incr Mvfaktor
Case 6
Incr Mplfaktor
Case 7
Incr Mvlfaktor
End Select
End If
End If
If Ping.0 = 0 Then 'Werte aus Display übernehmen
Waitms 3
If Ping.0 = 0 Then
While Ping.0 = 0 : Wend
P_faktor = Pfaktor
P_faktor = P_faktor / 10000
I_faktor = Ifaktor
I_faktor = I_faktor / 1000000
D_faktor = Dfaktor
D_faktor = D_faktor / 1000
Mp_faktor = Mpfaktor
Mp_faktor = Mp_faktor / 10000
Mv_faktor = Mvfaktor
Mv_faktor = Mv_faktor / 1000
Mpl_faktor = Mplfaktor
Mpl_faktor = Mpl_faktor / 10000
Mvl_faktor = Mvlfaktor
Mvl_faktor = Mvl_faktor / 1000
Sichern = 1
Call Lcd_cls
Lcd_print Titel , 0 , 0 , 1 , 1 , 1 , Yellow , Blue
Wait 2
End If
End If
Text = " Regelparameter:"
Text = Trimtext(text)
Lcd_print Text , 0 , 18 , 1 , 1 , 1 , Black , White
'**************************************************
Text = Str(pfaktor)
Text = " P = " + Text
Text = Trimtext(text)
If Editzeile = 1 Then
Lcd_print Text , 0 , 36 , 1 , 1 , 1 , Black , Green
'**************************************************
Else
Lcd_print Text , 0 , 36 , 1 , 1 , 1 , Black , White
'**************************************************
End If
Text = Str(ifaktor)
Text = " I = " + Text
Text = Trimtext(text)
If Editzeile = 2 Then
Lcd_print Text , 0 , 46 , 1 , 1 , 1 , Black , Green
'**************************************************
Else
Lcd_print Text , 0 , 46 , 1 , 1 , 1 , Black , White
'**************************************************
End If
Text = Str(dfaktor)
Text = " D = " + Text
Text = Trimtext(text)
If Editzeile = 3 Then
Lcd_print Text , 0 , 56 , 1 , 1 , 1 , Black , Green
'**************************************************
Else
Lcd_print Text , 0 , 56 , 1 , 1 , 1 , Black , White
'**************************************************
End If
Text = Str(mpfaktor)
Text = " MP = " + Text
Text = Trimtext(text)
If Editzeile = 4 Then
Lcd_print Text , 0 , 66 , 1 , 1 , 1 , Black , Green
'**************************************************
Else
Lcd_print Text , 0 , 66 , 1 , 1 , 1 , Black , White
'**************************************************
End If
Text = Str(mvfaktor)
Text = " MV = " + Text
Text = Trimtext(text)
If Editzeile = 5 Then
Lcd_print Text , 0 , 76 , 1 , 1 , 1 , Black , Green
'**************************************************
Else
Lcd_print Text , 0 , 76 , 1 , 1 , 1 , Black , White
'**************************************************
End If
Text = Str(mplfaktor)
Text = " MPL = " + Text
Text = Trimtext(text)
If Editzeile = 6 Then
Lcd_print Text , 0 , 86 , 1 , 1 , 1 , Black , Green
'**************************************************
Else
Lcd_print Text , 0 , 86 , 1 , 1 , 1 , Black , White
'**************************************************
End If
Text = Str(mvlfaktor)
Text = " MVL = " + Text
Text = Trimtext(text)
If Editzeile = 7 Then
Lcd_print Text , 0 , 96 , 1 , 1 , 1 , Black , Green
'**************************************************
Else
Lcd_print Text , 0 , 96 , 1 , 1 , 1 , Black , White
'**************************************************
End If
If Transferok = 1 Then
Lcd_print " Transfer OK" , 0 , 106 , 1 , 1 , 1 , Black , White
Transferok = 0
End if
Case 4 'siehe COM IN
'Siehe Datenempfang
Case 5 'Logging
'If Porte.7 = 0 Then Activate_sd_bus
'If Antriebaus = 0 Then 'Motoren laufen ->Werte Loggen
' If Dateiaktuell = 0 Then 'Keine Datei geöffnet
' Lname = 1
' Dateilaenge = 1 'Nächste Schleife einmal erzwingen
' While Dateilaenge > 0
' Dateiname = Str(lname)
' Dateiname = Dateiname + ".log"
' '0 voranstellen, damit sich die Dateien besser sortieren lassen.
' While Len(dateiname) < 12
' Dateiname = "0" + Dateiname
' Wend
' Dateilaenge = Filelen(dateiname)
' Incr Lname
' Wend
' If Porte.7 = 1 Then call Activate_display_bus
' Lcd_print Dateiname , 25 , 75 , 1 , 1 , 1 , Black , White
' If Porte.7 = 0 Then Activate_sd_bus
' Dateiaktuell = 1
' Loopcount = 0
' _sec = 0
' _min = 0
' _hour = 0
' Zeit = "00:00:00"
' Open Dateiname For Append As #2
' Logtext = "Zeit;Loopcount;U;I;Nick;GyroNick;Stellwert;Roll;Pl;Pr;Ksum;V"
' Print #2 , Logtext
' End If
' If Loopcount <> Aloopcount Then
' Ulog = U / 100
' Ilog = I / 100
' Kmhlog = Kmh / 10
' Logtext = Zeit
' Logtext = Logtext + ";"
' Logtext = Logtext + Str(loopcount)
' Logtext = Logtext + ";"
' Logtext = Logtext + Fusing(ulog , "#.#")
' Logtext = Logtext + ";"
' Logtext = Logtext + Fusing(ilog , "#.#")
' Logtext = Logtext + ";"
' Logtext = Logtext + Str(mit_acc_y)
' Logtext = Logtext + ";"
' Logtext = Logtext + Str(gyro_nick)
' Logtext = Logtext + ";"
' Logtext = Logtext + Fusing(stellwert , "#.###")
' Logtext = Logtext + ";"
' Logtext = Logtext + Str(mit_acc_x)
' Logtext = Logtext + ";"
' Logtext = Logtext + Str(ml)
' Logtext = Logtext + ";"
' Logtext = Logtext + Str(mr)
' Logtext = Logtext + ";"
' Logtext = Logtext + Fusing(k_sum , "#.##")
' Logtext = Logtext + ";"
' Logtext = Logtext + Fusing(kmhlog , "#.#")
' Print #2 , Logtext
' Aloopcount = Loopcount
' End If
'Else
' Close #2
' Dateiaktuell = 0
'End If
End Select
Loop
'***************************************************************************
Datenempfang:
!PUSH R24;
!IN R24, SREG;
!PUSH R24;
!LDS R24,{EP1}
!STS {EP0},R24
!LDS R24,{EP2}
!STS {EP1},R24
!LDS R24,{EP3}
!STS {EP2},R24
!LDS R24,{EP4}
!STS {EP3},R24
!LDS R24,{EP5}
!STS {EP4},R24
!IN R24,UDR1
!STs {EP5},R24
!POP R24;
!Out Sreg , R24;
!POP R24;
'Debugging
If Modus = 4 Then
Hexstr = Hex(ep0)
Text = Hexstr + " "
Hexstr = Hex(ep1)
Text = Text + Hexstr + " "
Hexstr = Hex(ep2)
Text = Text + Hexstr + " "
Hexstr = Hex(ep3)
Text = Text + Hexstr + " "
Hexstr = Hex(ep4)
Text = Text + Hexstr + " "
Hexstr = Hex(ep5)
Text = Text + Hexstr + " "
Lcd_print Text , 0 , 75 , 1 , 1 , 1 , Black , White
End If
'< Serielle Telegramme abarbeiten>
If Ep0 = 13 Then
If Ep5 = 13 Then
!lds R24,{EP1}
!LDs R25,{EP2}
!add R24,R25
!LDs R25,{EP3}
!add R24,R25
!STS {Bdummy},R24
If Bdummy = Ep4 Then 'Die Prüfsumme stimmt
Select Case Index 'Telegrammnummer
Case 1 'Spannung
U = Iwert
Case 2 'Strom
I = Iwert
Case 3 'km/h
Kmh = Iwert
Case 4 'Ta und Antriebaus
Antriebaus = Ep2
Ta = Ep3
Case 5 'Akkuprozente
Akkuprozente = Iwert
Case 6 'Kilometer
Kilometer = Wwert
Case 7 'Meter
Meter = Iwert
Case 8 'Roll_l
Maccx1 = Ep2
Maccx2 = Ep3
Case 9 'Roll_h
Maccx3 = Ep2
Maccx4 = Ep3
Mit_acc_x = Maccx
Case 10 'Nick_l
Maccy1 = Ep2
Maccy2 = Ep3
Case 11 'Nick_h
Maccy3 = Ep2
Maccy4 = Ep3
Mit_acc_y = Maccy
Case 12 'Null_Roll_l
Nullx1 = Ep2
Nullx2 = Ep3
Case 13 'Null_Roll_h
Nullx3 = Ep2
Nullx4 = Ep3
Null_x = Nullx
Case 14 'Null_Nick_l
Nully1 = Ep2
Nully2 = Ep3
Case 15 'Null_Nick_h
Nully3 = Ep2
Nully4 = Ep3
Null_y = Nully
Case 16
Sw1 = Ep2
Sw2 = Ep3
Case 17
Sw3 = Ep2
Sw4 = Ep3
Stellwert = Sw
Case 18
Gyronick1 = Ep2
Gyronick2 = Ep3
Case 19
Gyronick3 = Ep2
Gyronick4 = Ep3
Gyro_nick = Gyronick
Case 20
Kksum1 = Ep2
Kksum2 = Ep3
Case 21
Kksum3 = Ep2
Kksum4 = Ep3
K_sum = Kksum
Case 255
If Sichern = 1 Then
!lds R24,{P_f1}
!LDs R25,{P_f2}
!add R24,R25
!LDs R25,{P_f3}
!add R24,R25
!LDs R25,{P_f4}
!add R24,R25
!LDs R25,{I_f1}
!add R24,R25
!LDs R25,{I_f2}
!add R24,R25
!LDs R25,{I_f3}
!add R24,R25
!LDs R25,{I_f4}
!add R24,R25
!LDs R25,{D_f1}
!add R24,R25
!LDs R25,{D_f2}
!add R24,R25
!LDs R25,{D_f3}
!add R24,R25
!LDs R25,{D_f4}
!add R24,R25
!LDs R25,{Mp_f1}
!add R24,R25
!LDs R25,{Mp_f2}
!add R24,R25
!LDs R25,{Mp_f3}
!add R24,R25
!LDs R25,{Mp_f4}
!add R24,R25
!LDs R25,{Mv_f1}
!add R24,R25
!LDs R25,{Mv_f2}
!add R24,R25
!LDs R25,{Mv_f3}
!add R24,R25
!LDs R25,{Mv_f4}
!add R24,R25
!LDs R25,{Mpl_f1}
!add R24,R25
!LDs R25,{Mpl_f2}
!add R24,R25
!LDs R25,{Mpl_f3}
!add R24,R25
!LDs R25,{Mpl_f4}
!add R24,R25
!LDs R25,{Mvl_f1}
!add R24,R25
!LDs R25,{Mvl_f2}
!add R24,R25
!LDs R25,{Mvl_f3}
!add R24,R25
!LDs R25,{Mvl_f4}
!add R24,R25
!STS {Bdummy},R24
'Open "COM2:" For Binary As #1 'SD-Karte
'Print #1 , Chr(p_f1) ; Chr(p_f2) ; Chr(p_f3) ; Chr(p_f4);
'Print #1 , Chr(i_f1) ; Chr(i_f2) ; Chr(i_f3) ; Chr(i_f4);
'Print #1 , Chr(d_f1) ; Chr(d_f2) ; Chr(d_f3) ; Chr(d_f4);
'Print #1 , Chr(mp_f1) ; Chr(mp_f2) ; Chr(mp_f3) ; Chr(mp_f4);
'Print #1 , Chr(mv_f1) ; Chr(mv_f2) ; Chr(mv_f3) ; Chr(mv_f4);
'Print #1 , Chr(mpl_f1) ; Chr(mpl_f2) ; Chr(mpl_f3) ; Chr(mpl_f4);
'Print #1 , Chr(mvl_f1) ; Chr(mvl_f2) ; Chr(mvl_f3) ; Chr(mvl_f4);
'Print #1 , Chr(bdummy) ; Chr(13);
'Close #1
Transferok = 1
Sichern = 0
End If
Case 76 'Linker Motor
Ml = Ep3
If Ep2 = 0 Then Ml = Ml * -1
Incr Loopcount
Case 82 'Rechter Motor
Mr = Ep3
If Ep2 = 0 Then Mr = Mr * -1
End Select
If Modus = 2 Then
Select Case Index
Case 36 'Port a und C Status
Hauptstportc = Ep2
Hauptstporta = Ep3
Case 37 'Fussschalter 1
Ad0 = Wwert
Case 38 'Fussschalter 2
Ad1 = Wwert
Case 39 'Fussschalter gesamt
Fussschalter = Ep2
End Select
End If
If Modus < 3 Then
Select Case Index
Case 22
P_f1 = Ep2
P_f2 = Ep3
Case 23
P_f3 = Ep2
P_f4 = Ep3
Case 24
I_f1 = Ep2
I_f2 = Ep3
Case 25
I_f3 = Ep2
I_f4 = Ep3
Case 26
D_f1 = Ep2
D_f2 = Ep3
Case 27
D_f3 = Ep2
D_f4 = Ep3
Case 28
Mp_f1 = Ep2
Mp_f2 = Ep3
Case 29
Mp_f3 = Ep2
Mp_f4 = Ep3
Case 30
Mv_f1 = Ep2
Mv_f2 = Ep3
Case 31
Mv_f3 = Ep2
Mv_f4 = Ep3
Case 32
Mpl_f1 = Ep2
Mpl_f2 = Ep3
Case 33
Mpl_f3 = Ep2
Mpl_f4 = Ep3
Case 34
Mvl_f1 = Ep2
Mvl_f2 = Ep3
Case 35
Mvl_f3 = Ep2
Mvl_f4 = Ep3
End Select
End If
End If 'Prüfsumme stimmt
End If
End If
'</Serielle Telegramme abarbeiten>
Return
'******************************************************************************
Sub Activate_display_bus:
'remove SD Card from bus, must be "Reset PortF.7" for board D071x
'Reset Porte.7
'different to what the SD card needs
'Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 1
'Set Spsr.spi2x 'hidden parameter: doubles the speed of the SPI output
'Spiinit
End Sub
Sub Activate_sd_bus
'Deactivate Display
'Set Lcd_port.lcd_cs
'different to what the display needs
'Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , _
' Polarity = High , Phase = 1 , Clockrate = 4 , Noss = 1
'no double speed. You may remove this line to try out with your card.
'It may work.
'Reset Spsr.spi2x
'Spiinit
'connects SD Card to bus, must to be "Set PortF.7" for board D071x
'Set Porte.7
End Sub
Function Trimtext(t As String) As String
If Len(t) > 22 Then T = Left(t , 22)
While Len(t) < 22 : T = T + " " : Wend
End Function
Sub Minmax
Umin = 10000
Umax = -10000
Imin = 0
Imax = 0
Kmhmin = 0
Kmhmax = 0
Mlmax = 0
Mlmin = 0
Mrmax = 0
Mrmin = 0
Tamax = 0
End Sub
Tick:
Incr _sec
If _sec > 59 Then
_sec = 0
Incr _min
End If
If _min > 59 Then
_min = 0
Incr _hour
End If
Zeit = Time$
Return
Getdatetime:
Return
Sub Drawpagestatics
Call Lcd_print(titel , 0 , 0 , 1 , 1 , 1 , Yellow , Blue)
Select Case Modus
Case 0
Lcd_rect 8 , 84 , 124 , 95 , 0 , Black 'Rahmen für Akku Balken
Lcd_rect 24 , 125 , 124 , 135 , 0 , Black 'Rahmen für Horizontal Lenker
Lcd_rect 8 , 100 , 19 , 160 , 0 , Black 'Rahmen für Vertikal Lenker
Lcd_draw 20 , 130 , 22 , 130 , 0 , Black 'Vertikaler Balken, Mitteltick
Lcd_draw 74 , 136 , 74 , 138 , 0 , Black 'Horizontaler Balken, Mitteltick
Lcd_draw 0 , 167 , 132 , 167 , 0 , Black 'Hintergrund der Fußzeile
Case 4
Call Lcd_print( "COM-LOG" , 30 , 10 , 2 , 1 , 2 , Black , White)
Text = " 0 1 2 3 4 5"
Lcd_print Text , 0 , 60 , 1 , 1 , 1 , Black , White
Case 5
Call Lcd_print( "LOGGING" , 30 , 40 , 2 , 1 , 2 , Black , White)
'Dateiaktuell = 0
End Select
End Sub
End
$include "Y:\Programme\Tools\BASCOM-AVR\Display 3000\Displaymodul\Bascom Programme\für Include\GLCD21_display3000.bas"
$include "Y:\Programme\Tools\BASCOM-AVR\Display 3000\Displaymodul\Bascom Programme\für Include\GLCD21_fonts.bas"
Colortable:
Data 0
Sicherheitshinweis
Achtung! Gehen Sie so ein Projekt nur an, wenn Sie sehr gute Kenntisse in Mechanik und Elektronik haben.
Funktion
Kippt das Fahrzeug nach vorn, wird nach vorn beschleunigt und umgekehrt. Die Regelung erledigt ein PID-Regler. Danach kommen jedoch noch einige zusätzliche Faktoren die z.B. die Motorkennlinie ausgleichen sowie ungewollte Richtungsänderungen bei unebenen Oberflächen reduzieren. Ähnlich aufwändig wird es bei den Motorreglern. Eine reine Blockkommutierung, wie bei solchen Motoren üblich, ist auf unebenen Untergründen suboptimal. Hier wurde zusätzliche Hallsensoren installiert.
Die seitliche Stabilität garantiert der Kreiseleffekt den jeder vom Fahrrad kennt. Das endgültige Fahrzeug wird eine Lenkung bekommen, die auf dem Beharrungsmoment basiert. Eine konventionelle Lenkung ist nicht möglich weil es nur ein Rad gibt.
Elektronik
Motorcontroller
Der Motorcontroller regelt den Motor, misst und übermittelt der Motorregler auch Spannung, Strom und Fahrstrecke. Die Temperatur des Kühlkörpers wird ebenfalls gemessen und wenn nötig ein Lüfter zugeschaltet. Die Einheit wird vom PC aus über eine ISP Schnittstelle programmiert.
Der Motorregler ist auf einer doppelseitigen Platine aufgebaut. Die Verbindung zwischen den beiden Platinen bildet ein 10-adriges Flachkabel. Zusätzlich zu den beiden Platinen gehört zum Motorregler auch die im Motor verbaute Sensorplatine. Auf dieser werden die Signale der drei zusätzlichen Hallsensoren zu einem Signal zusammengefasst.
Hauptcontroller
Die Hauptcontroller erledigt die Lageregelung. Sie steuert die Motoren und gibt die entsprechenden Meldungen an den Anzeigecontroller aus. Sie stellt auch die 12V für den Tacho bereit. Bei beiden Controllern wird ein Chopperspannungsregler eingesetzt der bis zu 63V verträgt. Deshalb ist eine Versorgung aus dem 24..48V Netz möglich. Die Lageregelung speichert auch die gefahrenen Km, einigen Min-Max Werte und diverse Werte bei einem Notaus. Diese Werte werden im EEprom als Text abgelegt. Beachten Sie, daß Sie das Gerät dann nur noch auf Privatgelände mit Zustimmung des Eigentümers benutzen dürfen. Eine Bertriebserlaubnis für das Gerät existiert nicht. Eine Einzelabnahme kann beim TÜV beantragt werden.
Schaltbild
- HauptSteuerung I2C Prototyp Rev0.pdf
- MotorSteuerung Prototyp Rev0 Blatt1.pdf
- MotorSteuerung Prototyp Rev0 Blatt2.pdf
- Hallgeber D Prototyp.pdf
- Listrik01-Verdrahtung Prototyp.pdf
- Listrik01 Prototyp Parts Rev0.pdf
Neigungssensoradapter
Im Unterschied zu ähnlichen Projekten besitzt dieses Fahrzeug einen über den I2C Bus gesteuerten Gyro und Accelerometer. Zum Beschleunigen und Bremsen werden die Sensoren gekippt.
Wie geht es weiter
Ich werde diese Seite updaten, je nach Fortschritt. Habe die nächsten paar Monate wenig Zeit....