Teilbericht

Das Inhaltsverzeichnis steht hier.

Gamma-Knoten: Lenkwinkel SAUS: Gamma-Knoten: Lenkwinkel

Autoren:

Datum: 31.01.1996

Das Stichwortregister steht hier.

Zusammenfassung:

In diesem Dokument soll die Funktionalität des Gamma-Knotens vorgestellt werden, dessen Aufgabe das korrekte Setzen eines Lenkwinkels ist. Der Bericht gliedert sich dabei grob in die 2 Punkte: Soft- und Hardwareentwicklung.

Im ersten Teil erfolgt eine Beschreibung des Programms, der verwendeten Algorithmen sowie eine Einführung in die Funktionsweise des MC P8xC592 hinsichlich der Analog-Digital-Konvertierung und der Pulsweiten-Modulation, soweit dies für das Verständnis der Programme erforderlich ist. Anschließend sollen die notwendigen Hardwareanpassungen für die Lenkwinkelauswertung und -ansteuerung dargestellt werden.


Softwareentwicklung

Spezifikation

Die folgende, informelle Spezifikation der Aufgaben dieses Knotens soll einen Einstieg in die sich anschließende Beschreibung des Programm-Codes geben. Ferner ist die hier vorgestellte Schnittstellenbeschreibung bindend für die Kommunikation mit dem Gamma-Knoten.

Die Werte der im folgenden erwähnten Konstanten können im Kap. Konstanten nachgeschlagen werden. Weiterhin gilt, daß alle Nachrichten, die von oder zu dem Gamma-Knoten gesendet werden, den Identifier GAMMA_ID tragen müssen.

Aufgaben des Gamma-Knotens:

Vorbemerkung zur Source-Code-Beschreibung

Das auf dem MC verfügbare MICRO/C-51 ("Kernighan & Ritchie C") läßt eine Definition eigener Datentypen oder die Einschränkung von Wertebereichen vorhandener Datentypen nicht zu. Aus diesem Grund mußten z.B. Boolsche-Variablen, wie newangle, als char deklariert werden. Zum besseren Verständnis wurden jedoch die einzelnen, bedeutsamen Werte derartiger Variablen als Konstanten definiert. Überdies sind alle anderen als char definierten Variablen in diesem Programm als "Byte"-Werte zu interpretieren.

Import-Anweisungen

In mccan.h sind Prozeduren zum Senden und Empfangen von Nachrichten über den CAN-Bus vereinigt. Dieses Programm benötigt aus mccan.h: CANPutBuffer, CANTrRequest, CANRecBuffer, CANGetBuffer, CANReleaseBuffer, initCAN. Auf diese Prozeduren wird im folgenden nur oberflächlich eingegangen. Eine genaue Beschreibung liefert die Dokumentation zum "mccan.h"-Modul.

#include "mccan.h"

Konstanten

Zur übersichtlichen und flexiblen Handhabung des Programms folgt nun die Definition einiger Konstanten. Die zugewiesenen Werte ergeben sich aus ...

Somit können Änderungen, beispielsweise an den Hardware-Anschlüssen, durch Anpassung der entsprechenden Konstanten unproblematisch durchgeführt werden. /* default time-base (1599 = 3/10 sec.) */ #define DEFAULT 1599 /* it takes 250 cycles until timer-overflow */ #define PERIOD 5 /* gamma-message-id */ #define GAMMA_ID 48 /* sub-id interpretation */ #define ANGLE_SET 5 #define STR_ANGLE 7 /* port-pin (port 5) of the analog steering angle input */ #define ANGLEPIN 7 /* port-pins (digital port 4) of steering direction switches: the output is used to indicate on which side the intended steering angle lies. (pin 2 = 2^2 and pin 3 = 2^3) */ #define STR_LEFT 4 #define STR_RIGHT 8 /* ADC-values, if steering wheels are max. left or centered (max. right=255) */ #define ADCLEFT 57 #define ADCCENTER 186 /* degree-value that centers the wheels */ #define DEGREECENTER 140 /* adaptation factor means at what speed the steering angle changes: the less the quicker, but at too low values oversteering is possible. */ #define ADAP_FAC 6 /* adaptation difference controls the exactness of the steering angle: the less the more exact the result is. */ #define ADAP_DIFF 7 /* boolean */ #define FALSE 0 #define TRUE 1

