Diskussion:Arduino: Unterschied zwischen den Versionen

Aus BS-Wiki: Wissen teilen
Wechseln zu: Navigation, Suche
(Die Seite wurde neu angelegt: „// ********************************************************************** // interaktives Periodensystem der Elemente // schaltet gewünschte LED an // Detlef…“)
 
Zeile 4: Zeile 4:
 
// Detlef Giesler
 
// Detlef Giesler
 
// BBS Winsen (Luhe)
 
// BBS Winsen (Luhe)
// 29.04.2015
 
 
// **********************************************************************
 
// **********************************************************************
 
// letzte Änderungen:
 
// letzte Änderungen:
// 29.04.2015: Arduino als HTTP-Client
+
// Webserver aus wg. Speicherproblemen
 +
// 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
 
// 28.04.2015: Abfrage der seriellen Schnittstelle
 +
// **********************************************************************
 +
// TO DOs:
 +
// for-Schleife: Bedingung "Laufindex < Ausbaustufe" ersetzen durch "L. < A. +1", sonst fehlt der letzte Wert
 +
// Startwert i.d.R. 1, 0 soll unbenutzt bleiben
 +
//
 
// **********************************************************************
 
// **********************************************************************
 
#include <SPI.h>
 
#include <SPI.h>
 
#include <Ethernet.h>
 
#include <Ethernet.h>
 +
// globale Variablen:
 
byte mac[6] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
 
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")
 
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 gateway[4] = { 192, 168, 1, 1 }; // internet access via router
 
byte subnet[4] = { 255, 255, 255, 0 }; //subnet mask
 
byte subnet[4] = { 255, 255, 255, 0 }; //subnet mask
 
EthernetServer server(80); //server port
 
EthernetServer server(80); //server port
 
String readString;
 
String readString;
 +
String URL = "http://www.bs-wiki.de/mediawiki/index.php?title=";
  
// globale Variablen:
+
// Pinning Arduino & Schieberegister:
// Arduino-Pin verbunden mit SH_CP des 74HC595
+
// 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;
 
byte shiftPin = 8;
// Arduino-Pin verbunden mit ST_CP des 74HC595
+
// Arduino-Pin 9 verbunden mit ST_CP des 74HC595 (dort Pin 12, storage register clock input = latch pin)
 
byte storePin = 9;
 
byte storePin = 9;
// Arduino-Pin verbunden mit DS des 74HC595
+
// Arduino-Pin 10 verbunden mit DS des 74HC595 (dort Pin 14, serial data input)
 
byte dataPin = 10;
 
byte dataPin = 10;
  
 
// Elemente und LEDs:
 
// Elemente und LEDs:
// 24 ist die derzeitige Ausbaustufe, am Ende 120 LEDs
+
// 32 ist die derzeitige Ausbaustufe, am Ende 144 LEDs
byte Ausbaustufe = 24;
+
// 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 = 32;
  
 
// Auswahl
 
// Auswahl
 
// Ordnungszahl definiert Element 1...118
 
// Ordnungszahl definiert Element 1...118
 
byte Auswahl = 0;
 
byte Auswahl = 0;
// 0 = Legende,
+
// 0 = existiert nicht
 
// 1 = Wasserstoff, 2 = Helium ...
 
// 1 = Wasserstoff, 2 = Helium ...
 
// 131...137 = 1. - 7. Periode
 
// 131...137 = 1. - 7. Periode
 
// 141...148 = 1. - 8. Hauptgruppe
 
// 141...148 = 1. - 8. Hauptgruppe
 
// 160 = Metalle
 
// 160 = Metalle
// 170 = Halbmetalle
+
// 161 = Halbmetalle
// 180 = Nichtmetalle
+
// 162 = Nichtmetalle
 
// 190 = fest
 
// 190 = fest
 
// 191 = flüssig
 
// 191 = flüssig
Zeile 50: Zeile 70:
 
// 202 = Programm_y
 
// 202 = Programm_y
 
// 203 = Programm_z
 
// 203 = Programm_z
 +
// 222 = Browserfenster umschalten auf Arduino-Auswahlmenü
 
// 254 = alles_aus
 
// 254 = alles_aus
 
// 255 = alles_an
 
// 255 = alles_an
Zeile 56: Zeile 77:
 
unsigned int led_aus[145];
 
unsigned int led_aus[145];
 
// 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*:
// Pinning         -          p1 p2*p3* p4  p5  p6  p7  p8-p9 p10 p11 p12 p13 p14 p15  p16 -p17  p18  p19 p20 p21 p22  p23 p24-p25  p26  p27 p28 p29 p30  p31 p32-p33  p34  p35 p36 p37 p38  p39 p40-p41  p42  p43 p44 p45 p46  p47 p48-p49  p50  p51 p52 p53 p54  p55 p56-p57  p58  p59 p60 p61 p62  p63 p64-p65  p66  p67 p68 p69 p70  p71 p72-p73  p74  p75 p76 p77 p78  p79 p80-p81  p82  p83 p84 p85 p86  p87 p88-p89  p90  p91 p92 p93 p94  p95 p96-p97p98 p99 p100p101p102 p103p104-p105p106p107p108p109p110p111p112-p113p114p115p116p117p118p119p120-p121p122p123p124p125p126p127p128-p129p130p131p132p133p134p135p136-p137p138p139p140p141p142p143p144
+
const byte Element_an_Pin[145] = {
const byte Element_an_Pin[145] = {0, 1, 3, 11, 19, 37, 55, 87, 0, 4, 12, 20, 38, 56, 88, 119, 120, 121, 122, 21, 39, 71, 103, 57, 89, 123, 124, 22, 40, 72, 104, 58, 90, 125, 126, 23, 41, 73, 105, 59, 91, 127, 128, 24, 42, 74, 106, 60, 92, 129, 130, 25, 43, 75, 107, 61, 93, 131, 132, 26, 44, 76, 108, 62, 94, 133, 134, 27, 45, 77, 109, 63, 95, 135, 136, 28, 46, 78, 110, 64, 96, 137, 138, 29, 47, 79, 111, 65, 97, 139, 140, 30, 48, 80, 112, 66, 98, 5, 13, 31, 49, 81, 113, 67, 99, 6, 14, 32, 50, 82, 114, 68, 100, 7, 15, 33, 51, 83, 115, 69, 101, 8, 16, 34, 52, 84, 116, 70, 102, 9, 17, 35, 53, 85, 117, 141, 142, 2, 10, 18, 36, 54, 86, 118, 143};
+
  // Pinning ohne eine "Led #0"
 +
  // p1 p2*p3* p4  p5  p6  p7  p8-p9 p10 p11 p12 p13 p14 p15  p16 -p17  p18  p19 p20 p21 p22  p23 p24-
 +
  0, 1, 3, 11, 19, 37, 55, 87, 0, 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:
 
// Element_an_Pin[] nach steigender Ordungszahl notieren:
 
// TO DO wg. Speicherproblemen vorerst aus:
 
// TO DO wg. Speicherproblemen vorerst aus:
Zeile 64: Zeile 98:
 
byte Anzahl_angeschaltete_LEDs = 0;
 
byte Anzahl_angeschaltete_LEDs = 0;
 
unsigned int t_gesamt_in_sek = millis() / 1000;
 
unsigned int t_gesamt_in_sek = millis() / 1000;
// TO DO: über Poti einstellen
+
// TO DO: über Poti einstellen und von Pin einlesen oder über Webinterface
 
byte Eieruhr = 20;  // Vorgabe der Einschaltdauer einer LED in Sekunden
 
byte Eieruhr = 20;  // Vorgabe der Einschaltdauer einer LED in Sekunden
 
+
int zyklus = 0; // loop-Zyklen
 +
// Debugging
 +
int bremse = 0;  // 1 ... 60000 Standardwert für Entschleunigung in ms zwischen einigen Befehlen zwecks Debugging
 
// **********************************************************************
 
// **********************************************************************
 
void setup() {
 
void setup() {
 +
  Dimmer(10);
 
   Serial.begin(9600); // Kontrollausgabe über seriellen Monitor
 
   Serial.begin(9600); // Kontrollausgabe über seriellen Monitor
 
   // Pin 5 abfragen (analog, EMK) für Zufallszahl
 
   // Pin 5 abfragen (analog, EMK) für Zufallszahl
 
   randomSeed(analogRead(5));
 
   randomSeed(analogRead(5));
   // Pins 8,9,10 auf Ausgabe
+
   // Pins 3, 8,9,10 auf Ausgabe
 +
  pinMode(outputEnablePin, OUTPUT); // Dimmer
 
   pinMode(storePin, OUTPUT);
 
   pinMode(storePin, OUTPUT);
 
   pinMode(shiftPin, OUTPUT);
 
   pinMode(shiftPin, OUTPUT);
Zeile 85: Zeile 123:
 
   // Switchen, Element_an_Pin[] nach steigender Ordungszahl merken:
 
   // Switchen, Element_an_Pin[] nach steigender Ordungszahl merken:
 
   // TO DO wg. Speicherproblemen vorerst aus:
 
   // TO DO wg. Speicherproblemen vorerst aus:
   //  for (byte z = 0; z < 144; z++) {
+
   //  for (byte z = 1; z < 145; z++) {
 
   //    patch[Element_an_Pin[z]] = z;
 
   //    patch[Element_an_Pin[z]] = z;
 
   //    // Ordnungszahl
 
   //    // Ordnungszahl
Zeile 111: Zeile 149:
 
   //  delay(10000);
 
   //  delay(10000);
 
   // ***********************
 
   // ***********************
 +
  // TO DO: LED 0 ist  eigentlich gar nicht schaltbar...
 
   // LED Nr. 0 (Legende) immer an, ist gleichzeitig Kontrollleuchte für aktives Board:
 
   // LED Nr. 0 (Legende) immer an, ist gleichzeitig Kontrollleuchte für aktives Board:
   Led_an(0, 1);
+
   //  Led_an(0, 1);
   delay(1000);
+
   //  delay(1000);
  
 
   // 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(1000);
+
   delay(bremse);
 
   Serial.println("alle_Elemente_an");
 
   Serial.println("alle_Elemente_an");
 
   Auswahl_alles_an();
 
   Auswahl_alles_an();
 
   Serial.println("alle_Elemente sind an");
 
   Serial.println("alle_Elemente sind an");
   delay(3000);
+
   delay(bremse);
 
   Serial.println("alle_Elemente_aus");
 
   Serial.println("alle_Elemente_aus");
 
   Auswahl_alles_aus();
 
   Auswahl_alles_aus();
 
   Serial.println("alle_Elemente sind aus");
 
   Serial.println("alle_Elemente sind aus");
   delay(1000);
+
   delay(bremse);
   //  Serial.println("alle_Elemente Bingo");
+
   Legende_an();
  //  Auswahl_Bingo();
 
 
   Serial.println("jetzt startet die loop-Schleife ......");
 
   Serial.println("jetzt startet die loop-Schleife ......");
 
   Serial.println("--------------------------------------");
 
   Serial.println("--------------------------------------");
   delay(3000);
+
   delay(bremse);
 
}
 
}
 
// **********************************************************************
 
// **********************************************************************
 
void loop () {
 
void loop () {
   Serial.println("loop");
+
  zyklus = zyklus + 1;
 +
  Serial.print(zyklus);
 +
   Serial.println(". Loop");
 +
  // vergesse die bisherige Auswahl, LED nicht erneut anschalten:
 
   Auswahl = 0;
 
   Auswahl = 0;
   // horche an der seriellen Schnittstelle und
+
   // horche an der seriellen Schnittstelle und am Ethernet-Shield
   // erfrage Element; später mal durch Webserver nach Ordnungszahl o. ä. auswählen:
+
   // erfrage Element; nach Ordnungszahl o. ä. auswählen:
 
   // z.B. Nr. 1 - Wasserstoff:
 
   // z.B. Nr. 1 - Wasserstoff:
  //  while (Serial.available() == 0)
 
  //  {
 
  //
 
  //  }
 
 
   www();
 
   www();
 
   while (Serial.available() > 0)
 
   while (Serial.available() > 0)
 
   {
 
   {
 +
    Serial.println("Ich bin www-taub!");
 
     byte a = 0;
 
     byte a = 0;
 
     {
 
     {
Zeile 156: Zeile 195:
 
     Serial.write(Auswahl);
 
     Serial.write(Auswahl);
 
   }
 
   }
   delay(100);
+
   delay(bremse);
 
   switch (Auswahl) {
 
   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 160: Auswahl_Metalle(); break;
     case 170: Auswahl_Halbmetalle(); break;
+
     case 161: Auswahl_Halbmetalle(); break;
     case 180: Auswahl_Nichtmetalle(); break;
+
     case 162: Auswahl_Nichtmetalle(); break;
 
     case 190: Auswahl_fest(); break;
 
     case 190: Auswahl_fest(); break;
 
     case 191: Auswahl_liquid(); break;
 
     case 191: Auswahl_liquid(); break;
Zeile 170: Zeile 212:
 
     case 202: Auswahl_Programm_y(); break;
 
     case 202: Auswahl_Programm_y(); break;
 
     case 203: Auswahl_Programm_z(); break;
 
     case 203: Auswahl_Programm_z(); break;
 +
    //    case 222: www(); break;
 
     case 254: Auswahl_alles_aus(); break;
 
     case 254: Auswahl_alles_aus(); break;
 
     case 255: Auswahl_alles_an(); break;
 
     case 255: Auswahl_alles_an(); break;
     case 131: Auswahl_Periode(1, 2); break;
+
     default: // unbelegte Zahlen sind unsinnig und werden genullt:
    default:
+
      Serial.print("KOMISCHE Auswahl: ");
       Led_an(Auswahl, 1);
+
      Serial.println(Auswahl);
 +
      Auswahl = 0;
 +
       delay(bremse);
 
   }
 
   }
   // vergesse die bisherige Auswahl, also nicht erneut schalten:
+
   // TO DO: wenn Legende mit mehreren LED hinterleuchtet wird, diese Anzahl statt der "1" einsetzen:
  //  Auswahl = 0;
 
  //  for (int z = 1; z < Ausbaustufe; z++) {
 
  //    delay(1000);
 
  //    Led_an(z, 1);
 
  //    delay(100);
 
  //    //    Led_an(z, 0);
 
 
   if (Anzahl_angeschaltete_LEDs > 1) {
 
   if (Anzahl_angeschaltete_LEDs > 1) {
 
     Treppenlicht();
 
     Treppenlicht();
 
   }
 
   }
   Serial.println("--------------------");
+
  if (zyklus > 500) {        // 999
   delay(1000);
+
    // 1000-mal is nichts passiert, daher:
 +
    Auswahl_alles_aus();
 +
    //TO DO: ggf. Sleep-Modus mit Bewegungsmelder zum Reaktivieren
 +
  }
 +
   Serial.println("------------------------------------");
 +
   delay(bremse);
 
}
 
}
 
// **********************************************************************
 
// **********************************************************************
 
// ############### Unterprogramme nach ABC ##############################
 
// ############### Unterprogramme nach ABC ##############################
 +
// **********************************************************************
 +
void Auswahl_alles_an() {
 +
  for (byte z = 1; z < Ausbaustufe + 1; z++) {
 +
    Led_an(z, 1);
 +
  }
 +
}
 +
// **********************************************************************
 +
void Auswahl_alles_aus() {
 +
  // schaltet alle LEDs außer die für die Legende aus
 +
  for (byte z = 1; z < Ausbaustufe + 1; z++) {
 +
    Led_an(z, 0);
 +
  }
 +
  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_Metalle() {
 
void Auswahl_Metalle() {
   for (byte z = 1; z < Ausbaustufe; z++) {
+
   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)) {
 
     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);
 
       Led_an(z, 1);
Zeile 201: Zeile 300:
 
// **********************************************************************
 
// **********************************************************************
 
void Auswahl_Halbmetalle() {
 
void Auswahl_Halbmetalle() {
   for (byte z = 1; z < Ausbaustufe; z++) {
+
   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)) {
 
     if ((z == 5) || (z == 14) || (z == 32) || (z == 33) || (z == 34) || (z == 51) || (z == 52) || (z == 85) || (z == 135)) {
 
       Led_an(z, 1);
 
       Led_an(z, 1);
Zeile 209: Zeile 308:
 
// **********************************************************************
 
// **********************************************************************
 
void Auswahl_Nichtmetalle() {
 
void Auswahl_Nichtmetalle() {
   for (byte z = 1; z < Ausbaustufe; z++) {
+
   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)) {
 
     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);
 
       Led_an(z, 1);
Zeile 217: Zeile 316:
 
// **********************************************************************
 
// **********************************************************************
 
void Auswahl_fest() {
 
void Auswahl_fest() {
   for (byte z = 1; z < Ausbaustufe; z++) {
+
   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))) {
 
     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);
 
       Led_an(z, 1);
Zeile 225: Zeile 324:
 
// **********************************************************************
 
// **********************************************************************
 
void Auswahl_liquid() {
 
void Auswahl_liquid() {
   for (byte z = 1; z < Ausbaustufe; z++) {
+
   for (byte z = 1; z < Ausbaustufe + 1; z++) {
 
     if ((z == 35) || (z == 80)) {
 
     if ((z == 35) || (z == 80)) {
 
       Led_an(z, 1);
 
       Led_an(z, 1);
Zeile 240: Zeile 339:
 
}
 
}
 
// **********************************************************************
 
// **********************************************************************
void Auswahl_radioaktiv() {
+
void Auswahl_Periode() {
   for (byte z = 1; z < Ausbaustufe; z++) {
+
   byte anfang;
     if ((z == 43) || (z == 61) || ((z >= 84) && (z <= 118)) || (z == 134) || (z == 136)) {
+
  byte ende;
      Led_an(z, 1);
+
  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_biatomar() {
+
void Auswahl_Programm_x() { // 201
   for (byte z = 1; z < Ausbaustufe; z++) {
+
  // z. Zt. Dimmer-Test
     if ((z == 1) || (z == 7) || (z == 8) || (z == 9) || (z == 17) || (z == 35) || (z == 53) || (z == 138) ) {
+
   for (byte b = 0; b < 255; b = b + 5)
      Led_an(z, 1);
+
  {
     }
+
     Dimmer(b);
 +
    Led_an(1, 1);
 +
     delay(1000);
 
   }
 
   }
}
+
  Led_an(1, 0);
// **********************************************************************
 
void Auswahl_Programm_x() {
 
 
 
 
}
 
}
 
// **********************************************************************
 
// **********************************************************************
Zeile 267: Zeile 376:
  
 
}
 
}
 
 
// **********************************************************************
 
// **********************************************************************
void Auswahl_Periode(byte anfang, byte ende) {
+
void Auswahl_radioaktiv() {
   for (byte z = anfang; z < ende; z++) {
+
   for (byte z = 1; z < Ausbaustufe + 1; z++) {
     Led_an(z, 1);
+
     if ((z == 43) || (z == 61) || ((z >= 84) && (z <= 118)) || (z == 134) || (z == 136)) {
  }
+
      Led_an(z, 1);
}
+
     }
// **********************************************************************
 
void Auswahl_alles_an() {
 
  for (byte z = 1; z < Ausbaustufe; z++) {
 
    Led_an(z, 1);
 
  }
 
}
 
// **********************************************************************
 
void Auswahl_alles_aus() {
 
  for (byte z = 1; z < Ausbaustufe; z++) {
 
    Led_an(z, 0);
 
  }
 
}
 
// **********************************************************************
 
void Auswahl_Bingo() {
 
  // TO DO: evtl. nur 1x ohne die Schleife
 
  for (byte z = 1; z < Ausbaustufe; z++) {
 
    byte zufall = random(1, Ausbaustufe);
 
    // setzt 'zufall' mit einer Zufallszahl
 
    // zwischen 1 und Ausbaustufe gleich
 
    Serial.println(zufall);
 
    Led_an(zufall, 1);
 
     delay(500);
 
 
   }
 
   }
 
}
 
}
 
// **********************************************************************
 
// **********************************************************************
void www() {
+
void Dimmer(byte brightness) // 0 to 255
  // Create a client connection
+
// Funktion merkt sich Helligkeitswert für LEDs, ausbaubedingt z. Zt. nur am 1. Schieberister
  EthernetClient client = server.available();
+
// 0 = dunkel, weil 0% Einschaltdauer, 255 = volle Leistung, weil 100% ED
  if (client) {
+
{
    while (client.connected()) {
+
  analogWrite(outputEnablePin, 255 - brightness);
      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 debuging
 
          int pos = 1 + readString.indexOf('z=');
 
          Serial.println(pos);
 
          String zahl = readString.substring(pos);
 
          Serial.print("Zahl-String:");
 
          Serial.println(zahl);
 
          Auswahl = zahl.toInt();
 
          Serial.println(Auswahl);
 
          //                  delay(1000);
 
          client.println("HTTP/1.1 200 OK"); //send new page
 
          client.println("Content-Type: text/html");
 
          client.println();
 
          client.println("<HTML>");
 
          client.println("<HEAD>");
 
          client.println("<TITLE>Periodensystem der Elemente</TITLE>");
 
          client.println("</HEAD>");
 
          client.println("<BODY>");
 
          client.println("<H1>Periodensystem der Elemente</H1>");
 
          client.println("<hr />");
 
          client.println("<br />");
 
          client.println("<H2>Led auswählen</H2>");
 
          client.println("<br />");
 
          client.println("<a href=\"/?z=4\"\">[ 4 ]</a>");
 
          client.println("-");
 
          client.println("<a href=\"/?z=7\"\">[ 7 ]</a><br />");
 
          client.println("<br />");
 
          client.println("<br />");
 
          client.println("<a href=\"/?z=255\"\">[alle an]</a>");
 
          client.println("-");
 
          client.println("<a href=\"/?z=254\"\">[alle aus]</a><br />");
 
          client.println("<p>Created by Detlef Giesler. Visit http://www.bs-wiki.de for more info!</p>");
 
          client.println("<br />");
 
          client.println("</BODY>");
 
          client.println("</HTML>");
 
          delay(1);
 
          //stopping client
 
          client.stop();
 
          //controls the Arduino if you press the buttons
 
          Serial.write(Auswahl);
 
          //clearing string for next read
 
          readString = "";
 
        }
 
      }
 
    }
 
  }
 
 
}
 
}
 
// **********************************************************************
 
// **********************************************************************
Zeile 378: Zeile 410:
 
// **********************************************************************
 
// **********************************************************************
 
void Led_an(byte Element, boolean an) {
 
void Led_an(byte Element, boolean an) {
   // to do: switch Element/LED, z. B. bei Element 11 (Natrium) die 3. Led schalten
+
   // Funktion schaltet eine durch (Element) bestimmte LEDs an oder aus,
 +
  // 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
 
   // patch it:
 
   // patch it:
 
   // Element=patch[Element];
 
   // Element=patch[Element];
 +
  zyklus = 0; // Schlafmodus beenden
 
   Laufzeit_hhmmss();
 
   Laufzeit_hhmmss();
 
   Serial.print(Element);
 
   Serial.print(Element);
Zeile 387: Zeile 422:
 
   Serial.print(" -> ");
 
   Serial.print(" -> ");
 
   Serial.println(an);
 
   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:
 
   // 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)
Zeile 392: Zeile 431:
 
     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[Element] = an;
 
   Serial.print(Anzahl_angeschaltete_LEDs);
 
   Serial.print(Anzahl_angeschaltete_LEDs);
 
   Serial.print(" LEDs sind an: ");
 
   Serial.print(" LEDs sind an: ");
   for (byte z = 0; z < Ausbaustufe; z++) {
+
   for (byte z = 1; z < Ausbaustufe + 1; z++) {
 
     if (led[z]) {
 
     if (led[z]) {
 
       Serial.print(z);
 
       Serial.print(z);
Zeile 401: Zeile 441:
 
     }
 
     }
 
   }
 
   }
  Serial.println("");
 
 
   // nur für Fehlerabfrage
 
   // nur für Fehlerabfrage
 
   if (Anzahl_angeschaltete_LEDs > Ausbaustufe) {
 
   if (Anzahl_angeschaltete_LEDs > Ausbaustufe) {
     delay(30000);
+
    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_Startzeit[Element] = t_gesamt_in_sek;
 
 
     led_aus[Element] = t_gesamt_in_sek + Eieruhr; // vormerken: LED nach (Eieruhr) Sek. wieder ausschalten
 
     led_aus[Element] = t_gesamt_in_sek + Eieruhr; // vormerken: LED nach (Eieruhr) Sek. wieder ausschalten
 
   }
 
   }
 
   resetPins();
 
   resetPins();
   digitalWrite(storePin, LOW);
+
   // digitalWrite(storePin, LOW);
   for (byte i = 0; i < Ausbaustufe; i++) {
+
   for (byte i = 1; i < Ausbaustufe + 1; i++) {
 
     // Aktion passiert bei Wechsel von LOW auf HIGH
 
     // Aktion passiert bei Wechsel von LOW auf HIGH
 
     digitalWrite(shiftPin, LOW);
 
     digitalWrite(shiftPin, LOW);
Zeile 423: Zeile 462:
 
     digitalWrite(shiftPin, HIGH);
 
     digitalWrite(shiftPin, HIGH);
 
   }
 
   }
   // Wenn alle 8 Stellen im Register sind, jetzt das StorePin STCP
+
   // Wenn alle Stellen im Register sind, jetzt das StorePin STCP
 
   // von LOW auf HIGH, damit wird Registerinhalt an Ausgabepins
 
   // von LOW auf HIGH, damit wird Registerinhalt an Ausgabepins
 
   // kopiert und der Zustand an den LEDs sichtbar
 
   // kopiert und der Zustand an den LEDs sichtbar
Zeile 430: Zeile 469:
 
   // neues Muster einschalten:
 
   // neues Muster einschalten:
 
   digitalWrite(storePin, HIGH);
 
   digitalWrite(storePin, HIGH);
   delay(100);
+
   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(10);
+
   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 = 121; z < 139; z++) {
 +
  //      Led_an(z, 1);
 +
  //  }
 
}
 
}
 
// **********************************************************************
 
// **********************************************************************
Zeile 449: Zeile 497:
 
   // schaltet die LED nach (Eieruhr) Sek. wieder aus
 
   // schaltet die LED nach (Eieruhr) Sek. wieder aus
 
   Laufzeit_hhmmss();
 
   Laufzeit_hhmmss();
   for (byte z = 1; z < Ausbaustufe; z++) {
+
   for (byte z = 1; z < Ausbaustufe + 1; z++) {
 
     if (led[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?
 
       // max. Einschaltzeit überschritten?
 
       if (t_gesamt_in_sek > led_aus[z]) {
 
       if (t_gesamt_in_sek > led_aus[z]) {
Zeile 457: Zeile 509:
 
     }
 
     }
 
   }
 
   }
   delay(10);
+
   delay(bremse);
 +
  Legende_an();
 
   Serial.println();
 
   Serial.println();
 +
}
 +
// **********************************************************************
 +
void www() {
 +
  // Create a client connection
 +
  Serial.print("Ich höre www ...");
 +
  EthernetClient client = server.available();
 +
  if (client) {
 +
    while (client.connected()) {
 +
      if (client.available()) {
 +
        Serial.println("++++++++++");
 +
        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"
 +
          int pos = 1 + readString.indexOf('z=');
 +
          // komischerweise kommt von Handy: "GET /z%3D[pos] HTTP/1.1", daher:
 +
          if (pos == 0) {
 +
            pos = 1 + readString.indexOf('z%3D');
 +
          }
 +
          Serial.println(pos);
 +
          String zahl = readString.substring(pos);
 +
          Serial.print("Zahl-String:");
 +
          Serial.println(zahl);
 +
          Auswahl = zahl.toInt();
 +
          zahl = String(Auswahl);
 +
          Serial.print("Auswahl:");
 +
          Serial.println(Auswahl);
 +
          //    delay(60000);
 +
          client.println("HTTP/1.1 200 OK"); //send new page
 +
          client.println("Content-Type: text/html");
 +
          client.println();
 +
          client.println("<HTML>");
 +
          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:
 +
            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("<p class='monospace'>");
 +
            //            client.println("<H1>Periodensystem der Elemente</H1>");
 +
            //            client.println("<hr />");
 +
            //            client.println("<br />");
 +
            //            client.println("<H2>Led ausw&auml;hlen</H2>");
 +
            //            client.println("<br />");
 +
            //            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("<br />");
 +
            //            client.println("<br />");
 +
            //            client.println("<a href=\"/?z=255\"\">[alle an]</a>");
 +
            //            client.println("-");
 +
            //            client.println("<a href=\"/?z=254\"\">[alle aus]</a><br />");
 +
            //            client.println("</p>");
 +
            //            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>");
 +
          delay(1);
 +
          //stopping client
 +
          client.stop();
 +
          //controls the Arduino if you press the buttons
 +
          Serial.write(Auswahl);
 +
          //clearing string for next read
 +
          readString = "";
 +
        }
 +
      }
 +
    }
 +
  }
 
}
 
}

Version vom 4. Mai 2015, 01:18 Uhr

// ********************************************************************** // interaktives Periodensystem der Elemente // schaltet gewünschte LED an // Detlef Giesler // BBS Winsen (Luhe) // ********************************************************************** // letzte Änderungen: // Webserver aus wg. Speicherproblemen // 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: // for-Schleife: Bedingung "Laufindex < Ausbaustufe" ersetzen durch "L. < A. +1", sonst fehlt der letzte Wert // Startwert i.d.R. 1, 0 soll unbenutzt bleiben // // **********************************************************************

  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=";

// Pinning Arduino & 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: // 32 ist die derzeitige Ausbaustufe, am Ende 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 = 32;

// Auswahl // Ordnungszahl definiert Element 1...118 byte Auswahl = 0; // 0 = existiert nicht // 1 = Wasserstoff, 2 = Helium ... // 131...137 = 1. - 7. Periode // 141...148 = 1. - 8. Hauptgruppe // 160 = Metalle // 161 = Halbmetalle // 162 = Nichtmetalle // 190 = fest // 191 = flüssig // 192 = gasförmig // 193 = radioaktiv // 194 = biatomar // 200 = Bingo // 201 = Programm_x // 202 = Programm_y // 203 = Programm_z // 222 = Browserfenster umschalten auf Arduino-Auswahlmenü // 254 = alles_aus // 255 = alles_an

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

 // Pinning ohne eine "Led #0"
 // p1 p2*p3* p4  p5  p6  p7  p8-p9 p10 p11 p12 p13 p14 p15  p16 -p17  p18  p19 p20 p21 p22  p23 p24-
 0, 1, 3, 11, 19, 37, 55, 87, 0, 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: // TO DO wg. Speicherproblemen vorerst aus: // byte patch[145];

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 byte Eieruhr = 20; // Vorgabe der Einschaltdauer einer LED in Sekunden int zyklus = 0; // loop-Zyklen // Debugging int bremse = 0; // 1 ... 60000 Standardwert für Entschleunigung in ms zwischen einigen Befehlen zwecks Debugging // ********************************************************************** void setup() {

 Dimmer(10);
 Serial.begin(9600); // Kontrollausgabe über seriellen Monitor
 // 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);
 // start the Ethernet connection and the server:
 Ethernet.begin(mac, ip, gateway, subnet);
 server.begin();
 Serial.print("server is at ");
 Serial.println(Ethernet.localIP());
 resetPins();  // alle Pins auf LOW
 // Switchen, Element_an_Pin[] nach steigender Ordungszahl merken:
 // TO DO wg. Speicherproblemen vorerst aus:
 //  for (byte z = 1; z < 145; z++) {
 //    patch[Element_an_Pin[z]] = z;
 //    // Ordnungszahl
 //  }
 // ***********************
 // 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);
 //      delay(1000);
 //      Serial.print("Pin ");
 //      Serial.print(z);
 //      Serial.print(" - OZ ");
 //      Serial.println(Element_an_Pin[z]);
 //      Serial.print("Patch = ");
 //      Serial.println(patch[z]);
 //    }
 //  }
 //  delay(10000);
 // ***********************
 // TO DO: LED 0 ist  eigentlich gar nicht schaltbar...
 // LED Nr. 0 (Legende) immer an, ist gleichzeitig Kontrollleuchte für aktives Board:
 //  Led_an(0, 1);
 //  delay(1000);
 // für Testphase LEDs im setup einschalten, später in loop:
 //  Element = 7;  // blau
 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);
 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;
 // horche an der seriellen Schnittstelle und am Ethernet-Shield
 // erfrage Element; nach Ordnungszahl o. ä. auswählen:
 // z.B. Nr. 1 - Wasserstoff:
 www();
 while (Serial.available() > 0)
 {
   Serial.println("Ich bin www-taub!");
   byte a = 0;
   {
     Auswahl = Auswahl * 10;
     a = Serial.read() - '0';
     Auswahl = Auswahl + a;
     delay(1);
   }
   Serial.write(Auswahl);
 }
 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:
 if (Anzahl_angeschaltete_LEDs > 1) {
   Treppenlicht();
 }
 if (zyklus > 500) {         // 999
   // 1000-mal is nichts passiert, daher:
   Auswahl_alles_aus();
   //TO DO: ggf. Sleep-Modus mit Bewegungsmelder zum Reaktivieren
 }
 Serial.println("------------------------------------");
 delay(bremse);

} // ********************************************************************** // ############### Unterprogramme nach ABC ############################## // ********************************************************************** void Auswahl_alles_an() {

 for (byte z = 1; z < Ausbaustufe + 1; z++) {
   Led_an(z, 1);
 }

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

 // schaltet alle LEDs außer die für die Legende aus
 for (byte z = 1; z < Ausbaustufe + 1; z++) {
   Led_an(z, 0);
 }
 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_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. Dimmer-Test
 for (byte b = 0; b < 255; b = b + 5)
 {
   Dimmer(b);
   Led_an(1, 1);
   delay(1000);
 }
 Led_an(1, 0);

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

} // ********************************************************************** 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 brightness) // 0 to 255 // Funktion merkt sich Helligkeitswert für LEDs, ausbaubedingt z. Zt. nur am 1. Schieberister // 0 = dunkel, weil 0% Einschaltdauer, 255 = volle Leistung, weil 100% ED {

 analogWrite(outputEnablePin, 255 - brightness);

} // ********************************************************************** 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 eine durch (Element) bestimmte LEDs an oder aus,
 // 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
 // patch it:
 // Element=patch[Element];
 zyklus = 0; // Schlafmodus beenden
 Laufzeit_hhmmss();
 Serial.print(Element);
 Serial.print(". LED wird geschaltet von ");
 Serial.print(led[Element]);
 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[Element]) {
   Anzahl_angeschaltete_LEDs = Anzahl_angeschaltete_LEDs + an * 2 - 1; // Anz. = Anz. -1 oder +1
 }
 //}
 led[Element] = an;
 Serial.print(Anzahl_angeschaltete_LEDs);
 Serial.print(" LEDs sind an: ");
 for (byte z = 1; z < Ausbaustufe + 1; z++) {
   if (led[z]) {
     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!");
   delay(bremse);
 }
 // spart Speicher: unsigned long led_Start zu byte einkürzen:
 if (an) {
   led_aus[Element] = t_gesamt_in_sek + Eieruhr; // vormerken: LED nach (Eieruhr) Sek. wieder ausschalten
 }
 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]);
   // ALIAS  digitalWrite(dataPin, led[patch[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);
 delay(bremse);
 // 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 = 121; z < 139; z++) {
 //      Led_an(z, 1);
 //  }

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

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

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

 Serial.println("Treppenlicht");
 // schaltet die LED nach (Eieruhr) Sek. wieder aus
 Laufzeit_hhmmss();
 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 (t_gesamt_in_sek > led_aus[z]) {
       Led_an(z, 0);
     }
   }
 }
 delay(bremse);
 Legende_an();
 Serial.println();

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

 // Create a client connection
 Serial.print("Ich höre www ...");
 EthernetClient client = server.available();
 if (client) {
   while (client.connected()) {
     if (client.available()) {
       Serial.println("++++++++++");
       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"
         int pos = 1 + readString.indexOf('z=');
         // komischerweise kommt von Handy: "GET /z%3D[pos] HTTP/1.1", daher:
         if (pos == 0) {
           pos = 1 + readString.indexOf('z%3D');
         }
         Serial.println(pos);
         String zahl = readString.substring(pos);
         Serial.print("Zahl-String:");
         Serial.println(zahl);
         Auswahl = zahl.toInt();
         zahl = String(Auswahl);
         Serial.print("Auswahl:");
         Serial.println(Auswahl);
         //     delay(60000);
         client.println("HTTP/1.1 200 OK"); //send new page
         client.println("Content-Type: text/html");
         client.println();
         client.println("<HTML>");
         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:
           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(); //controls the Arduino if you press the buttons Serial.write(Auswahl); //clearing string for next read readString = ""; } } } }

}