Diskussion:Arduino: Unterschied zwischen den Versionen

Aus BS-Wiki: Wissen teilen
Wechseln zu: Navigation, Suche
Zeile 6: Zeile 6:
 
// **********************************************************************
 
// **********************************************************************
 
// letzte Änderungen:
 
// letzte Änderungen:
 +
// 08.07. serieller Input in Unterprogramm, www gekürzt
 +
// 07.07. Fernbedienung mit Interrupt
 +
// 05.07. Fernbedienung, Serial.begin(115200);
 +
// 23.06. Reset nach Standby
 +
// 21.06. Weiterleitung i. O.
 +
// 18.06. Weiterleitung kaputt? Abgleich mit 08.06., dort funzts
 +
// 08.05.2015: Patch Panel fix
 
// 06.05.2015: Patch Panel aktiviert TO DO: aber irgendwie verschoben
 
// 06.05.2015: Patch Panel aktiviert TO DO: aber irgendwie verschoben
 
// 05.05.2015: Anpassung an Mega 2560 wg. Speicherproblemen beim Uno
 
// 05.05.2015: Anpassung an Mega 2560 wg. Speicherproblemen beim Uno
Zeile 16: Zeile 23:
 
// **********************************************************************
 
// **********************************************************************
 
// TO DOs:
 
// TO DOs:
 +
// bei IR-FB mehrstellige Zahlen: nur die mehrst. OZ, nicht die einzelnen Z. anzeigen
 +
// www geht nich
 
// for-Schleife: Bedingung "Laufindex < Ausbaustufe" ersetzen durch "L. < A. +1", sonst fehlt der letzte Wert
 
// for-Schleife: Bedingung "Laufindex < Ausbaustufe" ersetzen durch "L. < A. +1", sonst fehlt der letzte Wert
 
// Startwert i.d.R. 1, 0 soll unbenutzt bleiben
 
// Startwert i.d.R. 1, 0 soll unbenutzt bleiben
 
//
 
//
 
// **********************************************************************
 
// **********************************************************************
 +
// Pinning Arduino:
 +
// Arduino-Pin 3 als "Dimmer" verbunden mit OE des 74HC595 (dort Pin 13, Output Enable)
 +
byte outputEnablePin = 3;
 +
// Arduino-Pin 8 als shiftPin verbunden mit SH_CP des 74HC595 (dort Pin 11, shift register clock input)
 +
byte shiftPin = 8;
 +
// Arduino-Pin 9 verbunden mit ST_CP des 74HC595 (dort Pin 12, storage register clock input = latch pin)
 +
byte storePin = 9;
 +
// Arduino-Pin 10 verbunden mit DS des 74HC595 (dort Pin 14, serial data input)
 +
byte dataPin = 10;
 
#include <SPI.h>
 
#include <SPI.h>
 
#include <Ethernet.h>
 
#include <Ethernet.h>
Zeile 34: Zeile 52:
 
String readString;
 
String readString;
 
String URL = "http://www.bs-wiki.de/mediawiki/index.php?title=";
 
String URL = "http://www.bs-wiki.de/mediawiki/index.php?title=";
 
+
String Input; // IR, Seriell oder www
// Pinning Arduino & Schieberegister:
+
// Pinning Schieberegister:
// Arduino-Pin 3 als "Dimmer" verbunden mit OE des 74HC595 (dort Pin 13, Output Enable)
 
byte outputEnablePin = 3;
 
// Arduino-Pin 8 als shiftPin verbunden mit SH_CP des 74HC595 (dort Pin 11, shift register clock input)
 
byte shiftPin = 8;
 
// Arduino-Pin 9 verbunden mit ST_CP des 74HC595 (dort Pin 12, storage register clock input = latch pin)
 
byte storePin = 9;
 
// Arduino-Pin 10 verbunden mit DS des 74HC595 (dort Pin 14, serial data input)
 
byte dataPin = 10;
 
 
 
 
// Elemente und LEDs:
 
// Elemente und LEDs:
// 32 ist die derzeitige Ausbaustufe, am Ende 144 LEDs
+
// Ausbaustufe 144 LEDs
 
// Hardware-Info: 12m²-PSE aus 6 Teildisplays, 144/6 = 24 LEDs/Teildisplay,
 
// Hardware-Info: 12m²-PSE aus 6 Teildisplays, 144/6 = 24 LEDs/Teildisplay,
 
// ... jedes Teildisplay angesteuert durch 3x8 Datenleitungen (3 Spalten, 8 Zeilen),
 
// ... jedes Teildisplay angesteuert durch 3x8 Datenleitungen (3 Spalten, 8 Zeilen),
 
// ... pro Spalte ein 8-bit-Schieberegister = 18 SR insgesamt
 
// ... pro Spalte ein 8-bit-Schieberegister = 18 SR insgesamt
byte Ausbaustufe = 32;
+
byte Ausbaustufe = 144;  // 144
 +
byte legende_anfang = 121;
 +
byte legende_ende = 139;
 +
byte Legenden_LEDs = 1 + legende_ende - legende_anfang;
 
// TO DO: vorerst ohne Patchen
 
// TO DO: vorerst ohne Patchen
 
boolean patchmodus = 0;
 
boolean patchmodus = 0;
 
// Auswahl
 
// Auswahl
 
// Ordnungszahl definiert Element 1...118
 
// Ordnungszahl definiert Element 1...118
byte Auswahl = 0;
+
int Auswahl = 0;  // 254
 +
boolean neue_Auswahl;
 
// 0 = existiert nicht
 
// 0 = existiert nicht
 
// 1 = Wasserstoff, 2 = Helium ...
 
// 1 = Wasserstoff, 2 = Helium ...
Zeile 63: Zeile 76:
 
// 161 = Halbmetalle
 
// 161 = Halbmetalle
 
// 162 = Nichtmetalle
 
// 162 = Nichtmetalle
 +
// 180 = Eieruhr auf 180 oder 20 Sekunden
 
// 190 = fest
 
// 190 = fest
 
// 191 = flüssig
 
// 191 = flüssig
Zeile 72: Zeile 86:
 
// 202 = Programm_y
 
// 202 = Programm_y
 
// 203 = Programm_z
 
// 203 = Programm_z
 +
// 209 = Reset
 +
// 210...215 = Helligkeit
 
// 222 = Browserfenster umschalten auf Arduino-Auswahlmenü
 
// 222 = Browserfenster umschalten auf Arduino-Auswahlmenü
 
// 254 = alles_aus
 
// 254 = alles_aus
Zeile 79: Zeile 95:
 
unsigned int led_aus[144];
 
unsigned int led_aus[144];
 
// virtuelles Patchpanel: Zuordnung Ordungszahl/Pin, z. B. Natrium mit OZ 11 an *Pin 3*:
 
// virtuelles Patchpanel: Zuordnung Ordungszahl/Pin, z. B. Natrium mit OZ 11 an *Pin 3*:
byte Element_an_Pin[144] = {
+
byte Pin_von_Element[145] = { 0, 1, 137
  // Pinning ohne eine "Led #0"
+
                              , 2, 9, 97, 105, 113, 121, 129, 138
  //p1p2*p3*p4  p5  p6  p7  p8 - p9 p10 p11 p12 p13 p14 p15  p16 -p17  p18  p19 p20 p21 p22  p23 p24-
+
                              , 3, 10, 98, 106, 114, 122, 130, 139
  1, 3, 11, 19, 37, 55, 87, 144, 4, 12, 20, 38, 56, 88, 119, 120, 121, 122, 21, 39, 71, 103, 57, 89
+
                              , 4, 11, 19, 27, 35, 43, 51, 59, 67, 75, 83, 91, 99, 107, 115, 123, 131, 140
  //
+
                              , 5, 12, 20, 28, 36, 44, 52, 60, 68, 76, 84, 92, 100, 108, 116, 124, 132, 141
  // p25 p26  p27 p28 p29 p30  p31 p32-p33  p34  p35 p36 p37 p38  p39 p40-p41  p42  p43 p44 p45 p46  p47 p48
+
                              , 6, 13, 23, 31, 39, 47, 55, 63, 71, 79, 87, 95, 103, 111, 119, 127, 21, 29, 37, 45, 53, 61, 69, 77, 85, 93, 101, 109, 117, 125, 133, 142
  , 123, 124, 22, 40, 72, 104, 58, 90, 125, 126, 23, 41, 73, 105, 59, 91, 127, 128, 24, 42, 74, 106, 60, 92
+
                              , 7, 14, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 22, 30, 38, 46, 54, 62, 70, 78, 86, 94, 102, 110, 118, 126, 134, 143, 15, 16, 17, 18, 25, 26, 33, 34, 41, 42, 49, 50, 57, 58, 65, 66, 73, 74, 81, 82, 89, 90, 135, 136, 144
  //
+
                              , 8
  // p49 p50  p51 p52 p53 p54  p55 p56-p57  p58  p59 p60 p61 p62  p63 p64-p65  p66  p67 p68 p69 p70  p71 p72
+
                            };
  , 129, 130, 25, 43, 75, 107, 61, 93, 131, 132, 26, 44, 76, 108, 62, 94, 133, 134, 27, 45, 77, 109, 63, 95
+
// TO DO: löschen:
  //
+
// byte Element_an_Pin[145] = { 0, 1, 3, 11, 19, 37, 55
  // p73 p74  p75 p76 p77 p78  p79 p80-p81  p82  p83 p84 p85 p86  p87 p88-p89  p90  p91 p92 p93 p94  p95 p96
+
//                            // Pinning ohne eine "Led #0"
  , 135, 136, 28, 46, 78, 110, 64, 96, 137, 138, 29, 47, 79, 111, 65, 97, 139, 140, 30, 48, 80, 112, 66, 98
+
//                            //p1p2*p3*p4  p5  p6  p7  p8 - p9 p10 p11 p12 p13 p14 p15  p16 -p17  p18  p19 p20 p21 p22  p23 p24-
  //
+
//                            , 87, 144, 4, 12, 20, 38, 56, 88, 119, 120, 121, 122, 21, 39, 71, 103, 57, 89
  // p97p98 p99 p100p101p102 p103p104-p105p106p107p108p109p110p111p112-p113p114p115p116p117p118p119p120
+
//                            //
  ,  5, 13, 31, 49, 81, 113, 67, 99, 6, 14, 32, 50, 82, 114, 68, 100, 7, 15, 33, 51, 83, 115, 69, 101
+
//                            // p25 p26  p27 p28 p29 p30  p31 p32-p33  p34  p35 p36 p37 p38  p39 p40-p41  p42  p43 p44 p45 p46  p47 p48
  //
+
//                            , 123, 124, 22, 40, 72, 104, 58, 90, 125, 126, 23, 41, 73, 105, 59, 91, 127, 128, 24, 42, 74, 106, 60, 92
  //p121p122p123p124p125p126p127p128-p129p130p131p132p133p134p135 p136-p137p138p139p140p141p142p143p144
+
//                            //
  , 8, 16, 34, 52, 84, 116, 70, 102, 9, 17, 35, 53, 85, 117, 141, 142, 2, 10, 18, 36, 54, 86, 118, 143
+
//                            // p49 p50  p51 p52 p53 p54  p55 p56-p57  p58  p59 p60 p61 p62  p63 p64-p65  p66  p67 p68 p69 p70  p71 p72
};
+
//                            , 129, 130, 25, 43, 75, 107, 61, 93, 131, 132, 26, 44, 76, 108, 62, 94, 133, 134, 27, 45, 77, 109, 63, 95
 +
//                            //
 +
//                            // p73 p74  p75 p76 p77 p78  p79 p80-p81  p82  p83 p84 p85 p86  p87 p88-p89  p90  p91 p92 p93 p94  p95 p96
 +
//                            , 135, 136, 28, 46, 78, 110, 64, 96, 137, 138, 29, 47, 79, 111, 65, 97, 139, 140, 30, 48, 80, 112, 66, 98
 +
//                            //
 +
//                            // p97p98 p99 p100p101p102 p103p104-p105p106p107p108p109p110p111p112-p113p114p115p116p117p118p119p120
 +
//                            ,  5, 13, 31, 49, 81, 113, 67, 99, 6, 14, 32, 50, 82, 114, 68, 100, 7, 15, 33, 51, 83, 115, 69, 101
 +
