5 Lampen mit 5 Schaltern ansteuern?

Hallo Experten,

als Medienkünstlerin beschäftige ich mich neuerdings mit dem Arduino
und ich habe in Eurem Forum leider keine ähnliche Frage gefunden, die mir bei meinem ersten Arduino Projekt weiterhelfen würde.

Daher würde ich mich sehr darüber freuen, wenn Ihr mir dabei helfen könntet, das Skript für mein erstes Projekt fertigzustellen:

Mein Plan ist es,

5 Schalter (Schalter1-5) als digitale Eingänge zu deklarieren.
5 Lampen (Lampe1-5) als digitale Ausgänge zu deklarieren.

Jedem Schalter ist numerisch eine Lampe zugeordnet.
Die Kippschalter haben 2 Zustände(1XUM bzw. Ein/Aus).

INPUT --> OUTPUT
Schalter 1 --> Lampe 1
Schalter 2 --> Lampe 2
Schalter 3 --> Lampe 3
Schalter 4 --> Lampe 4
Schalter 5 --> Lampe 5

Während der Einschaltzeit eines Schalters, z.B. Schalter3, darf nur die dazugehörige Lampe (in diesem Beispiel Lampe3) eingeschaltet sein, alle anderen Schaltereingänge und Lampenausgänge müssen solange deaktiviert / ausgeschaltet sein, bis dieser Schalter (hier Schalter3) und die dazugehörige Lampe (hier Lampe3) ausgeschaltet wird.

Erst, wenn ein Schalter / eine Lampe ausgeht, kann der nächste Schalter seine dazugehörige Lampe einschalten.

Das Ergebnis soll sein, das nur exklusiv eine Lampe leuchten kann, solange der dazugehörige Schalter eingeschaltet ist. Falls kein Schalter eingeschaltet ist, sind alle Lampen aus.

Ausschaltverzögerung

Da es mitunter sehr kurze Einschaltzeiten geben kann, soll ein Schalter mindestens für eine halbe Sekunde eingeschaltet sein. Daher wäre eine Ausschaltverzögerung um eine halbe Sekunde von Vorteil.

Bin schon gespannt auf Eure antworten.

Grüße aus Berlin

Nicole

  • Annahme: Ein Schalter wird eingeschaltet, die entsprechende Lampe fängt an zu leuchten. Innerhalb der Ausschaltverzögerung wird der Schalter aus- und dafür zwei andere eingeschaltet. Was soll passieren? Nichts? Es leuchtet die erstbeste Lampe? Es leuchtet die Lampe, deren Schalter Millisekunden vor dem anderen eingeschaltet wurde? Was Anderes?- Wenn ein Schalter eingeschaltet wird und die Lampe leuchtet, und dann ein (oder mehrere) anderer Schalter eingeschaltet wird leuchtet ja weiterhin nur die erste Lampe. Wenn ich nun den ersten ausschalte, fängt dann die zweite(/dritte/welche?) Lampe an zu leuchten oder müssen dazu alle Schalter in Aus-Stellung sein?Das Grundprinzip ist klar, aber um es sauber zu machen brauchen wir Informationen zu Grenzfällen... :wink:

  • Was ist mit den 1XUM-Schaltern, sind die alle als Ein/Aus-Schalter verkabelt?

Hi Joghurt

vielen lieben Dank für Deine schnelle Antwort :slight_smile:
Da ich nicht aus dem Elektronikbereich komme, sondern aus der Bildenden Kunst, ist es für mich nicht einfach, die Anweisung für
mein Projekt in der Arduino-Programmiersprache zu formulieren...:wink:

Ein Schalter1 wird eingeschaltet, die entsprechende Lampe1 fängt an zu leuchten. Innerhalb der Einschaltzeit und der Ausschaltverzögerung sollen alle anderen Schalter unterdrückt werden und es leuchtet nur
die Lampe 1.
Erst nachdem die Ausschaltverzögerung beendet ist, dürfen alle anderen
Schalter wieder abgefragt werden. Nur der erste nächste ausgelöste Schalter darf exklusiv seinen Lampenausgang einschalten-alle anderen Schalter und Lampen müssen während der Dauer eines Schaltvorgangs (inklusive der Zeit der Ausschaltverzögerung) unterdrückt werden.

Tatsächlich kommt es häufig vor, daß mehrere Schalter gleichzeitig eingeschaltet werden. Da aber nur maximal nur eine einzige Lampe leuchten darf, brauche ich diese spezielle Programmierung.

