Hallo ! Habe mir eine Aufzugsteuerung mit Ein-, Ausgangskarten und Mikrocontrollerboard(SAB80C537) gebaut. Habe in die Steuerung einen Sicherheits-Interrupt integriert. Sobald eine Schutzvorrichtung entfernt wird(Erkennung mit Magnetschaltern), so wird ein externer Interrupt generiert. Wird der Sicherheitsinterrupt generiert, so möchte ich entsprechend darauf reagieren, indem ich bestimmte Ausgänge zurücksetze und dem Anwender visualisiere (LCD, LEDs), dass die Steuerung still steht. Darüber hinaus muss ich auf einen Eingang warten, der mir bestätigt, dass alle Schutzvorrichtungen wieder geschlossen sind. Mein Problem: Ich möchte KEINE Endlosschleife, die die entsprechenden Eingänge (von den Schutzvorrichtungen kommend) in der Service-Routine haben - schlechter Programmierstil, oder ? Wie oben schon genannt, möchte ich beim Lösen eines Schutzes einen Text auf dem LCD ausgeben und ein Blinken von drei LEDs realisieren. Den dafür notwendigen C-Code in der Service-Routine zu integrieren, ist auch nicht besonders toll. Mein Lösungsansatz ist, ein Flag in der Service-Routine zu setzen und die Problembehandlung dann im Main zu realisieren. Aber ich weiß ja nicht, wann der Interrupt kommt und wo zu diesem Zeitpunkt der Program-Counter gerade steht. Deshalb könnte es sein, dass vor der eigentlichen Problembehandlung (Gelöste Schutzeinrichtung) noch Code ausgeführt wird, der eigentlich gar nicht ausgeführt werden dürfte. Wäre sehr froh über einen Tip von Euch ! Gruß und Vielen Dank ! Marcus
"Den dafür notwendigen C-Code in der Service-Routine zu integrieren, ist auch nicht besonders toll." In diesem spezifischen Fall - warum eigentlich nicht? Es geht hier ja nicht darum, daß der Interrupt oft bedient wird, wie ein Interrupthandler für eine serielle Schnittstelle oder ähnliches, sondern darum, daß der Interrupt einmal genau das auslöst, was er auslösen soll.
Die Interruptlösung ist in der Tat sehr unschön. 1. Du weißt nicht, was Du gerade unterbrochen hast. 2. Der Interrupt ist viel zu fix, d.h zu empfindlich gegenüber Störsignalen. Warscheinlich wird Dein Aufzug nie fahren, weil schon der Einschaltstromstoß des Motors Deinen Interrupt triggert. Daher ist es am sinnvollsten ihn wie jeden anderen Kontakt in der zentralen Tasten-entprell-und-gedrückt-erkennungs-Routine zu behandeln. Ob Du diesen Status in der Hauptschleife abfragen kannst, hängt nun ganz davon ab, wie Du sie programmiert hast. Es gibt Leute, die programmieren so: Wenn sie ins Kino gehen wollen, stellen sie sich frühmorgens vors Kino und warten, bis die Abendvorstellung beginnt. Sie könne derweil nichts anderes machen. Andere Leute programmieren menschlich: Wenn sie Sachen erst später machen wollen, dann machen sie erstmal was anderes, bis die Zeit ran ist. D.h. muß das Programm an irgendeiner Stelle auf etwas warten, dann kehrt es sofort zur Hauptschleife zurück und schaut später wieder mal vorbei. Nach dieser Methode wird die Hauptschleife immer sehr schnell durchlaufen und man kann Sicherheitsabfragen schnell und an einer optimalen Stelle ausführen. Auch sind solche Programme beliebig erweiterbar, da der Programmfluß ja nirgends anhält. Man muß eben seinen Programmierstil nur etwas umstellen von der rein sequentiellen auf die menschliche (parallele) Denkweise. Peter
Hallo ! Erstmal vielen Dank für Eure Antworten. @Peter Wie schnell erkannt wird, dass eine zuvor geöffnete Schutzeinrichtung wieder geschlossen ist, ist eigentlich egal. Mir geht es nicht um die Schnelligkeit, sondern dass Codezeilen im main oder anderen Funktionen nicht ausgeführt werden dürfen, solange die Schutzeinrichtung geöffnet ist. Man stelle sich vor, der Schutz wird geöffnet - PC durchläuft kurz die ISR und kehrt danach ins main zurück (Schutzeinrichtung ist noch immer geöffnet). Nun wird diejenige Codezeile bearbeitet, die das Fahren des Aufzugs veranlasst. Hand im Aufzugschacht - Hand ab - Sch... ! Bei Lösen des Schutzes wird natürlich über ein Relais auch die Spannung der sicherheitskritischen Einheiten abgeschaltet - also Hand wäre noch dran. Aber das Programm macht dann Dinge, die es eigentlich nicht tun dürfte. Zusammengefasst: Ich möchte dem Program-Counter einen strengen Weg vorgeben, wenn ein Schutz geöffnet wird. D. h. er darf nur bestimmten Code abarbeiten - wenn ich ständig in der ISR ist dies gegeben - aber wie wir schon gehört haben, ist dies nicht besonders toll und ich kann z. B. in der ISR auch kein printf ausführen und einen Timer starten, da dieser einen Interrupt generiert, der nieder priorer ist als der des Sicherheitsinterrupts. Gruß Marcus
Setze doch einfach im Interrupt ein Flag und alle Routinen, die nicht ausgeführt werden sollen, testen vorher dieses Flag, kostet doch nur 2 Zyklen. Und das Entprellen und Erkennen wie gesagt im Timerinterrupt, nicht im externen. Aber ich würde das Programm so umstellen, daß es nirgends wartet, sondern immer zum Main zurückkehrt. Peter
@Peter Wenn ich ein Flag setze und dieses vor jeder Routine abfrage ist gut, aber was ist, wenn der Interrupt generiert wird, wenn der Program-Counter schon in der Routine ist ? Dann bekomme ich ein Problem, oder ? Wenn ich ein Flag benutze, müsste ich jede sicherheitskritische Code-Zeile vorher abfragen und nicht mal dies wäre absolut sicher. Ich bin noch nicht so erfahren, was MC-Programmierung anbelangt - also bitte korrigier mich, wenn ich was Falsches erzähle. Gruß Marcus
Lass' doch Deine Interruptroutine solange nicht zurückkehren, wie das "befreiende" Kriterium nicht eingetreten ist. Natürlich solltest Du durch geeignete Maßnahmen sicherstellen, daß der Interrupt nicht fälschlicherweise ausgelöst wird, aber das ist mit einfachen Hardwaremitteln durchaus möglich (Entprellen durch Flipflop, RC-Glied zur Dämpfung hochfrequenter Anteile etc.) Da hier der Interrupt ein einmaliges Ereignis ist, kann hier innerhalb der Interruptroutine genauso verfahren werden, wie üblicherweise außerhalb von Interruptroutinen. Niemand schreibt einer Interruptroutine vor, wann und wie sie zu beenden ist. Oder auch, daß sie überhaupt zu beenden ist. Das einzige, worum Du Dir Gedanken machen musst, ist der Übergang vom "sicheren" Zustand in den Normalzustand, also um das, was geschieht, wenn der Störfall als beendet angesehen wird. Eine Möglichkeit wäre es, die Interruptroutine nicht mit RTI/IRET zu beenden, sondern ganz plump einen Reset auszulösen. Dein Steuergerät muss sich dann halt neu initialisieren, aber stört das?
Achtung ! Falls das einmal eine echte Aufzugssteuerung werden sollte: Keinesfalls Schutzfunktionen (Notaus) nur über Software auswerten, sondern zwingend über mechanisch- unterbrechende, dafür geeignete Schaltglieder (Notausrelaise, Notaus-Pilztaster). Eine Ausnahme bildet bis jetzt nur der ASI-Bus für erhöhte Sicherheitsanforderungen und spezielle SPS-Sicherheitssteuerungen. SG Josef
du nimmst mir die Worte aus dem Mund - Sicherheitsrelevante Sachen mit MCs zu steuern ist eine Herausforderung, die man nicht mal so eben aus dem Ärmel schüttelt. Und besteht bei Fehlfunktion sogar Gefahr für Gesundheit oder gar Leben von Menschen, kann ich dir nur einen einzigen Rat geben: lass die Finger komplett davon.
notausabschaltung über software?- da frag mal die berufsgenossenschaft ;-). wenn gefahrbringende bewegungen ausgeschlossen werden sollen, so muß das hardwaremäßig erfolgen (abschaltung der leistung - gibts von siemens so sicherheitsschütze, kabelbruchsicher etc.) klar braucht die steuerung auch ne meldung über den notaus (um zum beispiel meldungen aufs display zu bringen etc.), mittlerweile ists so verück, daß das 2 bis 4 kanalig ausgeführt werden muß (bei den autofritzen). mfg pripri
mit der interuptroutine würde ichs wie rufus machen, auch wenn der eine oder andere hier im forum strikt dagegen ist ;-).
Hallo ! Wie ich oben schon einmal geschrieben habe, veranlasst nicht nur der Mikrocontroller eine Abschaltung im sicherheitskritischen Fall, sondern eine redundante Sicherheitsabschaltung über Relais. Es müssten also meine Magnetsensoren, meine beiden Sicherheitsrelais und der Mikrocontroller im gleichen Moment fehlerhaft sein, damit eine gefährliche Situation entstehen kann. Natürlich ist die Schaltung so ausgelegt, dass bei Unterbrechung bestimmter Leitungen sofort abgeschaltet wird. Darüber hinaus sind die Magnetsensoren speziell für eine Sicherheitsabschaltung vorgesehen, d.h. sie haben nicht nur einen Öffner, sondern auch noch einen Schließer, mit dem ich ebenfalls im Fehlerfall ein Relais schalte, das die Versorgungsspannung des sicherheitskritischen Bereichs abschaltet. Ich bin ich sicherlich eher ein pessimistisch denkender Mensch und wenn ich mir nicht ganz sicher wäre, was ich tue, so würde ich die Finger davon lassen. Diese Diskussion driftet von meiner eigentlichen Frage ab - vorallem auch die Diskussion um die Entprellung des Eingangs für den Sicherheitsinterrupt - dieser funktioniert einwandfrei - ich hatte noch nie Probleme damit. Was ich eigentlich wissen wollte war, wie ich nach Verlassen der Service-Routine mit meiner Software weitermache. Mittlerweile habe ich es so umgesetzt, wie es Peter gesagt hat - ich schalte in der Service-Routine alle wichtigen Ausgänge ab und gleichzeitig setzte ich ein Flag. Nach der Rückkehr zum Main frage ich an mehreren Punkten den Wert des Flags ab. Ist das Flag gesetzt, so verzweige ich in eine Sicherheitsroutine, die mir mein Problem entsprechend behandelt. Die Routine wird nur verlassen, wenn ein entsprechender Eingang wieder vorhanden ist. Meiner Meinung nach ist das aber immer noch nicht die ideale Lösung - vielleicht hat ja doch noch ein "Alter Hase" unter Euch noch eine bessere Lösung ? Würde mich über viele Antworten freuen ! Es sei nochmals deutlich gesagt: Der Controller ist nur sehr eingeschränkt dafür verantwortlich, dass im sicherheitskritischen Fall bestimmte Einheiten abgeschaltet werden. Ist eine Schutzvorrichtung geöffnet, so sind sicherheitskritische Teile meiner Steuerung "doppelt und dreifach" über verschiedene Kontakte abgeschaltet. Der Controller soll nur in dieser Zeit nicht unkontrolliert irgendwelche Sachen machen, da nach Wiederverschließen der Schutzvorrichtung der Programmablauf kontrolliert fortgesetzt werden soll. Vielen Dank für Eure bisherigen Postings !! Gruß Marcus
Auch wenn ich inzwischen schon Fusseln am Mund habe, das sauberste ist und bleibt, wenn man nach jedem einzelnen Schritt zum Beginn der Main-Schleife zurückkehrt. Das geht z.B. mit einer Statemachine, d.h. man hat eine Variable, die jeden möglichen Zustand kennzeichnet und führt dann die Aktion aus, die in einen nächsten Zustand wechselt. Z.B.: 0 - einschalten 1 - Tür offen 2 - Tür schließen 3 - Tür geschlossen 4 - Fahrmotor ein 5 - Fahrmotor läuft 6 - Fahrmotor aus 7 - Fahrmotor steht ... xx - Sicherheitsabschaltung usw. Und das Flag setzt dann einfach diese Variable auf xx. In C programmiert man sowas mit der switch() Anweisung, hier mal ein Beispiel: http://home.tiscali.de/peterd/appl/soft/c51/thclock/main.c51 http://home.tiscali.de/peterd/appl/soft/c51/thclock/index.htm Auch bei der Projektplanung gilt die 1:10-Regel: Die Zeit, die man bei der Planung spart, benötigt man dann 10-fach mehr bei der Programmierung. Und wie ich es einschätze, ist die Planungsphase (Programmablaufplan) nicht gerade intensiv gewesen, sonst hättest Du ja die Sicherheitsabschaltung gleich mit berücksichtigt. Peter
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.