PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RC5 und Servos



recycle
26.04.2004, 02:44
Da ich noch keine Sensoren habe, möchte ich mein Chassis zum Test erst mal ein bischen mit der Fernbedienung durch die Gegend scheuchen.

Ich habe zuerst ein kleines Programm zur Auswertung der RC5 Signale der Fernbedienung zusammenkopiert, das funktioniert auch.

Dann habe ich das Beispielprogramm zur Servo-Ansteuerung das bei Bascom dabei ist etwas angepasst, das funktionierte auch.

Dann habe ich versucht beides zu kombinieren, das klappt aber nicht.

Ich bekomme ständig dieselbe Fehlermeldung, das blöde ist nur, dass die Zeile mit dem fehlerhaften Code immer hinter meinem Programmende liegt und mir die Fehlermeldung gar nichts sagt.

Die Fehlermeldungen lauten:

Error : 60 Line : 204 Duplicate label [_SYSTEM_T0_ISR ] , in File : C:\PROGRAMME\BASCOM-AVR\MYPROJECTS\MINIBOT2.BAS
Error : 60 Line : 204 Duplicate label [_SYSTEM_T0_ISR_EXIT ] , in File : C:\PROGRAMME\BASCOM-AVR\MYPROJECTS\MINIBOT2.BAS
Error : 221 Line : 204 Backward jump out of range [_SYSTEM_T0_ISR_EXIT [ 275]] , in File : C:\PROGRAMME\BASCOM-AVR\MYPROJECTS\MINIBOT2.BAS

Kann es sein, dass Bascom das angeblich doppelte Label selber verursacht, weil intern in den Routine für RC5 Auswertung und für die Servos jeweils ein Label mit demselben Namen verwendet wird?

Oder reservieren sich vielleicht beide Routinen denselben Timer oder irgendeine andere Resource?

Wenn ich entweder alles was mit Servos oder alles was mit RC5 zutun hat rauschmeisse sind die Fehlermeldungen weg.

Vielleicht kann ja mal jemand einen kurzen Blick auf den Code werfen, ob er den Fehler entdeckt.
Ist zwar relativ lang, sind aber nur ein paar relevante Zeilen, der Rest sind Konstanten und ein paar ganz simple Routinen.



'Servo's need a pulse in order to operate
'with the config statement CONFIG SERVOS we can specify how many servo's we
'will use and which port pins are used
'A maximum of 16 servos might be used
'The SERVO statements use one byte for an interrupt counter and the TIMER0
'This means that you can not use TIMER0 anymore
'The reload value specifies the interval of the timer in uS
'Config Servos = 2 , Servo1 = Portb.0 , Servo2 = Portb.1 , Reload = 10


'$lib "mcsbyte.lbx"

$crystal = 4000000
$baud = 9600

'we must configure the port pins used to act as output
Config Portd = Output

' PinD.2 als Eingang RC5-Fernbedienung
Config Pind.2 = Input
Config Rc5 = Pind.2

'we use 2 servos with 10 uS resolution(steps)
Config Servos = 2 , Servo1 = Portd.5 , Servo2 = Portd.4 , Reload = 10




'finally we must turn on the global interrupt
'Enable Interrupts

Print "################################################## #####################"
Print "Programmstart:"

'Konstanten für Tastenbelegung Fernbedienung
Const T_ahead1 = 2
Const T_ahead2 = 130
Const T_back1 = 8
Const T_back2 = 136
Const T_left1 = 4
Const T_left2 = 132
Const T_right1 = 6
Const T_right2 = 134
Const T_rotleft1 = 1
Const T_rotleft2 = 129
Const T_rotright1 = 3
Const T_rotright2 = 131
Const T_stop1 = 5
Const T_stop2 = 133
Const T_speedlow1 = 0
Const T_speedlow2 = 128
Const T_slower1 = 7
Const T_slower2 = 135
Const T_faster1 = 9
Const T_faster2 = 137
Const T_off1 = 45
Const T_off2 = 173


' Konstanten für Servo Ansteuerung
'links Stillstand = 56 portd.5
'rechts Stillstand = 59 Portd.4

Const Loff = 56
Const Lfor = 100
Const Lback = 0
Const Roff = 59
Const Rfor = 0
Const Rback = 100

Dim Adress As Byte , Command As Byte


Gosub _init
Wait 1
Gosub _init
Print "Programmstart:"

'################################################# ##############################

Do

Getrc5(adress , Command)

Waitms 50
Print Command


'Stop
If Command = T_stop1 Then
Print "Stop"

Elseif Command = T_stop2 Then
Print "Stop"


'Vor
Elseif Command = T_ahead1 Then
Print "Vor"
Elseif Command = T_ahead2 Then
Print "Vor"