Alle Schalter haben zwei Schaltstellungen: Ein und Aus.

Nun bin ich gespannt, ob jemand eine Idee zu dieser Programmierung
hat und mir weiterhelfen kann..

Grüße aus Berlin

Nicole

Nur der erste nächste ausgelöste Schalter darf exklusiv seinen Lampenausgang einschalten

Hmm, das klingt in der Konfiguration als müsste man dann mit Arrays und Schieben anfangen oder mit verketteten Listen oder so. Alles machbar, aber nicht unaufwendig... :-?

Stell Dir vor, jemand schaltet Schalter 1, dann Schalter 2, dann Schalter 4, dann Schalter 5 und dann Schalter 3 ein.
Dann wartet er/sie ein paar Sekunden, und schaltet dann Schalter 1 aus. Dann 2, 3, 4 und dann 5.

Was passiert? Und soll immer das passieren oder ist irgendwas nicht schlimm? Umso "nicht schlimmer" desdo weniger Aufwand. ::slight_smile:

Was von dem Verhalten ist wirklich wichtig, und was ist Beiwerk? Wie wichtig ist das Beiwerk? Wieviel Aufwand ist das Beiwerk wert?

Kannst Du uns was zum Hintergrund der Installation (oder was das werden soll) sagen?

Wenn ziemlich viel davon Beiwerk ist denke ich, dass wir mit vielleicht 20-30 Zeilen Code hinkommen könnten, das ist aber fast beliebig verkomplizierbar... :smiley:

Hallo Joghurt

der Hintergrund meines Arduino Projekts ist, das ich während einer
Performance eine spezielle Elektronik am Körper trage, und ich selbst die Schalter/Lampen mit meinen Bewegungen ein- und ausschalte.

Es ist mir wichtig, das nur ein Schalter in Echtzeit eine Lampe schaltet. Während dieser Einschaltzeit inklusive der Ausschaltverzögerung sollen alle anderen Schalter ignoriert werden.

Wenn das Projekt fertig ist, sende ich Dir gerne eine Webadresse,
in der Du das Ergebnis ansehen kannst :wink:

Du schreibst, es kämen da vielleicht 20-30 Zeilen Code zusammen-
nun bin ich ja sehr neugierig auf Deine Idee zu dieser speziellen Programmierung und ich freue mich schon auf Deine nächste Antwort...

Grüße

Nicole

Update: Streich das, war Quatsch. :wink:

Hi Joghurt

Da die Schalter in Echtzeit ihre Lampen schalten sollen,
ist es wichtig, das während eines aktiven Schaltvorganges alle anderen
Schalter nicht ausgelesen und deren Werte nicht gespeichert werden.

Zwischen den Zuständen des Einschaltens/ein Licht leuchtet, soll es auch Pausen/Zeiten geben, in denen kein Schalter eingeschaltet ist und keine Lampe leuchtet.

Daher soll nach dem Ausschalten eines Schalters/Lampe(+halbe Sekunde Ausschaltverzögerung) erst dann wieder der nächste Schalter ausgelesen werden, wenn er in Echtzeit eingeschaltet wird.

Hoffentlich habe ich mich zu dieser späten Stunde verständlich formuliert :slight_smile:

Vielleicht meintest Du das mit Deiner Frage:
...oder dürfte es auch der komplett zuletzt eingeschaltete Schalter sein?

Falls Du das Gleiche meinst, dann dürfte es nur der nächste eingeschaltete Schalter sein...nachdem der letzte Schalter ausging...

Grüße

Nicole

Nur der erste nächste ausgelöste Schalter darf exklusiv seinen Lampenausgang einschalten

Falls Du das Gleiche meinst, dann dürfte es nur der zuletzt eingeschaltete Schalter sein...

Öhm, ist das nicht das Gegenteil...?

Hi

Du hast Recht, ich werde versuchen, meine Vision zu dieser späten Stunde nochmal verständlicher zu formulieren.

Nach einem Schaltvorgang(+halbe Sekunde Ausschaltverzögerung) dürfte also nur der erste darauffolgende, in Echtzeit ausgelöste Schalter ausgelesen werden und seine Lampe einschalten.

Während eines Ein-Schaltvorgangs dürfen alle anderen Schalter nicht parallel ausgelesen und deren Werte nicht gespeichert werden.

Grüße