Globale Variablen

Da dem Timer-Interrupt keine Variablen übergeben werden können, ist es notwendig Variablen, die sowohl im Hauptprogramm als auch in der Interrupt-Routine benötigt werden, global zu definieren. Beispiele derartiger Variablen sind : angle, newangle ... . Überdies mußten Variablen, deren Werte bis zum nächsten Interruptaufruf erhalten bleiben sollten (static), global deklariert werden (sec und degree).

/* interrupt-counter */ int sec; /* CAN-bus-datas */ char datas[2]; /* flag : newangle=FALSE -> no change newangle=TRUE -> set a new steering angle and broadcast on success */ char newangle; /* intended steering angle */ int angle; /* steering angle that is written to PWM (the effective power output) */ int degree;

Timer Interrupt

Eine exakte Beschreibung der Funktionsweise des Timer-0-Interrupts (= Interrupt 1) ist in der Dokumentation zum Beta-Knoten (wizab96 ) enthalten. Hier sei nur soviel erwähnt, daß bei jedem Überlauf des TL0-Registers ein Timer-Interrupt ausgelöst wird.

Die Verwendung des Timer-Interrupts für das Setzen des Lenkwinkels dient dazu, die Anpassung an einen neu angeforderten Lenkwinkel in geregelten Korrekturschritten zu vollziehen. Hierbei ist es entscheidend, daß zum einen die Ermittlung und der Vollzug der notwendigen Änderung bei jedem Schritt nicht zu schnell erfolgt, damit die Änderung der Radstellung, die beim vorherigen Schritt ermittelt wurde, erst ausgeführt werden kann. Andererseits ist aber auch eine zügige Anpassung an den geforderten Lenkwinkel wünschenswert.