//                            //
 +
//                            //p121p122p123p124p125p126p127p128-p129p130p131p132p133p134p135 p136-p137p138p139p140p141p142p143p144
 +
//                            , 8, 16, 34, 52, 84, 116, 70, 102, 9, 17, 35, 53, 85, 117, 141, 142, 2, 10, 18, 36, 54, 86, 118, 143
 +
//                          };
 
// Element_an_Pin[] nach steigender Ordungszahl notieren:
 
// Element_an_Pin[] nach steigender Ordungszahl notieren:
// TO DO wg. Speicherproblemen vorerst aus:
 
 
byte patch[144];
 
byte patch[144];
 
 
byte Anzahl_angeschaltete_LEDs = 0;
 
byte Anzahl_angeschaltete_LEDs = 0;
unsigned int t_gesamt_in_sek = millis() / 1000;
 
 
// TO DO: über Poti einstellen und von Pin einlesen oder über Webinterface
 
// TO DO: über Poti einstellen und von Pin einlesen oder über Webinterface
byte Eieruhr = 20;  // Vorgabe der Einschaltdauer einer LED in Sekunden
+
unsigned int Eieruhr = 20;  // Vorgabe der Einschaltdauer einer LED in Sekunden
 +
byte last_Element = 0;
 
int zyklus = 0; // loop-Zyklen
 
int zyklus = 0; // loop-Zyklen
 +
unsigned int last_call = Laufzeit_in_sek();
 +
int serial_a = 0;
 +
int serial_nr = 0;
 
// Debugging
 
// Debugging
int bremse = 1;  // 1 ... 60000 Standardwert für Entschleunigung in ms zwischen einigen Befehlen zwecks Debugging
+
int bremse = 0;  // 1 ... 60000 Standardwert für Entschleunigung in ms zwischen einigen Befehlen zwecks Debugging
 +
//
 +
// IR - Fernbedienung
 +
// Arduino IR Remote Sniffer
 +
// Portions © Andrew Ippoliti - acipo.com
 +
// TODO: mehrstellige Zahlen abfragen
 +
const int pinIR = 2;
 +
volatile boolean bounced = 0;
 +
const byte CODE_LEN = 40;
 +
volatile unsigned long durations[CODE_LEN];
 +
int letzte_IR_Auswahl;
 +
boolean mehrstellig;
 
// **********************************************************************
 
// **********************************************************************
 
void setup() {
 
void setup() {
   Dimmer(127); // halbe Helligkeit = halbe Stromstärke
+
   pinMode(outputEnablePin, OUTPUT); // Dimmer
   Serial.begin(9600); // Kontrollausgabe über seriellen Monitor
+
  analogWrite(outputEnablePin, 255); // entspricht 5 Volt an OE und damit LEDs aus
 +
   Serial.begin(115200); // Kontrollausgabe über seriellen Monitor
 +
  Serial.flush(); // löscht den Inhalt des seriellen Puffers
 +
  // CHECK Fenster: es kommt Müll, wenn nicht 'kein Zeilenende' eingestellt ist!
 
   // Pin 5 abfragen (analog, EMK) für Zufallszahl
 
   // Pin 5 abfragen (analog, EMK) für Zufallszahl
 
   // randomSeed(analogRead(5));
 
   // randomSeed(analogRead(5));
 
   // Pins 3, 8,9,10 auf Ausgabe
 
   // Pins 3, 8,9,10 auf Ausgabe
   pinMode(outputEnablePin, OUTPUT); // Dimmer
+
   //  pinMode(outputEnablePin, OUTPUT); // Dimmer
 
   pinMode(storePin, OUTPUT);
 
   pinMode(storePin, OUTPUT);
 
   pinMode(shiftPin, OUTPUT);
 
   pinMode(shiftPin, OUTPUT);
 
   pinMode(dataPin, OUTPUT);
 
   pinMode(dataPin, OUTPUT);
 +
 +
  // IR-Fernbedienung
 +
  pinMode(pinIR, INPUT);
 +
  attachInterrupt(0, decodeIR, FALLING);
 +
  //FALLING for when the Digitalpin 2 goes from high to low.
 +
 
   // start the Ethernet connection and the server:
 
   // start the Ethernet connection and the server:
 
   Ethernet.begin(mac, ip, gateway, subnet);
 
   Ethernet.begin(mac, ip, gateway, subnet);
Zeile 126: Zeile 173:
 
   Serial.print("server is at ");
 
   Serial.print("server is at ");
 
   Serial.println(Ethernet.localIP());
 
   Serial.println(Ethernet.localIP());
 +
  Serial.println("PSE");
 +
  Serial.println("--------------------------------");
 +
  // TO DO: löschen:
 +
  // Switchen, Element_an_Pin[] nach steigender Ordungszahl merken:
 +
  //  for (byte z = 1; z < 144 + 1; z++) {
 +
  //    patch[Element_an_Pin[z]] = z;
 +
  //    //  //    // Ordnungszahl
 +
  //  }
  
   resetPins();  // alle Pins auf LOW
+
   // for (byte z = 1; z < 144 + 1; z++) {
  // Switchen, Element_an_Pin[] nach steigender Ordungszahl merken:
+
  //    //    Serial.print("Pin: ");
  // TO DO wg. Speicherproblemen vorerst aus:
+
  //    //    Serial.print(z);
  for (byte z = 1; z < 144 + 1; z++) {
+
  //    //    Serial.print(" = OZ: ");
    patch[Element_an_Pin[z]] = z;
+
  //    //    Serial.print(Element_an_Pin[z]);
    // //    // Ordnungszahl
+
  //    //    Serial.print(" = Patch(OZ): ");
   }
+
  //    Serial.print(patch[z]);
 +
  //   //    Serial.println();
 +
  //   Serial.print(", ");
 +
   //  }
 +
  //  Serial.println();
 +
  reset();
 
   // ***********************
 
   // ***********************
 
   // Kontrolle
 
   // Kontrolle
Zeile 145: Zeile 205:
 
   //      Serial.println(". Zeile");
 
   //      Serial.println(". Zeile");
 
   //      byte z = zeile + 8 * (spalte - 1);
 
   //      byte z = zeile + 8 * (spalte - 1);
  //      delay(1000);
+
   //      Serial.print("OZ ");
   //      Serial.print("Pin ");
 
 
   //      Serial.print(z);
 
   //      Serial.print(z);
   //      Serial.print(" - OZ ");
+
   //      Serial.print(" - Pin ");
   //      Serial.println(Element_an_Pin[z]);
+
   //      Serial.println(Pin_von_Element[z]);
  //      Serial.print("Patch = ");
 
  //      Serial.println(patch[z]);
 
 
   //    }
 
   //    }
 
   //  }
 
   //  }
 
   // für Testphase LEDs im setup einschalten, später in loop:
 
   // für Testphase LEDs im setup einschalten, später in loop:
 
   //  Element = 7;  // blau
 
   //  Element = 7;  // blau
 
 
   Led_an(7, 1);
 
   Led_an(7, 1);
  delay(bremse);
 
  Serial.println("alle_Elemente_an");
 
  Auswahl_alles_an();
 
  Serial.println("alle_Elemente sind an");
 
  delay(bremse);
 
  Serial.println("alle_Elemente_aus");
 
  Auswahl_alles_aus();
 
  Serial.println("alle_Elemente sind aus");
 
 
   delay(bremse);
 
   delay(bremse);
 
   Legende_an();
 
   Legende_an();
Zeile 175: Zeile 223:
 
void loop () {
 
void loop () {
 
   zyklus = zyklus + 1;
 
   zyklus = zyklus + 1;
   Serial.print(zyklus);
+
   //  Serial.print(zyklus);
   Serial.println(". Loop");
+
   //  Serial.println(". Loop");
 +
 
 
   // vergesse die bisherige Auswahl, LED nicht erneut anschalten:
 
   // vergesse die bisherige Auswahl, LED nicht erneut anschalten:
   Auswahl = 0;
+
   // Auswahl = 0;
   // horche an der seriellen Schnittstelle und am Ethernet-Shield
+
  //  neue_Auswahl = 0;
 +
   // horche an IR-FB (Interrupt), der seriellen Schnittstelle und am Ethernet-Shield
 
   // erfrage Element; nach Ordnungszahl o. ä. auswählen:
 
   // erfrage Element; nach Ordnungszahl o. ä. auswählen:
 
   // z.B. Nr. 1 - Wasserstoff:
 
   // z.B. Nr. 1 - Wasserstoff:
 +
  serielle();
 
   www();
 
   www();
   while (Serial.available() > 0)
+
 
   {
+
   if (neue_Auswahl) {
     Serial.println("Ich bin www-taub!");
+
    zyklus = 0; // Schlafmodus beenden
     byte a = 0;
+
    neue_Auswahl = 0;
     {
+
    last_call = Laufzeit_in_sek();
       Auswahl = Auswahl * 10;
+
    Serial.print("neue Auswahl von ");
       a = Serial.read() - '0';
+
    Serial.println(Input);
       Auswahl = Auswahl + a;
+
    //   delay(4000);
       delay(1);
+
     Serial.println(Auswahl);
 +
     Serial.println();
 +
     switch (Auswahl) {
 +
       case 1 ... 118: Led_an(Auswahl, 1); break;
 +
       case 131 ... 139: Auswahl_Periode(); break;      // = 1. - 7. Periode, Lanthanoide, A.
 +
      case 141 ... 148: Auswahl_Hauptgruppe(); break;  // = 1. - 8. Hauptgruppe
 +
      case 160: Auswahl_Metalle(); break;
 +
      case 161: Auswahl_Halbmetalle(); break;
 +
      case 162: Auswahl_Nichtmetalle(); break;
 +
      case 180: Eieruhr_switchen(); break;  //  auf 180 oder 20 Sekunden
 +
      case 190: Auswahl_fest(); break;
 +
      case 191: Auswahl_liquid(); break;
 +
      case 192: Auswahl_gas(); break;
 +
      case 193: Auswahl_radioaktiv(); break;
 +
      case 194: Auswahl_biatomar(); break;
 +
      case 200: Auswahl_Bingo(); break;
 +
      case 201: Auswahl_Programm_x(); break;
 +
      case 202: Auswahl_Programm_y(); break;
 +
      case 203: Auswahl_Programm_z(); break;
 +
      case 209: reset(); break;
 +
      case 210 ... 215: Auswahl_Helligkeit(); break;
 +
      //    case 222: www(); break;
 +
      case 254: Auswahl_alles_aus(); break;
 +
       case 255: Auswahl_alles_an(); break;
 +
       default:  // unbelegte Zahlen sind unsinnig und werden genullt:
 +
        Serial.println("keine neue Auswahl");
 +
        //    Auswahl = 0;
 
     }
 
     }
     Serial.write(Auswahl);
+
     Auswahl = 0;
  }
+
     //  delay(3000);
  delay(bremse);
 
  switch (Auswahl) {
 
    case 1 ... 118: Led_an(Auswahl, 1); break;
 
    case 131 ... 139: Auswahl_Periode(); break;      // = 1. - 7. Periode, Lanthanoide, A.
 
    case 141 ... 148: Auswahl_Hauptgruppe(); break;  // = 1. - 8. Hauptgruppe
 
    case 160: Auswahl_Metalle(); break;
 
    case 161: Auswahl_Halbmetalle(); break;
 
    case 162: Auswahl_Nichtmetalle(); break;
 
    case 190: Auswahl_fest(); break;
 
    case 191: Auswahl_liquid(); break;
 
    case 192: Auswahl_gas(); break;
 
    case 193: Auswahl_radioaktiv(); break;
 
    case 194: Auswahl_biatomar(); break;
 
    case 200: Auswahl_Bingo(); break;
 
    case 201: Auswahl_Programm_x(); break;
 
    case 202: Auswahl_Programm_y(); break;
 
    case 203: Auswahl_Programm_z(); break;
 
     //   case 222: www(); break;
 
    case 254: Auswahl_alles_aus(); break;
 
    case 255: Auswahl_alles_an(); break;
 
    default: // unbelegte Zahlen sind unsinnig und werden genullt:
 
      Serial.print("KOMISCHE Auswahl: ");
 
      Serial.println(Auswahl);
 
      Auswahl = 0;
 
      delay(bremse);
 
 
   }
 
   }
 +
 
   // TO DO: wenn Legende mit mehreren LED hinterleuchtet wird, diese Anzahl statt der "1" einsetzen:
 
   // TO DO: wenn Legende mit mehreren LED hinterleuchtet wird, diese Anzahl statt der "1" einsetzen:
   if (Anzahl_angeschaltete_LEDs > 1) {
+
   if (Anzahl_angeschaltete_LEDs > Legenden_LEDs) {
 
     Treppenlicht();
 
     Treppenlicht();
 
   }
 
   }
   if (zyklus > 500) {        // 999
+
   // Serial.println(Laufzeit_in_sek() - last_call);
    // 1000-mal is nichts passiert, daher:
+
  //  if ((last_call + 10) < Laufzeit_in_sek()) {
    Auswahl_alles_aus();
+
  //    Serial.println("----- 10s später -------------------------------");
    //TO DO: ggf. Sleep-Modus mit Bewegungsmelder zum Reaktivieren
+
  //            reset();
   }
+
  //  }
   Serial.println("------------------------------------");
+
  //  if (zyklus > 9999) {        // 999
   delay(bremse);
+
  //    // 1000-mal is nichts passiert, daher:
 +
  //    reset();
 +
  //    Serial.println("-----ALLE LEDS AUS -------------------------------");
 +
  //    delay(3000);
 +
  //    //TO DO: ggf. Sleep-Modus mit Bewegungsmelder zum Reaktivieren
 +
   //  }
 +
   //  Serial.println("------------------------------------");
 +
   //  delay(bremse);
 
}
 
}
 
// **********************************************************************
 
// **********************************************************************
 
// ############### Funktionen nach ABC ##############################
 
// ############### Funktionen nach ABC ##############################
 
// **********************************************************************
 
// **********************************************************************
void Auswahl_alles_an() {
+
void Auswahl_alles_an() {             // 255
 +
  Serial.println("alle_Elemente_an");
 
   for (byte z = 1; z < Ausbaustufe + 1; z++) {
 
   for (byte z = 1; z < Ausbaustufe + 1; z++) {
 
     Led_an(z, 1);
 
     Led_an(z, 1);
 
   }
 
   }
 +
  Serial.println("alle_Elemente sind an");
 
}
 
}
 
// **********************************************************************
 
// **********************************************************************
 
void Auswahl_alles_aus() {
 
void Auswahl_alles_aus() {
 
   // schaltet alle LEDs außer die für die Legende aus
 
   // schaltet alle LEDs außer die für die Legende aus
 +
  Serial.println("alle_Elemente_aus");
 
   for (byte z = 1; z < Ausbaustufe + 1; z++) {
 
   for (byte z = 1; z < Ausbaustufe + 1; z++) {
 
     Led_an(z, 0);
 
     Led_an(z, 0);
 
   }
 
   }
 +
  Serial.println("alle_Elemente sind aus");
 
   Legende_an();
 
   Legende_an();
 
}
 
}
Zeile 289: Zeile 353:
 
       Led_an(2, 1); Led_an(10, 1); Led_an(18, 1); Led_an(36, 1); Led_an(54, 1); Led_an(86, 1); Led_an(118, 1); break;
 
       Led_an(2, 1); Led_an(10, 1); Led_an(18, 1); Led_an(36, 1); Led_an(54, 1); Led_an(86, 1); Led_an(118, 1); break;
 
   }
 
   }
 +
}
 +