Nicole

a) Also ein Schalter schaltet ein, das Licht geht an.
b) Der Schalter schaltet wieder aus, das Licht geht aus.
c) Nach einer halben Sekunde gehts weiter mit a)

Wenn irgendwann zwischendrin ein Schalter geschaltet wird dann wird der einfach nicht berücksichtigt.

So? Wenn ja, wären dann Taster nicht effektiver? Die könnten dann ein- oder aus- oder eben nicht schalten, je nach Situation.
Immer vorausgesetzt, dass das für Deine Anwendung funktioniert.

PS: Hast Du Skype oder so? Schätze, per Voice könnte man das schneller klären... :slight_smile:

Lieber Joghurt...

das ist ein schönes Modell:

a) Also ein Schalter schaltet ein, das Licht geht an.
b) Der Schalter schaltet wieder aus, das Licht geht aus.
c) Nach einer halben Sekunde
d) (+ eventuelle Pausezeit=kein Schalter/Licht an-), gehts weiter mit
a)...

Wenn irgendwann zwischen drin ein Schalter geschaltet wird dann wird der einfach nicht berücksichtigt.

Taster sind in diesem Fall ausgeschlossen, da ich für diese Anwendung nur Kugelschalter verwenden kann.

Nun hoffe ich, das wir meine Vision von Funktion gemeinsam auf den Punkt gebracht haben - vielen lieben Dank dafür :slight_smile:

Vielleicht weisst Du, wie ein mögliche Programmierung aussehen könnte?
Meine wenigen Kenntnisse in Actionscript/Flash reichen leider für die Programmierung meines Arduino Projekts nicht aus.

Skype habe ich noch nicht bei mir eingerichtet und heute bin ich viel zu müde dafür.

Grüße

Nicole

Taster sind in diesem Fall ausgeschlossen, da ich für diese Anwendung nur Kugelschalter verwenden kann.

Kenn ich nicht, sind das sowas wie Quecksilberschalter? Hast Du mal nen Link zu so nem Ding? Willst Du Dir die Dinger an die Glieder schnallen und durch Bewegung schalten oder wie hast Dus vor?

Vielleicht weisst Du, wie ein mögliche Programmierung aussehen könnte?

Also wenn Dus wirklich so haben willst wie in Deiner letzten Post, ohne Schalterspeicherung während das Licht an ist und allem, dann sollten wir mit besagten 20-30 Zeilen effektivem Code hinkommen. :slight_smile:

Skype habe ich noch nicht bei mir eingerichtet und heute bin ich viel zu müde dafür.

::slight_smile: ;D

Ich werd mir Morgen tagsüber mal nen Prototypen nach dieser Spezifikation basteln, wenn ich dazu komme.

Hi,

mit Kugelschaltern meine ich Neigungsschalter, die den elektrischen Kontakt nicht mit Quecksilber, sondern mit einer beweglichen vergoldeten Kugel herstellen. Auf die schnelle habe ich keine URL gefunden, wenn es Dich interessiert, kann ich morgen Dir eine herraussuchen.

Über die Ergebnisse Deines Prototypen würde ich mich sehr freuen, vielleicht kannst Du mir in den nächsten Tagen mit einem möglichen Skript weiterhelfen?

Vielen lieben Dank für Deine Aufmerksamkeit.
Nun wünsche ich Dir eine gute Nacht...
Bis bald hoffentlich?

Nicole

mit Kugelschaltern meine ich Neigungsschalter, die den elektrischen Kontakt nicht mit Quecksilber, sondern mit einer beweglichen vergoldeten Kugel herstellen. Auf die schnelle habe ich keine URL gefunden, wenn es Dich interessiert, kann ich morgen Dir eine herraussuchen.

Nein, das reicht schon, danke. Auch Dir eine gute Nacht. :slight_smile:

Was in der Art sollte eigentlich funktionieren...

      /*
       * a) Also ein Schalter schaltet ein, das Licht geht an.
       * b) Der Schalter schaltet wieder aus, das Licht geht aus.
       * c) Nach einer halben Sekunde
       * d) (+ eventuelle Pausezeit=kein Schalter/Licht an-), gehts weiter mit
       * a)...
       * Wenn irgendwann zwischen drin ein Schalter geschaltet wird dann wird der einfach nicht berücksichtigt.
       */

      /*
       * Zusaetzlich hab ich eine variable Ausschaltzeitverzoegerung eingebaut, Du kannst jetzt mit
       * einem Potentiometer zwischen Betriebsspannung und Masse, mit dem Abgriff am analogen Pin 0
       * einstellen, wie lange die Ausschaltzeitverzoegerung sein soll, aktuell zwischen 0 und rund
       * 2 Sekunden.
       */

      void setup () {
            pinMode(2, INPUT); // Schalter 1
            pinMode(3, INPUT); // Schalter 2
            pinMode(4, INPUT); // Schalter 3
            pinMode(5, INPUT); // Schalter 4
            pinMode(6, INPUT); // Schalter 5

            pinMode(7, OUTPUT); // Lampe 1
            pinMode(8, OUTPUT); // Lampe 2
            pinMode(9, OUTPUT); // Lampe 3
            pinMode(10, OUTPUT); // Lampe 4
            pinMode(11, OUTPUT); // Lampe 5

            pinMode(13, OUTPUT); // Onboard-LED zur Ueberpruefung der Ausschaltzeitverzoegerung/Pausezeit
      }

      void check (int schalterPin, int lampenPin) {
            if (digitalRead(schalterPin) == HIGH) {
                  digitalWrite(lampenPin, HIGH); // Lampe einschalten
                  delay(500); // Einschaltzeitsicherung, mindestens so lang bleibt die Lampe immer an
                  while (digitalRead(schalterPin) == HIGH) {
                        // Waehrend der Schalter an ist hier warten!
                  }
                  digitalWrite(lampenPin, LOW); // Lampe ausschalten

                  digitalWrite(13, HIGH); // LED zur Ueberpruefung der Ausschaltzeitverzoegerung/Pausezeit einschalten
                  delay(analogRead(0) * 2); // Ausschaltzeitverzoegerung/Pausezeit -> 0 bis 2 Sekunden
                  digitalWrite(13, LOW); // LED zur Ueberpruefung der Ausschaltzeitverzoegerung/Pausezeit ausschalten
            }
      }

      void loop () {
            check(2, 7); // Schalter 1 / Lampe 1
            check(3, 8); // Schalter 2 / Lampe 2
            check(4, 9); // Schalter 3 / Lampe 3
            check(5, 10); // Schalter 4 / Lampe 4
            check(6, 11); // Schalter 5 / Lampe 5
      }

Kanns leider hier nicht sauber testen, entwickle in der Firma mit Java... :wink:

Guck mal ob der Link hier bei Dir geht...? Flackert das?

Hi Joghurt,

Deine Zeilen mit dem Skript werde ich sofort testen,
herzlichen Dank dafür!

Nun hoffe ich, das Deine Zeilen "des Rätsels Lösung" sind...da wäre ich alleine nie drauf gekommen!

Der Anfang für das Skript, denke ich sieht so ungefähr aus:

//array initialisieren, 5 Elemente/Lampen sind an Pin2-6 angeschlossen:

int lampenPin[5] = {2,3,4,5,6};

//array initialisieren, 5 Elemente/Schalter an Pin7-11 angeschlossen:

int schalterPin[5]={7,8,9,10,11};