/* function : timer0() interrupt 1 description : timer-interrupt to set the steering angle last change : 25.01.96 */ timer0() interrupt 1 using 1 { Es folgt die Deklaration der lokalen Variablen. Darüberhinaus werden mit EA=0 sämtliche Interrupts ausgeschaltet, damit ausgeschlossen ist, daß der Interrupt wieder durch einen Interrupt unterbrochen wird. /* actual steering angle measurement */ int adcresult; /* difference between actual steering angle measurement and intended steering angle */ int diff; /* disable interrupts */ EA=0; Die eventuell notwendige Nachregelung des Lenkwinkels soll jede 3/10 Sekunde erfolgen, so daß nur wenn der Interrupt-Counter für den Lenkwinkel sec größer DEFAULT ist, der nachfolgende Algorithmus abgearbeitet wird. In diesem Fall ist auch sec wieder mit Null zu initialisieren, um die Zeit bis zur nächsten Nachregelung abzumessen. /* interrupt-counting: check steering angle every "DEFAULT" sec. */ if (sec++>DEFAULT){ /* reset interrupt-counter */ sec = 0;

Analog-Digital-Wandlung

Das ADCON-Register steuert die Analog-Digital-Wandlung . Diese wird benötigt, um das analoge Lenkwinkelsignal, das von der werkseitig vorgesehenen Lenkwinkelsteuerung des Rollstuhls abgegriffen wird und den tatsächlichen Einschlag der beiden Räder repräsentiert, in ein digitales Signal zu konvertieren. Der Aufbau des ADCON-Registers geht aus der Tabelle ADCON hervor (exakte Beschreibung: ).

BIT76543210
SYMBOLADC.1ADC.0ADEXADCIADCSAADR2AADR1AADR0

Aufbau des ADCON-Registers
AADR2 .. AADR0
Die Bits 0 bis 2 bestimmen den Input-Port-Pin, an dem das analoge Signal angelegt wird. Am Port 5 stehen 8 Pins zur Verfügung, von denen einer über binär Kodierung angesprochen werden kann: 000 -> Pin 0; 001 -> Pin 1; 010 -> Pin 2 ...

ADEX
ADEX legt fest, ob der Start der AD-Konvertierung extern (= "getriggert" = 1) oder per Software (= 0) gestartet werden soll.

Diese und die Festlegung des Input-Pins müssen nur einmal beim Programmstart definiert werden. Deshalb werden diese Einstellungen im Rahmen der sogenannten Register-Initialisierung (Kap. Register-Initialisierung) des Hauptprogramms vorgenommen.

ADCI
Das ADC-Interrupt-Flag wird gesetzt, wenn die AD-Wandlung beendet ist und muß per Software zurückgesetzt werden.

ADCS
ADC-Start und -Status: Das Setzen dieses Bits führt zum Start der Konvertierung. Solange die AD-Wandlung andauert (etwa 50 Maschinenzyklen) bleibt das Bit gesetzt. ADCS wird auf Null zurückgesetzt, sobald die Konvertierung beendet und ADCI gesetzt ist.

ADC.1 und ADC.0
Die AD-Konvertierung hat ein Auflösung von 10 Bits. Das Resultat der Umwandlung wird in das Register ADCH (hohen 8 Bits) und die 2 niederen Bits in ADC.1 und ADC.0 geschrieben.
Im Programm stellt sich die AD-Wandlung so dar:

Mit ADCON = ADCON & 239 wird das ADC-Interrupt-Flag (ADCI) zunächst zurückgesetzt, damit es später die Beendigung der Konventierung signalisieren kann. Anschließend wird die AD-Wandlung gestartet, indem ADCS gesetzt wird. Solange der Konvertierungsvorgang arbeitet wird aktiv auf das Ende gewartet.

/* reset the ADC interrupt flag */ ADCON = ADCON & 239; /* start ADC */ ADCON = ADCON | 8; /* wait until ADC interrupt flag is set */ while (!(ADCON & 16)) {} Das Resultat der Umwandlung steht jetzt im ADCH-Register, wobei wir die unteren 2 Bits im ADCON unberücksichtigt lassen, da die Auflösung von 8-Bit ausreichend ist. Die Darstellung des tatsächlichen Lenkwinkels im ADCH wird durch die Tabelle ADCH1 charakterisiert.

LINKSMITTERECHTS
max max
57 (ca.) .... 127,-128 .... -70 (ca.) .. .. -1

ADCH (untransformiert)
Um auf einen ausschließlich positiven und kontinuierlichen Wertebereich zu kommen, werden negative Werte mit 256 addiert. Den so transformierten Wert speichern wir in adcresult (Vgl. Tabelle ADCH2). Der offensichtlich unsymetrische und wie sich zeigte auch nichtlineare Verlauf dieses gemessenen Wertes ist maßgeblich dafür verantwortlich, daß auch die Auflösung des zu setzenden Lenkwinkels diese Eigenschaften aufweist.

LINKSMITTERECHTS
max max
57 (ca.) .... 127, 128 .... 186 (ca.) .. .. 255
ADCLEFT ADCCENTER

ADCH (transformiert) = adcresult
/* read actual sterring angle */ if (ADCH<0) adcresult = 256 + ADCH; else adcresult = ADCH;

Regelkreis

Wie bereits in der Spezifikation angesprochen, ist eine wesentliche Aufgabe des Gamma-Knotens, das Setzen eines Lenkwinkels zu ermöglichen. Mit den PWM-Ausgängen (Pulse-Width-Modulation) des Knotens kann dazu über die Lenkwinkelsteuerung des Rollstuhls der Lenkeinschlag beider Räder gesteuert werden. Diese ausschließlich über den PWM-Ausgang geregelte Lenkung wird jedoch sowohl von der Belastung und Geschwindigkeit des Rollstuhls als auch vom jeweilige Untergrund beeinflußt, d.h. die Abgabe einer bestimmtem Leistung kann in einer Situation einen maximalen und unter etwas anderen Bedingungen einen weitaus geringeren Lenkeinschlag bedeuten. Um unabhängig von den jeweiligen Rahmenbedingungen einen gewünschten Lenkwinkel exakt setzen zu können, mußte zusätzlich noch der tatsächlich anliegende Winkel mit einbezogen werden. Dieser konnte aus einem Potentiometer der Lenkwinkelsteuerung abgegriffen werden. Der tatsächliche Lenkeinschlag (Istwinkel) wird, wie zuvor beschrieben, in adcresult gespeichert und bildet eine verläßliche Interpretationsgrundlage im Hinblick auf die Ausrichtung der Lenkräder. Wird nun die Auflösung des Sollwinkels angle noch der des Istwinkels angeglichen (Vgl. Abb. angleadc im Hauptprogramm), können Soll- und Istwinkel miteinander verglichen werden, was Grundlage für eine Nachregulierung und damit für den Regelkreis ist.

Der Aufbau eines Regelkreises ist erforderlich, da keine direkte Relation zwischen Sollwinkel und der mit PWM geregelten Lenkung hergestellt werden kann, weil die Motoraktion von den bereits erwähnten äußeren und damit unbestimmbaren Einflußfaktoren (Rollstuhlbelastung, Untergrund, etc.) abhängt. Die Aufgabe des Regelkreises ist es somit, die notwendige Änderung der zu setzenden PWM schrittweise an die tatsächlich gewünschte Änderung des Lenkwinkels (diff = Sollwinkel - Istwinkel) anzunähern. Die Variable degree beinhaltet den Lenkwinkel, der schließlich an das PWM-Register übergeben wird, wobei zu beachten ist, daß die Auflösung von degree eine andere als die des Ist- bzw. Sollwinkels ist. Der Wertebereich von degree und seine Bedeutung stimmt aber dahingehend mit angle und adcresult überein, daß kleinere Werte links von größeren liegen (Vgl. Tabelle degree).

LINKSMITTERECHTS
0.. .. .. 255

Auflösung von degree
Dementsprechend ist sichergestellt, daß die Richtung der gewünschten Änderung (Vorzeichen von diff) auch mit der des degree-Werts übereinstimmt. Modifizieren wir degree um einen Bruchteil (ADAP_FAC) der geforderten Änderung (diff), verkleinert sich in jedem Fall die Abweichung des Lenkeinschlags zum Sollwinkel. Im nächsten Durchlauf wird dann über den aktuell gemessenen Sollwinkel die Auswirkung (die Motor-Aktion) der vorherigen Änderung von degree berücksichtigt. Der Fehler zwischen degree und dem Sollwinkel im Hinblick auf den Lenkeinschlag soll so über den Regelkreis minimiert werden. Der gesamte Regelkreis ist anschaulich in Abb. Regelkreis abgebildet. (Abbildung: Regelkreis zum Setzen des Lenkwinkels ) /* compute the difference between wanted and actual steering angle */ diff = angle - adcresult; /* change the steering angle according to the difference */ degree = degree + diff/ADAP_FAC;

Pulsweiten-Modulation

Die Ansteuerung des Motors für die Lenkräder erfolgt über die PWM-Ausgänge des Kontens. Die Pulsweiten-Modulation hat eine Auflösung von 8 Bit, wobei die Leistungsabgabe über das Verhältnis von Puls (High-Pegel) und Wellenlänge gesteuert wird. Es gibt insgesamt 2 PWM-Ausgänge auf dem MC. Diese werden gemeinsam gesteuert durch das PWMP-Register, das die Wiederholungsfrequenz definiert, indem es die Taktfrequenz für den PWM-Zähler festlegt. Der 8-Bit Zähler zählt modulo 255. Der Wert des Zählers wird mit den Inhalten der Register PWM0 und PWM1 verglichen. Ist ein Wert dieser Register größer als der Zähler, wird der Output des entsprechenden PWM0- oder PWM1-Ausgangs auf LOW gesetzt, anderenfalls auf HIGH. (Beschreibung: )

Da es für die Ansteuerung der Lenkräder notwendig ist, die Bereiche links und rechts von der mittleren Radstellung zu unterscheiden, muß durch Setzen bzw. Rücksetzen zweier Schalter zunächst mitgeteilt werden, ob der an die PWM-Register übergebene Wert einen linken oder rechten Lenkwinkel darstellen soll. Insofern haben wir eine Auflösung von 2 x 255 Einheiten. Diese Schalter sind 2 Pins des 4. Ports und werden im Folgenden als STR_LEFT und STR_RIGHT bezeichnet. Wird bspw. STR_LEFT auf HIGH gesetzt und STR_RIGHT auf LOW bedeutet dies, daß es sich um einen linken Lenkwinkel handeln soll.

Ein degree-Wert von kleiner DEGREECENTER bedeutet, daß die Räder von der Mittelstellung aus gesehen absolut nach links ausgerichtet werden müssen. Mit ADAP_DIFF wird lediglich eine Toleranz angegeben, da der Lenkwinkelbereich so hoch aufgelöst wird, daß sehr nah nebeneinanderliegende Werte praktisch die gleiche Radstellung bedeuten. Nachdem die Richtungsschalter entsprechend gesetzt sind, kann anschließend der degree-Wert in das PWM1-Register geschrieben werden. Dabei ist zu berücksichtigen, daß aufgrund der Funktionsweise der Pulsweiten-Modulation gilt: Je höher der Wert im PWM-Register ist, desto kürzere Impulse werden produziert, d.h. desto geringer ist der Lenkausschlag. Für den linken Lenkwinkelbereich entspricht diese Darstellung der von degree, jedoch muß der linke Wertebereich von degree (0 bis ca. DEGREECENTER) noch nach oben verschoben werden, damit auch Radstellungen nahe der Mittelstellung realisiert werden können. Mit (degree-DEGREECENTER) kann die Verschiebung vorgenommen werden, da die resultierenden negativen Werte im Register P4 wie positive behandelt werden. Beim rechten Lenkeinschlag muß der Wertebereich zusätzlich gespiegelt werden, bevor er ins PWM-Register übernommen werden kann. Ist degree etwa DEGREECENTER (Mittelstellung), können beide Richtungsschalter ausgestellt werden. Auch das Setzen eines PWM-Wertes entfällt in diesem Fall, da dies die Normalstellung des Lenkwinkelmotors darstellt.

/* left-direction: the STR_LEFT-bit from port 4 must be set to high and the STR_RIGHT-bit to low. */ if (degree < DEGREECENTER-ADAP_DIFF) { P4 = P4 & (255-STR_RIGHT); P4 = P4 | STR_LEFT; PWM1 = degree-DEGREECENTER; /* the inverse setting indicates a right steering-direction */ } else if (degree > DEGREECENTER+ADAP_DIFF) { P4 = P4 & (255-STR_LEFT); P4 = P4 | STR_RIGHT; PWM1 = DEGREECENTER-degree; /* center steering angle: both direction-switches must be set to off */ } else { P4 = P4 & (255-STR_LEFT-STR_RIGHT); }

Meldung: Lenkwinkel erreicht

Fällt die verbleibende Lenkwinkeländerung unter einem bestimmten Toleranzbereich (ADAP_DIFF) und bestand eine Anforderung einen neuen Lenkwinkel zu setzen (newangle=TRUE), dann wird das Anliegen des gewünschten Lenkwinkels gemeldet.

Am Ende der Interrupt-Routine werden die Interrupts wieder zugelassen.

/* if the correct steering angle is set, broadcast a message to the PC */ if ((diff<ADAP_DIFF) && (diff>-ADAP_DIFF) && newangle) { newangle=FALSE; CANPutBuffer(0, BETA_ID, ANGLE_SET, 0, 0); CANTrRequest(); } } /* enable interrupts */ EA=1; }

