OO-Interfaces

ftComputing : Programme für die fischertechnik-Interfaces und -konstruktionskästen
  
ftComputing.de
Home
Back
OO-RoboFace
Sitemap
Index
Links
Impressum
Mail
 

C# : Objekte anstelle von Methoden

C# Assembly FishDevices40.DLL : FishDev40.PDF. Die Ein- und Ausgänge sind Objekte des zugehörenden Interfaces, sie werden nicht mehr über die Methoden des Interface-Objektes angesprochen. Sie verfügen meit über einen eigenen Thread (ExecuteRoutine EventLoop) um den aktuellen Interfacestand auswerten zu können. Im EventLoop können eigene Ereignisse auslösen. Z.B. ChangedToTrue, wenn der Zustand eines Taster von false auf true wechselt. Die Device-Objekte erlauben sowohl eine eventorientierte wie auch eine lineare Programmierung, da sie parallel zu einem kompletten Satz von Ereignissen auch mit einem Satz korrepondierender Methoden ausgestattet sind.

Über die Klasse FishDevices werden die Resourcen (Interfaces der ROBO Serie, Intelligent Interface) zentral verwaltet.

Download FishDev40.ZIP (enthält auch ein VB.NET-Beispiel (auf Basis von FishDevices40.DLL).

FishDevices : Zentrale Klasse zur Beschreibung und Steuerung des Interfaces.
Methoden : Connect, Start, Suspend, Resume, DisConnect | Finish, Pause

BinaryInput, Sensor, PhotoTransitor, ReedContact : Klassen zum Betrieb der I-Eingänge.
Ereignisse : ChangedToTrue, ChangedToFalse
Eigenschaften : IsTrue
Methoden : WaitForInput, WaitForHigh, WaitForLow

IRInput : Klassen zum Betrieb des IR-Einganges.
Ereignisse : ChangedToTrue, ChangedToFalse
Eigenschaften : IsTrue
Methoden : WaitForKey

AnalogInput, PhotoResistor, NTC, PotentioMeter
Klassen zum Betrieb der Analog-Eingänge (Widerstände).
Ereignisse : ChangedToLow, ChangedToHigh, ChangedToNormal, ShowActualValue
Eigenschaften : ActualValue

VoltageInput : Klasse zum Betrieb Spannungs-Eingänge.
Ereignisse : ChangedToLow, ChangedToHigh, ChangedToNormal, ShowActualValue
Eigenschaften : ActualValue

DualOutput, Motor, DLamp, DMagnet, DPneuValve, Buzzer : Klassen zum Betrieb der M-Ausgänge
Eigenschaften : State
Methoden : On, Off, Left, Right, Go | Forward, Backward, Up, Down 
DLamp : BlinkingOn, BlinkingOff

MonoOutput, Lamp, Magnet, PneuValve :
Klassen zur Beschreibung der "halben" O-Ausgänge
Methoden : On, Off | Lamp : BlinkingOn, BlinkingOff

LightBarrier, LimitedMotor, RobMotor, RobMotors, ImpulseSensor :
Objekte, die Ein- und Ausgänge zu einer Einheit zusammenfassen.
Ereignisse/LightBarrier : ChangedToFree, ChangeToBroken
Ereignisse/LimitedMotor : LeftToTrue, RightToTrue
Ereignisse/RobMotor(s) : ChangedPosition, FinalPosition
Ereignisse/ImpulseSensor : ChangedCount, FinalCount
Eigenschaften/LightBarrier : IsFree, IsBroken
Eigenschaften/LimitedMotor : IsLeft, IsRight
Eigenschaften/RobMotor : ActualPosition
Eigenschaften/RobMotors : State
Eigenschaften/ImpulseSensor : CourrenCounter
Methoden/LightBarrier : On, Off, WaitForBroken, WaitForFree, WaitForPassed
Methoden/LimitedMotor : GoLeft, GoRight, WaitForDone
Methoden/RobMotor : DriveHome, DriveDelta, DriveTo, WaitForDone
Methoden/RobMotors : MoveHome, MoveDelta, MoveTo, WaitforDone
Methoden/ImpulseSensor : CountChanges, CountPosition, WaitForDone

Hinweise zum Konzept

Ebenenkonzept der Klassenbibliothek FishDevices40.DLL

Vergleich FishFace40.DLL - FishDevices40.DLL

Standard-Lösung : FishFace40.DLL

Die bekannte Klassenbibliothek FishFace40 wird für eine größere Anzahl von Programmiersprachen - auch für C# - einheitlich angeboten. FishFace40 basiert auf umFish40.DLL und bietet mit der zentralen Klasse FishFace eine Beschreibung des angeschlossenen Interfaces an. Die Ein- und Ausgänge des Interfaces werden über Methoden der Klasse FishFace angesteuert :

FishFace ft = new FishFace();

ft.SetMotor(Out.M1, Dir.Links);

if(ft.GetInput(Inp.I1)) ft.SetMotor(Out.M1, Dir.Off);

Die Methode SetMotor startet z.B. einen am Ausgang M1 angeschlossenen Motor in Drehrichtung Links.

Die Methode GetInput ermittelt den aktuellen Status des Einganges E1. Der Motor an M1 wird ggf. abgeschaltet.

OO-Lösung mit FishDevices40.DLL

Mit FishDevices40 sieht das dann so aus :

FishDevices fd = new FishDevices();
Motor Antrieb = new Motor(fd, 1);
Sensor Endtaster = new Sensor(fd, 1);

Antrieb.Left();

if(Endtaster.IsTrue) Antrieb.Off();

Das Motor-Objekt Antrieb wird in Drehrichtung links gestartet.

Der Status des Sensor-Objektes Endtaster wird ermittelt. Der Antrieb wird ggf. abgeschaltet.

Wenn man zusätzlich eine Ereignisroutine zuordnet, kann man eine Zustandsänderung von Endtaster (Ereignis) auch in einer zugehörenden Ereignisroutine erfahren und darauf reagieren :

Endtaster.ChangedToTrue += BinaryInput.Changed(AntriebLinks);

void AntriebLinks(object sender) {
    Antrieb.Off();}

Hier kann auf das if verzichtet werden, der Antrieb wird "hinter der Leinwand" abgeschaltet.

Beispiel Parkhausschranke aus dem Computing Starter Kit

  "Durch Betätigen des Tasters E3 soll die Schranke geöffnet werden. Ist die Schranke offen, leuchtet die Ampel grün. Erst wenn die Lichtschranke passiert wurde, springt die Ampel auf rot und die Schranke schließt wieder." Originaltext aus der Anleitung.

Die Schranke wird nun auf folgende Objekte abgebildet :

FishDevices fd = new FishDevices();
LimitedMotor Schranke = new LimitedMotor(fd, new Motor(fd, 3), new Sensor(fd, 5), 
   new Sensor(fd, 7));
LightBarrier Durchfahrt = new LightBarrier(fd, new DLamp(fd, 4), new PhotoTransistor(fd, 2));
Sensor Anforderung = new Sensor(fd, 1);
DLamp Rot = new DLamp(fd, 2);
DLamp Gruen = new DLampt(fd, 1);

Die Schranke besteht hier aus dem Objekt LimitedMotor mit den Objekten Motor an M3 und dem Endtaster für "geschlossen" an I5 und "offen" an I7
Die Lichtschranke besteht hier aus dem Objekt LightBarrier mit den Objekten DLamp an M4 und PhotoTransistor an I2)
Der Rest sind einfache Objekte.

