// **********************************************************************
// letzte Änderungen:
// 11.07. Patchmodus gefixt
// 10.07. const Variablenumbennung
// 08.07. serieller Input in Unterprogramm, www gekürzt
// 07.07. Fernbedienung mit Interrupt
// **********************************************************************
// 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
//
// **********************************************************************
// verwendete Bibliotheken:
#include <SPI.h>
#include <Ethernet.h>
// ----------------------------------------------------------------------
// globale Variablen:
// KONSTANTEN
// Pinning Arduino:
const byte IR_PIN = 2;
// Arduino-Pin 3 als "Dimmer" verbunden mit OE des 74HC595 (dort Pin 13, Output Enable)
const byte outputEnablePin OUTPUT_ENABLE_PIN = 3;// Arduino-Pin 8 als shiftPin SHIFT_PIN verbunden mit SH_CP des 74HC595 (dort Pin 11, shift register clock input)const byte shiftPin SHIFT_PIN = 8;
// Arduino-Pin 9 verbunden mit ST_CP des 74HC595 (dort Pin 12, storage register clock input = latch pin)
const byte storePin STORE_PIN = 9;
// Arduino-Pin 10 verbunden mit DS des 74HC595 (dort Pin 14, serial data input)
const byte dataPin DATA_PIN = 10;#include <SPI.h>#include <Ethernet.h>// ---------------------------------------------------------------------- // globale VariablenInternet :
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")
EthernetServer server(80); //server port
String readString;
// String URL = "http://www.bs-wiki.de/mediawiki/index.php?title=";String Input; // IR---------------------------------------------------------------------- // LED-Wand: // Hardware-Info: 12m²-PSE aus 6 Teildisplays, 144/6 = 24 LEDs/Teildisplay, // ... jedes Teildisplay angesteuert durch 3x8 Datenleitungen (3 Spalten, 8 Zeilen) , Seriell oder www// ... pro Spalte ein 8-bit-Schieberegister = 18 SR insgesamt
// 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 insgesamtconst 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...118int Auswahl = 0; // 254boolean neue_Auswahl;
// 0 = existiert nicht
// 1 = Wasserstoff, 2 = Helium ...
, 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 }; // }---------------------------------------------------------------------- // Auswahl im laufenden Programm: String Input ;// IR, Seriell oder www // Element_an_Pin[] nach steigender Ordungszahl notieren:Ordnungszahl definiert Element 1...118 int Auswahl = 0; // 254 byte patch[144]boolean neue_Auswahl ;
byte Anzahl_angeschaltete_LEDs = 0;
// TO DO: über Poti einstellen und von Pin einlesen oder über WebinterfaceAuswahl (180)
unsigned int Eieruhr = 20; // Vorgabe der Einschaltdauer einer LED in Sekunden
byte last_Element = 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 byte IR_PIN = 2;
volatile boolean bounced = 0;
const byte CODE_LEN = 40;
volatile unsigned long durations[CODE_LEN];
int letzte_IR_Auswahl;
int IR_Auswahl;
boolean mehrstellig;
// **********************************************************************
void setup() {
pinMode(outputEnablePinOUTPUT_ENABLE_PIN , OUTPUT); // Dimmer analogWrite(outputEnablePinOUTPUT_ENABLE_PIN , 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
// randomSeed(analogRead(5));
// Pins 3, 8,9,10 auf Ausgabe
// pinMode(outputEnablePinOUTPUT_ENABLE_PIN , OUTPUT); // Dimmer pinMode(storePinSTORE_PIN , OUTPUT); pinMode(shiftPinSHIFT_PIN , OUTPUT); pinMode(dataPinDATA_PIN , OUTPUT);
// IR-Fernbedienung
pinMode(pinIRIR_PIN , INPUT);
attachInterrupt(0, decodeIR, FALLING);
//FALLING for when the Digitalpin 2 goes from high to low.
Serial.println("PSE"); Serial.println("--------------------------------");
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip, gateway, subnet);
server.begin();
Serial.print("server is at Server ist an IP ");
Serial.println(Ethernet.localIP());
Serial.print("Patchmodus ist "); if (patchmodus) { Serial.println("PSEeingeschaltet. "); } else { Serial.println("--------------------------------ausgeschaltet. "); }
// TO DO: löschen:
// Element_an_Pin[] nach steigender Ordungszahl notieren:
// Switchen, Element_an_Pin[] nach steigender Ordungszahl merken:
// for (byte z = 1; z < 144 + 1; z++) {
// }
// }
// für Testphase LEDs LED von Element = 7 im setup Setup einschalten, später in loop: // Element = 7; // blau
Led_an(7, 1);
delay(bremse);
Legende_an();
Serial.println("jetzt Jetzt startet die loopLoop -Schleife ......");
Serial.println("--------------------------------------");
delay(bremse);
// delay(3000);
}
// TO DO: wenn Legende mit mehreren LED hinterleuchtet wird, diese Anzahl statt der "1" einsetzen:
if (Anzahl_angeschaltete_LEDs > Legenden_LEDs) {
Treppenlicht();
// 0 = dunkel, weil 0% Einschaltdauer, 255 = volle Leistung, weil 100% ED
{
analogWrite(outputEnablePinOUTPUT_ENABLE_PIN , 255 - Helligkeit);
}
// **********************************************************************
// 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)
Anzahl_angeschaltete_LEDs = Anzahl_angeschaltete_LEDs + an * 2 - 1; // Anz. = Anz. -1 oder +1
}
//}
led[Pin] = an;
// Zwischenbilanz für Kontrolle
// spart Speicher: unsigned long led_Start zu byte einkürzen:
if (an) {
led_aus[PinElement ] = Laufzeit_in_sek() + Eieruhr; // vormerken: LED nach (Eieruhr) Sek. wieder ausschalten
last_Element = Element; // welches Element wurde zuletzt angeschaltet?
Serial.print("Element ");
Serial.print(Element);
Serial.print(" -> Pin ");
Serial.println(Pin);
}
resetPins();
// digitalWrite(storePinSTORE_PIN , LOW);
for (byte i = 1; i < Ausbaustufe + 1; i++) {
// Aktion passiert bei Wechsel von LOW auf HIGH
digitalWrite(shiftPinSHIFT_PIN , LOW);
// Jetzt den Wert der aktuellen Stelle ans Datenpin DS anlegen
digitalWrite(dataPinDATA_PIN , led[i]);
// Dann ShiftPin SHCP von LOW auf HIGH, damit wird der Wert
// am Datenpin ins Register geschoben.
digitalWrite(shiftPinSHIFT_PIN , HIGH);
}
// Wenn alle Stellen im Register sind, jetzt das StorePin STCP
// kopiert und der Zustand an den LEDs sichtbar
//analogWrite(storePinSTORE_PIN , 254);
// neues Muster einschalten:
digitalWrite(storePinSTORE_PIN , HIGH);
// // Serial.print(Element);
// // Serial.print(". LED ist ");
// **********************************************************************
void Legende_an() {
// TO DO: solange Ausbaustufe 144 noch nicht erreicht, ersatzweise Led #9diese LEDs immer anlassen : // Led_an(9TO DO: bei Sondergruppe die anderen ausblenden, z. B. Metalle an , 1); // wenn Ausbaustufe 144 erreicht, diese LEDs immer anlassen:dann Halb- u. Nichtmetalle aus
for (byte z = legende_anfang; z < legende_ende + 1; z++) {
Led_an(z, 1);
for (byte i = 1; i < Ausbaustufe + 1; i++) {
led[i] = 0;
digitalWrite(dataPinDATA_PIN , led[i]); digitalWrite(shiftPinSHIFT_PIN , HIGH);
}
Dimmer(127);
digitalWrite(storePinSTORE_PIN , HIGH);
Legende_an();
Auswahl = 0;
void resetPins() {
// Zuerst immer alle 3 Pins auf LOW
digitalWrite(storePinSTORE_PIN , LOW); digitalWrite(shiftPinSHIFT_PIN , LOW); digitalWrite(dataPinDATA_PIN , 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++) {
byte Element = z;
if (patchmodus) { // Normalfall: OZ 22 = Pin 27
Element = Element_an_Pin[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[zElement ]) {
// Legenden-LEDs immer an lassen:
if (z Element < legende_anfang || z Element > legende_ende)
{
Led_an(zElement , 0);
}
}
delay(bremse);
// Legende_an();
// Serial.println();
}
// **********************************************************************
}
}
// **********************************************************************
// 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ä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(); //clearing string for next read readString = ""; }
}
}
}
}
}
// **********************************************************************
for (i = 0; i < CODE_LEN; i += 1) {
//store the duration of the pulse (microseconds)
durations[i] = pulseIn(pinIRIR_PIN , 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,
// Serial.println(sauberes_signal);
switch (code) {
case 22: Auswahl IR_Auswahl = 0; break; case 12: Auswahl IR_Auswahl = 1; break; case 24: Auswahl IR_Auswahl = 2; break; case 94: Auswahl IR_Auswahl = 3; break; case 8: Auswahl IR_Auswahl = 4; break; case 28: Auswahl IR_Auswahl = 5; break; case 90: Auswahl IR_Auswahl = 6; break; case 66: Auswahl IR_Auswahl = 7; break; case 82: Auswahl IR_Auswahl = 8; break; case 74: Auswahl IR_Auswahl = 9; break; case 7: Auswahl IR_Auswahl = 210; break; // Vol-- case 9: Auswahl IR_Auswahl = 213; break; // [EQ] -> mittlere Helligkeit case 21: Auswahl IR_Auswahl = 215; break; // Vol++ case 69: Auswahl IR_Auswahl = 254; break; // CH- alles aus case 70: Auswahl IR_Auswahl = 200; break; // CH Zufallszahl -> Bingo case 71: Auswahl IR_Auswahl = 255; break; // CH+ alles an
case 64 : // next
switch (last_Element) { // Elemente, Hauptgruppen, Perioden ...
case 1 ... 118: Auswahl IR_Auswahl = min(118, last_Element + 1); break; case 131 ... 194: Auswahl IR_Auswahl = min(194, last_Element + 1); break;
}
break;
case 68 : // prev
Auswahl IR_Auswahl = max(1, last_Element - 1);
break;
case 25 : // 100+ als Init für mehrstellige Zahl
mehrstellig = 1;
Auswahl IR_Auswahl = 0;
break;
case 13 : // 200+ als Quit nach mehrstelliger Zahl
mehrstellig = 0;
Auswahl IR_Auswahl = letzte_IR_Auswahl;
letzte_IR_Auswahl = 0;
break;
case 67: Auswahl IR_Auswahl = 202; break; // Play/Pause -> Programm_y
}
if (mehrstellig) {
if (Auswahl IR_Auswahl < 10) { letzte_IR_Auswahl = letzte_IR_Auswahl * 10 + AuswahlIR_Auswahl ;
}
}
}
if (mehrstellig == 0) { Serial.print("IR-Auswahl: "); Auswahl = IR_Auswahl; // IR_Auswahl = 0; Serial.println(Auswahl); Serial.println(); neue_Auswahl = 1; Input = "Fernbedienung"; }
// last_Element = Auswahl;
// delay(3000);
Änderungen – BS-Wiki: Wissen teilen
Änderungen
64 Byte hinzugefügt ,
00:43, 11. Jul. 2015