// **********************************************************************
 +
void Auswahl_Helligkeit() {
 +
  //  210 ... 215
 +
  byte Helligkeit = 5 + 50 * (Auswahl - 210);
 +
  // 210 -> 5, 211 -> 55, ... 215 -> 255
 +
  Dimmer(Helligkeit);
 
}
 
}
 
// **********************************************************************
 
// **********************************************************************
Zeile 365: Zeile 436:
 
// **********************************************************************
 
// **********************************************************************
 
void Auswahl_Programm_x() { // 201
 
void Auswahl_Programm_x() { // 201
   // z. Zt. Dimmer-Test
+
   // z. Zt. -Test
 
   //  delay(5000);
 
   //  delay(5000);
 
   for (int b = 0; b <= 255; b = b + 15)
 
   for (int b = 0; b <= 255; b = b + 15)
Zeile 371: Zeile 442:
 
     Dimmer(b);
 
     Dimmer(b);
 
     Led_an(1, 1);
 
     Led_an(1, 1);
     delay(3000);
+
     delay(300);
 
   }
 
   }
 
   Led_an(1, 0);
 
   Led_an(1, 0);
 
}
 
}
 
// **********************************************************************
 
// **********************************************************************
void Auswahl_Programm_y() {
+
void Auswahl_Programm_y() { // 202
 
+
  unsigned int Eieruhr_2 = Eieruhr; // Standardwert merken und neu festlegen
 +
  Eieruhr = 1;
 +
  Serial.println("Flackermann");
 +
  for (byte z = 1; z < Ausbaustufe + 1; z++) {
 +
    byte zufall = random(1, Ausbaustufe);
 +
    // setzt 'zufall' mit einer Zufallszahl
 +
    // zwischen 1 und Ausbaustufe gleich
 +
    Serial.print("Zufalls-Element: ");
 +
    Serial.println(zufall);
 +
    Led_an(zufall, 1);
 +
    Treppenlicht();
 +
  }
 +
  Eieruhr = Eieruhr_2; // Standardwert zurückschreiben
 
}
 
}
 
// **********************************************************************
 
// **********************************************************************
Zeile 393: Zeile 476:
 
// **********************************************************************
 
// **********************************************************************
 
void Dimmer(byte Helligkeit) // 0 to 255
 
void Dimmer(byte Helligkeit) // 0 to 255
// Funktion merkt sich Helligkeitswert für LEDs, ausbaubedingt z. Zt. nur am 1. Schieberister
+
// Funktion merkt sich Helligkeitswert für LEDs, ausbaubedingt z. Zt. nur Einheitswert für alle Schieberister
 
// 0 = dunkel, weil 0% Einschaltdauer, 255 = volle Leistung, weil 100% ED
 
// 0 = dunkel, weil 0% Einschaltdauer, 255 = volle Leistung, weil 100% ED
 
{
 
{
Zeile 399: Zeile 482:
 
}
 
}
 
// **********************************************************************
 
// **********************************************************************
void Laufzeit_hhmmss() {
+
void Eieruhr_switchen() {  // switchen auf 180 oder 20 Sekunden
  t_gesamt_in_sek = millis() / 1000;
+
   Serial.print("Eieruhr switchen von ");
   // millis() gibt den Wert in Millisekunden als 'unsigned int' Datentyp zurück, berechnet seitdem das Arduino
+
   Serial.print(Eieruhr);
   // Board das aktuelle Programm gestartet hat.
+
   Serial.print(" auf ");
  // nullt bei ?? ms
+
   switch (Eieruhr) {
  byte t_gesamt_in_h = millis() / 3600000;
+
    case 20: Eieruhr = 180; break;      // LEDs 3 Minuten anlassen
   byte t_gesamt_in_m = millis() / 60000 - t_gesamt_in_h * 60;
+
    case 180: Eieruhr = 20; break;     // LEDs 20s anlassen
  byte t_gesamt_in_s = millis() / 1000 - t_gesamt_in_m * 60;
+
  }
   Serial.print("Laufzeit hh:mm:ss = ");
+
   Serial.print(Eieruhr);
   Serial.print(t_gesamt_in_h);
+
   Serial.print(" Sekunden");
  Serial.print(":");
+
}
   Serial.print(t_gesamt_in_m);
+
// **********************************************************************
   Serial.print(":");
+
unsigned int Laufzeit_in_sek() {
   Serial.print(t_gesamt_in_s);
+
   unsigned int t_gesamt_in_sek = millis() / 1000;
   Serial.println();
+
   return t_gesamt_in_sek;
 
}
 
}
 +
 +
// void Laufzeit_hhmmss() {
 +
//  t_gesamt_in_sek = millis() / 1000;
 +
// millis() gibt den Wert in Millisekunden als 'unsigned int' Datentyp zurück, berechnet seitdem das Arduino
 +
// Board das aktuelle Programm gestartet hat.
 +
// nullt bei ?? ms
 +
//  byte t_gesamt_in_h = millis() / 3600000;
 +
//  byte t_gesamt_in_m = millis() / 60000 - t_gesamt_in_h * 60;
 +
//  byte t_gesamt_in_s = millis() / 1000 - t_gesamt_in_m * 60;
 +
//  Serial.print("Laufzeit hh:mm:ss = ");
 +
//  Serial.print(t_gesamt_in_h);
 +
//  Serial.print(":");
 +
//  Serial.print(t_gesamt_in_m);
 +
//  Serial.print(":");
 +
//  Serial.print(t_gesamt_in_s);
 +
//  Serial.println();
 +
// }
 
// **********************************************************************
 
// **********************************************************************
 