Hauptprogramm

Beginn des Hauptprogramms, das im wesentlichen für das Empfangen und Auswerten von Nachrichten zuständig ist. Dies bedarf jedoch zuvor der Deklaration einiger Variablen.

Bemerkenswert dabei ist, daß das Array data[8] im Programm nie benutzt wird, jedoch das Fehlen dieser Deklaration den Empfang von Nachrichten verhindert. Ohne das Array sind sämtliche nachfolgend definierte Variablen bei der Entgegennahme von (korrekt versendeten) Nachrichten mit der Funktion CANGetBuffer(...) stets Null, was dementsprechend eine Auswertung von Nachrichten unmöglich macht. Mit der Deklaration des Feldes tritt dieser Fehler nicht auf.

main() { /* CAN-bus-variables */ char data[8]; /* do not delete !!! even if this variable seems to be unnecessary otherwise it is not possible to receive a CAN-message */ char length; char rtr; char id; char sub; Die nachfolgende Initialisierung der Variablen und Register darf nicht von einem Interrupt unterbrochen werden, da auch für den Interrupt erst entscheidende Variablen gesetzt werden müssen. Deshalb werden alle Interrupts kurzfristig ausgeschaltet, indem im IEN0-Register das EA-Bit (Interrupt-Enable) auf Null gesetzt wird. /* disable interrupts */ EA=0;

Variablen-Initialisierung

Der Interrupt-Zähler für den Lenkwinkel wird mit Null initialisiert.

sec=0; Der Wert, der an die PWM-Register zur Steuerung Lenkwinkelmotoren gegeben werden soll (degree), wird ungefähr auf die Mittelstellung eingestellt. Eine exakte Justierung der Räder ist jedoch nicht möglich, weil die Ansteuerung der Räder von vielen Faktoren, wie z.B. Belastung des Rollstuhls, Untergrund usw., abhängt. Da aber auch der Soll-Winkel angle so initialisiert wird, daß der vorgegeben Winkel zu Beginn der Mittelstellung entspricht, wird der Rollstuhl die Lenkräder nach kurzer Zeit zur Mitte hin ausgerichtet haben.

Das newangle-Flag wird auf FALSE gesetzt, da es nur signalisieren soll, wenn eine Lenkwinkelanforderung vom PC empfangen wurde.

degree=DEGREECENTER; angle=ADCCENTER; newangle=FALSE;

Register-Initialisierung

Im Analog-Digital-Kontrollregister ADCON bestimmen die ersten 3 Bits den Port-Pin von Port 5, an welchem ein analoges Signal gemessen werden soll. Die Konstante ANGLEPIN beinhaltet den Port-Pin des Lenkwinkelsignals und wird dem ADCON-Register zugewiesen. Weiterhin muß das 5. Bit von ADCON zurückgesetzt werden, damit die Konvertierung per Software gestartet werden kann (Vgl. Kap. AD-Wandlung>).

/* set analog input selection to ANGLEPIN */ ADCON = ADCON | ANGLEPIN; /* disable external start of conversion */ ADCON = ADCON & 223; CAN-Controller-Initialisierung: Es werden die Werte für Acceptance-Mask und -Code übergeben, so daß nur die für den Gamma-Knoten relevanten Nachrichten Beachtung finden. /* initialize CAN-controller */ initCAN(0,GAMMA_ID); Durch das PWMP-Register wird die Taktfrequenz der PWM-Zähler definiert (Vgl. Kap. PWM). Da diese Einstellung nur einmal vorgegeben werden muß, erfolgt dies im Hauptprogramm. /* set PWM-repetition frequency (prescaler) */ PWMP = 255; Indem im Register TMOD das 2. Bit gesetzt wird, stellt man den Timer 0 auf den Mode 2 ein. Ferner wird der eigentliche Timer-Counter TL0 (LSB) und der "reload"-Wert TH0 mit dem anfangs definierten PERIOD-Wert (= 5) initialisiert. Das Setzten von ET0 und TR0 bewirkt, daß der Timer 0 eingeschaltet und dann gestartet wird. /* timermode is set to "auto-reload" */ TMOD = TMOD | 2; /* initialize timer-interrupt: first value and "reload"-value. The first value is increased until it overflows and then intialized with the reload-value */ TL0 = PERIOD; TH0 = PERIOD; /* enable Timer-0 and Timer-0-Run */ ET0 = 1; TR0 = 1; Vor dem Beginn der Haupt-Routine werden die Interrupts wieder eingeschaltet. /* enable interrupts */ EA=1;

Auswertung empfangener Nachrichten

Im folgenden sollen ankommende Nachrichten entgegengenommen und ausgewertet werden. Diese Aufgabe des Knotens muß stets wiederholt werden, so daß der Algorithmus in eine Endlos-Schleife eingeschlossen wird.

while (1) { Die Evaluation ankommender Nachrichten setzt voraus, daß zunächst geprüft wird, ob eine neue Nachricht vorliegt und sollte das der Fall sein, daß diese entgegengenommen wird. Mit der Prozedur CANGetBuffer wird eine Message empfangen und deren Inhalt in die angegebenen Variablen geschrieben, so werden z.B. die eigentlichen Daten in das Array datas geschrieben. Die exakte Beschreibung der aus "mccan.h" importierten Funktionen CANRecBuffer, CANGetBuffer und CANReleaseRecBuffer kann der Dokumentation zu mccan.h entnommen werden. if (CANRecBuffer()) { /* receive message */ CANGetBuffer(&rtr, &id, &sub, &length, datas); CANReleaseRecBuffer(); Sämtliche Nachrichten, die für den Gamma-Knoten bestimmt sind, tragen den Identifier GAMMA_ID. Anhand der Sub-ID erfolgt dann die weitere Differenzierung, die es erlaubt, Funktionen bezüglich des Lenkwinkels anzusprechen. if (id==GAMMA_ID) { Ist die Sub-ID gleich STR_ANGLE, wurde ein neuer Lenkwinkel gesendet. Der Soll-Winkel angle wird entsprechend dem empfangenen Wert zuzüglich 128 gesetzt. Die Addition von 128 ist notwendig, da der Lenkwinkelbereich auf dem PC zur intuitiveren Darstellung, wie in Tabelle PC-Winkel dargestellt, definiert wurde.

LINKSMITTERECHTS
max max
-128....-64....0....64....127

PC-Lenkwinkeldarstellung
Auf der MC-Seite wird der Lenkwinkelbereich dagegen derart verschoben, daß auf eine negative Darstellung verzichtet werden kann. Demzufolge stellt sich der Wertebereich von angle vorläufig folgendermaßen dar (Vgl. Tabelle vorl. MC-Lenkwinkel).

LINKSMITTERECHTS
max max
0....64....128....192....255

vorläufige MC-Lenkwinkeldarstellung
Überdies muß der Lenkwinkel noch an den Wertebereich des tatsächlich zu messenden Lenkwinkels (adcresult = Istwinkel) angepaßt werden, damit im Regelkreis der Soll- und der Istwinkel miteinander verglichen werden können. Die Angleichung des Sollwinkels angle bietet den Vorteil, daß lediglich eine Umrechnung pro neuem Lenkwinkel durchgeführt werden muß. Würde man dagegen den Istwinkel an angle anpassen, müßte die Umrechnung nach jedem Auslesen des ADC-Registers erfolgen.

Sei der maximale linke Lenkausschlag von adcresult in der Konstanten ADCLEFT und die Mittelstellung in ADCCENTER gespeichert. Dann ergibt sich folgendes Bild (Abb. angleadc). (Abbildung: Vergleich: angle und adcresult ) Für die Umrechnung von angle muß zwischen dem linken und rechten Lenkausschlag differenziert werden, da die Auflösung der Bereiche unterschiedlich hoch ist. Für den linken Lenkwinkelbereich, also angle kleiner 128, ergibt sich der Umrechnungsfaktor aus dem Quotienten der Auflösung der linken Seite des adcresults und der von angle, d.h. aus (ADCCENTER-ADCLEFT)/(128-0). Zusätzlich muß der Bereichsanfang des adcresults addiert werden, so daß die Anpassung schließlich durch die Zeile :

angle=ADCLEFT+angle*(ADCCENTER-ADCLEFT)/128

ausgedrückt werden kann. Der Umrechnungsfaktor für den rechten Lenkwinkelbereich berechnet sich analog mit (255-ADCCENTER)/(255-128). Es muß jedoch beachtet werden, daß lediglich der Anteil von angle multipliziert wird, der den rechten Lenkausschlag repräsentiert, also (angle-128). Daraus folgt, daß sich die Angleichung der rechten Seite mit der Zeile :

angle=ADCCENTER+(angle-128)*(255-ADCCENTER)/128

angeben läßt.

Mit dem Setzen des Flags newangle auf TRUE, wird der Interrupt-Routine signalisiert, daß ein neuer Lenkwinkel angefordert wurde.

/* set steering angle */ if (sub==STR_ANGLE) { angle=datas[0]+128; if (angle<128) angle=ADCLEFT+angle*(ADCCENTER-ADCLEFT)/128; else angle=ADCCENTER+(angle-128)*(255-ADCCENTER)/128; newangle=TRUE; } } } } }

