Epi-Care
Koffer For Table of Contents please click dk2os logo
above
Epi-Koffer
mit Arduino und GSM-Waehleinheit
Aktualisiert
am 07.01.2014
Die
Anlage
funktioniert bestens. Das Epi-Care arbeitet wie gewohnt zuverlaessig
und das GSM-Funk-Telefon-Wahlgeraet
auch.
Im
"Epi-Care Koffer" wird die einfach zu handhabende
GSM-Waehleinheit GW-02/NO der Firma AMG-Alarmtechnik verwendet. Die
Einschaltverzoegerung zur Unterdrueckung des
Einschaltimpulses, der beim Einschalten des Epi-Cares einen Alarm
ausloesen wuerde, sowie die
Alarmverzoegerung, um genuegend Zeit zum Stoppen eines Fehlalarms zu
geben, werden nicht aufwaendig hardwaremaessig sondern auf
einfache Weise softwaremaessig mit einem Mikrocontroller ("Arduino")
bewerkstelligt.
Versuchsaufbau:

.
Und
so sieht der Koffer aus:
Links
Epi-Care [mit Bettsensor], rechts Epi-Care free [mit
Armbandsensor])
(Es
muessen nicht beide Epi-Care verwendet werden. Man kann auch nur eines
der beiden Epi-Care einsetzen.)
.
Epi-Koffer
-
Anschlussseite:

Rechts
der Testknopf fuer das Telefon-Wahlgeraet, daneben die
Netzanschlussbuchse.
Zwei
Buchsen: Die untere fuer die Pilotlampen an der Tuer, die andere fuer
zukuenftige Verwendung.
Das
Loch ist zum Durchfuehren des Bettsensor-Kabels sowie zum Durchfuehren
des Ladesteckers fuer das Epi-Care Free Armbandes.
GSM-Funk-Telefon-Wahlgeraet
GSM-02/NO:

Die
kleine
GSM-Wahleinheit
ist im Deckel des Koffers angebracht. Links ist die Antenne zu
sehen.
Rechts
der
Stecker der Stromvesorgung (12V), unten das Kabel zum
Relais. Oben guckt die SIM-Karte heraus.
Das
Geraet ist einfach zu programmieren. Man schickt einfach eine
SMS mit
der Telefonnummer, die
angerufen
werden soll, zu dieser Waehleinheit.
GW-02/NO
der
Firma AMG-Alarmtechnik
(NO bedeutet "Normally Open", d.h. bei
Kurzschliessen des Eingangs
waehlt die Funk-Telefonwahleinheit die ihr zuvor per SMS zugesandte
Telefonnummer.)
Wir
verwenden eine SIM-Karte der Deutschen Telekom und koennen auf der web
site der Telekom
unter "Mobilfunk" den Kontostand ersehen.
Die Wahleinheit sendet zuerst eine SMS (5 Cent)
und
taetigt danach noch einen Anruf (5 Cent).
Ist
der Kontostand um 10 Cent
gesunken, sind wir ziemlich sicher, dass auf das Handy der Nachtwache
ein Anfall gemeldet wurde. Im Ordner "Eingegangene SMS" und im
Ordner "Ankommende Anrufe" kann man spaeter den Zeitpunkt des
Anfalls
ersehen.
Und
das ist die Leiterplatte:
Achtung:
Das Bild zeigt noch die Stromversorgung des Arduino mit einem
USB-Ladeadapter. Um Stoerimpulse zu unterdruecken, ist der Arduino
jetzt ueber ein Spannungsreglerteil (12V auf 8V) am 12V-Netzadapter
angeschlossen.