'zurück
Elseif Command = T_back1 Then
Print "Zurück"
Elseif Command = T_back2 Then
Print "Zurück"


'links
Elseif Command = T_left1 Then
Print "Links"
Elseif Command = T_left2 Then
Print "Links"
' Gosub F_lmotoff


'rechts
Elseif Command = T_right1 Then
Print "Rechts"
Elseif Command = T_right2 Then
Print "Rechts"


'rotate links
Elseif Command = T_rotleft1 Then
Print "Rotate Links"
Elseif Command = T_rotleft2 Then
Print "Rotate Links"


'rotate rechts
Elseif Command = T_rotright1 Then
Print "Rotate Rechts"
Elseif Command = T_rotright2 Then
Print "Rotate Rechts"

End If

Waitms 50

Loop


'################################################# ##############################
_init:
Gosub _off
Return


_off:
Servo(1) = Loff
Servo(2) = Roff
Print "Motoren stopp"
Return

_for:
Servo(1) = Lfor
Servo(2) = Rfor
Print "fahre vorwaerts"
Return

_left:
Servo(1) = Loff
Servo(2) = Rfor
Print "fahre links"
Return

_right:
Servo(1) = Lfor
Servo(2) = Roff
Print "fahre rechts"
Return

_back:
Servo(1) = Lback
Servo(2) = Rback
Print "fahre rueckwaerts"
Return

_rotleft:
Servo(1) = Lfor
Servo(2) = Rback
Print "rotiere links"
Return

_rotright:
Servo(1) = Lback
Servo(2) = Rfor
Print "rotiere rechts"
Return


Ende:
'Do
Print "Programmende"
'Loop
End

recycle
26.04.2004, 04:04
Ich glaube ich habe die Ursache für den Fehler gefunden. Bei Bascom ist auch ein Demo für RC5 dabei. In den Kommentaren steht, dass die RC5 Routine Timer0 und den Interrupt von Timer0 verwendet. Im Beispiel für die Servos steht ungefähr dasselbe.

Hat jemand eine Idee, wie man das irgendwie umgehen kann? Die internen Routinen von Bascom kann man ja vermutlich nicht ändern, oder liegen die irgendwo in editierbarer Form rum?

13.05.2004, 12:21
Ich glaube das wird man nicht umgehen können. Ich würde für Servos dann selbst Routinen basteln. Oder hast du eine Lösung gefunden?

Gottfreak
13.05.2004, 13:02
Ich hab' noch'n Programm zum Erzeugen von Servopulsen in Bascom, das Timer1 benutzt. Musst du eventuell'n bisschen anpassen (an deine Taktfrequenz und so).


$regfile = "2313def.dat" 'AT90S2313
$crystal = 8000000

Config Timer1 = Timer , Prescale = 8

'Konstanten
Const S1offset = 1024
Const S2offset = 1024

'Variablen
Dim S1pos As Byte : Dim S1zeit As Word 'Servo S1 hängt an PB1
Dim S2pos As Byte : Dim S2zeit As Word

'Timer
Start Timer1
S1pos = 127 : S2pos = 127 'alle Servos in Neutralstellung

Ddrb = &H0F 'Die ersten 4 Pins von PortB auf Ausgang
Portb = &H00 'erstmal alles auf low

S1zeit = 6 * S1pos : S1zeit = S1zeit + S1offset
S2zeit = 6 * S2pos : S2zeit = S2zeit + S2offset
Timer1 = 0 : Count = 0
Do 'Servos stellen
If Timer1 > 20000 Then
Portb.1 = 0 : Portb.2 = 0
S1zeit = 6 * S1pos : S1zeit = S1zeit + S1offset
S2zeit = 6 * S2pos : S2zeit = S2zeit + S2offset
Timer1 = 0
End If
If Timer1 > S1zeit Then Portb.1 = 1
If Timer1 > S2zeit Then Portb.2 = 1
Loop
End

recycle
27.05.2004, 03:51
Hallo Gottfreak,
Danke für den Code. Habe meinen eigenen Thread mal wieder aus den Augen verloren und deine Antwort erst jetzt entdeckt.

Momentan liegen Fahrgestell, Servos und Platine einzeln hier rum. Aber sobald ich etwas Zeit habe, setze ich alles wieder zusammen und probiere deinen Code mal aus.
Wäre ja schon klasse, wenn ich Servos und TSOP gleichzeitig ans rennen bekomme.

Frank
27.05.2004, 08:55
Das Problem ist nur, das der Code nahezu die gesamte Rechenzeit des 2313 benutzt. Theoretisch würde zwar der Tsop nebenher funktionieren, aber leider hat der Controller kaum noch Zeit für den TSOP.
Das ist schon fast eine menschlich Eigenschaft die Du da umgesetzt hast ;-)
Es ist nicht einfach mit dem 2313 mehrere Servos zu steuern und nochwas nebenbei zu machen!

