| |
Personenaufzug : Graphisch und konventionell
Im Rahmen ihres Programms bietet die Firma LPE www.fischertechnik-in-der-schule.de
ein ROBOTIC Universal Set und ein ROBOTIC Starter Set an. Hier wird das Modell
Personenaufzug aus dem Universal Set vorgestellt und mit einer Lösung aus
fischertechnik pur und ROBO Pro bzw. C# 2008 + FishFace2005.DLL (Robo Interface)
verglichen, sowie mit Lösungen in VB2005 und C#2005 für den Robo TX
Controller.
Modell : LPE Cortex
|
Aus Kasten "ROBOTIC Universal Set"
Aufbau nach Handbuch "Schnellstart" - Bauanleitungen.
Bestandteile :
The Brain - der Controller (mit Flash Memory), programmierbar über PCS
Visual Logo und dessen Umsetzung in textorientiertes Logo und C.
Verwendet wird hier ein eigener Motor (der gelbe Kasten links), der auf einem
Servo basiert. Die Sensoren (hier IR Reflexsensor und Taster) sind auf
einheitlichen Platinen aufgebaut. Sie werden über einen fischertechnik
Baustein mit Loch angebaut. Die Verkabelung erfolgt durch
vorkonfektionierte Kabel mit Klinkensteckern.
Der Kasten enthält außer den Teilen für The Brain auch die für die
Modelle erforderlichen fischertechnik-Teile.
Der Aufzug kann über die Taster zwischen Erdgeschoß und erster Etage
arbeiten. Die jeweiligen Endlagen werden (berührungslos) über die
IR-Sensoren erkannt. |
Programm : PCS Visual Logo
|
Hauptprogramm und je ein Unterprogramm für
Hoch und Runter (aus Schnellstart Beispielen).
Das Main läßt in einem Endlos-Loop den Aufzugskorb Runter und Hoch
gehen. Zwischendurch wird auf die Betätigung eines der Taster (roter
Knopf) gewartet.
Die Unterprogramme schalten den Aufzugsmotor in der jeweils passenden
Richtung (Thisway, Thatway) und warten auf das Schalten des IR-Endsensors. |
Programm : PCS Simple C
#include<avr/io.h>
#include<avr/interrupt.h>
#include<rc3.h>
#define motA 0x88
#define leftFull -100
#define rightFull 100
#define fullStop 0
int main(){
init_rc3();
while(1){
runter();
while(!( swt(0) || swt(1) ));
hoch();
while(!( swt(0) || swt(1) ));
}
initPPU();
jumpBL();
return 0;
}
void hoch(){
MOTOR(motA, leftFull);
while(!( swt(3) ));
MOTOR(motA, 0);
}
void runter(){
MOTOR(motA, rightFull);
while(!( swt(2) ));
MOTOR(motA, fullStop);
} |
Basis des Programmes ist das aus PCS Visual
Logo generierte C Programm. Es wurde noch ein wenig "lesbarer"
gemacht.
Der Programmrumpf mit includes, Init- und Exit-Routinen sowiedem main
ist fest vorgegeben.
Die defines wurden von mir hinzugefügt. Ansonsten kann man das
Programm recht gut mit dem Visual Logo Programm vergleichen.
Wesentlicher Unterschied ist, dass hier die Motor-Operationen mit einem
Befehl abgehandelt werden. Die automatische Generierung macht da aber noch
mehr "Klimmzüge". Die Sensorabfragen werden über swt(.)
erledigt.
|
Modell : fischertechnik pur
|
Aufbau analog LPE Cortex. Verwendet wurde hier
ein Mini-Motor und anstelle der IR-Sensoren (aus Bequemlichkeit) normale
Taster. Der Fahrkorb enthält deswegen zwei Gewinde-Gewichte um das zum
Schalten (unten) erforderliche Gewicht zu erhalten. Hier wurden
zusätzlich noch Lampen zur Anzeige der Korb-Position montiert (ist bei
LPE Cortex auch möglich).
Betrieben wurde das Modell alternativ mit dem ROBO Interface und dem
neueren ROBO TX betrieben. |
Programm : ROBO Pro
|
Analog zu der PCS Logo Lösung. Hinzugekommen
ist das Schalten der Status-Lampen.
Das Programm ist insgesamt etwas kompakter, da hier die Befehle
Motor-Auswahl, Richtungswahl und Einschalten in einem Befehl erledigt
werden. |
Programm Scratch + ScratchFisch für das Robo
Interface
|
Analog zur PCS - Lösung. Hier wurde alles
inline programmiert, da die Motorsteuerung sehr kompakt ist.
Motor1.-7 steht dabei für Motor 1
fullSpeed links |
|
Hier in einer Version mit Unterprogrammen, die
der PCS-Lösung mehr entspricht.
Sende Hoch an alle und warten entspricht dabei einem UP-Aufruf, ohne
Warten wärs ein Thread-Start. |
Die Programmiersprache Scratch ist eine Entwicklung des MIT Lifelong
Kindergarten Group http://scratch.mit.edu
Die Erweiterung ScratchFisch zum Betrieb von fischertechnik Interfaces (z.Zt.
Robo Interface) stammt von Stephan Mecking www.scratchfisch.org.
Sie wurde in Java unter Nutzung von ftcomputing.robo.jar
erstellt.
Programm : C# 2008 mit FishFace2005.DLL
public
partial class
FishWindows : Form
FishFace
ft = new FishFace
private
void
Action() {
do
{
Runter();
while
(!ft.GetInput(Inp.I3)
&& !ft.GetInput(Inp.I4));
Hoch();
while
(!ft.GetInput(Inp.I3)
&& !ft.GetInput(Inp.I4));
} while
(!ft.Finish());
}
private void
Runter() {
lblStatus.Text = "Fährt";
ft.SetMotor(Out.M3,
Dir.Off);
ft.SetMotor(Out.M1,
Dir.Right);
ft.WaitForInput(Inp.I2);
ft.SetMotor(Out.M1,
Dir.Off);
ft.SetMotor(Out.M4,
Dir.On);
lblStatus.Text = "Unten";
}
private
void
Hoch() {
lblStatus.Text = "Fährt";
ft.SetMotor(Out.M4,
Dir.Off);
ft.SetMotor(Out.M1,
Dir.Left);
ft.WaitForInput(Inp.I1);
ft.SetMotor(Out.M1,
Dir.Off);
ft.SetMotor(Out.M3,
Dir.On);
lblStatus.Text = "Oben";
}
Lösung für das ROBO Interface. Entspricht im Aufbau der ROBO Pro Lösung.
Hier ist auch noch eine textuelle Statusanzeige hinzugekommen (Verwendet wurde
das Template FishWindowsCS von FishFace2005.DLL - Ende hier über Taster I3 und
ESC-Taste).
Programm : Java 6 / BlueJ mit ftcomputing.roboTX.jar
importe ftcomputing.roboTX.*;
public class PersonenAufzug
{
FishFaceTX tx = new FishFaceTX();
final Mot Aufzug = Mot.M1;
final Out LampeO = Out.O5;
final Out LampeU = Out.O7;
final Unv EndeO = Unv.I1;
final Unv EndeU = Unv.I2;
final Unv AnfO = Unv.I3;
final Unv AnfU = Unv.I4;
public static void main() {
PersonenAufzug pa = new PersonenAufzug();
System.out.println("PersonenAufzug gestartet");
System.out.println("FishFace-Version : " + FishFaceTX.Version());
try { pa.Action(); }
catch(FishFaceException eft) { System.out.println(eft);}
finally { System.out.println("Finito"); }
}
private void Action() {
tx.openController("COM4");
do {
Runter();
while(!tx.getInput(AnfO) && !tx.getInput(AnfU) && !tx.finish()) tx.pause(123);
Hoch();
while(!tx.getInput(AnfO) && !tx.getInput(AnfU) && !tx.finish()) tx.pause(123);
} while(!tx.finish());
tx.closeController();
}
private void Runter() {
System.out.println("Fährt");
tx.setLamp(LampeO, 0);
tx.setMotor(Aufzug, Dir.Right);
tx.waitForInput(EndeU, true);
tx.setMotor(Aufzug, Dir.Off);
tx.setLamp(LampeU, 512);
System.out.println("Unten");
}
private void Hoch() {
System.out.println("Fährt");
tx.setLamp(LampeU, 0);
tx.setMotor(Aufzug, Dir.Left);
tx.waitForInput(EndeO, true);
tx.setMotor(Aufzug, Dir.Off);
tx.setLamp(LampeO, 512);
System.out.println("Oben");
}
}
Lösung für den ROBO TX Controller.
Console Programm mit Textausgaben. Lampen zur Anzeige für Aufzug Oben/Unten.
Einsatz der Klasse FishFaceTX.
Programm : Python v3.1.1 mit FishFaTX.py
from FishFaTX import *
tx = FishFace()
Aufzug = 1
LampeO = 5
LampeU = 7
EndeO = 1
EndeU = 2
AnfO = 3
AnfU = 4
def Runter():
print("Fährt")
tx.SetLamp(0, LampeO, 0)
tx.SetMotor(0, Aufzug, tx.Rechts)
tx.WaitForInput(0, EndeU)
tx.SetMotor(0, Aufzug, tx.Aus)
tx.SetLamp(0, LampeU, 512)
print("Unten")
def Hoch():
print("Fährt")
tx.SetLamp(0, LampeU, 0)
tx.SetMotor(0, Aufzug, tx.Links)
tx.WaitForInput(0, EndeO)
tx.SetMotor(0, Aufzug, tx.Aus)
tx.SetLamp(0, LampeO, 512)
print("Oben")
tx.OpenController(4)
print("Aufzug in Betrieb")
while not tx.Finish():
Runter()
while (not tx.GetInput(0, AnfO) and not tx.GetInput(0, AnfU)
and not tx.Finish()): tx.Pause(123)
Hoch()
while (not tx.GetInput(0, AnfO) and not tx.GetInput(0, AnfU)
and not tx.Finish()): tx.Pause(123)
tx.CloseController()
Lösung für den ROBO TX Controller. Programm mit Textausgaben. Lampen zur Anzeige für Aufzug Oben/Unten.
Einsatz der Klasse FishFaTX.py.
Programm : C# 2005 mit FishFaceTX.DLL
public
partial class
frmMain : Form
FishControl
fc = new FishControl
Motor
Aufzug;
Lamp
LampeOben;
Lamp
LampeUnten;
PushButton
TasterOben;
PushButton
TasterUnten;
PushButton
AnforderungOben;
PushButton
AnforderungUnten;
private void
frmMain_Load(object sender, EventArgs
e) {
Aufzug
= new Motor(fc,
Ctr.Main, Mot.M1);
LampeOben
= new Lamp(fc,
Ctr.Main, Out.O5);
LampeUnten
= new Lamp(fc,
Ctr.Main, Out.O7);
TasterOben
= new PushButton(fc,
Ctr.Main, Unv.I1);
TasterUnten
= new PushButton(fc,
Ctr.Main, Unv.I2);
AnforderungOben
= new PushButton(fc,
Ctr.Main, Unv.I3);
AnforderungUnten
= new PushButton(fc,
Ctr.Main, Unv.I4);
}
private void Action()
{
do
{
Runter();
while
(AnforderungOben.IsFalse && !fc.Finish());
Hoch();
while
(AnforderungUnten.IsFalse && !fc.Finish());
} while
(!fc.Finish());
}
private void Runter()
{
lblStatus.Text = "Fährt";
LampeOben.Off();
Aufzug.Down();
TasterUnten.WaitForTrue();
Aufzug.Off();
LampeUnten.On();
lblStatus.Text = "Unten";
}
private
void Hoch() {
lblStatus.Text = "Fährt";
LampeUnten.Off();
Aufzug.Up();
TasterOben.WaitForTrue();
Aufzug.Off();
LampeOben.On();
lblStatus.Text = "Oben";
}
Lösung für den ROBO TX Controller. Hier wurden für die an den TX
Controller angeschlossenen Sensoren und Aktoren einzelne Objekte verwendet.
Dadurch erhöht sich der Overhead bei den Deklarationen, das Programm selber
wird dadurch aber übersichtlicher und flexibler. Der Aufbau entspricht sonst
aber genau dem C# 2008 oben. Die Aufzugsanforderung wurde hier auf jeweils einen
Taster reduziert, dafür wurde durch das Einbeziehen von !fc.Finish() das
Beenden des Programms vereinfacht. Zum objektorientierten Ansatz siehe auch FishDevices.
Auch hier wurde ein Template - analog FishWindowsCS - verwendet.
Programm : VB 2005 mit FishFaceTX - objektorientiert - ereignisgesteuert
Public
Class
PersonenAufzug
Dim
tx
As New
FishControl()
Dim
Aufzug As
Motor
Dim
LampeOben As
Lamp
Dim
LampeUnten As
Lamp
Dim
TasterOben As
PushButton
Dim
TasterUnten As
PushButton
Dim
AnforderungOben As
PushButton
Dim
AnforderungUnten As
PushButton
Private
Sub
PersonenAufzug_Load(ByVal
sender As
System.Object, ...
Label.CheckForIllegalCrossThreadCalls
= False
Aufzug
= New
Motor(tx, Ctr.Main, Mot.M1)
LampeOben
= New
Lamp(tx, Ctr.Main, Out.O5)
LampeUnten
= New
Lamp(tx, Ctr.Main, Out.O7)
TasterOben
= New
PushButton(tx, Ctr.Main, Unv.I1)
TasterUnten
= New
PushButton(tx, Ctr.Main, Unv.I2)
AnforderungOben
= New
PushButton(tx, True,
Ctr.Main, Unv.I3)
AnforderungUnten = New
PushButton(tx, True,
Ctr.Main, Unv.I4)
AddHandler
AnforderungOben.ChangedToTrue, AddressOf
RaufKommen
AddHandler
AnforderungUnten.ChangedToTrue, AddressOf
RunterKommen
End
Sub
Private
Sub
Action()
Runter()
Do tx.Pause(555) Loop
Until
tx.Finish()
End
Sub
Private
Sub RaufKommen(ByVal
sender As
BinaryInput)
If
TasterUnten.IsTrue Then
Hoch()
End
Sub
Private
Sub RunterKommen(ByVal
sender As
BinaryInput)
If
TasterOben.IsTrue Then
Runter()
End
Sub
Private
Sub
Runter()
lblStatus.Text = "Fährt"
LampeOben.Off()
Aufzug.Down()
TasterUnten.WaitForTrue()
Aufzug.Off()
LampeUnten.On()
lblStatus.Text = "Unten"
End
Sub
Private
Sub
Hoch()
.... entsprechend .....
End Sub
# Region
"---
ProgramControl ---"
Private
Sub cmdAction_Click(ByVal
sender As
System.Object, _
ByVal e As
System.EventArgs) Handles
cmdAction.Click
Try
tx.Connect(txtComName.Text)
tx.StartEvents()
.....Finally
tx.DisConnect()
......
#End
Region
End Class
Ereignisgesteuerte VB 2005 Lösung für den Robo TX
Controller. Vom Aufbau her entspricht das Programm weitgehend der vorher
vorgestellten linearen C# 2005 Lösung. Bei VB fehlen aber {;} dafür gibts ein
wenig mehr Text. Die Ereignisse allerdings sind gut versteckt und über das
ganze Programm verteilt :
- Die Instanzierungen von AnforderungOben, -Unten haben jetzt den Parameter True
: mit Ereignissen
- Über Addhandler werden dann die Ereignisroutinen zugeordnet (RaufKommen,
RunterKommen)
- Das Ereignis "Anforderungstaster gedrückt" wird im Objekt
AnforderungOben/Unten erkannt
- Das führt zum Aufruf der genannten Ereignisroutinen
- Dort wird dann der Fahrstuhl rauf oder runter geschickt (wenn's denn sein
muß)
- In der Sub Action passiert wenig : Der ordnunghalber wir er nach unten
geschickt und
dann wird auf das Ende gewartet.
- Und nicht vergessen : In der Region ProgrammControl müssen mit
tx.StartEvents()
die zugehörenden Ereignisthreads gestartet werden. Stand : 09.03.2010 |