PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Programm interruptgesteuert gestalten



daiyama
01.02.2005, 22:08
Hi
mein Robbi macht seine erste Fahrt durchs Wohnzimmer. Er ist mit dem RNBFRA1.2, 2 Getriebemotoren und einem Sharp Entfernungssensor ausgestattet, der durch ein Servo auf 11 verschiedene Positionen zur Messung gebracht wird. Also so eine Art Radar. Momentan fährt er einfach geradeaus und weicht bei einem Hindernis nach rechts aus. Mein Problem ist jetzt, das alles sequentiell abläuft, also die nächste Servoposition zur nächsten Entfernungsmessung erst gemacht wird, nachdem er mit dem Ausweichen fertig ist. Ich würde das Programm also gerne "parallelisieren". Kann mir jemand weiterhelfen? An welcher Stelle müsste man eine Interruptsteuerung einbauen?

Über etwas Hilfe würde ich mich sehr freuen 8-[

Gruß
daiyama



$regfile = "m32def.dat"

Const Posdelta = 25 '11 Schritte von 0° - 180°


Declare Sub Rnb_servob(byval Servonummer As Byte , Byval Position As Byte)
Declare Sub Scandistance
Declare Sub Nextscanpos
Declare Sub Initscanpos
Declare Sub Forward
Declare Sub Backward
Declare Sub Leftdir
Declare Sub Rightdir
Declare Sub Halt

Dim I As Word
Dim Arraywert As Byte
Dim Scanpos As Byte 'aktuelle Messposition
Dim Scandir As Bit 'Rechts herum = 1, Links herum = 0
Dim Scanpositions(11) As Byte 'Array mit Winkelpositionen

Dim Port As Byte
Dim Distance As Single 'Gemessene Entfernung
Dim Delta As Single 'Korrekturwert
Dim Adcoutput As Integer 'Ausgabewert des Sensors
Dim Vleft As Word 'V linker Motor
Dim Vright As Word 'V rechter Motor

Const B = 16.025 'Offset der Kurve GP2D12
Const A = 5233.5 'Steigung der Kurve GP2D12
Const Emin = 500
Const Emax = 80
Const Gmax = 400 'Max Geschwindigkeit für Geradeausfahrt
Const Kmax = 200 'Max Geschwindigkeit für Kurvenfahrt

$crystal = 8000000
$baud = 9600


Config Adc = Single , Prescaler = Auto

'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 Scl = Portc.0 'Ports fuer IIC-Bus
Config Sda = Portc.1

Enable Interrupts 'Interrupts aktivieren
Enable Adc
Start Adc 'Die ADC's starten

I2cinit
I2cstart
I2cwbyte &H74 'Schreibbefehl an PCF3 schicken
' Led´s ein ,Motorendstufen ein, Port-Peripherie ein, RBN-Bus Sleep Modus aus (also Peripherie aktiv)
I2cwbyte &B00000010 'Datenbyte an PCF3
I2cstop
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down

Tccr1b = Tccr1b Or &H02 'Prescaler = 8



Call Initscanpos 'Array mit Winkelpos. füllen...
Call Forward 'Vorwärts fahren
Do
Arraywert = ScanPositions(scanpos)
Call Rnb_servob(1 , Arraywert) 'Sensor-Servo auf Position bringen
Call Scandistance 'Entfernung messen
If Distance < 30 Then 'Hindernis in 30 cm...
Call Halt 'anhalten
Call Backward 'ein Stück zurück...
Call Leftdir 'etwas links drehen
Call Halt 'anhalten
Call Forward 'weiter fahren...
End If
Call Nextscanpos 'nächste Servopos.
Waitms 100
Loop



Sub Forward
Vleft = 0
Vright = 0
'Linker Motor ein
Portc.6 = 0 'bestimmt Richtung linker Motor
Portc.7 = 1 'bestimmt Richtung linker Motor
Portd.4 = 1 'Linker Motor EIN
'Rechter Motor ein
Portb.0 = 1 'bestimmt Richtung rechter Motor
Portb.1 = 0 'bestimmt Richtung rechter Motor
Portd.5 = 1 'rechter Motor EIN

I = 0 'Langsam anfahren...
Do
Vleft = I
Vright = I
Pwm1a = Vright
Pwm1b = Vleft
Waitms 50
I = I + 5
Loop Until I > Gmax
End Sub


Sub Backward
Vleft = 0
Vright = 0
'Linker Motor ein
Portc.6 = 1 'bestimmt Richtung linker Motor
Portc.7 = 0 'bestimmt Richtung linker Motor
Portd.4 = 1 'Linker Motor EIN
'Rechter Motor ein
Portb.0 = 0 'bestimmt Richtung rechter Motor
Portb.1 = 1 'bestimmt Richtung rechter Motor
Portd.5 = 1 'rechter Motor EIN

I = 0 'Langsam anfahren...
Do
Vleft = I
Vright = I
Pwm1a = Vright
Pwm1b = Vleft
Waitms 50
I = I + 10
Loop Until I > Gmax
End Sub


Sub Leftdir
Vleft = 0
Vright = 0
'Linker Motor ein
Portc.6 = 0 'bestimmt Richtung linker Motor
Portc.7 = 1 'bestimmt Richtung linker Motor
Portd.4 = 1 'Linker Motor EIN
'Rechter Motor ein
Portb.0 = 0 'bestimmt Richtung rechter Motor
Portb.1 = 1 'bestimmt Richtung rechter Motor
Portd.5 = 1 'rechter Motor EIN

I = 0 'Langsam anfahren...
Do
Vleft = I
Vright = I
Pwm1a = Vright
Pwm1b = Vleft
Waitms 50
I = I + 10
Loop Until I > Kmax
End Sub


Sub Rightdir
Vleft = 0
Vright = 0
'Linker Motor ein
Portc.6 = 1 'bestimmt Richtung linker Motor
Portc.7 = 0 'bestimmt Richtung linker Motor
Portd.4 = 1 'Linker Motor EIN
'Rechter Motor ein
Portb.0 = 1 'bestimmt Richtung rechter Motor
Portb.1 = 0 'bestimmt Richtung rechter Motor
Portd.5 = 1 'rechter Motor EIN

I = 0 'Langsam anfahren...
Do
Vleft = I
Vright = I
Pwm1a = Vright
Pwm1b = Vleft
Waitms 50
I = I + 10
Loop Until I > Kmax
End Sub

Sub Halt
Pwm1a = 0 'Linker Motor aus
Pwm1b = 0 'rechter Motor aus
End Sub


Sub ScanDistance
Adcoutput = Getadc(0)
If Adcoutput > Emin Then
Adcoutput = Emin
End If
If Adcoutput < Emax Then
Adcoutput = Emax
End If
Delta = Adcoutput - B
Distance = A / Delta
Distance = Round(Distance)
End Sub


Sub Initscanpos
ScanPositions(1) = 3
For Scanpos = 2 To 11
ScanPositions(scanpos) = ScanPositions(scanpos - 1) + Posdelta
Next Scanpos
Scanpos = 1 'Position für erste Messung
ScanDir = 1 'Rechts herum

For I = 1 To 50 'Bildschirm leer machen
Print
Next I

For I = 1 To 11
Next I
End Sub


Sub Nextscanpos
If ScanDir = 1 Then 'ScanDir = 1
If Scanpos < 11 Then
Scanpos = Scanpos + 1
Else
ScanDir = 0 'ScanDir umkehren
Scanpos = Scanpos - 1
End If
Else 'ScanDir = 0
If Scanpos > 1 Then
Scanpos = Scanpos - 1
Else
ScanDir = 1 'ScanDir umkehren
Scanpos = Scanpos + 1
End If
End If
End Sub

Sub Rnb_servob(byval Servonummer As Byte , Byval Position As Byte)
Open "comd.7:9600,8,n,1" For Output As #2
Print #2 , "#s" ; Chr(servonummer) ; Chr(position)
Close #2
End Sub



End>

daiyama
02.02.2005, 12:47
Hab noch mal überlegt. Ich brauche einen Interrupt vom Sensor bzw. vom Servo und zwar jedesmal dann, wenn er eine neue Messung gemacht hat. Aber wie - muss das ein Hardwareinterrupt sein - also von einer Gabellichtschranke oä. ausgelöst?
Hat jemand einen Tip? 8-[

sebastian.heyn
02.02.2005, 15:28
Vielleicht mit nem timer?

pebisoft
02.02.2005, 17:24
hallo, der sharp dauert zulange um einen quasi parallelprozess ablaufen zu lassen. du kannst zuerst alle messungen durchführen und danach die richtung nehmen wo kein hindernis ist oder wo das hindernis am weitesten entfernt ist.
mfg pebisoft

Hellmut
02.02.2005, 17:49
Hallo daiyama

Als "alter" Apple Fan, kann ich dir wärmstens das Prinzip der Event Loop der alten Macintosh Betriebssysteme empfehlen. Ich habe dieses früher mal bei der Entwicklung eines Minitel Terminals schon mal als RTOS selbst programmiert. Das Event Loop Prinzip war damals eine Revolution verglichen mit den noch älteren "modalen" Betriebssystemen.

Die Idee ist einfach eine Programmschleife zu machen, welche die Kontrolle über die Ausführung nacheinander an Programmcode-Module übergeben die in einer Warteschlange sind. Das zuletzt ausgeführte Modul wird dann an das Ende der Warteschlange gesetzt, das Oberste startet.

Damit das funktioniert, müssen die Module so programmiert werden, das sie immer nur eine kurze Ausführungszeit erfordern.

Wie man das implementiert hängt vom System und seinen Möglichkeiten ab. Bei Apple war es Interrupt gesteuert. "Unsoziale" Module setzten den Flag der Interrupts unterbindet, was damals für böses Blut sorgte. Bei einem AVR würde ich nicht mit Interrupts arbeiten, sondern einfach bei meinem Code-Modulen regelmäßig eine Routine zum Sichern der Ablaufumgebung aufrufen und an die "Main Event Loop" abgeben.

Die Verteilung der Rechnerresourcen ist hierbei natürlich nicht deterministisch, der overhead aber überraschend gering.

Tut mir leid keinen echten Code verfügbar zu haben. Könnte zwar aus den "Inside Macintosh" Büchern war rausziehen, ist aber viel zu aufwendig realisiert und in 68k Assembler.

daiyama
02.02.2005, 19:09
Hallo
vielen Dank erst mal für Eure Antworten. Da ich bisher eigentlich nur einigermassen fit in Delphi bin brauche ich ein wenig länger, um mich an Basic zu gewöhnen muss das Programm auf jeden Fall werden. Das RNBFRA hat ja einen Drehgeber-Port, der direkt mit 2 Interruptleitungen des ATMEGA32 verbunden ist. Könnte ich da eine Gabellichtschranke direkt anschliessen. Das würde dann noch etwas Bastelarbeit an meinem Servogetriebenen "Radar" bedeuten. Aber noch einmal zur Erklärung:
Das Servo dreht den Sensor z.B. alle 0,3 sec in eine neue Position, dann kann gemessen werden Das messen dauert 40 msec. In der Zwischenzeit kann was anderes gemacht werden. Also wäre es doch sinnvoll einen Interrupt auszulösen, wenn die neue Position erreicht ist oder?
Kann man den Interrupt auch softwaregesteuert auslösen? Ich könnte das Servo ja auch durch einen kleinen Schrittmotor ersetzen.
Wie müsste das programmtechnisch aussehen?
Grüsse
daiyama

daiyama
02.02.2005, 19:13
Oops da ist was verloren gegangen. Es sollte heissen:

Hallo
vielen Dank erst mal für Eure Antworten. Da ich bisher eigentlich nur einigermassen fit in Delphi bin brauche ich ein wenig länger, um mich an Basic zu gewöhnen. <Eventgesteuert> muss das Programm auf jeden Fall werden. Das RNBFRA hat ja einen Drehgeber-Port, der direkt mit 2 Interruptleitungen des ATMEGA32 verbunden ist. Könnte ich da eine Gabellichtschranke direkt anschliessen. Das würde dann noch etwas Bastelarbeit an meinem Servogetriebenen "Radar" bedeuten. Aber noch einmal zur Erklärung:
Das Servo dreht den Sensor z.B. alle 0,3 sec in eine neue Position, dann kann gemessen werden Das messen dauert 40 msec. In der Zwischenzeit kann was anderes gemacht werden. Also wäre es doch sinnvoll einen Interrupt auszulösen, wenn die neue Position erreicht ist oder?
Kann man den Interrupt auch softwaregesteuert auslösen? Ich könnte das Servo ja auch durch einen kleinen Schrittmotor ersetzen.
Wie müsste das programmtechnisch aussehen?
Grüsse
daiyama

pebisoft
02.02.2005, 20:01
hallo, nimm einen srf04 ultra, hat eine aufnahme von 45 grad, da kannst du schon ausrechnen in welcher entfernung er das hindenis vor deinem robby erkennt.
mfg pebisoft