Hardwareentwicklung

In diesem Kapitel soll zunächst auf einige allgemeine Eigenarten der verwendeten Knoten eingegangen werden. Anschließend erfolgt dann die Hardwarebeschreibung des Gamma-Knotens.

Analoge Eingabeports (D/A-Wandler)

Man muß darauf achten, daß die reale Belegung der Positionen der Pfostenleiste des "analogen Steckverbinders" nicht der entspricht, die auf den losen Schaltplänen angegeben ist. Vielmehr kann man die korrekte Anschlußbelegung für die Analog-Digital-Wandlung aus den Phytec-Unterlagen mit der Klebebindung entnehmen.

Gamma-Knoten

Der Gamma-Knoten ist ausschließlich für die Realisierung des Lenkwinkel-Regelkreises zuständig. Dies bedeutet im einzelnen, daß der Lenkwinkelmotor einen Sollwert in Form einer Spannung erhält, die vom PWM-Port 1 (also dem zweiten Pulsweiten-Modulation s-Port) abgegeben wird. Die tatsächliche Reaktion wird dann über den analogen Portpin P5.7 (s.o.) eingelesen. Die Software regelt dann bei Bedarf nach und paßt die PWM-Ausgangsspannung der Differenz zwischen Soll- und Ist-Lenkeinschlag an. (Abbildung: Schaltskizze des Gamma-Knotens )