Gruß Frank

Gottfreak
27.05.2004, 09:30
Das Problem ist nur, das der Code nahezu die gesamte Rechenzeit des 2313 benutzt. Theoretisch würde zwar der Tsop nebenher funktionieren, aber leider hat der Controller kaum noch Zeit für den TSOP.

Wenn des TSOP-Code den Timer0 und dessen Interrupt benutzt (das war, meine ich Recycles Problem oben), funktioniert schon noch bieliebig viel nebenher. Die Servoimpulse werden lediglich irgendwann ungenau, wenn der Interrupt zu lange für die Ausführung braucht.

Frank
27.05.2004, 10:07
Hi
Leider werden die Servo Signale auch bei sehr kurzen Interrupt-Routinen schon sehr ungenau. Viel ist wirklich nicht mehr nebenher machbar, ich hab das mal ausprobiert.
Oder hast Du ein Beispiel wo nach irgendwas sinnvolles nebenher läuft?

Gottfreak
27.05.2004, 15:03
Hab' ich mit dem Code von oben nicht ausprobiert(Interrupts in Bascom dauern, glaub ich, auch schon einige Dutzend Zyklen, wenn man nix 'reinschreibt.). Da der ganze Stellbereich des Servo in 1ms liegt, machen 80 Takte da schon 1% aus. Ich kann mir vorstellen, dass die dann 'rumzucken.
Ich teste aber grade 'ne Variante, in der ein 2313 neben dem Erzeugen von Servosignalen auch noch welche von 'nem Fernsteuer-Empfänger auswertet (ist aber nicht in Bascom sondern ASM geschrieben). Das scheint das Servo nicht groß zu stören (die Interrupt-Routine ist auch nur 7-15 Takte lang, 4 davon allein für reti).
PS: Weis jemand, wieviele Takte das Auslösen eines Interrupt beim AVR dauert, die der CPU blockiert ist, bevor der in der Routine ankommt?

27.05.2004, 15:15
Hallo

Datenblatt Seite 25

MFG

Gottfreak
27.05.2004, 16:15
Jau danke(es kommen also noch 4 dazu). Steht genau da, wo es logischerweise hingehört und beim Überfliegen hab' ich's trotzdem übersehn.

recycle
27.05.2004, 18:30
Leider werden die Servo Signale auch bei sehr kurzen Interrupt-Routinen schon sehr ungenau.

Ich glaube, dass ist für mich gar nicht mal so wirklich relevant. Mir gehts um gehackte Servos die zum Antrieb dienen. Genaue Positionen ansteuern muss ich also gar nicht, wenn die Signale noch genau genug sind um die Drehrichtung zu bestimmen reicht mir das fast schon.

Besonders elegant bewegt sich der Robby sowieso nicht, da ich die Räder selber ausgesägt habe. Vielleicht habe ich ja Glück und das Ruckeln der ungenauen Servosignale kompensiert das eiern der Räder ;-)



Es ist nicht einfach mit dem 2313 mehrere Servos zu steuern und nochwas nebenbei zu machen!

Wirklich viel wird der Robby auch niemals machen können. Ich habe ihn extra nur zum Testen und Experimentieren aus ein bischen Kunststoffplatte, 2 Servos und einer Lochplatine zusammengeschustert.
Ich wollte was haben, bei dem mir nicht gleich die Tränen kommen, falls er sich in Rauch auflöst ;-)
Deshalb auch nur der kleine Controller. Das Ding aufwendig mit teuren Sensoren auszustatten damit er sich alleine zurechtfindet, macht wenig Sinn.
Den TSOP möchte ich anschliessen, damit ich ihm überhaupt einen Input geben kann und damit ich nicht immer aufstehen muss um ihn von der Wand wegzuholen.

Da es mir nicht um die ideale Steuerung geht, sondern darum selber herumzuexperimentieren, kann ich mit dem Programm von Gottfried auf jeden Fall viel mehr anfangen als mit der internen Bascom Routine für Servos.

recycle
28.05.2004, 02:56
Leider werden die Servo Signale auch bei sehr kurzen Interrupt-Routinen schon sehr ungenau. Viel ist wirklich nicht mehr nebenher machbar, ich hab das mal ausprobiert.


Bei wieviel MHz hast du das denn ausprobiert? Falls das bei dir mit 10 MHz noch ungenau wird, brauche ich mit meinem 4 MHz Quarz vermutlich gar nicht erst anfangen und tausche ihn besser auch erst gegen einen 10er aus.