void Led_an(byte Element, boolean an) {
 
void Led_an(byte Element, boolean an) {
   // Funktion schaltet eine durch (Element) bestimmte LEDs an oder aus,
+
   // Funktion schaltet durch (Element) bestimmte Pins (= LEDs) an oder aus,
 
   // plant einen Ausschaltpunkt (led_aus[Element]) und merkt sich die Anzahl_angeschaltete_LEDs.
 
   // plant einen Ausschaltpunkt (led_aus[Element]) und merkt sich die Anzahl_angeschaltete_LEDs.
   // TO DO: switch Element/LED, z. B. bei Element 11 (Natrium) die 3. Led schalten
+
   // 'Element' ist die OZ, 'an' der Schaltzustand 0/1
   // patch it:
+
  // 'pin' ist der tatsächliche Anschlusspunkt der LED-Matrix, z. B. bei Element 22 (Titan, logisch)
   if (patchmodus) {
+
  //  die 27. Led (physikalisch) schalten. Zuordnung Pin/Element:
    Element = patch[Element];
+
   byte Pin = Element;  // Probebetrieb ohne Patchmodus: OZ 22 = Pin 22
   }
+
   //  if (patchmodus) {   // Normalfall: OZ 22 = Pin 27
   zyklus = 0; // Schlafmodus beenden
+
  //    Pin = Pin_von_Element[Element];
   Laufzeit_hhmmss();
+
   //  }
   Serial.print(Element);
+
   // Laufzeit_hhmmss();
   Serial.print(". LED wird geschaltet von ");
+
  // Serial.print(Pin);
   Serial.print(led[Element]);
+
   //  Serial.print(". Pin = ");
   Serial.print(" -> ");
+
   //  Serial.print(Element);
   Serial.println(an);
+
   //  Serial.print(". Element wird geschaltet von ");
 +
   //  Serial.print(led[Pin]);
 +
   //  Serial.print(" -> ");
 +
   //  Serial.println(an);
 
   // TO DO: wenn Ausbaustufe 144 erreicht, diese LEDs immer anlassen:
 
   // TO DO: wenn Ausbaustufe 144 erreicht, diese LEDs immer anlassen:
 
   // solange Ausbaustufe 144 noch nicht erreicht, ersatzweise Led #9:
 
   // solange Ausbaustufe 144 noch nicht erreicht, ersatzweise Led #9:
Zeile 437: Zeile 540:
 
   // mitzählen, wieviel LEDs insgesamt an sind:
 
   // mitzählen, wieviel LEDs insgesamt an sind:
 
   // nur ausführen, wenn (an -> aus) oder (aus -> an), nicht bei (bleibt an) oder (bleibt aus)
 
   // nur ausführen, wenn (an -> aus) oder (aus -> an), nicht bei (bleibt an) oder (bleibt aus)
   if (an != led[Element]) {
+
   if (an != led[Pin]) {
 
     Anzahl_angeschaltete_LEDs = Anzahl_angeschaltete_LEDs + an * 2 - 1; // Anz. = Anz. -1 oder +1
 
     Anzahl_angeschaltete_LEDs = Anzahl_angeschaltete_LEDs + an * 2 - 1; // Anz. = Anz. -1 oder +1
 
   }
 
   }
 
   //}
 
   //}
   led[Element] = an;
+
   led[Pin] = an;
   Serial.print(Anzahl_angeschaltete_LEDs);
+
   // Zwischenbilanz für Kontrolle
   Serial.print(" LEDs sind an: ");
+
  //  Serial.print(Anzahl_angeschaltete_LEDs);
   for (byte z = 1; z < Ausbaustufe + 1; z++) {
+
   //  Serial.print(" LEDs sind an: ");
    if (led[z]) {
+
   //  for (byte z = 1; z < Ausbaustufe + 1; z++) {
      Serial.print(z);
+
  //    if (led[z]) {
      Serial.print("-");
+
  ////      Serial.print("p_");
    }
+
  ////      Serial.print(z);
   }
+
  ////      Serial.print("-");
   // nur für Fehlerabfrage
+
  //    }
   if (Anzahl_angeschaltete_LEDs > Ausbaustufe) {
+
   //  }
    Serial.println("F E H L E R : zuviele LEDs geschaltet!");
+
   //  Serial.println();
    delay(bremse);
+
  //  // nur für Fehlerabfrage
   }
+
   //  if (Anzahl_angeschaltete_LEDs > Ausbaustufe) {
 +
  //    Serial.println("F E H L E R : zuviele LEDs geschaltet!");
 +
  //    delay(bremse);
 +
   //  }
 
   // spart Speicher: unsigned long led_Start zu byte einkürzen:
 
   // spart Speicher: unsigned long led_Start zu byte einkürzen:
 
   if (an) {
 
   if (an) {
     led_aus[Element] = t_gesamt_in_sek + Eieruhr; // vormerken: LED nach (Eieruhr) Sek. wieder ausschalten
+
     led_aus[Pin] = Laufzeit_in_sek() + Eieruhr; // vormerken: LED nach (Eieruhr) Sek. wieder ausschalten
 +
    last_Element = Element;  // welches Element wurde zuletzt angeschaltet?
 
   }
 
   }
 
   resetPins();
 
   resetPins();
Zeile 466: Zeile 573:
 
     // Jetzt den Wert der aktuellen Stelle ans Datenpin DS anlegen
 
     // Jetzt den Wert der aktuellen Stelle ans Datenpin DS anlegen
 
     digitalWrite(dataPin, led[i]);
 
     digitalWrite(dataPin, led[i]);
    // ALIAS  digitalWrite(dataPin, led[patch[i]]);
 
 
     // Dann ShiftPin SHCP von LOW auf HIGH, damit wird der Wert
 
     // Dann ShiftPin SHCP von LOW auf HIGH, damit wird der Wert
 
     // am Datenpin ins Register geschoben.
 
     // am Datenpin ins Register geschoben.
Zeile 478: Zeile 584:
 
   // neues Muster einschalten:
 
   // neues Muster einschalten:
 
   digitalWrite(storePin, HIGH);
 
   digitalWrite(storePin, HIGH);
   delay(bremse);
+
   //  // Serial.print(Element);
  // Serial.print(Element);
+
   //  //  Serial.print(". LED ist ");
   //  Serial.print(". LED ist ");
+
   //  // Serial.println(an);
   // Serial.println(an);
+
   //  Serial.println("--------------------");
   Serial.println("--------------------");
+
   //  delay(bremse);
   delay(bremse);
 
 
}
 
}
 
// **********************************************************************
 
// **********************************************************************
 
void Legende_an() {
 
void Legende_an() {
 
   // TO DO: solange Ausbaustufe 144 noch nicht erreicht, ersatzweise Led #9:
 
   // TO DO: solange Ausbaustufe 144 noch nicht erreicht, ersatzweise Led #9:
   Led_an(9, 1);
+
   //  Led_an(9, 1);
 
   // wenn Ausbaustufe 144 erreicht, diese LEDs immer anlassen:
 
   // wenn Ausbaustufe 144 erreicht, diese LEDs immer anlassen:
  //   for (byte z = 121; z < 139; z++) {
+
   for (byte z = legende_anfang; z < legende_ende + 1; z++) {
  //      Led_an(z, 1);
+
    Led_an(z, 1);
   // }
+
   }
 +
}
 +
// **********************************************************************
 +
void reset() {
 +
  resetPins();
 +
  Dimmer(0);
 +
  Eieruhr = 20;
 +
  Anzahl_angeschaltete_LEDs = 0;
 +
  for (byte i = 1; i < Ausbaustufe + 1; i++) {
 +
    led[i] = 0;
 +
    digitalWrite(dataPin, led[i]);
 +
    digitalWrite(shiftPin, HIGH);
 +
  }
 +
  Dimmer(127);
 +
  digitalWrite(storePin, HIGH);
 +
  Legende_an();
 +
  Auswahl = 0;
 +
  neue_Auswahl = 0;
 +
  zyklus = 0; // Schlafmodus beenden
 
}
 
}
 
// **********************************************************************
 
// **********************************************************************
Zeile 503: Zeile 626:
 
// **********************************************************************
 
// **********************************************************************
 
void Treppenlicht() {
 
void Treppenlicht() {
   Serial.println("Treppenlicht");
+
   //TO DO an Pin anpassen
 +
  //  Serial.println("Treppenlicht");
 
   // schaltet die LED nach (Eieruhr) Sek. wieder aus
 
   // schaltet die LED nach (Eieruhr) Sek. wieder aus
   Laufzeit_hhmmss();
+
   //  t_gesamt_in_sek = Laufzeit_in_Sek();
 
   for (byte z = 1; z < Ausbaustufe + 1; z++) {
 
   for (byte z = 1; z < Ausbaustufe + 1; z++) {
 
     if (led[z]) {
 
     if (led[z]) {
       Serial.print("t_gesamt_in_sek: ");
+
       //    Serial.print("t_gesamt_in_sek: ");
       Serial.println(t_gesamt_in_sek);
+
       //      Serial.println(t_gesamt_in_sek);
       Serial.print("led_aus[z]): ");
+
       //      Serial.print("led_aus[z]): ");
       Serial.println(led_aus[z]);
+
       //    Serial.println(led_aus[z]);
 
       // max. Einschaltzeit überschritten?
 
       // max. Einschaltzeit überschritten?
       if (t_gesamt_in_sek > led_aus[z]) {
+
       if (Laufzeit_in_sek() > led_aus[z]) {
         Led_an(z, 0);
+
         // Legenden-LEDs immer an lassen:
 +
        if (z < legende_anfang || z > legende_ende)
 +
        {
 +
          Led_an(z, 0);
 +
        }
 
       }
 
       }
 
     }
 
     }
 
   }
 
   }
 
   delay(bremse);
 
   delay(bremse);
   Legende_an();
+
   //  Legende_an();
   Serial.println();
+
   //  Serial.println();
 +
}
 +
// **********************************************************************
 +
void serielle() {
 +
  if  (Serial.available()) {
 +
    Serial.println("Ich bin www-taub!");
 +
    serial_a = 0;
 +
    serial_nr = 0;
 +
    while (Serial.available() > 0)
 +
    {
 +
      serial_nr = serial_nr * 10;
 +
      serial_a = Serial.read() - '0'; // ASCII-Textversatz für 0 entfernen
 +
      serial_nr = serial_nr + serial_a;
 +
      delay(5);  // delay in between reads for stability
 +
    }
 +
    neue_Auswahl = 1;
 +
    Auswahl = int(serial_nr);
 +
    Input = "serieller Schnittstelle";
 +
  }
 
}
 
}
 +
 +
 
// **********************************************************************
 
// **********************************************************************
 
