Cyrus777
27.06.2011, 16:35
Hi,
Unser FTS-Projekt (https://www.roboternetz.de/community/showthread.php?52910-Projekt-fahrerloses-Transportsystem&p=509913#post509913)nähert sich langsam dem Ende.
Die induktive Spurführung klappt fast immer, also der Lenkmotor lenkt wenn er soll und auch wieder zurück. Manchmal gibt es aber ein paar Probleme. Mein betreuender Prof meinte ich soll da nen digitalen Tiefpassfilter programmieren... Ähm genau... Mal gucken ob wir das auch anders lösen können.
Aber irgendwie haut das mit dem Timer nicht so hin. Der Timer1 sollte eigentlich 10 Mal pro Sekunde den Interrupt aufrufen und zum einen überprüfen, ob die beiden induktiven Sensoren sich noch auf der Spur befinden und dann ggf. den Antriebsmotor stoppen wenn sich das FTS außerhalb der Spur befindet. Um zum anderen soll der Infrarotsensor vor dem Fahrzeug abgefragt werden ob sich ein Hindernis in einem bestimmten Abstand vor dem Fahrzeug befindet und den Antriebsmotor anhalten.
Aber als ich heute das Programm aufgespielt hatte, ging irgendwie gar nichts mehr. Weder die Taste 1 um das Programm zu starten noch der Resetknopf. Und das kam mir schon ziemlich seltsam vor. Hab es dann nochmal ein paar Mal kompiliert und aufgespielt, aber immer das gleiche Problem. Die alte Version ohne Timer ging ohne Probleme.
Man könnte das sicher auch ohne Timer machen und jeweils ne Funktion schreiben und diese vor jeder Schleife oder auch dazwischen aufrufen. Aber mit Interrupt wäre das ganze natürlich eleganter ;)
Wo könnte das Problem liegen? Die Werte für den Timer hab ich mir von dem Roboternetz Berechnungstool ausgeben lassen. Der Code für den Timer steht einmal ganz am Anfang und ganz am Ende. Der Rest ist im Prinzip nicht soo interessant da das ja halbwegs läuft.
Vielen Dank schon mal!
'Hier wird der Timer und der Teiler festgelegt
Config Timer1 = Timer , Prescale = 64
'Hier wird das Unterprogramm festgelegt, das
'in dem von ihnen eingestellten Intervall aufgerufen wird
On Timer1 Timer_irq
'Diese Vorgabe wurde berechnet um die genaue Intervallfrequenz zu erreichen
'10 Interrupts pro Sekunde
Const Timervorgabe = 40536
'Hier werden die Timer aktiviert
Enable Timer1
Enable Interrupts
Declare Sub Fahrt()
Declare Sub Kalibrierung()
Declare Sub Lenkung_von_rechts_zur_mitte()
Declare Sub Lenkung_von_links_zur_mitte()
Declare Function Tastenabfrage() As Byte
$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
Dim I As Integer
Dim N As Integer
Dim Ton As Integer
$crystal = 16000000 'Quarzfrequenz
$baud = 9600
Config Adc = Single , Prescaler = Auto 'Für Tastenabfrage und Spannungsmessung
Config Pina.7 = Input 'Für Tastenabfrage
Porta.7 = 1 'Pullup Widerstand ein
Const Ref = 5 / 1023 'Für Batteriespannungsberechnung
Dim Taste As Byte
Dim Volt As Single
' Für Motorentest
'Ports für linken Motor
Config Pinc.6 = Output 'Linker Motor Kanal 1
Config Pinc.7 = Output 'Linker Motor Kanal 2
Config Pind.4 = Output 'Linker Motor PWM
'Ports für rechten Motor
Config Pinb.0 = Output 'Rechter Motor Kanal 1
Config Pinb.1 = Output 'Rechter Motor Kanal 2
Config Pind.5 = Output 'Rechter Motor PWM
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down
Pwm1a = 0
Pwm1b = 0
Tccr1b = Tccr1b Or &H02 'Prescaler = 8
I = 0
Sound Portd.7 , 400 , 450 'BEEP
Sound Portd.7 , 400 , 800 'BEEP
Sound Portd.7 , 400 , 450 'BEEP
Print
Print "**** RN-CONTROL 1.4 *****"
Print "Das neue Experimentier- und Roboterboard"
Print "Weitere passende Zusatzboards bei www.robotikhardware.de"
Print
Do
Taste = Tastenabfrage()
If Taste <> 0 Then
Select Case Taste
Case 1
Call Fahrt
End Select
Sound Portd.7 , 400 , 500 'BEEP
End If
Waitms 100
Loop
End
'Diese Unterfunktion fragt die Tastatur am analogen Port ab
Function Tastenabfrage() As Byte
Local Ws As Word
Tastenabfrage = 0
Ton = 600
Start Adc
Ws = Getadc(7)
' Print "Tastenabfrage anpassen!ADC Wert ws=" ; Ws
If Ws < 500 Then
Select Case Ws
Case 400 To 450
Tastenabfrage = 1
Ton = 550
Case 330 To 380
Tastenabfrage = 2
Ton = 500
Case 260 To 305
Tastenabfrage = 3
Ton = 450
Case 180 To 220
Tastenabfrage = 4
Ton = 400
Case 90 To 130
Tastenabfrage = 5
Ton = 350
End Select
Sound Portd.7 , 400 , Ton 'BEEP
End If
End Function
Sub Fahrt()
'Testprogramm zur induktiven Spurführung
Config Porta = Input
Local Links As Word
Local Rechts As Word
Local Sensor_lichtschranke As Word
Start Adc
'Lenkungskalibrierung
Call Kalibrierung
'Lenkungskalibrierung Ende
Portb.0 = 0 'Antrieb ein
Portb.1 = 1
Portd.5 = 1
Pwm1a = 1023
Do
Links = Getadc(2)
Rechts = Getadc(3)
If Links < 700 And Rechts >= 700 Then
'"rechts neben der Spur"
Do
Links = Getadc(2)
Rechts = Getadc(3)
Portc.6 = 1 'bestimmt Richtung 0,1 Gegen Uhrzeiger (Rechtsdrehung)
Portc.7 = 0
Portd.4 = 1
Pwm1b = 1023
Loop Until Links < 700 And Rechts < 700
'Mitte
Pwm1b = 0
'Drehung von rechts zur Mitte
Call Lenkung_von_rechts_zur_mitte
'***************************
Links = Getadc(2)
Rechts = Getadc(3)
Elseif Links >= 700 And Rechts < 700 Then
'"links neben der Spur"
Do
Links = Getadc(2)
Rechts = Getadc(3)
Portc.6 = 0 'bestimmt Richtung 0,1 Gegen Uhrzeiger (Rechtsdrehung)
Portc.7 = 1
Portd.4 = 1
Pwm1b = 1023
Loop Until Links < 700 And Rechts < 700
'Mitte
Pwm1b = 0
'Drehung von links zur Mitte
Call Lenkung_von_links_zur_mitte
End If
Loop
End Sub
Sub Kalibrierung()
'Programm zur Kalibrierung der Lenkung in Mittelstellung
Local Sensor_lichtschranke As Word
Portc.6 = 1 'bestimmt Richtung 0,1 Gegen Uhrzeiger (Rechtsdrehung)
Portc.7 = 0
Portd.4 = 1
Wait 3
Pwm1b = 0
Portc.6 = 0 'bestimmt Richtung 0,1 Gegen Uhrzeiger (Rechtsdrehung)
Portc.7 = 1
Portd.4 = 1
Do
Sensor_lichtschranke = Getadc(4)
Pwm1b = 1023
Loop Until Sensor_lichtschranke < 800
Pwm1b = 0
End Sub
Sub Lenkung_von_rechts_zur_mitte()
'Programm zur Drehung des Lenkmotors von rechts zur Mitte
Local Sensor_lichtschranke As Word
Portc.6 = 0 'bestimmt Richtung 0,1 Gegen Uhrzeiger (Rechtsdrehung)
Portc.7 = 1
Portd.4 = 1
Do
Sensor_lichtschranke = Getadc(4)
Pwm1b = 1023
Loop Until Sensor_lichtschranke < 800
Pwm1b = 0
End Sub
Sub Lenkung_von_links_zur_mitte()
'Programm zur Drehung des Lenkmotors von links zur Mitte
Local Sensor_lichtschranke As Word
Portc.6 = 1 'bestimmt Richtung 0,1 Gegen Uhrzeiger (Rechtsdrehung)
Portc.7 = 0
Portd.4 = 1
Do
Sensor_lichtschranke = Getadc(4)
Pwm1b = 1023
Loop Until Sensor_lichtschranke < 800
Pwm1b = 0
End Sub
'Timer
Timer_irq:
Timer1 = Timervorgabe
'Hier könnte nun ihre beliebige IRQ-Routine stehen
'Dabei sollte man darauf achten das diese nicht mehr Zeit
'benötigt, als das Intervall zuläßt
Dim Links As Word
Dim Rechts As Word
Dim Ifr As Word
Links = Getadc(2)
Rechts = Getadc(3)
If Links >= 700 And Rechts >= 700 Then
'Außerhalb Der Spur
Portd.5 = 0
Pwm1a = 0
Else
Portd.5 = 1
Pwm1a = 1023
End If
'Infrarotsensor Abfrage
Ifr = Getadc(0)
Ifr = Ifr / 4
If Ifr >= 128 Then
Portd.5 = 0
Pwm1a = 0
Else
Portd.5 = 1
Pwm1a = 1023
End If
Return
Unser FTS-Projekt (https://www.roboternetz.de/community/showthread.php?52910-Projekt-fahrerloses-Transportsystem&p=509913#post509913)nähert sich langsam dem Ende.
Die induktive Spurführung klappt fast immer, also der Lenkmotor lenkt wenn er soll und auch wieder zurück. Manchmal gibt es aber ein paar Probleme. Mein betreuender Prof meinte ich soll da nen digitalen Tiefpassfilter programmieren... Ähm genau... Mal gucken ob wir das auch anders lösen können.
Aber irgendwie haut das mit dem Timer nicht so hin. Der Timer1 sollte eigentlich 10 Mal pro Sekunde den Interrupt aufrufen und zum einen überprüfen, ob die beiden induktiven Sensoren sich noch auf der Spur befinden und dann ggf. den Antriebsmotor stoppen wenn sich das FTS außerhalb der Spur befindet. Um zum anderen soll der Infrarotsensor vor dem Fahrzeug abgefragt werden ob sich ein Hindernis in einem bestimmten Abstand vor dem Fahrzeug befindet und den Antriebsmotor anhalten.
Aber als ich heute das Programm aufgespielt hatte, ging irgendwie gar nichts mehr. Weder die Taste 1 um das Programm zu starten noch der Resetknopf. Und das kam mir schon ziemlich seltsam vor. Hab es dann nochmal ein paar Mal kompiliert und aufgespielt, aber immer das gleiche Problem. Die alte Version ohne Timer ging ohne Probleme.
Man könnte das sicher auch ohne Timer machen und jeweils ne Funktion schreiben und diese vor jeder Schleife oder auch dazwischen aufrufen. Aber mit Interrupt wäre das ganze natürlich eleganter ;)
Wo könnte das Problem liegen? Die Werte für den Timer hab ich mir von dem Roboternetz Berechnungstool ausgeben lassen. Der Code für den Timer steht einmal ganz am Anfang und ganz am Ende. Der Rest ist im Prinzip nicht soo interessant da das ja halbwegs läuft.
Vielen Dank schon mal!
'Hier wird der Timer und der Teiler festgelegt
Config Timer1 = Timer , Prescale = 64
'Hier wird das Unterprogramm festgelegt, das
'in dem von ihnen eingestellten Intervall aufgerufen wird
On Timer1 Timer_irq
'Diese Vorgabe wurde berechnet um die genaue Intervallfrequenz zu erreichen
'10 Interrupts pro Sekunde
Const Timervorgabe = 40536
'Hier werden die Timer aktiviert
Enable Timer1
Enable Interrupts
Declare Sub Fahrt()
Declare Sub Kalibrierung()
Declare Sub Lenkung_von_rechts_zur_mitte()
Declare Sub Lenkung_von_links_zur_mitte()
Declare Function Tastenabfrage() As Byte
$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
Dim I As Integer
Dim N As Integer
Dim Ton As Integer
$crystal = 16000000 'Quarzfrequenz
$baud = 9600
Config Adc = Single , Prescaler = Auto 'Für Tastenabfrage und Spannungsmessung
Config Pina.7 = Input 'Für Tastenabfrage
Porta.7 = 1 'Pullup Widerstand ein
Const Ref = 5 / 1023 'Für Batteriespannungsberechnung
Dim Taste As Byte
Dim Volt As Single
' Für Motorentest
'Ports für linken Motor
Config Pinc.6 = Output 'Linker Motor Kanal 1
Config Pinc.7 = Output 'Linker Motor Kanal 2
Config Pind.4 = Output 'Linker Motor PWM
'Ports für rechten Motor
Config Pinb.0 = Output 'Rechter Motor Kanal 1
Config Pinb.1 = Output 'Rechter Motor Kanal 2
Config Pind.5 = Output 'Rechter Motor PWM
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down
Pwm1a = 0
Pwm1b = 0
Tccr1b = Tccr1b Or &H02 'Prescaler = 8
I = 0
Sound Portd.7 , 400 , 450 'BEEP
Sound Portd.7 , 400 , 800 'BEEP
Sound Portd.7 , 400 , 450 'BEEP
Print "**** RN-CONTROL 1.4 *****"
Print "Das neue Experimentier- und Roboterboard"
Print "Weitere passende Zusatzboards bei www.robotikhardware.de"
Do
Taste = Tastenabfrage()
If Taste <> 0 Then
Select Case Taste
Case 1
Call Fahrt
End Select
Sound Portd.7 , 400 , 500 'BEEP
End If
Waitms 100
Loop
End
'Diese Unterfunktion fragt die Tastatur am analogen Port ab
Function Tastenabfrage() As Byte
Local Ws As Word
Tastenabfrage = 0
Ton = 600
Start Adc
Ws = Getadc(7)
' Print "Tastenabfrage anpassen!ADC Wert ws=" ; Ws
If Ws < 500 Then
Select Case Ws
Case 400 To 450
Tastenabfrage = 1
Ton = 550
Case 330 To 380
Tastenabfrage = 2
Ton = 500
Case 260 To 305
Tastenabfrage = 3
Ton = 450
Case 180 To 220
Tastenabfrage = 4
Ton = 400
Case 90 To 130
Tastenabfrage = 5
Ton = 350
End Select
Sound Portd.7 , 400 , Ton 'BEEP
End If
End Function
Sub Fahrt()
'Testprogramm zur induktiven Spurführung
Config Porta = Input
Local Links As Word
Local Rechts As Word
Local Sensor_lichtschranke As Word
Start Adc
'Lenkungskalibrierung
Call Kalibrierung
'Lenkungskalibrierung Ende
Portb.0 = 0 'Antrieb ein
Portb.1 = 1
Portd.5 = 1
Pwm1a = 1023
Do
Links = Getadc(2)
Rechts = Getadc(3)
If Links < 700 And Rechts >= 700 Then
'"rechts neben der Spur"
Do
Links = Getadc(2)
Rechts = Getadc(3)
Portc.6 = 1 'bestimmt Richtung 0,1 Gegen Uhrzeiger (Rechtsdrehung)
Portc.7 = 0
Portd.4 = 1
Pwm1b = 1023
Loop Until Links < 700 And Rechts < 700
'Mitte
Pwm1b = 0
'Drehung von rechts zur Mitte
Call Lenkung_von_rechts_zur_mitte
'***************************
Links = Getadc(2)
Rechts = Getadc(3)
Elseif Links >= 700 And Rechts < 700 Then
'"links neben der Spur"
Do
Links = Getadc(2)
Rechts = Getadc(3)
Portc.6 = 0 'bestimmt Richtung 0,1 Gegen Uhrzeiger (Rechtsdrehung)
Portc.7 = 1
Portd.4 = 1
Pwm1b = 1023
Loop Until Links < 700 And Rechts < 700
'Mitte
Pwm1b = 0
'Drehung von links zur Mitte
Call Lenkung_von_links_zur_mitte
End If
Loop
End Sub
Sub Kalibrierung()
'Programm zur Kalibrierung der Lenkung in Mittelstellung
Local Sensor_lichtschranke As Word
Portc.6 = 1 'bestimmt Richtung 0,1 Gegen Uhrzeiger (Rechtsdrehung)
Portc.7 = 0
Portd.4 = 1
Wait 3
Pwm1b = 0
Portc.6 = 0 'bestimmt Richtung 0,1 Gegen Uhrzeiger (Rechtsdrehung)
Portc.7 = 1
Portd.4 = 1
Do
Sensor_lichtschranke = Getadc(4)
Pwm1b = 1023
Loop Until Sensor_lichtschranke < 800
Pwm1b = 0
End Sub
Sub Lenkung_von_rechts_zur_mitte()
'Programm zur Drehung des Lenkmotors von rechts zur Mitte
Local Sensor_lichtschranke As Word
Portc.6 = 0 'bestimmt Richtung 0,1 Gegen Uhrzeiger (Rechtsdrehung)
Portc.7 = 1
Portd.4 = 1
Do
Sensor_lichtschranke = Getadc(4)
Pwm1b = 1023
Loop Until Sensor_lichtschranke < 800
Pwm1b = 0
End Sub
Sub Lenkung_von_links_zur_mitte()
'Programm zur Drehung des Lenkmotors von links zur Mitte
Local Sensor_lichtschranke As Word
Portc.6 = 1 'bestimmt Richtung 0,1 Gegen Uhrzeiger (Rechtsdrehung)
Portc.7 = 0
Portd.4 = 1
Do
Sensor_lichtschranke = Getadc(4)
Pwm1b = 1023
Loop Until Sensor_lichtschranke < 800
Pwm1b = 0
End Sub
'Timer
Timer_irq:
Timer1 = Timervorgabe
'Hier könnte nun ihre beliebige IRQ-Routine stehen
'Dabei sollte man darauf achten das diese nicht mehr Zeit
'benötigt, als das Intervall zuläßt
Dim Links As Word
Dim Rechts As Word
Dim Ifr As Word
Links = Getadc(2)
Rechts = Getadc(3)
If Links >= 700 And Rechts >= 700 Then
'Außerhalb Der Spur
Portd.5 = 0
Pwm1a = 0
Else
Portd.5 = 1
Pwm1a = 1023
End If
'Infrarotsensor Abfrage
Ifr = Getadc(0)
Ifr = Ifr / 4
If Ifr >= 128 Then
Portd.5 = 0
Pwm1a = 0
Else
Portd.5 = 1
Pwm1a = 1023
End If
Return