Die Steuerung sieht dann so aus :

do {
    Schranke.GoLeft();
    Schranke.WaitForDone();
    Anforderung.WaitForHigh();
    Schranke.GoRight();
    Schranke.WaitForDone();
    Rot.Off();
    Gruen.On();
    Durchfahrt.WaitForPassed();
    Rot.On();
    Gruen.Off();
} while(!ft.Finish());

Die Steuerung läuft in einer Endlosschleife, die durch ESC abgebrochen werden kann. Der Reihe nach wird hier die Schranke geschlossen, auf eine Anforderung zu Durchfahrt gewartet, die Ampel geschaltet, die Durchfahrt abgewartet und wieder die Ampel geschaltet.

Und ereignisgesteuert :

private void SchrankeOeffnen(object sender){
	if(SchrankeBusy) return;
	SchrankeBusy = true;
	lblStatus.Text = "--- SchrankeBusy ---";
	Schranke.GoRight(); }
private void SchrankeFreigeben(object sender){
	Rot.Off();
	Gruen.On(); }
private void SchrankeSchliessen(object sender) {
	ft.Pause(555);
	Rot.On();
	Gruen.Off();
	Schranke.GoLeft(); }
private void SchrankeWarten(object sender) {
	SchrankeBusy = false;
	lblStatus.Text = "--- Schranke betriebsbereit ---"; }

Anstelle der Endlosschleife eine Folge von Ereignisroutinen, die das gleiche tun. Sie sind in der Reihenfolge ihrer Nutzung aufgeführt. Das vollständige Programm ist im Downloadpäckchen enthalten.

Zeitverhalten

FishDevices zeigt bei ereignisgesteuerten Programmen ein sehr gutes Zeitverhalten, wenn man darauf achtet die Eventroutinen nicht ausufern zu lassen. Gemischte Programme (lineare Programme mit ereignisgesteuerter Anzeige von Werten) sind völlig unproblematisch. Bei rein linearen Programmen kann der Ereignis-Loop des entsprechenden Objekts abgeschaltet werden (Parameter WithEvents = false). Die Zeitaussagen beziehen sich auf einen 1,7 GHz-Rechner unter Windows 2000 SP4 und .NET Final SP2.

Das jetzt überholte RoboFace ist zu Vergleichszwecken z.Zt. noch unter RoboFace.HTM zugänglich.

Downloads

Das vollständige Beispielprogramm, einschließlich einer ereignisgesteuerten Lösung und weiteren Beispielen und - natürlich - die übersetzte FishDevices40.DLL und die Sources dazu in FishDev40.ZIP. Die Dokumentation auch separat in FishDev40.PDF.

Stand : 10.05.2007