Mit
wenigen Teilen kommt man aus:
Arduino,
zwei Relais, drei Opto-Kopplern
(der eine sitzt unter dem Arduino)
Da
die beiden
Buchsenleisten der einen Seite auf dem Arduino leider nicht den
genormten Stiftabstand haben, musste
ich mich mit dieser Konstruktion
behelfen, um den Arduino auf meiner Leiterplatte aufstecken zu koennen.
Oberseite
Unterseite
[nach
oben]
Der
Arduino erledigt Folgendes:
1.
Bei Einschalten des Koffers verhindert er, dass der Ausgangsimpuls des
Epi-Cares das Wahlgeraet zum Waehlen veranlasst.
2.
Bei Fehlalarm drueckt man den orangefarbenen Taster. Mittels
Relais schaltet der Arduino das Epi-Care aus und dann
wieder ein. Der beim Einschalten des Epi-Cares
auftretende Ausgangsimpuls wird wie bei Einschalten
der Anlage (mit dem
gruenen Schalter) unterdrueckt.
Statt
der
Fehlalarm-Stopptaste koennte
auch ein Fehlalarm mit der gruenen Ein/Aus-Taste gestoppt werden, wie
es auch bei der Anlage "
Epi-Care
&
Telefon-Alarmeinheit" gemacht
ist.
Allerdings scheint es fuer
die Benutzer angenehmer zu sein, wenn eine auffallende
"Stopptaste" vorhanden ist. Aus diesem Grunde habe ich die
orangefarbene Stopptaste vorgesehen, die groesser als der
Ein/Aus-Schalter ist. Und das war auch richtig so.
Zum
Stoppen eines Alarms (Fehlalarm oder auch richtiger Alarm) einfach auf
die orangefarbene Taste druecken, und alles andere erledigt der Arduino.
Sowohl
bei Ein- als auch bei Ausschalten ertoent ueber den Lautsprecher ein
(unterschiedlicher) Ton. Und bei Ausloesen eines Tel-Alarms ebenfalls
ein Ton mit einer anderen Frequenz.Das
12-V-Netzteil ist ein
preiswerter Netzadapter fuer PCs. Fuer den Arduino wird ein
preiswertes USB-Netzteil verwendet. Es waere allerdings einfacher,
den Arduino ueber die Stromversorgungsbuchse mit 12V zu
betreiben.
Die
Relais gibt es speziell fuer den Arduino und koennen Geraete mit hoher
Leistung schalten, die wir hier eigentlich nicht haben. Aber sie sind
preiswert und waren billiger als ein einzelnes Relais mit
geringer
Stromaufnahme (Ausgangsstrom fuer den Arduino darf 30 mA nicht
uebersteigen!)
[07.01.2014 ]
Bei Einschalten der Nachttischlampe (besonders bei Halogenlampe mit
Transformator-Einheit und sogar auch bei einer normalen Gluehlampe)
machte sich ein Stoerimpuls an der gemeinsamen Mehrsteckerleiste
bemerkbar, so dass der Arduino reagierte. (Sogar mit einem an der
Steckerleiste angeschlossenen Analogmeter konnte man sehen, wie sich
die Nadel bei Ein-/Ausschalten der Lampe bewegte.) Die
schnellste Loesung war zunaechst, die Nachttischlampe an einer
anderen Wandsteckdose anzuschliessen, was allerdings keine
zufriedenstellende ist.
Abhilfe schaffte schliesslich ein (externer) Pullup-Widerstand von 10k
Ohm am Eingang der StoppTaste (Pin4).
Im Code war zwar der interne Pullup-Widerstand mit
"digitalWrite (StoppTastePin, HIGH)" aktiviert, allerdings sei dies
stoeranfaellig, gerade bei so einem Schalter, wie mir ein
guter Freund sagte. Bei den anderen Eingaengen sollte ich auch besser
einen externen Pullup-Widerstand verwenden. Allerdings gab es bei denen
kein Problem mit dem internen Pullup.
Schaltung:
[ Anklicken, um eine groessere Darstellung zu erhalten. ]
[

Der
gelbe
Teil ist fuer ein zweites Epi-Care gedacht. (Das Epi-Care mit
Bettsensor als "normales" und das neue mit dem Armband-Sensor als
Zusatzgeraet)
Das
Epi-Care gibt bei Alarm eine Spannung von 12 V aus. Ueber einen
Optokoppler wird das Signal an den Eingang des Arduinos geleitet.
Der
Widerstand zwischen dem Epi-Care-Ausgang und Optokoppler
betraegt 1 KOhm.
Die
Betriebsspannung des Epi-Care wird auch ueber einen Optokoppler an
einen
Eingang des Arduino geleitet, um
festzustellen, ob der Koffer
ein- oder ausgeschaltet ist.
Bei
Fehlalarm drueckt man den orangefarbenen Taster, womit das Epi-Care
ausgeschaltet und wieder eingeschaltet wird.
Das
Telefon-Wahlgeraet wird wie der Arduino stets mit Strom versorgt.
Wie
im Bild der Leiterplatte zu sehen ist, wird der
Arduino UNO ueber ein USB-Netzteil mit Strom versorgt. Die 5V,
die in
der Schaltung angegeben sind, kommen vom 5V-Anschluss des Arduinos. Zum
Programmieren des Arduinos wird das USB-Kabel an einen PC angeschlossen.
Der
Arduino UNO kann allerdings ueber seine Stromversorgungsbuchse mit 12V
versorgt werden, wie es im Schaltbild oben gezeigt ist. Das
USB-Netzteil wird in diesem Fall nicht benoetigt.
Die
Test-Schalter am Signal-Eingang (Pin12 / Pin11) dienen
lediglich
zum Testen der Software. Die Test-Taste fuer das
Telefon-Waehlgeraet
ist an der Rueckseite des Koffers angebracht.
Bei
Bedarf kann dann
jeder ueberpruefen, ob das Wahlgeraet ordnungsfrei funktioniert.
Arduino:
Siehe arduino.cc
: Arduino
Uno
R3. Das bekommt
man von verschiedenen Anbietern
Relais: von MiniInThebox:
"Keyes
_SR1y"
Telefon-Wahlgeraet:
Von AMG-Wahltechnik: GW-02 NO (NO bedeutet
"Normally Open"
= Normalerweise offen, d.h. Aktivierung wenn der Kontakt geschlossen
wird)
[nach
oben]
Der Code:
Beschreibung
(danach der Code selbst)
(Am Anfang) |
Festlegung
der Variablen |
|
|
void
setup() |
Initialisierung der
Ein- und
Ausgaenge |
|
|
void
loop () |
(Hauptroutine) |
|
Es wird ueberprueft,
ob der Koffer
ein- oder |
|
ausgeschaltet ist
[digitalRead(PinEinAus)==??] |
|
|
|
Wenn der Koffer
eingeschaltet ist, |
|
wird die Subroutine
[Check_Alarm]
aufgerufen. |
|
|
|
Wenn der Koffer
ausgeschaltet ist, |
|
wird die Subroutine
[Check_Ein]
aufgerufen. |
|
|
void
Check_Ein() |
Unendliche Schleife |
|
Wird der Koffer
eingeschaltet
[digitalRead(PinEinAus)==HIGH], so wird die Schleife |
|
verlassen, und es geht
zurueck zur
Hauptroutine (loop) |
|
|
void
Check_Alarm() |
Der Koffer ist
eingeschaltet.
Sobald das Epi-Care Alarm gibt, |
|
[digitalRead(PinEpi1)==LOW]
wird
das Relais zum Aktivieren des Telefon-Waehlgeraets |
|
eingeschaltet. |
|
- Es wird stets
ueberprueft, ob der
Koffer ausgeschaltet wird. |
|
- Es wird stets
ueberprueft, ob die
Stopptaste gedrueckt wurde. |
|
|
void
Check_Reset() |
Routine zur
Ueberpruefung, ob die
Stopptaste gedrueckt wurde. |
|
[(digitalRead(PinStoppTaste)==??)] |
|
Wenn HIGH, dann wurde
die
Stopptaste gedrueckt, und FReset wird auf 1 gesetzt. |
|
FReset ist das Flag
fuer Stopptaste
gedrueckt oder nicht gedrueckt (siehe unten). |
|
|
void
Reset() |
Zum Abschalten des
Ausgangsrelais
(Relais am Telefon-Wahlgeraet) |
|
|
void
Ton_Ein() |
Ton, der beim
Einschalten des
Koffers ertoent. |
|
|
void
Ton_Reset() |
Ton, der bei Druecken
der
Stopptaste bzw. beim Ausschalten des Koffers |
|
(mit der gruenen
Ein/Aus-Taste)
ertoent. |
|
|
void
Ton_Alarm1() |
Wenn das
Telefon-Relais aktiviert
wird, ertoent dieser Ton. |
void
Ton_Alarm2() |
Wenn die
Telefoneinheit zu waehlen
beginnt, ertoent dieser Ton. |
|
|
Flags: |
|
FRest=0 |
Die Stopptaste wurde
nicht
gedrueckt. |
FRest=1 |
Die Stopptaste wurde
gedrueckt. |
|
|
FAusloesung
= 0 |
Das Relais zum
Aktivieren des
Telefon-Wahlgeraetes ist nicht aktiviert (aus). |
FAusloesung
= 1 |
Das Relais zum
Aktivieren des
Telefon-Wahlgeraetes ist aktiviert (ein). |
[nach
oben]
Und hier
der Code:
// EpiKoffer2 140106_FE.ino
int
WarteEin =
10; // Wieviel Sekunden Wartezeit nach Einschalten des EpiCare, damit
das Ausgangssignal keinen Alarm ausloest. (5=ok)
int
WarteAlarm = 4; // Wieviel Sekunden bevor das AlarmRelais anspricht
(4 Sekunden sind das Minimum. Besser eine laengere Wartezeit)
int
WarteAusEin = 3; // Wieviel Sekunden Wartezeit bei autom. Aus- und
Wiedereinschalten
int
Epi1Pin = 12;
int
Epi2Pin = 11;
int
EinAusPin = 5;
int
TelAlarmPin = 9;
int
StoppTastePin = 4;
int
ResetPin = 7;
int
LautsprecherPin = 8;
int
FReset = 0; // Reset-Zustand
int
FAusloesung = 0; // Ausgangsrelais-Zustand
int
TonFreqEin = 2000;
int
TonFreqReset= 1500;
int
TonFreqAlarm1 = 500; // Ton wenn AlarmRelais anspricht
int
TonFreqAlarm2 = 400; // Ton wenn Telefonwaehleinheit
beginnt zu waehlen
int
TonDauerEin = 1500;
int
TonDauerReset = 1500;
int
TonDauerAlarm = 6000;
int
AlarmSignalDauer = 0;
int
AlarmSignalDauer_ = 100;
int
TTT = 0;
int
ZZ = 0;
int
i = 0;
void
setup()
{
//Serial.begin(9600);
// open the serial port at 9600 bps:
pinMode(Epi1Pin, INPUT);
pinMode(Epi2Pin, INPUT);
pinMode(EinAusPin, INPUT);
pinMode(TelAlarmPin, OUTPUT);
pinMode(StoppTastePin, INPUT);
pinMode(ResetPin, OUTPUT);
pinMode(LautsprecherPin, OUTPUT);
digitalWrite (Epi1Pin, HIGH); //
Pullup-Widerstand aktivieren
digitalWrite (Epi2Pin, HIGH); //
Pullup-Widerstand aktivieren
digitalWrite (EinAusPin, HIGH); // Pullup-Widerstand
aktivieren
//2014.01.06 Arthur's advice to fit a 10k Ohm pullup resistors instead
//digitalWrite
(StoppTastePin, HIGH); // Pullup-Widerstand
aktivieren
digitalWrite (EinAusPin, HIGH); // Pullup-Widerstand
aktivieren
// digitalWrite (StoppTastePin, HIGH); //
Pullup-Widerstand aktivieren
WarteAlarm = WarteAlarm * 10;
WarteAusEin = WarteAusEin * 1000;
WarteEin = WarteEin * 1000;
}
void
loop ()
{
if (digitalRead(EinAusPin)==LOW) // Der
Koffer ist eingeschaltet
{
if (FAusloesung == 0){
AlarmSignalDauer =
AlarmSignalDauer_;
Check_Alarm();
}
Check_Reset();
if (FAusloesung == 1) // Wenn das
Ausgangsrelais geschaltet wurde
{
AlarmSignalDauer =
AlarmSignalDauer - 1 ;
delay(100);
if (AlarmSignalDauer
< 0){
digitalWrite(TelAlarmPin, LOW); // Das Ausgangsrelais abschalten
FAusloesung = 2;
}
}
if (FReset ==
1) // Wenn die Stopptaste gedrueckt wurde
{
digitalWrite(TelAlarmPin, LOW); // Das Ausgangsrelais abschalten
FAusloesung = 0;
Ton_Reset();
delay(WarteAusEin);
digitalWrite(ResetPin, LOW); // Das Reset-Relais wieder abschalten
}
}
if (digitalRead(EinAusPin)==HIGH) { // Der Koffer
ist ausgeschaltet
Check_Ein(); // Rueckkehr
erst, wenn der Koffer eingeschaltet wurde
}
}
void
Check_Ein()
{
TTT = 0;
ZZ=0;
while(TTT == 0){
//if
(ZZ==0){Serial.println("t");} ZZ=1;
if
(digitalRead(EinAusPin)==LOW){ // Wenn der Koffer
eingeschaltet wird
Ton_Ein();
//Serial.println("e");
delay(WarteEin);
TTT =
1; // aus der Schleife raus und zurueck
}
}
}
void
Check_Alarm()
{
FAusloesung = 0;
TTT = 0;
ZZ=0;
//////////////////////////////////////////////////////////////////
while(TTT == 0){
//if
(ZZ==0){Serial.println("T");} ZZ=1;
if
(digitalRead(EinAusPin)==HIGH) { // Der Koffer wird
ausgeschaltet
Reset();
//Serial.println("a");
TTT
= 1;
}
if ((digitalRead(Epi1Pin)==LOW) ||
(digitalRead(Epi2Pin)==LOW)) {
Ton_Alarm1();
//Serial.print("A");
/// Warteschleife
/// bis Ausloesen des Alarms
for (int i=0;
i<WarteAlarm; i++){
delay(100);
Check_Reset();
if (FReset == 1){
i = WarteAlarm;
}
}
Ton_Alarm2();
digitalWrite(TelAlarmPin, HIGH); // Das Ausgangsrelais einschalten
FAusloesung = 1;
/// Warteschleife
ENDE ///
TTT = 1; // Wenn das Epi-Care Alarm gibt, zurueck
}
Check_Reset();
}
/// While ENDE
///////////////////////////////////////////////////////
if (FReset == 1){ // Wenn die Stopptaste gedrueckt
wurde, zurueck
TTT =
1;
noTone(LautsprecherPin);
FAusloesung = 0;
}
if (digitalRead(EinAusPin)==HIGH) { // Der Koffer
wird ausgeschaltet
Reset();
TTT = 1; // Wenn der Koffer
ausgeschaltet wurde, zurueck
}
}
void
Check_Reset()
{
FReset = 0;
if (digitalRead(StoppTastePin)==LOW){ // Die
Stopptaste wurde gedrueckt
digitalWrite(TelAlarmPin, LOW); // Das
Ausgangsrelais sofort ausschalten
digitalWrite(ResetPin, HIGH); // Den
Koffer ausschalten
FReset = 1;
FAusloesung = 0;
AlarmSignalDauer=AlarmSignalDauer_;
}
}
void
Reset() {
digitalWrite(TelAlarmPin, LOW); // Das Ausgangsrelais sofort
ausschalten
Ton_Reset();
FReset = 1;
}
void
Ton_Ein(){
tone(LautsprecherPin, TonFreqEin, TonDauerEin);
}
void
Ton_Reset(){
tone(LautsprecherPin, TonFreqReset, TonDauerReset);
}
void
Ton_Alarm1(){ // Ton wenn das TelRelais anspricht
//
tone(LautsprecherPin, TonFreqAlarm, TonDauerAlarm); // Die
Tondauer ist begrenzt
tone(LautsprecherPin,
TonFreqAlarm1); // der Ton soll andauern, bis die Stopptaste
gedrueckt wird
}
void
Ton_Alarm2(){ // Ton, wenn die Telefoneinheit beginnt zu waehlen
tone(LautsprecherPin,
TonFreqAlarm2); // der Ton soll andauern, bis die Stopptaste
gedrueckt wird
}
---------------------
ENDE des Codes
-----------------------------------------
aktualisiert
am 12.11.2013