void www() {
 
void www() {
 
   // Create a client connection
 
   // Create a client connection
   Serial.print("Ich höre www ...");
+
   //  Serial.print("Ich horche, ob www ...");
 
   EthernetClient client = server.available();
 
   EthernetClient client = server.available();
 
   if (client) {
 
   if (client) {
 +
    Serial.println("Client ist connected!");
 
     while (client.connected()) {
 
     while (client.connected()) {
 
       if (client.available()) {
 
       if (client.available()) {
        Serial.println("++++++++++");
 
 
         char c = client.read();
 
         char c = client.read();
 
         //read char by char HTTP request
 
         //read char by char HTTP request
Zeile 541: Zeile 689:
 
           Serial.println(readString); //print to serial monitor for debugging
 
           Serial.println(readString); //print to serial monitor for debugging
 
           // normalerweise kommt von Browser: "GET /z=[pos] HTTP/1.1"
 
           // normalerweise kommt von Browser: "GET /z=[pos] HTTP/1.1"
           int pos = 1 + readString.indexOf('z=');
+
          String stringOne = readString;
 +
           int pos = 2 + stringOne.indexOf('z');
 +
          //      int pos = readString.indexOf('z=');   //+1
 
           // komischerweise kommt von Handy: "GET /z%3D[pos] HTTP/1.1", daher:
 
           // komischerweise kommt von Handy: "GET /z%3D[pos] HTTP/1.1", daher:
           if (pos == 0) {
+
           //          if (pos == 0) {
            pos = 1 + readString.indexOf('z%3D');
+
          //            pos = 1 + stringOne.indexOf('z%3D');
           }
+
           //          }
 
           Serial.println(pos);
 
           Serial.println(pos);
 
           String zahl = readString.substring(pos);
 
           String zahl = readString.substring(pos);
Zeile 551: Zeile 701:
 
           Serial.println(zahl);
 
           Serial.println(zahl);
 
           Auswahl = zahl.toInt();
 
           Auswahl = zahl.toInt();
 +
          neue_Auswahl = 1;
 
           zahl = String(Auswahl);
 
           zahl = String(Auswahl);
 
           Serial.print("Auswahl:");
 
           Serial.print("Auswahl:");
 
           Serial.println(Auswahl);
 
           Serial.println(Auswahl);
           //    delay(60000);
+
           Input = "www";
           client.println("HTTP/1.1 200 OK"); //send new page
+
           //          client.println("HTTP/1.1 200 OK"); //send new page
           client.println("Content-Type: text/html");
+
           //          client.println("Content-Type: text/html");
           client.println();
+
           //          client.println();
           client.println("<HTML>");
+
           //          client.println("<HTML>");
           client.println("<HEAD>");
+
           //          client.println("<HEAD>");
           // charset=utf-8
+
           //         if (Auswahl != 222) {
          // TO DO: Weiterleitung vorerst aus, bei QR-Code zurücksetzen auf "if (Auswahl != 222) {"
+
           // Weiterleitung an Elementseite auf bs-wiki:
           if (Auswahl != 222) {
+
          //          client.print("<meta http-equiv=\"refresh\"content=\"0; URL=");
            // Weiterleitung an Elementseite auf bs-wiki:
+
//          client.print(URL);
            client.print("<meta http-equiv=\"refresh\"content=\"0; URL=");
+
//          client.print(zahl);
            client.print(URL);
+
//          client.println("\">");
            client.print(zahl);
+
//        }
            client.println("\">");
+
        //          else {
          }
+
        //            // 222: Browserfenster umschalten auf Arduino-Auswahlmenü
          else {
+
        //            client.println("<style>p{font:16px/1.5em;}.monospace{font-family: monospace;}</style>");
            // 222: Browserfenster umschalten auf Arduino-Auswahlmenü
+
        //            client.println("<TITLE>Periodensystem der Elemente</TITLE>");
            client.println("<style>p{font:16px/1.5em;}.monospace{font-family: monospace;}</style>");
+
        //            client.println("</HEAD>");
            client.println("<TITLE>Periodensystem der Elemente</TITLE>");
+
        //            client.println("<BODY>");
            client.println("</HEAD>");
+
        //            client.println("<p class='monospace'>");
            client.println("<BODY>");
+
        //            client.println("<H1>Periodensystem der Elemente</H1>");
            client.println("<p class='monospace'>");
+
        //            client.println("<hr />");
            client.println("<H1>Periodensystem der Elemente</H1>");
+
        //            client.println("<br />");
            client.println("<hr />");
+
        //            client.println("<H2>Led ausw&auml;hlen</H2>");
            client.println("<br />");
+
        //            client.println("<br />");
            //            client.println("<H2>Led ausw&auml;hlen</H2>");
+
        //            for (int z = 1; z < 256; z++) {
            //            client.println("<br />");
+
        //              client.print("<a href=\"/?z=");
            //            for (int z = 1; z < 256; z++) {
+
        //              client.print(z);
            //              client.print("<a href=\"/?z=");
+
        //              client.print("\"\">[ ");
            //              client.print(z);
+
        //              client.print(z);
            //              client.print("\"\">[ ");
+
        //              client.println(" ]</a> ");
            //              client.print(z);
+
        //            }
            //              client.println(" ]</a> ");
+
        //            client.println("<br />");
            //            }
+
        //            client.println("<br />");
            //            client.println("<br />");
+
        //            client.println("<a href=\"/?z=255\"\">[alle an]</a>");
            //            client.println("<br />");
+
        //            client.println("-");
            //            client.println("<a href=\"/?z=255\"\">[alle an]</a>");
+
        //            client.println("<a href=\"/?z=254\"\">[alle aus]</a><br />");
            //            client.println("-");
+
        //            client.println("</p>");
            //            client.println("<a href=\"/?z=254\"\">[alle aus]</a><br />");
+
        //            client.println("<p>Created by Detlef Giesler. Visit <a href='http://www.bs-wiki.de'>bs-wiki.de</a> for more info!</p>");
            //            client.println("</p>");
+
        //            client.println("<br />");
            //            client.println("<p>Created by Detlef Giesler. Visit <a href='http://www.bs-wiki.de'>bs-wiki.de</a> for more info!</p>");
+
        //          }
            //            client.println("<br />");
+
        //          client.println("</BODY>");
          }
+
        //          client.println("</HTML>");
          client.println("</BODY>");
+
        delay(1);
          client.println("</HTML>");
+
        //stopping client
          delay(1);
+
        client.stop();
          //stopping client
+
        //clearing string for next read
          client.stop();
+
        readString = "";
          //controls the Arduino if you press the buttons
+
      }
          Serial.write(Auswahl);
+
    }
          //clearing string for next read
+
  }
           readString = "";
+
}
 +
}
 +
// **********************************************************************
 +
void decodeIR() {
 +
  if (bounced) {
 +
    return;
 +
  }
 +
  bounced = 1;
 +
  //stop all interrupts
 +
  noInterrupts();
 +
  byte i;
 +
  //for each "bit" in the code
 +
  for (i = 0; i < CODE_LEN; i += 1) {
 +
    //store the duration of the pulse (microseconds)
 +
    durations[i] = pulseIn(pinIR, HIGH, 20000);  // 100000 timeout
 +
    // pulseIn(pin, value, timeout) liest einen Puls (HIGH oder LOW) auf einem Pin aus.
 +
    // Zum Beispiel, wenn value gleich HIGH ist, wartet pulseIn() bis der Pin auf HIGH geht, startet die Zeit,
 +
    // dann wird gewartet, bis der Pin auf LOW ist und die Zeit wird gestoppt.
 +
    // Zurückgegeben wird die Länge des Puls in Mikrosekunden. Nach einer bestimmten Zeit wird 0 zurückgegeben,
 +
    // wenn kein Pulse kommt.
 +
  }
 +
  //enable interrupts
 +
  interrupts();
 +
  if (bounced) {
 +
    bounced = 0;
 +
    boolean sauberes_signal = 1; // optimistisch sein
 +
    // 8 Adress-Bits + 8 invertierte Adress-Bits + 8 Kommando-Bits + 8 invertierte Kommando-Bits
 +
    // erwartungsgemäß 8 Nullen:
 +
    byte a_code = B00000000;
 +
    for (i = 1; i < 9; i += 1) {
 +
      switch (durations[i]) {
 +
        case 100 ... 840: bitSet(a_code, i - 1); break;  // 560µs Pause ist 0-Bit
 +
        default: sauberes_signal = 0;    return;
 +
      }
 +
    }
 +
    //    Serial.println(a_code);
 +
 
 +
    // erwartungsgemäß 8 Einsen:
 +
    byte a_i_code = B00000000;
 +
    for (i = 9; i < 17; i += 1) {
 +
      switch (durations[i]) {
 +
        case 1400 ... 2100: bitSet(a_i_code, i - 9); break;  // 1690µs Pause ist 1-Bit
 +
        default: sauberes_signal = 0;    return;
 +
      }
 +
    }
 +
    //    Serial.println(a_i_code);
 +
 
 +
    byte code = B00000000;
 +
    for (i = 17; i < 25; i += 1) {
 +
      //      Serial.print(i);
 +
      //      Serial.print(" - ");
 +
      //      Serial.println(durations[i]);
 +
      //      Serial.println((unsigned long)durations[i]);
 +
      //      delay(3000);
 +
      switch (durations[i]) {
 +
        //      case 100 ... 840: bit = 0; break;  // 560µs Pause ist 0-Bit
 +
        case 1400 ... 2100: bitSet(code, i - 17); break; // 1690µs Pause ist 1-Bit
 +
      }
 +
 
 +
    }
 +
    Serial.print("IR-Code: ");
 +
    Serial.println(code);
 +
    //   Serial.print(" = ");
 +
    byte i_code = B00000000;
 +
    for (i = 25; i < 33; i += 1) {
 +
      switch (durations[i]) {
 +
        case 100 ... 840: bitSet(i_code, i - 25); break;  // 560µs Pause ist 0-Bit
 +
      }
 +
    }
 +
    if (i_code != code) {
 +
      sauberes_signal = 0;
 +
      return;
 +
    }
 +
    //    Serial.println(i_code);
 +
    //    Serial.print("sauberes_signal = ");
 +
    //    Serial.println(sauberes_signal);
 +
    switch (code) {
 +
      case 22: Auswahl = 0; break;
 +
      case 12: Auswahl = 1; break;
 +
      case 24: Auswahl = 2;  break;
 +
      case 94: Auswahl = 3; break;
 +
      case 8: Auswahl = 4;  break;
 +
      case 28: Auswahl = 5;  break;
 +
      case 90: Auswahl = 6;  break;
 +
      case 66: Auswahl = 7; break;
 +
      case 82: Auswahl = 8;  break;
 +
      case 74: Auswahl = 9;  break;
 +
      case 7: Auswahl = 210;  break; // Vol--
 +
      case 9: Auswahl = 213;  break; // [EQ] -> mittlere Helligkeit
 +
      case 21: Auswahl = 215;  break; // Vol++
 +
      case 69: Auswahl = 254;  break; // CH- alles aus
 +
      case 70: Auswahl = 200;  break; // CH Zufallszahl -> Bingo
 +
      case 71: Auswahl = 255;  break; // CH+ alles an
 +
      case 64 :  // next
 +
        switch (last_Element) {  // Elemente, Hauptgruppen, Perioden ...
 +
          case 1 ... 118:  Auswahl = min(118, last_Element + 1); break;
 +
           case 131 ... 194:  Auswahl = min(194, last_Element + 1); break;
 
         }
 
         }
 +
        break;
 +
      case 68 :    // prev
 +
        Auswahl = max(1, last_Element - 1);
 +
        break;
 +
      case 25 : // 100+ als Init für mehrstellige Zahl
 +
        mehrstellig = 1;
 +
        Auswahl = 0;
 +
        break;
 +
      case 13 :  // 200+ als Quit nach mehrstelliger Zahl
 +
        mehrstellig = 0;
 +
        Auswahl = letzte_IR_Auswahl;
 +
        letzte_IR_Auswahl = 0;
 +
        break;
 +
      case 67: Auswahl = 202;  break; // Play/Pause -> Programm_y
 +
    }
 +
    if (mehrstellig) {
 +
      if (Auswahl < 10) {
 +
        letzte_IR_Auswahl = letzte_IR_Auswahl * 10 + Auswahl;
 
       }
 
       }
 
     }
 
     }
 
   }
 
   }
 +
  Serial.print("IR-Auswahl: ");
 +
  Serial.println(Auswahl);
 +
  Serial.println();
 +
  neue_Auswahl = 1;
 +
  Input = "Fernbedienung";
 +
  // last_Element = Auswahl;
 +
  // delay(3000);
 +
  /*
 +
  0: 22
 +
  100+: 25
 +
  200+: 13
 +
  1: 12
 +
  2: 24
 +
  3: 94
 +
  4: 8
 +
  5: 28
 +
  6: 90
 +
  7: 66
 +
  8: 82
 +
  9: 74
 +
  CH-: 69
 +
  CH: 70
 +
  CH+: 71
 +
  prev: 68
 +
  next: 64
 +
  Play: 67
 +
  Vol-: 7
 +
  Vol+:  21
 +
  eq: 9
 +
  */
 
}
 
}

Version vom 9. Juli 2015, 00:10 Uhr

// ********************************************************************** // interaktives Periodensystem der Elemente // schaltet gewünschte LED an // Detlef Giesler // BBS Winsen (Luhe) // ********************************************************************** // letzte Änderungen: // 08.07. serieller Input in Unterprogramm, www gekürzt // 07.07. Fernbedienung mit Interrupt // 05.07. Fernbedienung, Serial.begin(115200); // 23.06. Reset nach Standby // 21.06. Weiterleitung i. O. // 18.06. Weiterleitung kaputt? Abgleich mit 08.06., dort funzts // 08.05.2015: Patch Panel fix // 06.05.2015: Patch Panel aktiviert TO DO: aber irgendwie verschoben // 05.05.2015: Anpassung an Mega 2560 wg. Speicherproblemen beim Uno // 04.05.2015: rudimentäre Dimmfunktion // 03.05.2015: Ausbaustufe = 32, LED #0 gibt es nicht mehr, automatisches Abschalten nach 500 Leerzyklen // 02.05.2015: Aufruf auch von bs-wiki möglich // 01.05.2015: Schalten über HTTP GET // 29.04.2015: Arduino als HTTP Client // 28.04.2015: Abfrage der seriellen Schnittstelle // ********************************************************************** // TO DOs: // bei IR-FB mehrstellige Zahlen: nur die mehrst. OZ, nicht die einzelnen Z. anzeigen // www geht nich // for-Schleife: Bedingung "Laufindex < Ausbaustufe" ersetzen durch "L. < A. +1", sonst fehlt der letzte Wert // Startwert i.d.R. 1, 0 soll unbenutzt bleiben // // ********************************************************************** // Pinning Arduino: // Arduino-Pin 3 als "Dimmer" verbunden mit OE des 74HC595 (dort Pin 13, Output Enable) byte outputEnablePin = 3; // Arduino-Pin 8 als shiftPin verbunden mit SH_CP des 74HC595 (dort Pin 11, shift register clock input) byte shiftPin = 8; // Arduino-Pin 9 verbunden mit ST_CP des 74HC595 (dort Pin 12, storage register clock input = latch pin) byte storePin = 9; // Arduino-Pin 10 verbunden mit DS des 74HC595 (dort Pin 14, serial data input) byte dataPin = 10;

  1. include <SPI.h>
  2. include <Ethernet.h>

// globale Variablen: byte mac[6] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address byte ip[4] = { 192, 168, 178, 104 }; // ip in lan (that's what you need to use in your browser. ("192.168.178.104") // Aufruf dann z. B. über http://192.168.178.104/?z=4 // "Arduino an IP 192..., schalte Led Nr. 4 an!" // Aufruf dann z. B. über http://192.168.178.104/?z=222 // "Arduino an IP 192..., zeige Auswahl an!" byte gateway[4] = { 192, 168, 1, 1 }; // internet access via router byte subnet[4] = { 255, 255, 255, 0 }; //subnet mask EthernetServer server(80); //server port String readString; String URL = "http://www.bs-wiki.de/mediawiki/index.php?title="; String Input; // IR, Seriell oder www // Pinning Schieberegister: // Elemente und LEDs: // Ausbaustufe 144 LEDs // Hardware-Info: 12m²-PSE aus 6 Teildisplays, 144/6 = 24 LEDs/Teildisplay, // ... jedes Teildisplay angesteuert durch 3x8 Datenleitungen (3 Spalten, 8 Zeilen), // ... pro Spalte ein 8-bit-Schieberegister = 18 SR insgesamt byte Ausbaustufe = 144; // 144 byte legende_anfang = 121; byte legende_ende = 139; byte Legenden_LEDs = 1 + legende_ende - legende_anfang; // TO DO: vorerst ohne Patchen boolean patchmodus = 0; // Auswahl // Ordnungszahl definiert Element 1...118 int Auswahl = 0; // 254 boolean neue_Auswahl; // 0 = existiert nicht // 1 = Wasserstoff, 2 = Helium ... // 131...137 = 1. - 7. Periode // 141...148 = 1. - 8. Hauptgruppe // 160 = Metalle // 161 = Halbmetalle // 162 = Nichtmetalle // 180 = Eieruhr auf 180 oder 20 Sekunden // 190 = fest // 191 = flüssig // 192 = gasförmig // 193 = radioaktiv // 194 = biatomar // 200 = Bingo // 201 = Programm_x // 202 = Programm_y // 203 = Programm_z // 209 = Reset // 210...215 = Helligkeit // 222 = Browserfenster umschalten auf Arduino-Auswahlmenü // 254 = alles_aus // 255 = alles_an

