Forum: Mikrocontroller und Digitale Elektronik Sicherheitsinterrupt


von Marcus (Gast)


Lesenswert?

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

von Rufus T. Firefly (Gast)


Lesenswert?

"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.

von peter dannegger (Gast)


Lesenswert?

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

von Marcus (Gast)


Lesenswert?

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

von peter dannegger (Gast)


Lesenswert?

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

von Marcus (Gast)


Lesenswert?

@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

von Rufus T. Firefly (Gast)


Lesenswert?

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?

von josef (Gast)


Lesenswert?

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

von crazy horse (Gast)


Lesenswert?

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.

von pripri (Gast)


Lesenswert?

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

von pripri (Gast)


Lesenswert?

mit der interuptroutine würde ichs wie rufus machen, auch wenn der eine
oder andere hier im forum strikt dagegen ist ;-).

von Marcus (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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
Noch kein Account? Hier anmelden.