Die Ansteuerungselektronik des Rollstuhl funktioniert leider nicht "linear", also nicht so daß bei kleinen Spannungen große Ausschläge nach links und bei großen Spannungen große Ausschläge nach rechts zu verzeichnen wären. Dies würde uns angesichts des Bereiches von 0V - 5V, den die PWM-Ausgänge abdecken, am weitesten entgegenkommen. Stattdessen gibt es zwei Eingänge auf der Seite der Motorelektronik, so daß die Höhe der Spannung (immer positiv) die Stärke des Ausschlags und der jeweilige Eingang die Richtung angibt. Geradeausfahren entspricht 0 V auf beiden Eingängen, 2,5 V auf dem einen Eingang führt zu einem mittleren Einschlag in die eine Richtung, 5 V auf dem anderen Eingang führt zum vollen Einschlag in die andere Richtung. Die Eingänge "zerren" also gegeneinander, wobei der Rollstuhl bei einem Gleichgewicht der Spannungen geradeaus fährt.

Da die beiden PWM-Register nicht vollkommen unabhängig voneinander angesteuert werden können, mußten wir zwei Transistoren einsetzen die - über die digitalen Ports P4.2 und P4.3 angesteuert - wechselweise (Vgl. Kapitel PWM) als Schalter (oder quasi Relais) Strom je nach gewünschter Lenkrichtung auf den einen oder den anderen Eingang der Motorelektronik geben (Siehe Abbildung Schaltskizze). Die zunächst realisierte Glättung des PWM-Signals über eine RC-Brücke erwies sich nachträglich als unnötig.

Da über den AD-Wandler Strom abfließt und somit das Meßergebnis anfangs verfälscht wurde, mußten wir recht große Widerstände für den Spannungsteiler einsetzen (110 bzw. 200 kOhm). Der Einsatz kleinerer Widerstände hatte zur Folge, daß der Lenkwinkel sich schon allein durch Anschluß der CAN-Karte um ca. die Hälfte des maximalen Lenkeinschlages veränderte. Zunächst hatten wir auch noch einen Operationsverstärker vorgesehen, der so geschaltet sein sollte, daß er eine Spannungsverstärkung von 1 (also einen identischen Spannungswert) erzeugt, aber einen sehr hohen Eingangswiderstand gehabt hätte. Aber auch dieser erwies sich durch die Verwendung der großen Widerstände als überflüssig.