boolean led[144]; unsigned int led_aus[144]; // virtuelles Patchpanel: Zuordnung Ordungszahl/Pin, z. B. Natrium mit OZ 11 an *Pin 3*: byte Pin_von_Element[145] = { 0, 1, 137

                             , 2, 9, 97, 105, 113, 121, 129, 138
                             , 3, 10, 98, 106, 114, 122, 130, 139
                             , 4, 11, 19, 27, 35, 43, 51, 59, 67, 75, 83, 91, 99, 107, 115, 123, 131, 140
                             , 5, 12, 20, 28, 36, 44, 52, 60, 68, 76, 84, 92, 100, 108, 116, 124, 132, 141
                             , 6, 13, 23, 31, 39, 47, 55, 63, 71, 79, 87, 95, 103, 111, 119, 127, 21, 29, 37, 45, 53, 61, 69, 77, 85, 93, 101, 109, 117, 125, 133, 142
                             , 7, 14, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 22, 30, 38, 46, 54, 62, 70, 78, 86, 94, 102, 110, 118, 126, 134, 143, 15, 16, 17, 18, 25, 26, 33, 34, 41, 42, 49, 50, 57, 58, 65, 66, 73, 74, 81, 82, 89, 90, 135, 136, 144
                             , 8
                           };

// TO DO: löschen: // byte Element_an_Pin[145] = { 0, 1, 3, 11, 19, 37, 55 // // Pinning ohne eine "Led #0" // //p1p2*p3*p4 p5 p6 p7 p8 - p9 p10 p11 p12 p13 p14 p15 p16 -p17 p18 p19 p20 p21 p22 p23 p24- // , 87, 144, 4, 12, 20, 38, 56, 88, 119, 120, 121, 122, 21, 39, 71, 103, 57, 89 // // // // p25 p26 p27 p28 p29 p30 p31 p32-p33 p34 p35 p36 p37 p38 p39 p40-p41 p42 p43 p44 p45 p46 p47 p48 // , 123, 124, 22, 40, 72, 104, 58, 90, 125, 126, 23, 41, 73, 105, 59, 91, 127, 128, 24, 42, 74, 106, 60, 92 // // // // p49 p50 p51 p52 p53 p54 p55 p56-p57 p58 p59 p60 p61 p62 p63 p64-p65 p66 p67 p68 p69 p70 p71 p72 // , 129, 130, 25, 43, 75, 107, 61, 93, 131, 132, 26, 44, 76, 108, 62, 94, 133, 134, 27, 45, 77, 109, 63, 95 // // // // p73 p74 p75 p76 p77 p78 p79 p80-p81 p82 p83 p84 p85 p86 p87 p88-p89 p90 p91 p92 p93 p94 p95 p96 // , 135, 136, 28, 46, 78, 110, 64, 96, 137, 138, 29, 47, 79, 111, 65, 97, 139, 140, 30, 48, 80, 112, 66, 98 // // // // p97p98 p99 p100p101p102 p103p104-p105p106p107p108p109p110p111p112-p113p114p115p116p117p118p119p120 // , 5, 13, 31, 49, 81, 113, 67, 99, 6, 14, 32, 50, 82, 114, 68, 100, 7, 15, 33, 51, 83, 115, 69, 101 // // // //p121p122p123p124p125p126p127p128-p129p130p131p132p133p134p135 p136-p137p138p139p140p141p142p143p144 // , 8, 16, 34, 52, 84, 116, 70, 102, 9, 17, 35, 53, 85, 117, 141, 142, 2, 10, 18, 36, 54, 86, 118, 143 // }; // Element_an_Pin[] nach steigender Ordungszahl notieren: byte patch[144]; byte Anzahl_angeschaltete_LEDs = 0; // TO DO: über Poti einstellen und von Pin einlesen oder über Webinterface unsigned int Eieruhr = 20; // Vorgabe der Einschaltdauer einer LED in Sekunden byte last_Element = 0; int zyklus = 0; // loop-Zyklen unsigned int last_call = Laufzeit_in_sek(); int serial_a = 0; int serial_nr = 0; // Debugging int bremse = 0; // 1 ... 60000 Standardwert für Entschleunigung in ms zwischen einigen Befehlen zwecks Debugging // // IR - Fernbedienung // Arduino IR Remote Sniffer // Portions © Andrew Ippoliti - acipo.com // TODO: mehrstellige Zahlen abfragen const int pinIR = 2; volatile boolean bounced = 0; const byte CODE_LEN = 40; volatile unsigned long durations[CODE_LEN]; int letzte_IR_Auswahl; boolean mehrstellig; // ********************************************************************** void setup() {

 pinMode(outputEnablePin, OUTPUT); // Dimmer
 analogWrite(outputEnablePin, 255); // entspricht 5 Volt an OE und damit LEDs aus
 Serial.begin(115200); // Kontrollausgabe über seriellen Monitor
 Serial.flush(); // löscht den Inhalt des seriellen Puffers
 // CHECK Fenster: es kommt Müll, wenn nicht 'kein Zeilenende' eingestellt ist!
 // Pin 5 abfragen (analog, EMK) für Zufallszahl
 // randomSeed(analogRead(5));
 // Pins 3, 8,9,10 auf Ausgabe
 //  pinMode(outputEnablePin, OUTPUT); // Dimmer
 pinMode(storePin, OUTPUT);
 pinMode(shiftPin, OUTPUT);
 pinMode(dataPin, OUTPUT);
 // IR-Fernbedienung
 pinMode(pinIR, INPUT);
 attachInterrupt(0, decodeIR, FALLING);
 //FALLING for when the Digitalpin 2 goes from high to low.
 // start the Ethernet connection and the server:
 Ethernet.begin(mac, ip, gateway, subnet);
 server.begin();
 Serial.print("server is at ");
 Serial.println(Ethernet.localIP());
 Serial.println("PSE");
 Serial.println("--------------------------------");
 // TO DO: löschen:
 // Switchen, Element_an_Pin[] nach steigender Ordungszahl merken:
 //  for (byte z = 1; z < 144 + 1; z++) {
 //    patch[Element_an_Pin[z]] = z;
 //    //  //    // Ordnungszahl
 //  }
 //  for (byte z = 1; z < 144 + 1; z++) {
 //    //    Serial.print("Pin: ");
 //    //    Serial.print(z);
 //    //    Serial.print(" = OZ: ");
 //    //    Serial.print(Element_an_Pin[z]);
 //    //    Serial.print(" = Patch(OZ): ");
 //    Serial.print(patch[z]);
 //    //    Serial.println();
 //    Serial.print(", ");
 //  }
 //  Serial.println();
 reset();
 // ***********************
 // Kontrolle
 //  for (byte spalte = 1; spalte < 19; spalte++) {
 //    Serial.println();
 //    Serial.print(spalte);
 //    Serial.println(". Spalte = #IC");
 //    Serial.println("------------------");
 //    for (byte zeile = 1; zeile < 9; zeile++) {
 //      Serial.print(zeile);
 //      Serial.println(". Zeile");
 //      byte z = zeile + 8 * (spalte - 1);
 //      Serial.print("OZ ");
 //      Serial.print(z);
 //      Serial.print(" - Pin ");
 //      Serial.println(Pin_von_Element[z]);
 //    }
 //  }
 // für Testphase LEDs im setup einschalten, später in loop:
 //  Element = 7;  // blau
 Led_an(7, 1);
 delay(bremse);
 Legende_an();
 Serial.println("jetzt startet die loop-Schleife ......");
 Serial.println("--------------------------------------");
 delay(bremse);

} // ********************************************************************** void loop () {

 zyklus = zyklus + 1;
 //  Serial.print(zyklus);
 //  Serial.println(". Loop");
 // vergesse die bisherige Auswahl, LED nicht erneut anschalten:
 // Auswahl = 0;
 //  neue_Auswahl = 0;
 // horche an IR-FB (Interrupt), der seriellen Schnittstelle und am Ethernet-Shield
 // erfrage Element; nach Ordnungszahl o. ä. auswählen:
 // z.B. Nr. 1 - Wasserstoff:
 serielle();
 www();
 if (neue_Auswahl) {
   zyklus = 0; // Schlafmodus beenden
   neue_Auswahl = 0;
   last_call = Laufzeit_in_sek();
   Serial.print("neue Auswahl von ");
   Serial.println(Input);
   //   delay(4000);
   Serial.println(Auswahl);
   Serial.println();
   switch (Auswahl) {
     case 1 ... 118: Led_an(Auswahl, 1); break;
     case 131 ... 139: Auswahl_Periode(); break;      // = 1. - 7. Periode, Lanthanoide, A.
     case 141 ... 148: Auswahl_Hauptgruppe(); break;  // = 1. - 8. Hauptgruppe
     case 160: Auswahl_Metalle(); break;
     case 161: Auswahl_Halbmetalle(); break;
     case 162: Auswahl_Nichtmetalle(); break;
     case 180: Eieruhr_switchen(); break;  //  auf 180 oder 20 Sekunden
     case 190: Auswahl_fest(); break;
     case 191: Auswahl_liquid(); break;
     case 192: Auswahl_gas(); break;
     case 193: Auswahl_radioaktiv(); break;
     case 194: Auswahl_biatomar(); break;
     case 200: Auswahl_Bingo(); break;
     case 201: Auswahl_Programm_x(); break;
     case 202: Auswahl_Programm_y(); break;
     case 203: Auswahl_Programm_z(); break;
     case 209: reset(); break;
     case 210 ... 215: Auswahl_Helligkeit(); break;
     //    case 222: www(); break;
     case 254: Auswahl_alles_aus(); break;
     case 255: Auswahl_alles_an(); break;
     default:  // unbelegte Zahlen sind unsinnig und werden genullt:
       Serial.println("keine neue Auswahl");
       //     Auswahl = 0;
   }
   Auswahl = 0;
   //  delay(3000);
 }
 // TO DO: wenn Legende mit mehreren LED hinterleuchtet wird, diese Anzahl statt der "1" einsetzen:
 if (Anzahl_angeschaltete_LEDs > Legenden_LEDs) {
   Treppenlicht();
 }
 // Serial.println(Laufzeit_in_sek() - last_call);
 //  if ((last_call + 10) < Laufzeit_in_sek()) {
 //    Serial.println("----- 10s später -------------------------------");
 //            reset();
 //  }
 //  if (zyklus > 9999) {         // 999
 //    // 1000-mal is nichts passiert, daher:
 //    reset();
 //    Serial.println("-----ALLE LEDS AUS -------------------------------");
 //    delay(3000);
 //    //TO DO: ggf. Sleep-Modus mit Bewegungsmelder zum Reaktivieren
 //  }
 //  Serial.println("------------------------------------");
 //  delay(bremse);

} // ********************************************************************** // ############### Funktionen nach ABC ############################## // ********************************************************************** void Auswahl_alles_an() { // 255

 Serial.println("alle_Elemente_an");
 for (byte z = 1; z < Ausbaustufe + 1; z++) {
   Led_an(z, 1);
 }
 Serial.println("alle_Elemente sind an");

} // ********************************************************************** void Auswahl_alles_aus() {

 // schaltet alle LEDs außer die für die Legende aus
 Serial.println("alle_Elemente_aus");
 for (byte z = 1; z < Ausbaustufe + 1; z++) {
   Led_an(z, 0);
 }
 Serial.println("alle_Elemente sind aus");
 Legende_an();

} // ********************************************************************** void Auswahl_biatomar() {

 Serial.println("Auswahl_biatomar");
 for (byte z = 1; z < Ausbaustufe + 1; z++) {
   if ((z == 1) || (z == 7) || (z == 8) || (z == 9) || (z == 17) || (z == 35) || (z == 53) || (z == 138) ) {
     Led_an(z, 1);
   }
 }

} // ********************************************************************** void Auswahl_Bingo() {

 Serial.println("Elemente-Bingo");
 byte zufall = random(1, Ausbaustufe);
 // setzt 'zufall' mit einer Zufallszahl
 // zwischen 1 und Ausbaustufe gleich
 Serial.print("Zufalls-Element: ");
 Serial.println(zufall);
 Led_an(zufall, 1);
 delay(bremse);

} // ********************************************************************** void Auswahl_Hauptgruppe() {

 switch (Auswahl) {
   case 141: // 1. Hauptgruppe
     Led_an(1, 1); Led_an(3, 1); Led_an(11, 1); Led_an(19, 1); Led_an(37, 1); Led_an(55, 1); Led_an(87, 1); break;
   case 142: // 2. Hauptgruppe
     Led_an(4, 1); Led_an(12, 1); Led_an(20, 1); Led_an(38, 1); Led_an(56, 1); Led_an(88, 1); break;
   case 143: // 3. Hauptgruppe
     Led_an(5, 1); Led_an(13, 1); Led_an(31, 1); Led_an(49, 1); Led_an(81, 1); Led_an(113, 1); break;
   case 144: // 4. Hauptgruppe
     Led_an(6, 1); Led_an(14, 1); Led_an(32, 1); Led_an(50, 1); Led_an(82, 1); Led_an(114, 1); break;
   case 145: // 5. Hauptgruppe
     Led_an(7, 1); Led_an(15, 1); Led_an(33, 1); Led_an(51, 1); Led_an(83, 1); Led_an(115, 1); break;
   case 146: // 6. Hauptgruppe
     Led_an(8, 1); Led_an(16, 1); Led_an(34, 1); Led_an(52, 1); Led_an(84, 1); Led_an(116, 1); break;
   case 147: // 7. Hauptgruppe
     Led_an(9, 1); Led_an(17, 1); Led_an(35, 1); Led_an(53, 1); Led_an(85, 1); Led_an(117, 1); break;
   case 148: // 7. Hauptgruppe
     Led_an(2, 1); Led_an(10, 1); Led_an(18, 1); Led_an(36, 1); Led_an(54, 1); Led_an(86, 1); Led_an(118, 1); break;
 }

} // ********************************************************************** void Auswahl_Helligkeit() {

 //  210 ... 215
 byte Helligkeit = 5 + 50 * (Auswahl - 210);
 // 210 -> 5, 211 -> 55, ... 215 -> 255
 Dimmer(Helligkeit);

} // ********************************************************************** void Auswahl_Metalle() {

 for (byte z = 1; z < Ausbaustufe + 1; z++) {
   if ((z == 3) || (z == 4) || (z == 11) || (z == 12) || (z == 13) || ((z >= 19) && (z <= 31))
       || ((z >= 37) && (z <= 50))
       || ((z >= 55) && (z <= 84)) || ((z >= 87) && (z <= 118)) || (z == 133)) {
     Led_an(z, 1);
   }
 }

} // ********************************************************************** void Auswahl_Halbmetalle() {

 for (byte z = 1; z < Ausbaustufe + 1; z++) {
   if ((z == 5) || (z == 14) || (z == 32) || (z == 33) || (z == 34) || (z == 51) || (z == 52) || (z == 85)
       || (z == 135)) {
     Led_an(z, 1);
   }
 }

} // ********************************************************************** void Auswahl_Nichtmetalle() {

 for (byte z = 1; z < Ausbaustufe + 1; z++) {
   if ((z == 1) || (z == 2) || ((z >= 6) && (z <= 10)) || ((z >= 15) && (z <= 18)) || ((z >= 35) && (z <= 36))
       || ((z >= 53) && (z <= 54)) || (z == 86) || (z == 137)) {
     Led_an(z, 1);
   }
 }

} // ********************************************************************** void Auswahl_fest() {

 for (byte z = 1; z < Ausbaustufe + 1; z++) {
   if (((z >= 3) && (z <= 6)) || ((z >= 11) && (z <= 16)) || ((z >= 19) && (z <= 34)) || ((z >= 37) && (z <= 53))
       || ((z >= 55) && (z <= 85)) || ((z >= 87) && (z <= 118))) {
     Led_an(z, 1);
   }
 }

} // ********************************************************************** void Auswahl_liquid() {

 for (byte z = 1; z < Ausbaustufe + 1; z++) {
   if ((z == 35) || (z == 80)) {
     Led_an(z, 1);
   }
 }

} // ********************************************************************** void Auswahl_gas() {

 for (byte z = 1; z < Ausbaustufe; z++) {
   if ((z == 1) || (z == 2) || (z == 7) || (z == 8) || (z == 9) || (z == 10) || (z == 17) || (z == 18)
       || (z == 36) || (z == 54) || (z == 86)) {
     Led_an(z, 1);
   }
 }

} // ********************************************************************** void Auswahl_Periode() {

 byte anfang;
 byte ende;
 switch (Auswahl) {
   case 131: anfang = 1; ende = 2; break;      // 1. Periode: 1-H, 2-He
   case 132: anfang = 3; ende = 10; break;
   case 133: anfang = 11; ende = 18; break;
   case 134: anfang = 19; ende = 36; break;
   case 135: anfang = 37; ende = 54; break;
   case 136: anfang = 55; ende = 86; break;
   case 137: anfang = 87; ende = 118; break;  // 7. Periode: Fr-Uuo
   case 138: anfang = 57; ende = 71; break; // Lanthanoide
   case 139: anfang = 89; ende = 103; break; // Actinoide
 }
 for (byte z = anfang; z < ende + 1; z++) {
   Led_an(z, 1);
 }

} // ********************************************************************** void Auswahl_Programm_x() { // 201

 // z. Zt. -Test
 //   delay(5000);
 for (int b = 0; b <= 255; b = b + 15)
 {
   Dimmer(b);
   Led_an(1, 1);
   delay(300);
 }
 Led_an(1, 0);

} // ********************************************************************** void Auswahl_Programm_y() { // 202

 unsigned int Eieruhr_2 = Eieruhr; // Standardwert merken und neu festlegen
 Eieruhr = 1;
 Serial.println("Flackermann");
 for (byte z = 1; z < Ausbaustufe + 1; z++) {
   byte zufall = random(1, Ausbaustufe);
   // setzt 'zufall' mit einer Zufallszahl
   // zwischen 1 und Ausbaustufe gleich
   Serial.print("Zufalls-Element: ");
   Serial.println(zufall);
   Led_an(zufall, 1);
   Treppenlicht();
 }
 Eieruhr = Eieruhr_2; // Standardwert zurückschreiben

} // ********************************************************************** void Auswahl_Programm_z() {

} // ********************************************************************** void Auswahl_radioaktiv() {

 for (byte z = 1; z < Ausbaustufe + 1; z++) {
   if ((z == 43) || (z == 61) || ((z >= 84) && (z <= 118)) || (z == 134) || (z == 136)) {
     Led_an(z, 1);
   }
 }

} // ********************************************************************** void Dimmer(byte Helligkeit) // 0 to 255 // Funktion merkt sich Helligkeitswert für LEDs, ausbaubedingt z. Zt. nur Einheitswert für alle Schieberister // 0 = dunkel, weil 0% Einschaltdauer, 255 = volle Leistung, weil 100% ED {

 analogWrite(outputEnablePin, 255 - Helligkeit);

} // ********************************************************************** void Eieruhr_switchen() { // switchen auf 180 oder 20 Sekunden

 Serial.print("Eieruhr switchen von ");
 Serial.print(Eieruhr);
 Serial.print(" auf ");
 switch (Eieruhr) {
   case 20: Eieruhr = 180; break;      // LEDs 3 Minuten anlassen
   case 180: Eieruhr = 20; break;      // LEDs 20s anlassen
 }
 Serial.print(Eieruhr);
 Serial.print(" Sekunden");

} // ********************************************************************** unsigned int Laufzeit_in_sek() {

 unsigned int t_gesamt_in_sek = millis() / 1000;
 return t_gesamt_in_sek;

}