Jetzt werde ich das mal so ausprobieren und sehen, ob`s funktioniert...

Was für Sachen bastelst Du denn so mit dem Arduino?
Deine Webseite flackert nicht.
Wie funktioniert denn diese Animation mit dem Arduino, gibt es eine Anleitung dazu?

Über die Ergebnisse werde ich schnellstmöglich berichten :wink:

Nicole

Deine Zeilen mit dem Skript werde ich sofort testen, herzlichen Dank dafür!

Kein Problem. :slight_smile:

Nun hoffe ich, das Deine Zeilen "des Rätsels Lösung" sind...da wäre ich alleine nie drauf gekommen!

Schaun wir mal, ob das tatsächlich das ist, was Du wolltest... :wink:

Der Anfang für das Skript, denke ich sieht so ungefähr aus:
//array initialisieren, 5 Elemente/Lampen sind an Pin2-6 angeschlossen:
int lampenPin[5] = {2,3,4,5,6};
//array initialisieren, 5 Elemente/Schalter an Pin7-11 angeschlossen:
int schalterPin[5]={7,8,9,10,11};

Öhm, wofür willst Du denn die Arrays verwenden...?

Was für Sachen bastelst Du denn so mit dem Arduino?

Nichts bisher, leider, mir fehlt noch sämtliche Hardware, ich bin noch trockener Theoretiker. :sunglasses:
Ich hab hier noch drei andere große Projekte, bevor meine Regierung mir den Großeinkauf erlaubt... ::slight_smile: :wink:
Schätze mal, in zwei Monaten oder so ist es soweit.

Dann hab ich vor mir ne CNC-Fräse zu bauen, anschließend einen automatischen, gründlichen Reinigungsbot samt Fernsteuerung auf XBee-Basis mit Display, und anschließend einen Hexapod. Aber das kann alles noch etwas dauern, ich bin auch noch nicht wirklich ausreichend gut in C, ich hab definitiv mehr Hobbies als Zeit. ;D

Deine Webseite flackert nicht.

Schön zu hören. :slight_smile:

Wie funktioniert denn diese Animation mit dem Arduino, gibt es eine Anleitung dazu?

Was meinst Du, was es ist oder was es macht?

Es macht ganz genau das, was ich Dir in meiner vorletzten Post gequoted hab, ist der gleiche Code. :slight_smile:

Dahinter steckt ein Arduino-Emulator-Applet in Java, den ich mir letzt mal gebastelt hab. Hier hab ich spaßeshalber z.B. mal die ganzen Basic Examples umgesetzt, und da kann man auch die kompletten Sources runterladen, falls Dus Dir mal angucken willst.

Damit kann ich mich mit der Materie beschäftigen und schnell mal was grundsätzliches wie Deins entwickeln und prüfen, auch wenn mir die echte Hardware noch fehlt. :smiley:

wow hast du die nachgebastelt?
Oder ist das echt nen Interpreter für einfachen Code?

Naja, ich hab die Grundfunktionen der Arduino-IDE nachgebaut, und die Zustände der Ports auf die Grafik gemappt.

Eigentlich keine große Sache, das einzig Kniffelige daran war, den Arduino-Code möglichst unverändert verwenden zu können. :slight_smile:

@Nicole
Zurück zum Thema:

Um nach einem beendeten "Leuchtevent" festzustellen welcher Schalter als nächstes geschlossen wird musst du zunächst mal wissen, welche Schalter in dem Moment alle schon geschlossen sind.

Das merkst du dir z.B. in einem Feld:

#define ANZ_PINS 5
char letzter_status[ANZ_PINS];

Dann klapperst du der Reihe nach jeden Schalter ab und prüfst, ob er von LOW auf HIGH gewechselt hat. Hast du einen solchen gefunden, dann startest du dafür das passende Leuchtevent.

Quick hack, ungetestet:

#define ANZ_PINS 5
char schalter[ANZ_PINS] ={2, 3, 4, 5, 6}; 
char lampe[ANZ_PINS] ={7, 8, 9, 10, 11}; 
char letzter_status[ANZ_PINS];
// in pos merken wir uns, welcher Schalter als nächstes dran ist
char pos;

// Das Leuchtevent
void leuchtevent(char pin)
{
  // Lampe einschalten... 
  digitalWrite(lampe[pin], HIGH);
  // ...mindestens halbe Sekunde warten...
  delay(500); 
  // ... warten bis der Schalter ausgeschaltet wird...
  while (digitalRead(schalter[pin]) == HIGH) {}
  // ...alle Schalterstellungen merken...
  for (int i = 0; i < ANZ_PINS; i++)
  {
    letzter_status[i] = digitalRead(schalter[i]);
  }
  // ... und Lampe wieder ausschalten.
  digitalWrite(lampe[pin], LOW);
}

void setup()
{
  for (int i = 0; i < ANZ_PINS; i++)
  {
    // Schalter sind Input
    pinMode(schalter[i], INPUT);
    // Lampen sind Output
    pinMode(lampe[i], OUTPUT);
    // die Stellung des i-ten Schalters merken
    letzter_status[i] = digitalRead(schalter[i]);
    pos = 0;
  }
}

void loop()
{
  // den aktuellen Schalter abfragen
  char status = digitalRead(schalter[pos]);
  // wurde er eingeschaltet?
  if((letzter_status[pos]==LOW) && (status == HIGH))
    // Ja: Leuchtevent starten
    leuchtevent(pos);
  // für den nächsten Durchlauf den nächsten Schalter benutzen
  pos++;
  // Überlauf: Nach (ANZ_PINS -1) kommt wieder 0
  if(pos >= ANZ_PINS) pos = 0;
}

Gruß
pi