// void Laufzeit_hhmmss() { // t_gesamt_in_sek = millis() / 1000; // millis() gibt den Wert in Millisekunden als 'unsigned int' Datentyp zurück, berechnet seitdem das Arduino // Board das aktuelle Programm gestartet hat. // nullt bei ?? ms // byte t_gesamt_in_h = millis() / 3600000; // byte t_gesamt_in_m = millis() / 60000 - t_gesamt_in_h * 60; // byte t_gesamt_in_s = millis() / 1000 - t_gesamt_in_m * 60; // Serial.print("Laufzeit hh:mm:ss = "); // Serial.print(t_gesamt_in_h); // Serial.print(":"); // Serial.print(t_gesamt_in_m); // Serial.print(":"); // Serial.print(t_gesamt_in_s); // Serial.println(); // } // ********************************************************************** void Led_an(byte Element, boolean an) {

 // Funktion schaltet durch (Element) bestimmte Pins (= LEDs) an oder aus,
 // plant einen Ausschaltpunkt (led_aus[Element]) und merkt sich die Anzahl_angeschaltete_LEDs.
 // 'Element' ist die OZ, 'an' der Schaltzustand 0/1
 // 'pin' ist der tatsächliche Anschlusspunkt der LED-Matrix, z. B. bei Element 22 (Titan, logisch)
 //  die 27. Led (physikalisch) schalten. Zuordnung Pin/Element:
 byte Pin = Element;  // Probebetrieb ohne Patchmodus: OZ 22 = Pin 22
 //  if (patchmodus) {   // Normalfall: OZ 22 = Pin 27
 //    Pin = Pin_von_Element[Element];
 //  }
 // Laufzeit_hhmmss();
 //  Serial.print(Pin);
 //  Serial.print(". Pin = ");
 //  Serial.print(Element);
 //  Serial.print(". Element wird geschaltet von ");
 //  Serial.print(led[Pin]);
 //  Serial.print(" -> ");
 //  Serial.println(an);
 // TO DO: wenn Ausbaustufe 144 erreicht, diese LEDs immer anlassen:
 // solange Ausbaustufe 144 noch nicht erreicht, ersatzweise Led #9:
 //   for (byte z = 121; z < 139; z++) {
 // if ((Element > 0) && (Element < Ausbaustufe + 1) && ((Element < 9) || (Element > 9))) {
 // mitzählen, wieviel LEDs insgesamt an sind:
 // nur ausführen, wenn (an -> aus) oder (aus -> an), nicht bei (bleibt an) oder (bleibt aus)
 if (an != led[Pin]) {
   Anzahl_angeschaltete_LEDs = Anzahl_angeschaltete_LEDs + an * 2 - 1; // Anz. = Anz. -1 oder +1
 }
 //}
 led[Pin] = an;
 // Zwischenbilanz für Kontrolle
 //  Serial.print(Anzahl_angeschaltete_LEDs);
 //  Serial.print(" LEDs sind an: ");
 //  for (byte z = 1; z < Ausbaustufe + 1; z++) {
 //    if (led[z]) {
 ////      Serial.print("p_");
 ////      Serial.print(z);
 ////      Serial.print("-");
 //    }
 //  }
 //  Serial.println();
 //  // nur für Fehlerabfrage
 //  if (Anzahl_angeschaltete_LEDs > Ausbaustufe) {
 //    Serial.println("F E H L E R : zuviele LEDs geschaltet!");
 //    delay(bremse);
 //  }
 // spart Speicher: unsigned long led_Start zu byte einkürzen:
 if (an) {
   led_aus[Pin] = Laufzeit_in_sek() + Eieruhr; // vormerken: LED nach (Eieruhr) Sek. wieder ausschalten
   last_Element = Element;  // welches Element wurde zuletzt angeschaltet?
 }
 resetPins();
 // digitalWrite(storePin, LOW);
 for (byte i = 1; i < Ausbaustufe + 1; i++) {
   // Aktion passiert bei Wechsel von LOW auf HIGH
   digitalWrite(shiftPin, LOW);
   // Jetzt den Wert der aktuellen Stelle ans Datenpin DS anlegen
   digitalWrite(dataPin, led[i]);
   // Dann ShiftPin SHCP von LOW auf HIGH, damit wird der Wert
   // am Datenpin ins Register geschoben.
   digitalWrite(shiftPin, HIGH);
 }
 // Wenn alle Stellen im Register sind, jetzt das StorePin STCP
 // von LOW auf HIGH, damit wird Registerinhalt an Ausgabepins
 // kopiert und der Zustand an den LEDs sichtbar
 //analogWrite(storePin, 254);
 // neues Muster einschalten:
 digitalWrite(storePin, HIGH);
 //  // Serial.print(Element);
 //  //  Serial.print(". LED ist ");
 //  // Serial.println(an);
 //  Serial.println("--------------------");
 //  delay(bremse);

} // ********************************************************************** void Legende_an() {

 // TO DO: solange Ausbaustufe 144 noch nicht erreicht, ersatzweise Led #9:
 //  Led_an(9, 1);
 // wenn Ausbaustufe 144 erreicht, diese LEDs immer anlassen:
 for (byte z = legende_anfang; z < legende_ende + 1; z++) {
   Led_an(z, 1);
 }

} // ********************************************************************** void reset() {

 resetPins();
 Dimmer(0);
 Eieruhr = 20;
 Anzahl_angeschaltete_LEDs = 0;
 for (byte i = 1; i < Ausbaustufe + 1; i++) {
   led[i] = 0;
   digitalWrite(dataPin, led[i]);
   digitalWrite(shiftPin, HIGH);
 }
 Dimmer(127);
 digitalWrite(storePin, HIGH);
 Legende_an();
 Auswahl = 0;
 neue_Auswahl = 0;
 zyklus = 0; // Schlafmodus beenden

} // ********************************************************************** void resetPins() {

 // Zuerst immer alle 3 Pins auf LOW
 digitalWrite(storePin, LOW);
 digitalWrite(shiftPin, LOW);
 digitalWrite(dataPin, LOW);

} // ********************************************************************** void Treppenlicht() {

 //TO DO an Pin anpassen
 //  Serial.println("Treppenlicht");
 // schaltet die LED nach (Eieruhr) Sek. wieder aus
 //  t_gesamt_in_sek = Laufzeit_in_Sek();
 for (byte z = 1; z < Ausbaustufe + 1; z++) {
   if (led[z]) {
     //     Serial.print("t_gesamt_in_sek: ");
     //      Serial.println(t_gesamt_in_sek);
     //      Serial.print("led_aus[z]): ");
     //     Serial.println(led_aus[z]);
     // max. Einschaltzeit überschritten?
     if (Laufzeit_in_sek() > led_aus[z]) {
       // Legenden-LEDs immer an lassen:
       if (z < legende_anfang || z > legende_ende)
       {
         Led_an(z, 0);
       }
     }
   }
 }
 delay(bremse);
 //  Legende_an();
 //  Serial.println();

} // ********************************************************************** void serielle() {

 if  (Serial.available()) {
   Serial.println("Ich bin www-taub!");
   serial_a = 0;
   serial_nr = 0;
   while (Serial.available() > 0)
   {
     serial_nr = serial_nr * 10;
     serial_a = Serial.read() - '0'; // ASCII-Textversatz für 0 entfernen
     serial_nr = serial_nr + serial_a;
     delay(5);  // delay in between reads for stability
   }
   neue_Auswahl = 1;
   Auswahl = int(serial_nr);
   Input = "serieller Schnittstelle";
 }

}


// ********************************************************************** void www() {

 // Create a client connection
 //  Serial.print("Ich horche, ob www ...");
 EthernetClient client = server.available();
 if (client) {
   Serial.println("Client ist connected!");
   while (client.connected()) {
     if (client.available()) {
       char c = client.read();
       //read char by char HTTP request
       if (readString.length() < 100) {
         //store characters to string
         readString += c;
       }
       //if HTTP request has ended
       if (c == '\n') {
         Serial.println(readString); //print to serial monitor for debugging
         // normalerweise kommt von Browser: "GET /z=[pos] HTTP/1.1"
         String stringOne = readString;
         int pos = 2 + stringOne.indexOf('z');
         //       int pos = readString.indexOf('z=');   //+1
         // komischerweise kommt von Handy: "GET /z%3D[pos] HTTP/1.1", daher:
         //          if (pos == 0) {
         //            pos = 1 + stringOne.indexOf('z%3D');
         //          }
         Serial.println(pos);
         String zahl = readString.substring(pos);
         Serial.print("Zahl-String:");
         Serial.println(zahl);
         Auswahl = zahl.toInt();
         neue_Auswahl = 1;
         zahl = String(Auswahl);
         Serial.print("Auswahl:");
         Serial.println(Auswahl);
         Input = "www";
         //          client.println("HTTP/1.1 200 OK"); //send new page
         //          client.println("Content-Type: text/html");
         //          client.println();
         //          client.println("<HTML>");
         //          client.println("<HEAD>");
         //          if (Auswahl != 222) {
         // Weiterleitung an Elementseite auf bs-wiki:
         //          client.print("<meta http-equiv=\"refresh\"content=\"0; URL=");

// client.print(URL); // client.print(zahl); // client.println("\">"); // }

       //          else {
       //            // 222: Browserfenster umschalten auf Arduino-Auswahlmenü
       //            client.println("<style>p{font:16px/1.5em;}.monospace{font-family: monospace;}</style>");
       //            client.println("<TITLE>Periodensystem der Elemente</TITLE>");
       //            client.println("</HEAD>");
       //            client.println("<BODY>");
// client.println("

"); // client.println("

Periodensystem der Elemente

"); // client.println("
");
       //            client.println("
");
// client.println("

Led auswählen

");
       //            client.println("
"); // for (int z = 1; z < 256; z++) { // client.print("<a href=\"/?z="); // client.print(z); // client.print("\"\">[ "); // client.print(z); // client.println(" ]</a> "); // } // client.println("
"); // client.println("
"); // client.println("<a href=\"/?z=255\"\">[alle an]</a>"); // client.println("-"); // client.println("<a href=\"/?z=254\"\">[alle aus]</a>
");
// client.println("

"); // client.println("

Created by Detlef Giesler. Visit <a href='http://www.bs-wiki.de'>bs-wiki.de</a> for more info!

");
       //            client.println("
"); // } // client.println("</BODY>"); // client.println("</HTML>"); delay(1); //stopping client client.stop(); //clearing string for next read readString = ""; } } }

} } // ********************************************************************** void decodeIR() {

 if (bounced) {
   return;
 }
 bounced = 1;
 //stop all interrupts
 noInterrupts();
 byte i;
 //for each "bit" in the code
 for (i = 0; i < CODE_LEN; i += 1) {
   //store the duration of the pulse (microseconds)
   durations[i] = pulseIn(pinIR, HIGH, 20000);   // 100000 timeout
   // pulseIn(pin, value, timeout) liest einen Puls (HIGH oder LOW) auf einem Pin aus.
   // Zum Beispiel, wenn value gleich HIGH ist, wartet pulseIn() bis der Pin auf HIGH geht, startet die Zeit,
   // dann wird gewartet, bis der Pin auf LOW ist und die Zeit wird gestoppt.
   // Zurückgegeben wird die Länge des Puls in Mikrosekunden. Nach einer bestimmten Zeit wird 0 zurückgegeben,
   // wenn kein Pulse kommt.
 }
 //enable interrupts
 interrupts();
 if (bounced) {
   bounced = 0;
   boolean sauberes_signal = 1; // optimistisch sein
   // 8 Adress-Bits + 8 invertierte Adress-Bits + 8 Kommando-Bits + 8 invertierte Kommando-Bits
   // erwartungsgemäß 8 Nullen:
   byte a_code = B00000000;
   for (i = 1; i < 9; i += 1) {
     switch (durations[i]) {
       case 100 ... 840: bitSet(a_code, i - 1); break;  // 560µs Pause ist 0-Bit
       default: sauberes_signal = 0;    return;
     }
   }
   //    Serial.println(a_code);
   // erwartungsgemäß 8 Einsen:
   byte a_i_code = B00000000;
   for (i = 9; i < 17; i += 1) {
     switch (durations[i]) {
       case 1400 ... 2100: bitSet(a_i_code, i - 9); break;  // 1690µs Pause ist 1-Bit
       default: sauberes_signal = 0;    return;
     }
   }
   //    Serial.println(a_i_code);
   byte code = B00000000;
   for (i = 17; i < 25; i += 1) {
     //      Serial.print(i);
     //      Serial.print(" - ");
     //      Serial.println(durations[i]);
     //      Serial.println((unsigned long)durations[i]);
     //      delay(3000);
     switch (durations[i]) {
       //       case 100 ... 840: bit = 0; break;  // 560µs Pause ist 0-Bit
       case 1400 ... 2100: bitSet(code, i - 17); break; // 1690µs Pause ist 1-Bit
     }
   }
   Serial.print("IR-Code: ");
   Serial.println(code);
   //    Serial.print(" = ");
   byte i_code = B00000000;
   for (i = 25; i < 33; i += 1) {
     switch (durations[i]) {
       case 100 ... 840: bitSet(i_code, i - 25); break;  // 560µs Pause ist 0-Bit
     }
   }
   if (i_code != code) {
     sauberes_signal = 0;
     return;
   }
   //    Serial.println(i_code);
   //    Serial.print("sauberes_signal = ");
   //    Serial.println(sauberes_signal);
   switch (code) {
     case 22: Auswahl = 0; break;
     case 12: Auswahl = 1; break;
     case 24: Auswahl = 2;  break;
     case 94: Auswahl = 3; break;
     case 8: Auswahl = 4;  break;
     case 28: Auswahl = 5;  break;
     case 90: Auswahl = 6;  break;
     case 66: Auswahl = 7; break;
     case 82: Auswahl = 8;  break;
     case 74: Auswahl = 9;  break;
     case 7: Auswahl = 210;  break; // Vol--
     case 9: Auswahl = 213;  break; // [EQ] -> mittlere Helligkeit
     case 21: Auswahl = 215;  break; // Vol++
     case 69: Auswahl = 254;  break; // CH- alles aus
     case 70: Auswahl = 200;  break; // CH Zufallszahl -> Bingo
     case 71: Auswahl = 255;  break; // CH+ alles an
     case 64 :  // next
       switch (last_Element) {  // Elemente, Hauptgruppen, Perioden ...
         case 1 ... 118:  Auswahl = min(118, last_Element + 1); break;
         case 131 ... 194:  Auswahl = min(194, last_Element + 1); break;
       }
       break;
     case 68 :    // prev
       Auswahl = max(1, last_Element - 1);
       break;
     case 25 : // 100+ als Init für mehrstellige Zahl
       mehrstellig = 1;
       Auswahl = 0;
       break;
     case 13 :   // 200+ als Quit nach mehrstelliger Zahl
       mehrstellig = 0;
       Auswahl = letzte_IR_Auswahl;
       letzte_IR_Auswahl = 0;
       break;
     case 67: Auswahl = 202;  break; // Play/Pause -> Programm_y
   }
   if (mehrstellig) {
     if (Auswahl < 10) {
       letzte_IR_Auswahl = letzte_IR_Auswahl * 10 + Auswahl;
     }
   }
 }
 Serial.print("IR-Auswahl: ");
 Serial.println(Auswahl);
 Serial.println();
 neue_Auswahl = 1;
 Input = "Fernbedienung";
 // last_Element = Auswahl;
 // delay(3000);
 /*
 0: 22
 100+: 25
 200+: 13
 1: 12
 2: 24
 3: 94
 4: 8
 5: 28
 6: 90
 7: 66
 8: 82
 9: 74
 CH-: 69
 CH: 70
 CH+: 71
 prev: 68
 next: 64
 Play: 67
 Vol-: 7
 Vol+:  21
 eq: 9
 */

}