Homeduino: universeller LAN/WLAN-Arduino für die Hausautomat

Problemlösungen und Hinweise von allgemeinem Interesse zur Haussteuerung mit HomeMatic

Moderator: Co-Administratoren

Benutzeravatar
funkleuchtturm
Beiträge: 2368
Registriert: 13.06.2011, 16:42
Hat sich bedankt: 23 Mal
Danksagung erhalten: 357 Mal
Kontaktdaten:

Re: Homeduino: universeller LAN/WLAN-Arduino für die Hausaut

Beitrag von funkleuchtturm » 26.02.2017, 19:34

SciBee hat geschrieben:wenn ich den gesamten Code incl. Erläuterungen auf deiner HP poste wird es doch - mangels Code Tags - sehr unübersichtlich.
Evtl. willst Du ja dort selbst einen Link hierher setzen?
Hast recht. Ich schau mal, wie wir das am besten machen.
SciBee hat geschrieben:Das Umprogrammieren ist ja nun nicht ganz trivial und ich wollte erst Mal die anderen Fehlerquellen ausschließen: in erster Linie mich und dann auch die Lib.
Das Flashen ist relativ umständlich und die Informationen zu den Adressen sind oft widersprüchlich. Hab ich viel Lehrgeld bezahlt :mrgreen:
SciBee hat geschrieben:Allerdings sehe ich noch keine Anwendung, die es erfordert mit dem Homeduino gleichzeitig über LAN und WLAN im - üblicherweise gleichen - Netz zu sein
So war das auch nicht gedacht! Es sollte die Möglichkeit da sein, entweder LAN oder WLAN zu nutzen. Viele Homematiker mögen lieber Draht als Funk und das Angebot an Wired-Komponenten ist nun nicht gerade umfangreich.
SciBee hat geschrieben:Willst Du dem HD noch Router/AP Funktionalität verpassen?
Weiß ich noch nicht. Möchte aber versuchen , wie beim WIFFI dem Homeduino auch eine eigene Webseite zu verpassen, auf der man die Messwerte dann mit dem Browser ansehen kann. Ich weiß aber noch nicht, ob der MEGA2560 dafür groß genug ist.

Hast Du evtl. Lust, das neue MEGA-Wifi-Shield zu testen ? Dann schick ich Dir einen Bausatz zu. Bitte mir dann Deine Adresse über PN schicken .
Viele Gruesse
Eugen
________________________________________________
SmartHome-Eintopf mit feinem Homeduino-Gemüse
... und für Feinschmecker gibt´s den WIFFI, den WEATHERMAN-2, den PULSECOUNTER und den AIRSNIFFER
mit vielen Kochrezepten für den ambitionierten Homematiker

Benutzeravatar
funkleuchtturm
Beiträge: 2368
Registriert: 13.06.2011, 16:42
Hat sich bedankt: 23 Mal
Danksagung erhalten: 357 Mal
Kontaktdaten:

Re: Homeduino: universeller LAN/WLAN-Arduino für die Hausaut

Beitrag von funkleuchtturm » 27.02.2017, 16:05

Hallo SciBee,
hat Dein Skript für den ESP01 bei Dir funktioniert ?

Ich habe es genauer ausprobiert und habe erhebliche Probleme mit der verwendeten ESP-Library. Das Senden der Daten an die CCU-Systemvariablen funktioniert im Prinzip, aber mit einer unverständlichen Fehlermeldung und so großem Zeitverzug, daß der normale Programmzyklus nicht mehr eingehalten wird.

In umgekehrter Richtung, Dateneingabe per Browser, funktioniert bei mir gar nichts.
Viele Gruesse
Eugen
________________________________________________
SmartHome-Eintopf mit feinem Homeduino-Gemüse
... und für Feinschmecker gibt´s den WIFFI, den WEATHERMAN-2, den PULSECOUNTER und den AIRSNIFFER
mit vielen Kochrezepten für den ambitionierten Homematiker

Benutzeravatar
SciBee
Beiträge: 5
Registriert: 25.02.2017, 23:50

Re: Homeduino: universeller LAN/WLAN-Arduino für die Hausaut

Beitrag von SciBee » 27.02.2017, 21:26

Habe bis eben mit dem FW Update des ESP01 auf die Espressif Version gekämpft. Mit meinen FTDI Adaptern bin ich voll in den gefürchteten "invalid head of packet" Fehler gerannt.
Ich musste mir erst ein Programmierinterface mit 3V3 Regler und Level shifting bauen. Programmiert habe ich es dann, indem ich statt dem FTDI Adapter einen Arduino Uno missbraucht habe.
Drauf ist jetzt die momentan aktuellste Version 2.0.0 von http://bbs.espressif.com/viewtopic.php?f=46&t=2451.
Verwendet habe ich diese Settings:
Settings.jpg
ESP Flashtool Settings
Jetzt muss ich den Code mal mit dieser Firmware testen.

Was meinst Du mit Script? Das Uhrzeit Script auf der CCU? Das läuft bei mir recht zuverlässig.
Die Homeduinos übertragen ihre IPs und die Zustände auch an die CCU. Es scheinen also beide Richtungen zu funktionieren - zumindest bei mir.
Wenn ich Daten über den Browser eingebe kommt/kam es eben manchmal zu den geschilderten Problemen. Der Browser bekommt keine Antwort vom HD und rennt in einen Timeout. Der Code am HD dann auch. Er bleibt in der Warteschleife auf die Blank line hängen. Deshalb wollte ich ja mal die Espressif FW testen. Unverständliche Fehlermeldungen hatte ich aber bisher nicht.
Im Code ist übrigens schon eine Website. Die liefert der HD zurück, wenn Du ihm per Browser Daten schickst. Da gibt es einen Aufrufzähler, Feedback, wie lang das Kommando war und welches Kommando gesendet wurde. Im Code ab Zeile 1227. Da könnte man natürlich auch Sensorwerte zurückgeben oder z.B. An/Aus- Buttons mit Hyperlinks anlegen

So, habe jetzt den ESP01 mit Espressif FW an den HD gehängt und das sieht schon stabiler aus. Das könnte allerdings auch an der Stromversorgung liegen. Vorher hat der "Saver ESP" die 3V3 aus den 5V des Mega erzeugt. Jetzt speise ich separat ein mit einem 1,5A 3V3 LDO (Nicht kleckern - KLOTZEN) :D
Falls das die Ursache sein sollte könnte es mit Deinem MEGA-Wifi-Shield problematisch werden, denn ich vermute mal, Du holst die 3V3 auch aus den 5V des Mega.

Die Lib habe ich nachgesehen. Diese hier wird verwendet:
WIFIEsp.jpg
WIFIEsp Library
Ich verwende übrigens eine CCU1 - falls das einen Unterschied macht. Aber auf die Kommunikation Browser<->HD sollte das keinen Einfluss haben :?
Hast Du evtl. Sonderzeichen wie @, | ~ in Deinem WLAN Passwort? Da habe ich schon die merkwürdigsten Dinge erlebt.
Ich probiere Dein Shield gerne mal aus. Bekommst eine PN.
CCU1 + CCU2

Benutzeravatar
SciBee
Beiträge: 5
Registriert: 25.02.2017, 23:50

Re: Homeduino: universeller LAN/WLAN-Arduino für die Hausaut

Beitrag von SciBee » 12.03.2017, 16:53

Hier nun eine überarbeitete Version des Codes.
Die Verbindung zur CCU ist nun stabiler und es können auch ganze Textzeilen an das Display gesendet werden.
Dazu ist aber eine Vergrößerung des seriellen RX Puffers auf 256Byte in der Arduino IDE nötig.
Wie das geht ist prinzipiell hier beschrieben: http://www.hobbytronics.co.uk/arduino-s ... uffer-size
Allerdings müssen ein paar Details angepasst werden. So muss man die HardwareSerial.h editieren und nicht die HardwareSerial.cpp und die liegt bei mir unter "C:\Users\[Benutzername]\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.17\cores\arduino" (vor der core-Kopie).

Code: Alles auswählen

#if !defined(SERIAL_TX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_TX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#endif
#endif
#if !defined(SERIAL_RX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_RX_BUFFER_SIZE 16
#else
#define SERIAL_RX_BUFFER_SIZE 256
#endif
#endif
#if (SERIAL_TX_BUFFER_SIZE>256)
Die Einträge müssen natürlich für den Mega und nicht für den Uno gemacht werden.
Dazu kopiert man unter dem Abschnitt "mega.name=Arduino/Genuino Mega or Mega 2560" in der boards.txt (C:\Users\[Benutzername]\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.17\boards.txt) folgenden Abschnitt rein nachdem man das ...\cores\arduino Verzeichnis nach ...\cores\arduino_256_serialbuffer kopiert hat:

Code: Alles auswählen

##############################################################

mega256.name=Arduino Mega 2560 265kB SerialBuffer

mega256.vid.0=0x2341
mega256.pid.0=0x0010
mega256.vid.1=0x2341
mega256.pid.1=0x0042
mega256.vid.2=0x2A03
mega256.pid.2=0x0010
mega256.vid.3=0x2A03
mega256.pid.3=0x0042
mega256.vid.4=0x2341
mega256.pid.4=0x0210
mega256.vid.5=0x2341
mega256.pid.5=0x0242

mega256.upload.tool=avrdude
mega256.upload.maximum_data_size=8192

mega256.bootloader.tool=avrdude
mega256.bootloader.low_fuses=0xFF
mega256.bootloader.unlock_bits=0x3F
mega256.bootloader.lock_bits=0x0F

mega256.build.f_cpu=16000000L
mega256.build.core=arduino_256_serialbuffer
mega256.build.variant=mega
# default board may be overridden by the cpu menu
mega256.build.board=AVR_MEGA2560

## Arduino/Genuino Mega w/ ATmega2560
## -------------------------
mega256.menu.cpu.atmega2560=ATmega2560 (Mega 2560)

mega256.menu.cpu.atmega2560.upload.protocol=wiring
mega256.menu.cpu.atmega2560.upload.maximum_size=253952
mega256.menu.cpu.atmega2560.upload.speed=115200

mega256.menu.cpu.atmega2560.bootloader.high_fuses=0xD8
mega256.menu.cpu.atmega2560.bootloader.extended_fuses=0xFD
mega256.menu.cpu.atmega2560.bootloader.file=stk500v2/stk500boot_v2_mega2560.hex

mega256.menu.cpu.atmega2560.build.mcu=atmega2560
mega256.menu.cpu.atmega2560.build.board=AVR_MEGA2560


##############################################################
Dann startet man die IDE neu und wählt als Board den neuen ATMega mit 256k SerialBuffer aus.
Ein Umprogrammieren des ESP-01 ist nicht nötig. Sowohl die Espressif wie auch die AI Tinker FW funktionieren bei mir.

Ich habe Eugen's erstes ESP-01 WiFi Shield mit dem Code getestet. Hat astrein funktioniert! Sogar bis 250kBaud - da hat dann aber der RX Puffer wieder nicht gereicht, weil der Mega zu langsam ist. Ich bin daher bei der Default Rate von 115200Baud geblieben.
Der Code ist für das Elegoo Display eingestellt. Wer andere Displays hat muss den Code eben an den entsprechenden Stellen modifizieren.

Code: Alles auswählen

const String Version = "hduino504_ESP_SciBee";  /*Stand: 12.03.2017 / Verfasser: Eugen Stall/SciBee
erprobt fuer Arduino Mega 2560 mit Arduino 1.6.13
hier ist immer die aktuelle V4.x Basis-Version:
http://www.stall.biz/project/homeduino-4-0-das-universelle-mess-und-aktormodul-fuer-die-hausautomation
das folgende homeduino-programm sendet messdaten zur ccu (homeduino als webclient) ...
und empfängt ausgabedaten für die homeduino-outputs (homeduino als webserver)

_________________            ________________
|port 8181 server|<---------<| client        |
|                |           |               |
| CCU            |           |     Homeduino | 
|                |           |               |
|          client|>--------->|server port 80 | 
|________________|           |_______________|

/Quellen:Arduino website plus http://arduino.cc/en/Tutorial/WebClient und ...
 http://tushev.org/articles/arduino/item/52-how-it-works-ds18b20-and-arduino und ...  

Intrudeced a command type parameter to adress different functions in the CCU/HD communication:
D controls Data operations e.g. control outputs - same behaviour as in versions < 5
T goes to text - displays a line of text in controlable size and color
C goes to Clock - sets the internal software clock. No additional hardware RTC required.

Example textline with a TFT display: 'http://123.456.789.123/?T0:This is a test,2,CYAN'
Syntax: http://[Homeduino_IP]/?T[linenumber 0...7]:[text with spaces],[fontsize 1...4],[textcolor] 
Maximum size is 100 characters including the fontsize, textline number and color value including the format commas
because of the tft_print textline String buffer. 
Remember: a 'Space' already consumes 3 characters because the browser translates it to '%20'!

Example setting the clock via browser: http://123.456.789.123/?C:27.05.2017,23:56:57 sets the internal clock of Homeduino at IP 123.456.789.123 to
Day: 27, Month: 05, Year: 2017, Hour: 23, Minute: 56, Second 57
You may use any separating character you like instead of dots or commas as the positions in the command are used.
the date is not increased automatically when midnight is over! This relies on the CCU clock. 
Update the clock via script every hour because the software clock in the HD is not very precise.

Example textline with LCD Display: 'http://123.456.789.123/?T0:0123456789ABCDEF' max. 16 characters
Syntax: http://[Homeduino_IP]/?T[linenumber 0...1]:[text with spaces] 
No fontsize or color parameters of course.

Example setting port D22 of Homeduino to "0" (Low) via browser: http://123.456.789.123/?D22:0
Same behaviour as before.

Example set a systemvariable in your CCU via browser:
http://123.456.789.123:8181/xy.exe?antwort=dom.GetObject('homeduino_001_IP').State('123.456.789.124')
which sets the varable named 'homeduino_001_IP' to the value '123.456.789.124'
 */
//#############################################################################################
//#############################################################################################
//Auswahl der verwendeten Shields: 
#define tft_display //"tft_display" oder "lcd_display"                         <<user-eingabe<< 
                    //"lcd_display" auch wenn kein display verwendet wird 
                    // TFT display details are defined starting near line 350.   <<user-eingabe<<
                    // Enable the sequence mating your TFT!!!

#define esp8266       //"cc3000"  Wifi-Modul or "w5100" ethernet shield or "esp8266" WiFi      <<user-eingabe<< 

//#define DEBUG //enable if you want to see more verbose output at the serial debug port
//#define ShowSeconds //enable if you want the clock to show seconds 12:34:56 elses it shows just 12:34

const byte ccu[4] = { 123, 456, 789, 123 };      //IP der CCU                                      <<user-eingabe<< 

//MAC-Adresse dieses Homeduinos ,bei mehreren Homeduinos MAC-.Adresse ändern!!:
// no need for a user specified MAC adress at ESP8266. ESP-01 has a preprogrammed MAC
const byte mac[6] = { 0x00, 0x10, 0x13, 0x00, 0x26, 0x07 };  //                                 <<user-eingabe<<

const byte homeduino[4] = { 123, 456, 789, 124 }; //IP des Homeduino,wenn DHCP versagt             <<user-eingabe<< 

const char ap_ssid[] = "myWLAN_SSID"; //SSID WLAN in Anführungszeichen                              <<user-eingabe<< 

const char ap_password[] = "myPassword"; //Passwort WLAN in Anführungszeichen         <<user-eingabe<< 

//xyz ist indiv. Bezeichnung dieses homeduino, keine sonderzeichen, öäüß...
const String homeduino_nummer = "001";  //                                                      <<user-eingabe<< 
const String hm_systemvariable = "homeduino_" + homeduino_nummer +"_";
//#############################################################################################
//#############################################################################################
//I/O-Kennung: hier wird die Funktion aller verwendbaren IO´s mit einer Kennziffer festgelegt 
//dabei haben alle IO´s die Standardfunktionen plus spez. Sonderfunktionen
//     Standardfunktionen sind:
//     '0' =andere Nutzg; '1' =dig_in; '2' =dig_out; '3' =1wire '4' =DHTxx; '5' =U_Schall; '17' = date and time; '18' =reserved line for text from CCU
//     6 textlines from CCU are activated in No 80...85 because there is no physical I/O beyond 79

const byte iomodus_D[87] = { 0,0,
 31, //D2 :      Std-fkt; '15' = IR_Rx??  '6' =ImpCount; '31' =tft;   <<user IO-Shield20<< 
 31, //D3 :      Std-fkt; '7' = 433_Rx??  '6' =ImpCount; '31' =tft;   <<user IO-Shield20<< 
 31, //D4 :      Std-fkt; '7' = 433_Tx??  '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D5 :      Std-fkt;                 '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D6 :      Std-fkt; '9' = buzzer    '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D7 :      Std-fkt;                 '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D8 :      Std-fkt;                 '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D9 :      Std-fkt; '16' = IR_Tx??  '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 0, //D10 :     Std-fkt; '20' = W5100 SS-Pin;
 0,  //D11 :     Std-fkt;  
 2,  //D12 :     Std-fkt;  
 2,  //D13 :     Std-fkt;
 0,  //D14/TX3 : Std-fkt; '0' =ESP8266;   '12' = rfid3;                <<user IO-Shield-Plus<< 
 0,  //D15/RX3 : Std-fkt; '0' =ESP8266;   '12' = rfid3;                <<user IO-Shield-Plus<< 
 0,  //D16/TX2 : Std-fkt; '0' =ESP8266;   '12' = rfid2;                <<user IO-Shield-Plus<< 
 0,  //D17/RX2 : Std-fkt; '0' =ESP8266;   '12' = rfid2;                <<user IO-Shield-Plus<< 
 0,  //D18/TX1 : Std-fkt; '6' =ImpCount;  '21' =CC3000                 <<user IO-Shield-Plus<< 
 0,  //D19/RX1 : Std-fkt; '6' =ImpCount;                               <<user IO-Shield-Plus<< 
 0,  //D20/SDA : Std-fkt; '6' =ImpCount;  '8' =I2C;                    <<user IO-Shield-Plus<< 
 0,  //D21/SCL : Std-fkt; '6' =ImpCount;  '8' =I2C;                    <<user IO-Shield-Plus<< 
 0,  //D22 :     Std-fkt; Resrved for ESP-01 reset;                        <<user IO-Shield-Plus<< 
 2,  //D23 :     Std-fkt; '12' = rfid2-oeffner;                        <<user IO-Shield-Plus<< 
 1,  //D24 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 0,  //D25 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 5,  //D26 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 0,  //D27 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 0,  //D28 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 4,  //D29 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 20, //MISO      '20' =W5100;  '21' =CC3000;   ICSP-Stecker
 20, //MOSI      '20' =W5100;  '21' =CC3000;   ICSP-Stecker
 20, //SCK       '20' =W5100;  '21' =CC3000;   ICSP-Stecker
 0, //SS                      '21' =CC3000;
 31, //D54 A0 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft; '30' =lcd; ser IO-Shield-20<< 
 31, //D55 A1 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft;         <<user IO-Shield-20<< 
 31, //D56 A2 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft;         <<user IO-Shield-20<< 
 31, //D57 A3 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft;         <<user IO-Shield-20<< 
 31, //D58 A4 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft;         <<user IO-Shield-20<< 
 0,  //D59 A5 :  Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-20<< 
 0,0,  
 0,  //D62 A8 :  Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D63 A9 :  Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D64 A10 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D65 A11 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D66 A12 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D67 A13 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D68 A14 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D69 A15 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;    '8' =I2C;                               <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;    '8' =I2C;                               <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;    '8' =I2C;                               <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;    '8' =I2C;                               <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 18, // '18' = reserved for text sent from CCU
 18, // '18' = reserved for text sent from CCU
 18, // '18' = reserved for text sent from CCU
 18, // '18' = reserved for text sent from CCU
 18, // '18' = reserved for text sent from CCU
 18, // '18' = reserved for text sent from CCU
 17  // '17' = reserved for date and time
}; 
//#############################################################################################
//hier werden Sensoren am I2C-Eingang aktiviert
const byte iomodus_baro = 0; //'0' =nc; '1' =BMP180,                   <<user IO-Shield-Plus<<
const byte iomodus_lux =  0; //'0' =nc; '1' =BH1750,                   <<user IO-Shield-Plus<<
//#############################################################################################
//hier werden die Kennwerte fuer die Impulszaehler festgelegt
volatile unsigned long pulsecounter[6] = 
{ 0, //Zaehlerstand fuer D2 -Impulseingang bei Reset                    <<user IO-Shield20<<
 0, //Zaehlerstand fuer D3 -Impulseingang bei Reset                     <<user IO-Shield20<<
 0, //Zaehlerstand fuer D21-Impulseingang bei Reset                     <<user IO-Shield-Plus<< 
 3, //Zaehlerstand fuer D20-Impulseingang bei Reset                     <<user IO-Shield-Plus<< 
 4711, //Zaehlerstand fuer D19-Impulseingang bei Reset                  <<user IO-Shield-Plus<< 
 5 //Zaehlerstand fuer D18-Impulseingang bei Reset                      <<user IO-Shield-Plus<< 
}; 
//hier wird der Teilerfaktor für die Impulszaehler festgelegt
const int pulsedivider[6] = 
{6, //Teilerfaktor D2 :                                                 <<user IO-Shield20<<
 1, //Teilerfaktor D3 :                                                 <<user IO-Shield20<<
 1, //Teilerfaktor D21 :                                                <<user IO-Shield-Plus<<
 1, //Teilerfaktor D20 :                                                <<user IO-Shield-Plus<<
 2, //Teilerfaktor D19 :                                                <<user IO-Shield-Plus<<
 1, //Teilerfaktor D18 :                                                <<user IO-Shield-Plus<<
}; 
//#############################################################################################
//#############################################################################################
//hier werden die anzeigetexte für das tft und lcd display festgelegt 
//Default message placeholder are at #80...#85
const String display_message[87] = {
"0","0",         //                              '0' =keine anzeige
"beweg tuer:    ",  //anzeigetext fuer port D02
"beweg gart:    ",  //anzeigetext fuer port D03
"0","0","0","0","0","0",  // ports belegt durch lcd-shield     
"0",  // belegt durch ethernet W5100-shield, lcd-Shield PIN D10 abbiegen! 
"11 Status :  ",  //anzeigetext fuer port D11                             <<user IO-Shield-20<<
"12 Status :  ",  //anzeigetext fuer port D12                             <<user IO-Shield-20<<
"13 Status :  ",  //anzeigetext fuer port D13                             <<user IO-Shield-20<<
"14 Status :  ",  //anzeigetext fuer port D14 /TX3                        <<user IO-Shield-Plus<<
"RFID Tuer :  ",  //anzeigetext fuer port D15 /RX3                        <<user IO-Shield-Plus<<
"16 Status :  ",  //anzeigetext fuer port D16 /TX2                        <<user IO-Shield-Plus<<
"RFID Gara :  ",  //anzeigetext fuer port D17 /RX2                        <<user IO-Shield-Plus<<
"18 Status :  ",  //anzeigetext fuer port D18 /TX1 /impulszaehler S03     <<user IO-Shield-Plus<<
"19 gas/m3 :  ",  //anzeigetext fuer port D19 /RX1 /impulszaehler S02     <<user IO-Shield-Plus<<
"21 I2C SDA:  ",  //anzeigetext fuer port D20 /SDA /impulszaehler S01     <<user IO-Shield-Plus<<
"21 I2C SCL:  ",  //anzeigetext fuer port D21 /SCL /impulszaehler S00     <<user IO-Shield-Plus<<
"22 ESP-01 :  ",  //anzeigetext fuer port D22                             <<user IO-Shield-Plus<<
"Ladegeraete:  ",  //anzeigetext fuer port D23                            <<user IO-Shield-Plus<<
"24 Bewegt :  ",  //anzeigetext fuer port D24                             <<user IO-Shield-Plus<<
"25 Status :  ",  //anzeigetext fuer port D25                             <<user IO-Shield-Plus<<
"26 Abstand:  ",  //anzeigetext fuer port D26                             <<user IO-Shield-Plus<<
"27 Status :  ",  //anzeigetext fuer port D27                             <<user IO-Shield-Plus<<
"28 DS18B20:  ",  //anzeigetext fuer port D28                             <<user IO-Shield-Plus<<
"29 T_DHT22:  ",  //anzeigetext fuer port D29                             <<user IO-Shield-Plus<<
"0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0",
"0",  // port belegt durch lcd-shield
"Temp_auss.:  ",  //anzeigetext fuer port D55 /A1                         <<user IO-Shield-20<<
"Temp_innen:  ",  //anzeigetext fuer port D56 /A2                         <<user IO-Shield-20<<
"57 Status :  ",  //anzeigetext fuer port D57 /A3                         <<user IO-Shield-20<<
"58 Status :  ",  //anzeigetext fuer port D58 /A4                         <<user IO-Shield-20<<
"59 Spg_A5 :  ",  //anzeigetext fuer port D59 /A5                         <<user IO-Shield-20<<
"0","0",
"62 Status :  ",  //anzeigetext fuer port D62 /A8                         <<user IO-Shield-Plus<<
"63 Status :  ",  //anzeigetext fuer port D63 /A9                         <<user IO-Shield-Plus<<
"64 Status :  ",  //anzeigetext fuer port D64 /A10                        <<user IO-Shield-Plus<<
"65 Status :  ",  //anzeigetext fuer port D65 /A11                        <<user IO-Shield-Plus<<
"66 Status :  ",  //anzeigetext fuer port D66 /A12                        <<user IO-Shield-Plus<<
"67 Status :  ",  //anzeigetext fuer port D67 /A13                        <<user IO-Shield-Plus<<
"68 Status :  ",  //anzeigetext fuer port D68 /A14                        <<user IO-Shield-Plus<<
"Abstand/cm:  ",  //anzeigetext fuer port D69 /A15                        <<user IO-Shield-Plus<<
// die folgenden Anzeigetexte sind für Module mit mehreren Datenpunkten z.b. I2C-Module
"L-Druck/mB:  ",  //anzeigetext fuer I2C 
"L-Temp./C :  ",  //anzeigetext fuer I2C 
"Lux/lx    :  ",   //anzeigetext fuer I2C 
"UV-Index  :  ",  //anzeigetext fuer I2C
"74 Status :  ",  //anzeigetext fuer 
"75 Status :  ",  //anzeigetext fuer 
"76 Status :  ",  //anzeigetext fuer 
"77 Status :  ",  //anzeigetext fuer 
"78 Status :  ",  //anzeigetext fuer 
"79 Status :  ",   //anzeigetext fuer   
"Text 1", //Anzeigetext 1 von CCU
"Text 2", //Anzeigetext 2 von CCU
"Text 3", //Anzeigetext 3 von CCU
"Text 4", //Anzeigetext 4 von CCU
"Text 5", //Anzeigetext 5 von CCU
"Text 6", //Anzeigetext 6 von CCU
"Zeit: " // Default text time and date
};
//#############################################################################################
//#############################################################################################
//hier werden die Zugangsberechtigungen für den RDM6300 Rfid-Reader und FOBs festgelegt
const byte fob_anzahl = 20;
const String fob[3*fob_anzahl] = {
"2381286","eugen","1",   // '0' = kein Tueroeffner                      <<user IO-Shield-Plus<<
"2381287","eugen","1",   // '1' = Tueroeffner1 D22                      <<user IO-Shield-Plus<<
"2381381","eugen","2",   // '2' = Tueroeffner2 D23                      <<user IO-Shield-Plus<<
"2380830","leonie","3",  // '3' = beide Tueroeffner                     <<user IO-Shield-Plus<<
"2409284","fabian","2"   //                                             <<user IO-Shield-Plus<<
"2409385","fabian","2"   //                                             <<user IO-Shield-Plus<<
"2409289","fabian","2"   //                                             <<user IO-Shield-Plus<<
"2519298","not used","0" //                                             <<user IO-Shield-Plus<<
"2519208","not used","0" //                                             <<user IO-Shield-Plus<<
"2519388","not used","0" //                                             <<user IO-Shield-Plus<<
"2519488","not used","0" //                                             <<user IO-Shield-Plus<<
"2511288","not used","0" //                                             <<user IO-Shield-Plus<<
"2529288","not used","0" //                                             <<user IO-Shield-Plus<<
"2619288","not used","0" //                                             <<user IO-Shield-Plus<<
"2719288","not used","0" //                                             <<user IO-Shield-Plus<<
"3519208","not used","0" //                                             <<user IO-Shield-Plus<<
"2519088","not used","0" //                                             <<user IO-Shield-Plus<<
"2519088","not used","0" //                                             <<user IO-Shield-Plus<<
"2510288","not used","0" //                                             <<user IO-Shield-Plus<<
"2510288","not used" "0" //                                             <<user IO-Shield-Plus<<
};
const unsigned long unlock_time1 = 5000; //oeffnungszeit rfid1 in ms    <<user IO-Shield-Plus<<
const unsigned long unlock_time2 = 5000; //oeffnungszeit rfid2 in ms    <<user IO-Shield-Plus<<
const boolean oeffner_polarity = 1;   // '1' normal, '0'  invers        <<user IO-Shield-Plus<<
//#############################################################################################
//#############################################################################################
//#############################################################################################

#include <SPI.h>
#include <Wire.h> 
#include <OneWire.h>   //für Temperatursensoren DS18B20
                       //http://www.hacktronics.com/code/OneWire.zip
#include <NewPing.h>   //für Ultraschallsensoren SR04
                       //https://arduino-new-ping.googlecode.com/files/NewPing_v1.5.zip
#include "DHT.h"       //für Temperatursensoren SHT22
                       //https://github.com/adafruit/DHT-sensor-library/archive/master.zip
#include <AS_BH1750.h> //für I2C-Luxmeter
                       //https://github.com/hexenmeister/AS_BH1750/archive/master.zip
#include <SFE_BMP180.h>//für I2C-Barometer
                       //https://github.com/sparkfun/BMP180_Breakout/archive/master.zip
#include <RCSwitch.h>  // läuft noch nicht!
#include <EEPROM.h>

#include <WiFiEsp.h>   //https://github.com/bportaluri/WiFiEsp
                       //für ESP-01 Modul

//#include <IRremote.h>// läuft noch nicht!

//der folgende Bereich ist bei verwendung w5100 auszukommentieren
//ausblenden mit " #if defined (5100)" funktioniert leider nicht!! 
/*
//Initialisierung des CC3000 Wifi auf dem IO-Shield-Plus  
#include <SFE_CC3000.h>// fuer cc3000 wifi
                 // http://github.com/sparkfun/SFE_CC3000_Library/archive/master.zip
#include <SFE_CC3000_Client.h>
// Pins
#define CC3000_INT 18  // int-Pin mit Wifi Shield ist D3, mit breakout auf IO-Shield-Plus D18
#define CC3000_EN 46   // en-Pin mit Wifi Shield ist D5, mit breakout auf IO-Shield-Plus  D46
#define CC3000_CS 53   // cs-Pin mit Wifi Shield ist D10, mit breakout auf IO-Shield-Plus D53
SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS);
SFE_CC3000_Client client = SFE_CC3000_Client(wifi);
unsigned int ap_security = WLAN_SEC_WPA2; // Security of network
unsigned int timeout = 30000; // Milliseconds
char server[] = "192,168,178,50"; // Remote host site
*/
#if defined (w5100)  //************************************************************************ 
//der folgende Bereich ist die Initialisierung des LAN bei Verwendung des LAN-Shields
#include <Ethernet.h> 
EthernetClient client;
EthernetServer server(80);
#endif  //************************************************************************************* 

#if defined (esp8266)
    WiFiEspClient client;
    WiFiEspServer server(80);
#endif 
    unsigned long reqCount = 0;

#if defined(tft_display)  //*******************************************************************
#include <Adafruit_GFX.h>    //Quelle: https://github.com/adafruit/Adafruit-GFX-Library
#include <Adafruit_TFTLCD.h> //Quelle:   https://github.com/buhosoft/TFTLCD-Library
#include <stdint.h>
#include "TouchScreen.h"      
//Quelle: http://www.smokeandwires.co.nz/blog/a-2-4-tft-touchscreen-shield-for-arduino/

#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0
#define tft_rotation 3 //3 oder 1 abhägig vom tft-shield typ  Achtung! bei 3 und IL9327 Offset beobachtet   <<user-eingabe<< 
#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin


Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
int touch_y;
const byte zeilenzahl = 6; //set 6 for ...x240 displays, set 8 for ...x320 displays 
int px,py,pz;
unsigned long next_touch_time = 0; 
int fontgroesse;
int espbyte = 0;
boolean centertouch = 1;
boolean receivingcommand = false;

//2,4'' display 320x240
/*
const long int px_A = 901,  py_A = 183;  //touch-koordinaten oben-links                
const long int px_B = 192,  py_B = 189;  //touch-koordinaten oben-rechts              
const long int px_C = 936,  py_C = 860;  //touch-koordinaten unten-links              
#define schriftgroesse 3 
#define tft_type 1   // 1 ist 2,4''display   2 ist 3.95''display
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 330);
*/
/*
//3,95'' display 480x320
const long int px_A = 302, py_A = 890;  //touch-koordinaten oben-links               
const long int px_B =280,  py_B = 115;  //touch-koordinaten oben-rechts             
const long int px_C =842,  py_C = 900;  //touch-koordinaten unten-links              
#define schriftgroesse 4  
#define tft_type 2   // 1 ist 2,4''display   2 ist 3.95''display
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 330);
*/
/*
//3,5'' display 400x240 controller: IL9327
const long int px_A = 946,  py_A = 135;  //touch-koordinaten oben-links                
const long int px_B = 76,   py_B = 118;  //touch-koordinaten oben-rechts              
const long int px_C = 953,  py_C = 893;  //touch-koordinaten unten-links              
#define schriftgroesse 3 
#define tft_type 3   // 1 ist 2,4''display   2 ist 3.95''display   3 ist 3,5" Display
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 330);
*/
/*
//3,5'' display 480x320 controller: IL9341
const long int px_A = 980,  py_A = 110;  //touch-koordinaten oben-links                
const long int px_B = 83,   py_B = 127;  //touch-koordinaten oben-rechts              
const long int px_C = 957,  py_C = 909;  //touch-koordinaten unten-links              
#define schriftgroesse 3 
#define tft_type 4   // 1 ist 2,4''display   2 ist 3.95''display   3 ist 3,5" Display
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 330);
*/

//2,8'' display 320x240 Elegoo controller: IL9341
//https://www.amazon.de/gp/product/B01EUVJYME?ref%5F=pe%5F386171%5F51767411%5FTE%5Fdp%5F2&pldnSite=1
const long int px_A = 148,  py_A = 96;  //touch-koordinaten oben-links                
const long int px_B = 135,  py_B = 914;  //touch-koordinaten oben-rechts              
const long int px_C = 913,  py_C = 103;  //touch-koordinaten unten-links              
#define schriftgroesse 2 
#define tft_type 5   // 1 ist 2,4''display   2 ist 3.95''display   3 ist 3,5" Display
#define YP A3 // must be an analog pin, use "An" notation!
#define XM A2 // must be an analog pin, use "An" notation!
#define YM 9  // can be a digital pin
#define XP 8  // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);


// color definitions for e.g. ILI9327 TFT, tft_type == 3 or 5
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

// color definitions for e.g. ILI9341 TFT tft_type == 4
//#define BLACK   0xFFFF  
//#define BLUE    0xFFE0 
//#define RED     0x07FF 
//#define GREEN   0xF81F 
//#define CYAN    0xF800 
//#define MAGENTA 0x07E0 
//#define YELLOW  0x001F 
//#define WHITE   0x0000 

#define default_color WHITE //standard text color on TFTs   <-- User Eingabe


long int p_x, p_y ;   //normierte aktuelle touch-koordinaten: 
                      //oben links ist 0,0 und unten rechts ist 1000,1000
#endif  //*************************************************************************************

#if defined(lcd_display)  //*******************************************************************
//https://www.dfrobot.com/wiki/index.php?title=Arduino_LCD_KeyPad_Shield_%28SKU:_DFR0009%29
#include <LiquidCrystal.h> 
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // initialize library with numbers of the interface pins
const byte zeilenzahl = 2;
#endif  //*************************************************************************************

int x, x_alt;
byte zeile_pointer[8];
String zeile_data[8] = {"     ","     ","     ","     ","     ","     ","     ","     "};
String display_zeile_alt[8],display_zeile[8];
int text_line;
String text_content = "";
long int text_farbe;
String taster;

char zeichen,buffer[50];
boolean fob_da =0;
String zeich, fob_hex, fob_dec,Name, lcd_rfid_message, oeffner, Value;
unsigned long fob_zahl,time_rfid3 = 0,time_rfid2 = 0; 
byte zeichen_zahl;

//********************************************************************************************* 
AS_BH1750 sensor; //Initialize BH1750 Luxmeter library
float lux;
long Lux;
int laenge;
const float ALTITUDE = 299.0; // eigene seehoehe in metern              <<user IO-Shield-Plus<<
SFE_BMP180 pressure;
char status;
double T,P,p0;
boolean reading = false;
String command = "";

String baro_string,baroT_string, lux_string;
//********************************************************************************************* 
boolean last_digital_value_D[88];
float last_value_D[88],last_IR_value,last_RF_value;
unsigned long next_Time[88];  
double last_baro_value,last_baroT_value;
boolean complete_loop =1; // wenn 1, dann einmal komplett durchlaufen
String befehl,sub_command = String(20),parameter = String(20),header = String(20);
int param,port_pin;
boolean port_data;
boolean value;
String I;
int analogwert;
//********************************************************************************************* 
float tempNTC;
const float B_wert = 3950; //aus dem Datenblatt des NTC //<<user-eingabe<<
const float Tn = 298.15; //25°Celsius in °Kelvin 
const float Rv = 10000; //Vorwiderstand
const float Rn = 10000; //NTC-Widerstand bei 25°C
float Rt,temp_tur,humidity;
 
const float delta_onewire = 0.2; //Deltas für Sendeauslösung 
const float delta_DHT = 0.2; //in °C 
const float delta_us = 5.0; // in cm
const float delta_analog = 2.0; // in inkrement
const float delta_ntc = 0.5; //in °C
const float delta_lux = 15; //in lux
const float delta_counter = 5; //in counter inkrement
const double delta_baro = 0.5; //in mB
const double delta_baroT = 0.5; //in °C
 
long duration, cm; //variable für Ultraschallsensor
unsigned long time_sr04;
 
unsigned long next_full_loop = 0;
unsigned long delta_time = 3600000; // jede Stunde werden alle Inputs aktualisiert
unsigned long delta_tx = 200; //in ms, minimaler Abstand der Telegramme an die CCU
unsigned long next_tx = 0, time_wait = 0; 

int rf_key;
String rfkey;
RCSwitch mySwitch = RCSwitch();

unsigned zaehlwert;
unsigned last_zaehlwert[6] = {0,0,0,0,0,0};

unsigned long previousMillis = 0,  years = 0;
unsigned int seconds = 0, minutes = 0, hours = 0, days = 0, months = 0;
//#############################################################################################
//#############################################################################################
void setup() 
{Serial.begin(115200); 
 command.reserve(100); // reserve memory for the CCU text to avoid memory fragmentation and buffer overruns. Remember: Space becomes %20 (3 characters) instead of one character
                       // %20 is replaced by ' ' AFTER transmission
text_content.reserve(60);
previousMillis = millis();
 
//+++++++ einrichtung der interrupts fuer impulszahler D2,D3,D18,D19,D20,D21
 if ((pulsedivider[0] > 0) && (iomodus_D[2] == 6)) 
   {pinMode(2, INPUT_PULLUP); attachInterrupt(0, ISR_0, FALLING);}
 if ((pulsedivider[1] > 0) && (iomodus_D[3] == 6)) 
   {pinMode(3, INPUT_PULLUP); attachInterrupt(1, ISR_1, FALLING);} 
 if ((pulsedivider[2] > 0) && (iomodus_D[21] == 6)) 
   {pinMode(21, INPUT_PULLUP); attachInterrupt(2, ISR_2, FALLING);}
 if ((pulsedivider[3] > 0) && (iomodus_D[20] == 6)) 
   {pinMode(20, INPUT_PULLUP); attachInterrupt(3, ISR_3, FALLING);}
 if ((pulsedivider[4] > 0) && (iomodus_D[19] == 6)) 
   {pinMode(19, INPUT_PULLUP); attachInterrupt(4, ISR_4, FALLING);}

 #if defined (w5100)  //************************************************************************* 
 if ((pulsedivider[5] > 0) && (iomodus_D[18] == 6))  //interrupt reserviert fuer cc3000
   {pinMode(18, INPUT_PULLUP); attachInterrupt(5, ISR_5, FALLING);}
 #endif  //*************************************************************************************

//+++++++ rfid initialisieren
// if ((iomodus_D[15] == 12) && (iomodus_D[14] == 12)){Serial3.begin(9600);}
// if ((iomodus_D[17] == 12) && (iomodus_D[16] == 12)){Serial2.begin(9600);}

#if defined (lcd_display)  //******************************************************************
//+++++++ lcd initialisieren
 lcd.begin(16, 2); delay(200);  //16 zeichen in 2 zeilen
 lcd.setCursor(0,0);
 lcd.print(F(" Homeduino 5.04 "));
 #endif  //*************************************************************************************

#if defined (tft_display)  //******************************************************************
//+++++++ tft initialisieren
 tft.reset();
 int identifier = tft.readID();  
 if (identifier == 0)
  {Serial.print(F("Unknown LCD driver chip: "));
    Serial.println(identifier, HEX);
    Serial.print(F("I try use ILI9341 LCD driver "));
    identifier = 0x9341;
  }
 tft.begin(identifier);
 Serial.print(F("TFT identifier:" )); Serial.println(identifier, HEX);   
 delay(100);
 tft.fillScreen(BLACK); tft.setRotation(tft_rotation);
 if (tft_type ==1) //2,4'' display 320x240
   {tft_print (1,"  Homeduino",4,YELLOW);
    tft_print (2,"     5.04",4,YELLOW);
    tft_print (5,"www.stall.biz",4,CYAN);
    tft.drawRect(0,0, 319, 240, GREEN);
   } 
  if (tft_type ==2)  //3,95'' display 480x320
   {tft_print (1,"   Homeduino",5,YELLOW);
    tft_print (2,"      5.04",5,YELLOW);
    tft_print (5," www.stall.biz",5,CYAN);
    tft.drawRect(5,5, 475, 310, GREEN);
   }   
if (tft_type ==3) //3,5'' display 400x240
   {tft_print (1,"  Homeduino",5,YELLOW);
    tft_print (2,"     5.04",5,YELLOW);
    String wlan_ssid = " Connecting to WLAN: " + String::String(ap_ssid);
    tft_print (4,wlan_ssid,2,WHITE);
    tft_print (5,"  www.stall.biz",4,CYAN);
    tft.drawRect(0,0, 399, 239, GREEN);
   } 
if (tft_type ==4) //3,5'' display 480x320
   {tft.fillScreen((BLACK));
    tft_print (1,"   Homeduino",5,(YELLOW));
    tft_print (2,"      5.04",5,(YELLOW));
    String wlan_ssid = " Connecting to WLAN: " + String::String(ap_ssid);
    tft_print (4,wlan_ssid,2,(WHITE));
    tft_print (5,"   www.stall.biz",4,CYAN);
    tft.drawRect(0,0, 480, 320, (GREEN));
//
  #ifdef DEBUG
    Serial.println(F("Printing colored rectangles to check the color definitions:"));
    Serial.println(F("BLACK, BLUE, RED, GREEN, CYAN, MAGENTA, YELLOW, WHITE"));
    tft.fillRect(125,280, 20, 20, (BLACK));
    tft.fillRect(155,280, 20, 20, (BLUE));
    tft.fillRect(185,280, 20, 20, (RED));
    tft.fillRect(215,280, 20, 20, (GREEN));
    tft.fillRect(245,280, 20, 20, (CYAN));
    tft.fillRect(275,280, 20, 20, (MAGENTA));
    tft.fillRect(305,280, 20, 20, (YELLOW));
    tft.fillRect(335,280, 20, 20, (WHITE));
  #endif    
   } 
if (tft_type ==5) //2,8'' Elegoo display 320x240
   {tft.fillScreen((BLACK));
    tft_print (1," Homeduino",5,(YELLOW));
    tft_print (2,"   5.04",5,(YELLOW));
    String wlan_ssid = " Connecting to WLAN: " + String::String(ap_ssid);
    tft_print (4,wlan_ssid,1,(WHITE));
    tft_print (3,"  www.stall.biz",3,CYAN);
    tft.drawRect(0,0, 320, 240, (GREEN));
//
  #ifdef DEBUG
    Serial.println(F("Printing colored rectangles to check the color definitions:"));
    Serial.println(F("BLACK, BLUE, RED, GREEN, CYAN, MAGENTA, YELLOW, WHITE"));
    tft.fillRect(45,210, 20, 20, (BLACK));
    tft.fillRect(75,210, 20, 20, (BLUE));
    tft.fillRect(105,210, 20, 20, (RED));
    tft.fillRect(135,210, 20, 20, (GREEN));
    tft.fillRect(165,210, 20, 20, (CYAN));
    tft.fillRect(195,210, 20, 20, (MAGENTA));
    tft.fillRect(225,210, 20, 20, (YELLOW));
    tft.fillRect(255,210, 20, 20, (WHITE));
  #endif    
   } 

#endif  //*************************************************************************************

for(int i=0; i<zeilenzahl; i++)
   {zeile_pointer[i] = EEPROM.read(i);  //anzeige-pointer aus eeprom holen
    if (zeile_pointer[i] >86) {zeile_pointer[i] = 0;}  //wenn eeprom erstes mal benutzt wird
   } 

#if defined (w5100)  //************************************************************************
//hier folgt die LAN Initialisierung 
char myIpString[24];
 if (Ethernet.begin(mac) == 0) // start the Ethernet connection:
   {Serial.println(F("Failed to configure Ethernet using DHCP")); Ethernet.begin(mac, homeduino);}
    delay(1000);// give the Ethernet shield a second to initialize:
    Serial.println(F("connecting...")); // if you get a connection, report back via serial:
 if (client.connect(ccu, 8181)) {}
   else {Serial.println(F("connection failed"));} // if you didn't get a connection to the server:
 client.stop(); 
 IPAddress myIp = Ethernet.localIP();
 sprintf(myIpString, "%d.%d.%d.%d", myIp[0], myIp[1], myIp[2], myIp[3]); 
 I = myIpString;
 befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"IP"+"').State('"+ I + "')";
 set_sysvar(); 
 server.begin();
#endif  //*************************************************************************************

#if defined (cc3000)  //**********************************************************************
// hier folgt die CC3000 Initialisierung 
 ConnectionInfo connection_info;
 char myIpString[24]; 
 Serial.println(F("SparkFun CC3000 - WebClient"));
 if ( wifi.init() ) {Serial.println(F("init complete"));} 
 else {Serial.println(F("problem with init!"));}
 // Connect using DHCP
 if (!wifi.connect(ap_ssid, ap_security, ap_password, timeout)) 
   {Serial.println(F("no connection to AP"));}
 //build IP address
 if ( !wifi.getConnectionInfo(connection_info) ) {Serial.println(F("no connection details"));} 
   else {sprintf(myIpString, "%d.%d.%d.%d", connection_info.ip_address[0], 
   connection_info.ip_address[1],connection_info.ip_address[2], connection_info.ip_address[3]); 
         I = myIpString;
        }
 befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"IP"+"').State('" + I + "')";
 set_sysvar(); 
 client.stop();
#endif  //*************************************************************************************

#if defined (esp8266)  //**********************************************************************
// Starting ESP8266 Init 
    #ifdef DEBUG
        Serial.print(F("SERIAL_TX_BUFFER_SIZE: ")); Serial.println(SERIAL_TX_BUFFER_SIZE);
        Serial.print(F("SERIAL_RX_BUFFER_SIZE: ")); Serial.println(SERIAL_RX_BUFFER_SIZE);
    #endif
       char myIpString[24]; 
       pinMode(22,OUTPUT); digitalWrite(22,1); // Reset-Pin auf 1 setzen
       Serial3.begin(115200); // Standard baudrate for current ESP-01 modules with Espressif firmware. Old ones use 9600 baud
        // initialize ESP module to different baudrate. HANDLE WITH CARE!!! Only enable next lines if you know what you are doing!
/*        Serial3.write("AT+UART_DEF=115200,8,1,0,0\r\n"); //Modify default baudrate of 115200 (current Espressif FW) to reduce ESP Timeout Problems
        Auf_OK_warten(); //Only throws OK when the module is reconfigured for the first time. On subsequent boots a Timeout occurs because the comm-rate already IS @ the target rate
        Serial3.end();
        delay(3000); 
        Serial3.begin(115200); 
*/        
       Serial.println(F("Resetting ESP-01 module"));
       digitalWrite(22,0); delay(100); digitalWrite(22,1); delay(1000);//reset-Impuls ausgeben und Bootmeldungen abwarten
       Serial.println(F("Espressif ESP8266 - WebClient"));

        Serial3.write("AT\r\n");
        Auf_OK_warten(); //wait until reset is completed and ESP-01 responds again

      // initialize ESP module
        WiFi.init(&Serial3);
      
       // check for the presence of the shield
        if (WiFi.status() == WL_NO_SHIELD) {
          Serial.println(F("WiFi shield not present"));
          tft_print (4," No WLAN shield! STOP!!!",2,(RED));
          tft_print (3,"",3,BLACK);
            if (tft_type ==5) //2,8'' Elegoo display 320x240
            {tft.drawRect(0,0, 320, 240, (RED));}
          // don't continue
          while (true);
        }

            // attempt to connect to WiFi network
          while ( status != WL_CONNECTED) {
            Serial.print(F("Attempting to connect to WPA SSID: "));
            Serial.println(ap_ssid); 
            tft_print (4,"     WLAN shield ok - trying to connect...",1,(MAGENTA));
            if (tft_type ==5) {tft.drawRect(0,0, 320, 240, (MAGENTA));}               //2,8'' Elegoo display 320x240
            // Connect to WPA/WPA2 network
            status = WiFi.begin(ap_ssid, ap_password);
            }

              // you're connected now, so print out the data
            Serial.println(F("You're connected to the network"));
            
             // print the SSID of the network you're attached to
              Serial.print(F("SSID: "));
              Serial.println(WiFi.SSID());
            
              // print your WiFi shield's IP address
              IPAddress ip = WiFi.localIP();
              Serial.print(F("IP Address: "));
              Serial.println(ip);
              sprintf(myIpString, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
              I = myIpString;
              // print my MAC address
              byte mac[6];
              WiFi.macAddress(mac);
              char buf[20];
              sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]);
              Serial.print(F("MAC address: "));
              Serial.println(buf);
#if defined DEBUG
              Serial.print(F("String IP Address: "));
              Serial.println(myIpString);
#endif
              // print the received signal strength
              long rssi = WiFi.RSSI();
              Serial.print(F("Signal strength (RSSI):"));
              Serial.print(rssi);
              Serial.println(F(" dBm"));
              delay(6000); //let the Wifi connection establish itself
              Serial.println(F("Announcing my IP"));
              befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"IP"+"').State('"+ I + "')";
              set_sysvar(); 
              server.begin();
       
#endif  //*************************************************************************************


#if defined (lcd_display)  //****************************************************************** 
    //bei erfolgreichem einloggen ausgabe ip-adresse 
    lcd.setCursor(0,1);
    lcd.print(myIpString);
    delay(3000);
#endif  //*************************************************************************************

#if defined (tft_display) //*******************************************************************
//bei erfolgreichem einloggen ausgabe ip-adresse 
tft.fillScreen(BLACK);
if (tft_type ==1) //2,4'' display
  {tft.setCursor(8, 230); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(1);
   tft.print(Version + "   Homeduino IP: "); tft.print(myIpString);
  }
if (tft_type ==2) //3,95'' display 480x320
  {tft.setCursor(1, 300); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(2);
   tft.print(Version + " IP: "); tft.print( myIpString);
  }
if (tft_type ==3) //3,5'' display 400x240
  {tft.setCursor(0, 230); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(1);
   tft.print(Version + "   " + hm_systemvariable); tft.print( myIpString);
//   Serial.print(Version + "   Homeduino IP: "); Serial.print( myIpString); tft.print("   Nr.: " + homeduino_nummer);
  }
if (tft_type ==4) //3,5'' display 480x320
  {tft.setCursor(0, 310); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(1);
   tft.print(Version + "   " + hm_systemvariable); tft.print( myIpString);
//   Serial.print(Version + "   Homeduino IP: "); Serial.print( myIpString); tft.print("   Nr.: " + homeduino_nummer);
  }
if (tft_type ==5) //2,8'' Elegoo display 320x240
  {tft.setCursor(0, 230); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(1);
   tft.print(Version + "   " + hm_systemvariable); tft.print( myIpString);
//   Serial.print(Version + "   Homeduino IP: "); Serial.print( myIpString); tft.print("   Nr.: " + homeduino_nummer);
  }

#endif  //*************************************************************************************
for (int i = 0; i < 87; i++) {next_Time[i]=0;} //
 //delay(2000);
}
//#############################################################################################
//#############################################################################################
void loop() 
{
/* Enable following sequence to see the available character map.   
  tft.setCursor(0, 0); 
   tft.setTextColor(WHITE);  
   tft.setTextSize(3);
  for (int m = 0; m < 256; m++)
   {tft.print(char(m));}
  while (true); //end of character map sequence
*/   
  complete_loop = 0;
 if (millis() > next_full_loop) //mindestens jede Stunde eine komplette Aktualisierung
   {complete_loop = 1; next_full_loop = millis() + delta_time; 
    if (next_full_loop < millis()) {complete_loop = 0;} //wichtig wegen Zahlensprung 
                                                        //von millis() alle 50 Tage
   } 

//*********************************************************************************************
 for (int i = 2; i < 87; i++) //behandlung aller Ports D2 bis D69 und der Texte
 {while ((iomodus_D[i] == 0) || (iomodus_D[i] >29 )) {i++;}  // unbenutzte pins überspringen
// Serial.print("i: "); Serial.println(i);
  datenempfang(); //nach jeder Messung auf Datenempfang schalten
  display_data(); //display ausgeben und abfragen
  clockservice(); //update the clock
 //******************************************************************************************** 
 if (iomodus_D[i] == 1) //behandlung digitaleingänge 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +1000;  //digitaleingänge nicht häufiger als alle 1000ms abfragen
       pinMode(i, INPUT_PULLUP); 
       digitalWrite(i, HIGH);
       value =digitalRead(i);
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) 
            {if (value ==0) {zeile_data[m] = "LOW";} else {zeile_data[m] = "HIGH";}}}
       if ((!value == last_digital_value_D[i]) || complete_loop) 
         {I = String(i);
           befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+value+"')";
          set_sysvar();
          last_digital_value_D[i] = value;
         }
      } 
   }
   datenempfang();
//********************************************************************************************* 
 if (iomodus_D[i] == 3) //behandlung onewire 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +10000;  //onewire nicht häufiger als alle 10s abfragen 
       pinMode(i, INPUT_PULLUP);
       digitalWrite(i,HIGH);
       OneWire ds(i); 
       #define DS18S20_ID 0x10
       #define DS18B20_ID 0x28 
       byte present = 0;   byte data[12];    byte addr[8];
       temp_tur = 1000.0;
       if (!ds.search(addr)) { ds.reset_search(); temp_tur = -1000.0; } //find a device
       if ((OneWire::crc8( addr, 7) != addr[7]) && (temp_tur > -1000.0)) {temp_tur = -1000.0; }
       if ((addr[0] != DS18S20_ID && addr[0] != DS18B20_ID)&& (temp_tur > -1000.0)) 
         {temp_tur = -1000.0;}
       if (temp_tur > -1000.0) 
         {ds.reset(); 
          ds.select(addr); 
          ds.write(0x44, 1); // Start conversion
          //delay(850); // Wait some time...
          time_wait = millis() +850;                                  //wahrend der 2s wartezeit, daten empfangen, clock
          while (millis() < time_wait) {datenempfang();display_data;clockservice();} //und display weiter bedienen 
          present = ds.reset(); 
          ds.select(addr);
          ds.write(0xBE); // Issue Read scratchpad command
          for ( int k = 0; k < 9; k++) { data[k] = ds.read(); } // Receive 9 bytes
          temp_tur = ( (data[1] << 8) + data[0] )*0.0625; // Calculate temperature value 18B20
          //temp_tur = ( (data[1] << 8) + data[0] )*0.5 // Calculate temperature value 18S20
         }
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = String(temp_tur,1);}
         }
       if ((temp_tur > (last_value_D[i] + delta_onewire)) 
                            || (temp_tur < (last_value_D[i] - delta_onewire)) || complete_loop) 
         {I = String(i);
           befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+temp_tur+"')";
          set_sysvar();
          last_value_D[i] = temp_tur;
         }
      }   
  }
  datenempfang();
//********************************************************************************************* 
 if (iomodus_D[i] == 4) //behandlung DHT temperatur- und feuchtesensoren
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +30000;  //DHT nicht häufiger als alle 30s abfragen 
       DHT dht(i, DHT22); //je nach verwendetem sensor "DHT11", "DHT22" (AM2302),"DHT 21" (AM2301)
       dht.begin();
       //delay(2000); // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
       time_wait = millis() +2000;                                 //wahrend der 2s wartezeit, daten empfangen, clock
       while (millis() < time_wait) {datenempfang();display_data;clockservice();} //und display weiter bedienen 
       humidity = dht.readHumidity(); // Read temperature as Celsius
       temp_tur = dht.readTemperature(); 
       if (isnan(humidity) || isnan(temp_tur) ) // Check if any reads failed and 
         {//Serial.println("Failed to read from DHT sensor!");
          temp_tur = -1000;
         }
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = (String(temp_tur,1) + (char(247)) + "C/" + String(humidity,1) + "%");}
         }
       if ((temp_tur > (last_value_D[i] + delta_DHT))|| (temp_tur < (last_value_D[i] - delta_DHT)) 
                                                  || complete_loop) 
         {I = String(i);
          befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+temp_tur+"')";
          set_sysvar();
           befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"_1').State('"+humidity+"')";
          set_sysvar();
          last_value_D[i] = temp_tur;
        } 
     }
   } 
 //******************************************************************************************** 
 if (iomodus_D[i] == 5) //behandlung ultraschallsensoren 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +2000;  //ultraschall nicht häufiger als alle 2s abfragen 
 //achtung: zu beachten 
 //bei verwendung der US-Sensoren beim IO-Shield-Plus sind die 150-Ohm-Schutzwiderstände 
 //zu überbrücken (Jumper setzen!), entsprechend beim IO-Shield20 der Jumper 4-5 zu setzen!! 
       NewPing sonar(i, i, 200); // NewPing setup of pin and maximum distance.
       unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
       int cm = uS / US_ROUNDTRIP_CM;
       if (cm == 0) {}
       else {
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = (String(cm) + "cm");}} // display_value[i] = (String(cm) + "cm");} }
          if ((cm > (last_value_D[i] + delta_us)) || (cm < (last_value_D[i] - delta_us)) || complete_loop) 
            {I = String(i);
              befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+cm+"')";
             set_sysvar();
             last_value_D[i] = cm;
            }
       } 
      }
   }
   datenempfang();
//********************************************************************************************* 
 if (iomodus_D[i] == 10) //behandlung analogeingänge 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +1000;  //analogeingänge nicht häufiger als alle 1000ms abfragen 
       analogwert =analogRead(i);
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = String(analogwert);}}
       if ((analogwert > (last_value_D[i] + delta_analog)) 
                || (analogwert < (last_value_D[i] - delta_analog)) || complete_loop) 
         {I = String(i);
         Serial.print(F("i6: ")); Serial.println(i);
           befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State6("+analogwert+")";
          set_sysvar();
          last_value_D[i] = analogwert;
         }
      }
   } 
   datenempfang();
//*********************************************************************************************
 if (iomodus_D[i] == 11) //behandlung NTC 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +10000;  //NTC-eingänge nicht häufiger als alle 10s abfragen
       Rt = Rv/((1024.0/analogRead(i))- 1.0);
       tempNTC = (B_wert * Tn / ( B_wert + (Tn * log(Rt/Rn)))) -Tn +25.0 ;
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = String(tempNTC,1);}}
          if ((tempNTC > (last_value_D[i] + delta_ntc)) || (tempNTC < (last_value_D[i] - delta_ntc)) 
                                                   || complete_loop) 
            {I = String(i);
              befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+tempNTC+"')";
             set_sysvar();
             last_value_D[i] = tempNTC;
            } 
      }
   }    
   datenempfang(); 
//********************************************************************************************* 
 if (iomodus_D[i] == 6) //behandlung impulszahler D2,D3,D21,D20,D19,D18 
   {byte offset =23;
    if (i ==2) {offset = 4;} if (i ==3) {offset = 6;}
    zaehlwert = pulsecounter[offset - i ] / pulsedivider[offset - i ];
    for (int m=0; m < zeilenzahl; m++)
      {if (zeile_pointer[m] == i) {zeile_data[m] = String(zaehlwert);}}
       if ((pulsedivider[offset -i] > 0) && ((zaehlwert > (last_zaehlwert[offset - i]+ delta_counter) 
                           || complete_loop))) 
         {I = String(offset -i);
           befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"imp"+I+"').State('"+zaehlwert+"')";
          set_sysvar();
          last_zaehlwert[offset - i] = zaehlwert;
         } 
   }
   datenempfang(); 
//*********************************************************************************************
//behandlung I2C sensoren an pin 20(sda) und pin 21 (scl)
 if ((iomodus_D[i] == 8)&&(i == 20))
   {i++;  // da I2C Bus 2 eingaenge belegt
  
//behandlung Luxmeter BH1750 an SCL pin21 und SDA pin 20 ***********************************
// for normal sensor resolution (1 lx resolution, 0-65535 lx, 120ms, no PowerDown) 
//use: sensor.begin(RESOLUTION_NORMAL, false); 
    if (iomodus_lux ==1)
      {if (millis() > next_Time[72])
         {next_Time[72] = next_Time[72] +5000;  //luxmeter nicht häufiger als alle 5s abfragen 
          if(!sensor.begin()) { Serial.println(F("Sensor not present")); }
          lux = sensor.readLightLevel(); //delay(1000);
          Lux = (int)lux;
          //Serial.print(F("Helligkeit/lux: ")); Serial.print(lux); Serial.println();
          lux_string = "      " + String(Lux);
          int laenge = lux_string.length();
          lux_string = lux_string.substring(laenge -6,laenge);
          for (int m=0; m < zeilenzahl; m++)
            {if (zeile_pointer[m] == 72) {zeile_data[m] = lux_string;}}
             if (((Lux > (last_value_D[72] + delta_lux)) || (Lux < (last_value_D[72] - delta_lux)) 
                                                || complete_loop)) 
               {befehl="GET /xy.exe?antwort=dom.GetObject('" + hm_systemvariable+"lux"+"').State('"+Lux+"')";
                set_sysvar();
                last_value_D[72] = Lux;
               }
         } 
       } 
   datenempfang(); 
       
   //behandlung barometer BMP180 an SCL pin21 und SDA pin 20
    if (iomodus_baro ==1)
      {if (millis() > next_Time[70])
         {next_Time[70] = next_Time[70] +30000;  //barometer nicht häufiger als alle 30s abfragen 
          if (pressure.begin()) {status = pressure.startTemperature();}
          if (status) {delay(status); status = pressure.getTemperature(T);} //messung T
          if (status) {status = pressure.startPressure(3);} // //messung P mit resolution 0 bis 3
          if (status) {delay(status); status = pressure.getPressure(P,T);}
          if (status) {p0 = pressure.sealevel(P,ALTITUDE);} // umrechnung auf N.N.
//Serial.print("Hoehe/m: "); Serial.print(ALTITUDE); Serial.print(" Temperatur/C: "); 
//Serial.print(T); Serial.print(" Normaldruck /mb: "); Serial.println(p0); 
          baro_string = "     " + String(p0);
          laenge = baro_string.length();
          baro_string = baro_string.substring(laenge -7,laenge -1);
          baroT_string = "      " + String(T);
          laenge = baroT_string.length();
          baroT_string = baroT_string.substring(laenge -7,laenge -1);
          for (int m=0; m < zeilenzahl; m++) {if (zeile_pointer[m] == 70) {zeile_data[m] = baro_string;}}
          if ((p0 > (last_baro_value + delta_baro)) || (p0 < (last_baro_value - delta_baro)) 
                                                || complete_loop) 
            {befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"baro"+"').State('"+p0+"')";
             set_sysvar();
             last_baro_value = p0;
             last_value_D[70] = p0;
            }
          for (int m=0; m < zeilenzahl; m++) {if (zeile_pointer[m] == 71) {zeile_data[m] = baroT_string;}}  
          if ((T > (last_baroT_value + delta_baroT)) || (p0 < (last_baroT_value - delta_baroT)) 
                                                     || complete_loop) 
            {befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"baroT"+"').State('"+T+"')";
             set_sysvar();
             last_baroT_value = T;
             last_value_D[71] = T;
            } 
         }
      } 
      datenempfang();
  }  
//*********************************************************************************************
 if (iomodus_D[3] == 7) //behandlung 433Mhz-rx 
   {if (mySwitch.available()) 
      {int value = mySwitch.getReceivedValue();
       if (value == 0) {client.print(F("Unknown encoding"));} 
          else {Serial.print(F("Pin D3 received : "));
                Serial.print (mySwitch.getReceivedValue() );
                Serial.print (F(" / "));
                Serial.print( mySwitch.getReceivedBitlength() );
                Serial.print(F("bit Protocol: "));
                Serial.println( mySwitch.getReceivedProtocol() + " \n\r" );
               }
      mySwitch.resetAvailable();
     }
   } 
   datenempfang();
  //******************************************************************************************* 
 if ((iomodus_D[i] == 12) && (i==22))  //behandlung rfid3 tueroeffner an D22 des Mega
   {pinMode(i,OUTPUT);
    if (millis()< time_rfid3)         //D22-als normal-Ausgang für tueröffner schalten
      {Value = " AUF"; 
       if (oeffner_polarity) {digitalWrite(i, HIGH);} else {digitalWrite(i,LOW);}
       }
         else {Value = "  ZU"; if (!oeffner_polarity) 
                               {digitalWrite(i, HIGH);} else {digitalWrite(i,LOW);}}
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = Value;}}
    }
  if ((iomodus_D[i] == 12) && (i==23))  //behandlung rfid2 tueroeffner  an D23 des Mega
    {pinMode(i,OUTPUT);
     if (millis()< time_rfid2)         //D23-als normal-Ausgang für tueröffner schalten
       {Value = " AUF"; if (oeffner_polarity) 
                          {digitalWrite(i, HIGH);} 
                          else {digitalWrite(i,LOW);}}
       else {Value = "  ZU"; if (!oeffner_polarity) {digitalWrite(i, HIGH);} 
                                                    else {digitalWrite(i,LOW);}} 
     for (int m=0; m < zeilenzahl; m++)
       {if (zeile_pointer[m] == i) {zeile_data[m] = Value;}
       }
    }
    datenempfang();
 //******************************************************************************************** 
if (iomodus_D[i] == 18)  //Behandlung reine Texte von CCU
    {for (int m=0; m < zeilenzahl; m++)
       {if (zeile_pointer[m] == i) {zeile_data[m] = "";} 
       }
    }
 //******************************************************************************************** 
if (iomodus_D[i] == 17)  //Behandlung Uhrzeit von CCU
    {clockservice();
      for (int m=0; m < zeilenzahl; m++)
       {String min10 = ""; String hours10 = ""; String seconds10 = ""; String days10 = ""; String months10 = "";
        if (zeile_pointer[m] == i) { //add leading zeros
           if (seconds < 10)  {seconds10 = "0";}
           if (minutes < 10) {min10 = "0";}
           if (hours < 10)  {hours10 = "0";}
           if (days < 10)  {days10 = "0";}
           if (months < 10)  {months10 = "0";}
 
#if defined (tft_display)
    #if defined (ShowSeconds)
           zeile_data[m] = (days10 + String(days) + "." + months10 + String(months) + "." + String(years) + "  " + hours10 + String(hours) + ":" + min10 + String(minutes) + ":" + seconds10 + String(seconds)); 
    #else            
           zeile_data[m] = (days10 + String(days) + "." + months10 + String(months) + "." + String(years) + "     " + hours10 + String(hours) + ":" + min10 + String(minutes));
    #endif           
#endif
#if defined (lcd_display)
    #if defined (ShowSeconds)
           zeile_data[m] = (days10 + String(days) + "." + months10 + String(months) + "  " + hours10 + String(hours) + ":" + min10 + String(minutes) + ":" + seconds10 + String(seconds)); 
    #else            
           zeile_data[m] = (days10 + String(days) + "." + months10 + String(months) + "   " + hours10 + String(hours) + ":" + min10 + String(minutes));
    #endif           
#endif

        }
      }
    }
    datenempfang();
 //******************************************************************************************** 
/*  if (iomodus_D[i] == 12) //behandlung rfid-modul RDM6300 
    {int m = 0; fob_zahl=0;  fob_hex ="";
     if (i == 15){while((Serial3.available()>0)&&(m <11 ))  //behandlung rfid3
                       {fob_da=1;  m++;  zeichen = Serial3.read();
                        if (m>4)  //die ersten 4 zeichen ignorieren
                          {fob_hex += zeichen; fob_zahl = hexToDec(fob_hex);}
                        if (m > 10) //Datenübertragung fertig, dann buffer leeren 
                          {while(Serial3.available()>0) {zeichen = Serial3.read();}}
             }
         }    
     if (i == 17){while((Serial2.available()>0)&&(m <11 ))//behandlung rfid2
                      {fob_da=1;  m++;  zeichen = Serial2.read();
                       if (m>4)  //die ersten 4 zeichen ignorieren
                         {fob_hex += zeichen; fob_zahl = hexToDec(fob_hex);}
                       if (m > 10) //Datenübertragung fertig, dann buffer leeren 
                         {while(Serial2.available()>0) {zeichen = Serial2.read();}}
            }
           }
     if (fob_da)
       {fob_dec = ""; 
        sprintf(buffer,"%lu", fob_zahl); //zahl umwandeln in string
        for(int k = 0; k<7; k++) {fob_dec += buffer[k];} 
        Name = "";  //gueltigen namen und oeffner aus tabelle ermitteln  
        for (int k = 0; k < fob_anzahl; k++) {if (fob_dec == fob[3*k]) 
                                                {Name += fob[(3*k)+1];
                                                 oeffner= fob[(3*k)+2]; 
                                                 break;
                                                }
                                              }
        if ((Name != "") && ((oeffner =="1") ||(oeffner =="3"))) 
          {time_rfid3 = millis() + unlock_time1;}
        if ((Name != "") && ((oeffner =="2") ||(oeffner =="3")))  
          {time_rfid2 = millis() + unlock_time2;}
        if (Name == "") {Name = fob_dec;}
        lcd_rfid_message = Name + "          "; //lcd mmeldung modifizieren für rfid
        lcd_rfid_message = lcd_rfid_message.substring(0,9);
         
        for (int n=0; n < zeilenzahl; n++)
          {if (zeile_pointer[n] == i) 
             {display_message[i]= lcd_rfid_message; zeile_data[n] = fob_dec;}
          }
           
     //Serial.println(Name + " " + fob_dec);
        I = String(i);
        befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+Name+"')";
        set_sysvar();
        fob_da =0;
       }
     delay(500);  
    }
*/
//**************************   ende loop  *****************************************************
 }
} 
//#############################################################################################
//#############################################################################################
//#############################  Unterprogramme   #############################################

void datenempfang() //Unterprogramm datenempfang: daten von ccu an homeduino senden
{command = ""; 

#if defined (w5100)  //************************************************************************
 EthernetClient client = server.available();   //mit W5100
#endif  //************************************************************************************* 

#if defined (cc3000)  //***********************************************************************
 SFE_CC3000_Client client = SFE_CC3000_Client(wifi);   //mit CC3000
#endif  //************************************************************************************* 

#if defined (esp8266)  //***********************************************************************
  WiFiEspClient client = server.available();   //using ESP8266 (ESP-01 module)
#endif  //************************************************************************************* 

  if (client)  {
    receivingcommand = false;
    Serial.println(F("New client"));
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    unsigned long breakMillis = millis();
    while (client.connected())
    { //Serial.println(F("Client still connected"));
      if ((millis() - breakMillis) > 500) {sendHttpResponse(client); break;}
      if (client.available())
      {
        char c = client.read(); 
//        Serial.write(c);
        breakMillis = millis();
          if (reading && c == ' ') {reading =false;}
          if (c == '?') {reading = true; receivingcommand = true;} // beginn der Befehlssequenz 
          if (reading) 
            { if (command.length() < 100) //read char by char HTTP request
               {command = command + c;} // Serial.println(command);} //store characters to string
            } 
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
         if (c == '\n' && currentLineIsBlank) {sendHttpResponse(client);break;}
          if (c == '\n') {currentLineIsBlank = true;} 
            else if (c != '\r') { currentLineIsBlank = false;}
      }
    }
    delay(10);        // give the web browser time to receive the data
    client.stop();    // close the connection:
    Serial.println(F("Client disconnected"));
  }
  
    if (command.length() > 2) //behandlung Datenempfang von ccu: port auf 0/1 setzen or write textline or set clock
        {

#if defined (tft_display) //**************************************************
       String commandType = command.substring(1,2); // detect command type: "D" for data, "T" for text, "C" for clock (date, time)
          if (commandType == ("D")) {
             int colonPosition = command.indexOf(':');
             sub_command = command.substring(2,colonPosition); //portpin erkennen
             Serial.print("D" + sub_command + " :");
             port_pin = sub_command.toInt();
             command = command.substring((colonPosition+1)); //Rest-command bilden
              SetOutputPort (); //If command adresses an output port toggle it
                if ((iomodus_D[port_pin] == 7) && (port_pin ==4)) 
                  {rf_send(command); Serial.println(command);} 
                if ((iomodus_D[port_pin] == 5) && (port_pin ==9)) 
                  {ir_send(command); Serial.println(command);} 
          }
          if (commandType == ("T")) {
//            Serial.println(command);
             int colonPosition = command.indexOf(':');
             sub_command = command.substring(2,3 ); //select textline erkennen value 0-7 for line 1-8
             text_line = sub_command.toInt();
             String text_content_full = command.substring((colonPosition+1)); //isolate remaining text 
             char text_content_array[text_content_full.length() + 1]; // copy text to char array and split by separator comma in segments
             text_content_full.toCharArray(text_content_array, text_content_full.length() + 1);
             char* token = strtok(text_content_array, ",");
             char* text_content_char = token;
//             Serial.println(text_content_char);
             token= strtok(0, ",");
             char* text_size = token;
             token = strtok(0, ",");
             char* text_color_char = token;
             text_content = ((char*)text_content_char);
//             text_content_char = (text_content_char + '\0');
             String text_content = String(text_content_char);
//             Serial.println(text_content);
             text_content.replace("%20", " "); // %20 = HTML for Space. Enable formatting texts with spaces
             fontgroesse = atoi( text_size );
             String text_color = ((char*) text_color_char );
             if (text_color == "BLACK") {text_farbe = BLACK;}
             if (text_color == "BLUE") {text_farbe = BLUE;}
             if (text_color == "RED") {text_farbe = RED;}
             if (text_color == "GREEN") {text_farbe = GREEN;}
             if (text_color == "CYAN") {text_farbe = CYAN;}
             if (text_color == "MAGENTA") {text_farbe = MAGENTA;}
             if (text_color == "YELLOW") {text_farbe = YELLOW;}
             if (text_color == "WHITE") {text_farbe = WHITE;}
      #ifdef DEBUG
                    Serial.print(F("Zeile: "));Serial.println(text_line);
                    Serial.print(F("Text: "));Serial.println(text_content);
                    Serial.print(F("Groesse: "));Serial.println(text_size);
                    Serial.print(F("Farbe: "));Serial.println(text_color);
                    freeRam();
      #endif   

             tft_print (text_line,text_content,fontgroesse,text_farbe); 
          }
         if (commandType == ("C")) {
             command.replace("%20", " "); // %20 = HTML for space. Formatting Time / Date with Spaces possible
             Serial.print(F("C-Command received: ")); Serial.println(command);
             int colonPosition = command.indexOf(':');
             sub_command = command.substring((colonPosition + 1),(colonPosition + 3)); 
             days = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 4),(colonPosition + 6)); 
             months = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 7),(colonPosition + 11)); 
             years = (sub_command.toInt());

             sub_command = command.substring((colonPosition + 12),(colonPosition + 14)); 
             hours = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 15),(colonPosition + 17)); 
             minutes = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 18),(colonPosition + 20)); 
             seconds = (sub_command.toInt());
          } 
   #endif
   
   #if defined (lcd_display)
        String commandType = command.substring(1,2); // Kommandotyp abfragen: "D" für Daten oder "T" für Text
//       Serial.println("Kommandotyp: " + commandType);
          if (commandType == ("D")) {
      int colonPosition = command.indexOf(':');
       sub_command = command.substring(2,colonPosition); //portpin erkennen
       Serial.print("D" + sub_command + " :");
       port_pin = sub_command.toInt();
       command = command.substring((colonPosition+1)); //Rest-command bilden
          SetOutputPort (); //If command adresses an output port toggle it
          if ((iomodus_D[port_pin] == 7) && (port_pin ==4)) 
            {rf_send(command); Serial.println(command);} 
          if ((iomodus_D[port_pin] == 5) && (port_pin ==9)) 
            {ir_send(command); Serial.println(command);} 
          }
 
         if (commandType == ("T")) {
             int colonPosition = command.indexOf(':');
             sub_command = command.substring(2,3 ); //Textzeile erkennen Werte 0-1 für Zeile 1-2
             text_line = sub_command.toInt();
             String text_content_full = command.substring((colonPosition+1)); //Restlichen Text isolieren max. 22 Zeichen
                #ifdef DEBUG
                    Serial.print(F("Text: "));Serial.println(text_content_full);
                #endif   
             text_content_full.replace("%20", " "); // %20 = HTML für Space. Formatierung des Textes mit Spaces ermöglichen
             lcd.setCursor(0,text_line);
             lcd.print("                "); // delete 16 characters per line
             lcd.setCursor(0,text_line);
             lcd.print(text_content_full);
          }

        if (commandType == ("C")) {
             command.replace("%20", " "); // %20 = HTML for space. Formatting Time / Date with Spaces possible
             Serial.print(F("C-Command received: ")); Serial.println(command);
             int colonPosition = command.indexOf(':');
             sub_command = command.substring((colonPosition + 1),(colonPosition + 3)); 
             days = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 4),(colonPosition + 6)); 
             months = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 7),(colonPosition + 11)); 
             years = (sub_command.toInt());

             sub_command = command.substring((colonPosition + 12),(colonPosition + 14)); 
             hours = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 15),(colonPosition + 17)); 
             minutes = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 18),(colonPosition + 20)); 
             seconds = (sub_command.toInt());
          } 
          
      #endif
      }
  } 
//*********************************************************************************************
void set_sysvar() // subroutine HTTP request absetzen:
{while (millis() < next_tx) {} //warten bis time > next_tx oder timeout
 next_tx = millis() +delta_tx;
 if (client.connect(ccu, 8181)) 
   {byte transmitbytes = 0;
    unsigned long breakMillis = millis();
    Serial.println(befehl);
    transmitbytes = client.println(befehl);
    while (transmitbytes != (befehl.length() + 2)) {
      Serial.println(F("Transmission failed! Retrying..."));
      delay(10);
      transmitbytes = client.println(befehl);
      if ((millis() - breakMillis) > 100) {Serial.println(F("Transmission failed 10 times!!! Check the WLAN connection to your CCU!")); break;}
      }
    client.println();
    client.flush();
    client.stop();
   } else {Serial.println(F("connection failed"));}
}

//*********************************************************************************************
void rf_send(String rf_command) // subroutine rf telegramm senden
{
}
//*********************************************************************************************
void ir_send(String ir_command) // subroutine ir telegramm senden
{
}
//*********************************************************************************************
//hier sind die interrupt-service-routinen fuer die impulszaehler  //**************************
void ISR_0() //Interrupt an D2
{pulsecounter[0]++;}
void ISR_1() //Interrupt an D3
{pulsecounter[1]++;}
void ISR_2() //Interrupt an D21
{pulsecounter[2]++;}
void ISR_3() //Interrupt an D20
{pulsecounter[3]++;}
void ISR_4() //Interrupt an D19
{pulsecounter[4]++;}
void ISR_5() //Interrupt an D18 
{pulsecounter[5]++;}
//*********************************************************************************************
//Unterprogramm:  Converting from Hex (unsigned long) to Decimal: *****************************
//Quelle https://github.com/benrugg/Arduino-Hex-Decimal-Conversion/blob/master/hex_dec.ino
unsigned long hexToDec(String hexString) 
{unsigned long decValue = 0;
 int nextInt;
 for (int k = 0; k < hexString.length(); k++) 
   {nextInt = int(hexString.charAt(k));
    if (nextInt >= 48 && nextInt <= 57) nextInt = map(nextInt, 48, 57, 0, 9);
    if (nextInt >= 65 && nextInt <= 70) nextInt = map(nextInt, 65, 70, 10, 15);
    if (nextInt >= 97 && nextInt <= 102) nextInt = map(nextInt, 97, 102, 10, 15);
    nextInt = constrain(nextInt, 0, 15);
    decValue = (decValue * 16) + nextInt;
  }
 return decValue;
}

//*********************************************************************************************
void display_data() //gibt daten auf dem lcd oder tft display aus

//*********************************************************************************************
#if defined (lcd_display)  //behandlung lcd-display: erkennung des tasters und lcd-anzeige
{x = analogRead (0);  //abfrage A0
 if (x < (x_alt -100))  {tastererkennung();}
 x_alt = x; 
 for (int m = 0; m < zeilenzahl; m++)
   {while (zeile_data[m].length() < 5) {zeile_data[m] = " " + zeile_data[m];}
    if (display_message[zeile_pointer[m]] == "0") {zeile_data[m] = "                ";}
    display_zeile[m] =  display_message[zeile_pointer[m]] + zeile_data[m];
   
    if (display_zeile[m] != display_zeile_alt[m])  //datenausgabe auf display nur wenn aenderung 
      {lcd.setCursor(0,m); lcd.print (display_zeile[m]); display_zeile_alt[m] = display_zeile[m];}
   } 
} 
//*********************************************************************************************
void tastererkennung()
{if (x < 60) 
   {taster == "right"; 
    zeile_pointer[0]--;  if (zeile_pointer[0] ==1) {zeile_pointer[0] = 87;}
    while((iomodus_D[zeile_pointer[0]] ==0) || (iomodus_D[zeile_pointer[0]] >19))
         {zeile_pointer[0]--; if (zeile_pointer[0] ==1) {zeile_pointer[0] =87;} }
    EEPROM.write(0,zeile_pointer[0]);//delay(4);
   } 
   else if (x < 200) 
          {taster == "up";
           zeile_pointer[0]++;  if (zeile_pointer[0] ==87) {zeile_pointer[0] = 2;}
           while((iomodus_D[zeile_pointer[0]] ==0) || (iomodus_D[zeile_pointer[0]] >19))
               {zeile_pointer[0]++; if (zeile_pointer[0] ==87) {zeile_pointer[0] = 2;} }
           EEPROM.write(0,zeile_pointer[0]);//delay(4);
          } 
          else if (x < 400) 
                   {taster == "down";
                    zeile_pointer[1]++; if (zeile_pointer[1] ==87) {zeile_pointer[1] = 2;}
                    while((iomodus_D[zeile_pointer[1]] ==0) || (iomodus_D[zeile_pointer[1]] >19))
                         {zeile_pointer[1]++; if (zeile_pointer[1] ==87) {zeile_pointer[1] = 2;} } 
                    EEPROM.write(1,zeile_pointer[1]);//delay(4);     
                   } 
                  else if (x < 600)
                         {taster == "left";
                          zeile_pointer[1]--;
                          if (zeile_pointer[1] ==1) {zeile_pointer[1] = 87;}
                          while((iomodus_D[zeile_pointer[1]] ==0) || (iomodus_D[zeile_pointer[1]] >19))
                               {zeile_pointer[1]--; if (zeile_pointer[1] ==1) {zeile_pointer[1] =87;} }
                          EEPROM.write(1,zeile_pointer[1]);//delay(4);
                         } 
                         else if (x < 800)
                                {taster = "select";}
                                else {taster ="";}
}
#endif  //************************************************************************************* 

//*********************************************************************************************
#if defined (tft_display)  //behandlung tft toucheingabe und  display 2.4''
 {if (millis() > next_touch_time)  //touch-display abfragen
   {TSPoint p = ts.getPoint();// a point object holds x y and z coordinates
    px = p.x; py = p.y; pz =p.z;  
    pinMode(XM, OUTPUT);   pinMode(YP, OUTPUT);
    if (pz > MINPRESSURE && pz < MAXPRESSURE ) 
      {
#ifdef DEBUG
       Serial.print(F("px : "));Serial.print( px); Serial.print(F("  py : " )); Serial.print(py);
       Serial.print(F("  pz : " )); Serial.print(pz);
#endif       
       if (abs(px_B - px_A) > 100) {p_x = (1000 *(px- px_A))/(px_B -px_A); p_y = (1000 *(py - py_A))/(py_C -py_A);} 
         else {p_x = (1000 *(py -py_A))/(py_B - py_A); p_y = (1000 *(px - px_A)) /(px_C - px_A);}
       Serial.print(F("  p_x : "));Serial.print( p_x); Serial.print(F("  p_y : " )); Serial.print(p_y);

    if (tft_type != 4) {
       if (p_y < 154) {touch_y = 0;}   //p_y = 1000 entspricht 6,5 Zeilen 
         else {if (p_y < 308) {touch_y = 1;}
                 else {if (p_y < 462) {touch_y = 2;}
                         else {if (p_y < 616) {touch_y = 3;}
                                 else {if (p_y < 770) {touch_y = 4;}
                                         else {touch_y = 5;}}}}}}

    if (tft_type == 4) {
       if (p_y < 106) {touch_y = 0;}   //p_y = 1000 entspricht 8,5 Zeilen 
         else {if (p_y < 212) {touch_y = 1;}
                 else {if (p_y < 370) {touch_y = 2;}
                         else {if (p_y < 500) {touch_y = 3;}
                                 else {if (p_y < 590) {touch_y = 4;}
                                        else {if (p_y < 690) {touch_y = 5;}
                                              else {if (p_y < 790) {touch_y = 6;}
                                                  else {touch_y = 7;}}}}}}}}


       Serial.print(F("     touch_y ")); Serial.print(touch_y); Serial.println();
       centertouch = 1;
       if (p_x < 333) {zeile_pointer_minus();  Serial.println(zeile_pointer[touch_y]); centertouch = 0;}
       if (p_x > 666) {zeile_pointer_plus();  Serial.println(zeile_pointer[touch_y]); centertouch = 0;} //reserve center area for other action
       if ((centertouch) && ((iomodus_D[zeile_pointer[touch_y]]) == 2)) {
        port_pin = zeile_pointer[touch_y];
#ifdef DEBUG
        Serial.print (F("iomodus_D[zeile_pointer[touch_y]] Touch Mitte - Modus: ")); Serial.println (iomodus_D[port_pin]); 
        Serial.print (F("Port_Pin: D")); Serial.println(port_pin);
        Serial.print(F("Status des Ausgangs: ")); Serial.println(digitalRead(port_pin));
#endif
        next_touch_time = millis() + 200;
        if (((iomodus_D[port_pin]) == 2) && (digitalRead(port_pin) == LOW)) {
            command = "1"; SetOutputPort ();} 
          else {
            command = "0"; SetOutputPort ();} //toggle output pin
        centertouch = 0;}
      }
      for (int m = 0; m < zeilenzahl; m++)  //datenausgabe auf tft-display
      {while (zeile_data[m].length() < 7) {zeile_data[m] = " " + zeile_data[m];}
       display_zeile[m] =  display_message[zeile_pointer[m]] + zeile_data[m];
       if (display_zeile[m] != display_zeile_alt[m]) //displayausgabe nur wenn aenderung 
         {tft_print (m,display_zeile[m],schriftgroesse,default_color); display_zeile_alt[m] = display_zeile[m];
        }
      }
   } 
}
//*********************************************************************************************
//mit diesem Unterprogramm wird auf dem tft display ein zeilen-display 6 x 16 bis 8 x 26 emuliert
void tft_print (int line, String textline, int font_size, long int color)
{if (tft_type ==1)
   {tft.fillRect(0,38*line, 319, 38, BLACK); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(0, 38*line+6);              //und dann erst schreiben
   }
 if (tft_type ==2)
   {tft.fillRect(0,50*line, 479, 50, BLACK); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(5, 50*line+6);              //und dann erst schreiben
   }  
if (tft_type ==3)
   {tft.fillRect(0,38*line, 399, 38, BLACK); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(0, 38*line+6);              //und dann erst schreiben
   }
if (tft_type ==4)
   {tft.fillRect(0,38*line, 479, 38, (BLACK)); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(0, 38*line+6);              //und dann erst schreiben
   }
if (tft_type ==5)
   {tft.fillRect(0,38*line, 320, 38, (BLACK)); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(0, 38*line+6);              //und dann erst schreiben
   }
 tft.setTextColor(color);  
 tft.setTextSize(font_size);
 tft.print(textline);
}

//mit diesen Unterprogrammen wird der zeile_pointer im eeprom abgelegt
void zeile_pointer_plus()
{next_touch_time = millis() + 200; 
  zeile_pointer[touch_y]++; if (zeile_pointer[touch_y] >86) {zeile_pointer[touch_y] = 2;}
 while((iomodus_D[zeile_pointer[touch_y]] ==0) || (iomodus_D[zeile_pointer[touch_y]] >19))
  {zeile_pointer[touch_y]++; if (zeile_pointer[touch_y] >86) {zeile_pointer[touch_y] = 2;} }
 EEPROM.write(touch_y,zeile_pointer[touch_y]);//delay(4);
}
void zeile_pointer_minus()
{next_touch_time = millis() + 200; 
  zeile_pointer[touch_y]--; if (zeile_pointer[touch_y] <2) {zeile_pointer[touch_y] = 86;}
 while((iomodus_D[zeile_pointer[touch_y]] ==0) || (iomodus_D[zeile_pointer[touch_y]] >19))
   {zeile_pointer[touch_y]--; if (zeile_pointer[touch_y] <2) {zeile_pointer[touch_y] =86;}  }
 EEPROM.write(touch_y,zeile_pointer[touch_y]);//delay(4);
}      
#endif  //************************************************************************************* 

/* just needed in case you want to communicate with the ESP-01 without using the ESPwifi lib */
   void Auf_OK_warten()
{ Serial3.flush(); 
  boolean Ook = false;
  boolean Kok = false;
  unsigned long Counter = 0;
  
  while(!Kok)
  {
    if (Serial3.available())     espbyte = Serial3.read();
    if (espbyte == 79) Ook = true;
    if (espbyte == 75) Kok = true;
    Counter++;
    if (Counter > 200000){Serial.print(F("Timeout while communicating with ESP-01 module!\n\r")); break;}
  }
  if (Ook && Kok) Serial.println();
}

//*************************************************************************************
      int freeRam () { //just for debugging
          extern int __heap_start, *__brkval; 
          int v; 
          int fr = (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
          Serial.print(F("Free ram: "));
          Serial.println(fr);
       }
//*************************************************************************************
      void SetOutputPort () {
               if (((iomodus_D[port_pin] == 2)||(iomodus_D[port_pin] == 12)) && (command == "0")) 
               {for (int m=0; m < zeilenzahl; m++)
                  {if (zeile_pointer[m] == port_pin) {zeile_data[m] = " Aus";} // display_value[port_pin] = " LOW";}
                  }
                pinMode(port_pin, OUTPUT); digitalWrite(port_pin, LOW); Serial.println(command);
               }
             if ((iomodus_D[port_pin] == 2) && (command == "1")) 
               {for (int m=0; m < zeilenzahl; m++)
                  {if (zeile_pointer[m] == port_pin) {zeile_data[m] = "   An";} // display_value[port_pin] = " HIGH";}
                  }
                pinMode(port_pin, OUTPUT); digitalWrite(port_pin, HIGH); Serial.println(command);}
          String I = String(port_pin);
          befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+command+"')";
          set_sysvar();
       }
 
//*************************************************************************************
      void clockservice () {
        if ((millis() - previousMillis) >= 998) { //should be 1000. Different value for compensation and depends on quartz and program precision
              previousMillis = millis(); // save current time to previousMillis
                seconds = ++seconds;
             if (seconds == 60) {
                 seconds = 0;
                 minutes = ++minutes;}
             if (minutes == 60) {
                 minutes = 0; 
                 hours = ++hours;}
             if (hours == 24) {hours = 0;}
        }
      }

//*************************************************************************************
void sendHttpResponse(WiFiEspClient client)
    {
    if (receivingcommand == true) {
          clockservice();
          Serial.println(F("Sending command response"));
          // send a standard http response header
          // use \r\n instead of many println statements to speedup data send
          client.print(F( "HTTP/1.1 200 OK\r\n"
                          "Content-Type: text/html\r\n"
                          "Connection: close\r\n"             // the connection will be closed after completion of the response
//                          "Refresh: 10\r\n"                   // refresh the page automatically every 10 sec. Useful for tests if you compare command to received command
                          "\r\n"));
          client.print(F("<!DOCTYPE HTML>\r\n"
                         "<html>\r\n"
                         "<h1>Welcome at "));
          client.print(hm_systemvariable);
          client.print(F( "</h1>\r\n"
                          "Requests received: "));
          client.print(++reqCount);
          client.print(F( "<br>\r\n"
                          "<br>\r\n"
                          "Command received: "));
          client.print(command);
          client.print(F( "<br>\r\n"
                          "<br>\r\n"
                          "Command length: "));
          client.print(command.length());
          client.print(F( " out of a maximum of 100"
                          "<br>\r\n"
                          "<br>\r\n"
                          "</html>\r\n"));
          client.flush();
          next_tx = millis() +delta_tx;
          clockservice();
          receivingcommand = false;
         }
         else {
              Serial.println(F("Sending 404 response after invalid request"));
              client.print(F("HTTP/1.1 404 \r\n" //shortest possible answer
              "\r\n"));
              next_tx = millis() +delta_tx;
              }
    }
CCU1 + CCU2

linadd
Beiträge: 6
Registriert: 17.09.2016, 20:34

Re: Homeduino: universeller LAN/WLAN-Arduino für die Hausaut

Beitrag von linadd » 11.05.2017, 21:23

Hallo, nun ist es geschaft. In den Homeduino 4.0 von Eugen ist der BME280 integriert mit dem Wettertrend aus dem WIFFI-voice.
Die Einbindung und Bibiloteken habe ich aus dem Wiki vom WeMos D1 mini. dondaik hat das alles gut erklärt, so das mann es umsetzen konnte. Ist noch nicht umgestellt auf die neue Firmware der CCU.
Der BME280 funktioniert super, den Wettertrend muß ich noch beobachten.[

Code: Alles auswählen

const String Version = "hduino412_LAN_170511_280"; 
/*Version = "hduino412_LAN  eig_red
 * Systemvariablen mit +display_message[i] werden direktangezeigt,z.B.
 //befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State("+tempNTC+")";
   befehl="GET /xy.exe?antwort=dom.GetObject('"+display_message[i]+"').State("+tempNTC+")";
-BME280 und Wettertrend integriert   
-HNTC eingefügt für hohe Temperatur
-Lux geandert kein negativ Wert mehr
-Türen als Eingang zugefügt D24,D25
-tft eingestellt
-touch ist geaendert fuer 2,4" immer aendern bei Bildschirmgroeße
-Zeile 408  tft Treiber geaendert aufint identifier = 0x9341; tft.begin(identifier);
Stand: 2015.09.07 / Verfasser: Eugen Stall
erprobt fuer Arduino Mega 2560 mit Arduino 1.6.5r2 übertragen am 26.03.2016
hier ist immer die aktuelle Version:
http://www.stall.biz/project/homeduino-4-0-das-universelle-mess-und-aktormodul-fuer-die-hausautomation
das folgende homeduino-programm 8 sendet messdaten zur ccu (homeduino als webclient) ...
und empfängt ausgabedaten für die homeduino-outputs (homeduino als webserver)
_________________            ________________
|port 8181 server|<---------<| client        |
|                |           |               |
| CCU            |           |     Homeduino | 
|                |           |               |
|          client|>--------->|server port 80 | 
|________________|           |_______________|

/Quellen:Arduino website plus http://arduino.cc/en/Tutorial/WebClient und ...
 http://tushev.org/articles/arduino/item/52-how-it-works-ds18b20-and-arduino und ...  */
//#############################################################################################
//#############################################################################################
//Auswahl der verwendeten Shields: 
#define tft_display //"tft_display" oder "lcd_display"                         <<tft_display<< 
                    //"lcd_display" auch wenn kein display verwendet wird 
#define w5100       //"cc3000"  Wifi-Modul oder "w5100" ethernet shield        <<w5100<< 

byte ccu[] = { xxx, xxx, xxx, xxx };      //IP der CCU                          <<xxx, xxx,xxx, xxx<< 
//MAC-Adresse dieses Homeduinos ,bei mehreren Homeduinos MAC-.Adresse ändern!!:
byte mac[] = { 0xAC, 0xCC, 0xCC, 0xCC, 0xAC, 0xBC };  //                       <<0xAC, 0xCC, 0xCC, 0xCC, 0xAC, 0xBC<<

byte homeduino[] = { xxx, xxx,xxx, xxx }; //IP des Homeduino,wenn DHCP versagt <<xxx, xxx, xxx, xxx<< 

char ap_ssid[] = "ssid"; //SSID WLAN in Anführungszeichen                      <<user-eingabe<< 

char ap_password[] = "password"; //Passwort WLAN in Anführungszeichen          <<user-eingabe<< 

//xyz ist indiv. Bezeichnung dieses homeduino, keine sonderzeichen, öäüß...
const String homeduino_nummer = "xyz";  //                                     <<a<< 
const String hm_systemvariable = "homeduino_" + homeduino_nummer +"_";
//#############################################################################################
//#############################################################################################
//I/O-Kennung: hier wird die Funktion aller verwendbaren IO´s mit einer Kennziffer festgelegt 
//dabei haben alle IO´s die Standardfunktionen plus spez. Sonderfunktionen
//     Standardfunktionen sind:
//     '0' =andere Nutzg; '1' =dig_in; '2' =dig_out; '3' =1wire '4' =DHTxx; '5' =U_Schall 

const byte iomodus_D[80] = { 0,0,
 31, //D2 :      Std-fkt; '15' = IR_Rx??  '6' =ImpCount; '31' =tft;   <<user IO-Shield20<< 
 31, //D3 :      Std-fkt; '7' = 433_Rx??  '6' =ImpCount; '31' =tft;   <<user IO-Shield20<< 
 31, //D4 :      Std-fkt; '7' = 433_Tx??  '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D5 :      Std-fkt;                 '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D6 :      Std-fkt; '9' = buzzer    '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D7 :      Std-fkt;                 '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D8 :      Std-fkt;                 '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D9 :      Std-fkt; '16' = IR_Tx??  '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 20, //D10 :     Std-fkt; '20' = W5100 SS-Pin;
 0,  //D11 :     Std-fkt;  
 0,  //D12 :     Std-fkt;  
 0,  //D13 :     Std-fkt;
 0,  //D14/TX3 : Std-fkt; '0' =ESP8266;   '12' = rfid3;                <<user IO-Shield-Plus<< 
 0,  //D15/RX3 : Std-fkt; '0' =ESP8266;   '12' = rfid3;                <<user IO-Shield-Plus<< 
 0,  //D16/TX2 : Std-fkt; '0' =ESP8266;   '12' = rfid2;                <<user IO-Shield-Plus<< 
 0,  //D17/RX2 : Std-fkt; '0' =ESP8266;   '12' = rfid2;                <<user IO-Shield-Plus<< 
 6,  //D18/TX1 : Std-fkt; '6' =ImpCount;  '21' =CC3000                 <<user IO-Shield-Plus<< 
 6,  //D19/RX1 : Std-fkt; '6' =ImpCount;                               <<user IO-Shield-Plus<< 
 8,  //D20/SDA : Std-fkt; '6' =ImpCount;  '8' =I2C;                    <<user IO-Shield-Plus<< 
 8,  //D21/SCL : Std-fkt; '6' =ImpCount;  '8' =I2C;                    <<user IO-Shield-Plus<< 
 0,  //D22 :     Std-fkt; '12' = rfid3-oeffner;                        <<user IO-Shield-Plus<< 
 0,  //D23 :     Std-fkt; '12' = rfid2-oeffner;                        <<user IO-Shield-Plus<< 
 2,  //D24 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 2,  //D25 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 2,  //D26 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 2,  //D27 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 1,  //D28 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 1,  //D29 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 20, //MISO      '20' =W5100;  '21' =CC3000;   ICSP-Stecker
 20, //MOSI      '20' =W5100;  '21' =CC3000;   ICSP-Stecker
 20, //SCK       '20' =W5100;  '21' =CC3000;   ICSP-Stecker
 0, //SS                      '21' =CC3000;
 31, //D54 A0 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft; '30' =lcd; ser IO-Shield-20<< 
 31, //D55 A1 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft;         <<user IO-Shield-20<< 
 31, //D56 A2 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft;         <<user IO-Shield-20<< 
 31, //D57 A3 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft;         <<user IO-Shield-20<< 
 31, //D58 A4 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft;         <<user IO-Shield-20<< 
 0,  //D59 A5 :  Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-20<< 
 0,0,  
 13,  //D62 A8 :  Std-fkt; '10' =analog; '11' =NTC; '13' =HNTC;       <<user IO-Shield-Plus<< 
 11,  //D63 A9 :  Std-fkt; '10' =analog; '11' =NTC; '13' =HNTC;       <<user IO-Shield-Plus<< 
 11,  //D64 A10 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 11,  //D65 A11 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 11,  //D66 A12 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 11,  //D67 A13 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 1,  //D68 A14 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 1,  //D69 A15 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 8,  // '0' =andere Nutzg;    '8' =I2C;                               <<user IO-Shield-Plus<< 
 8,  // '0' =andere Nutzg;    '8' =I2C;                               <<user IO-Shield-Plus<< 
 8,  // '0' =andere Nutzg;    '8' =I2C;                               <<user IO-Shield-Plus<< 
 8,  // '0' =andere Nutzg;    '8' =I2C;                               <<user IO-Shield-Plus<< 
 8,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 8,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
}; 
//#############################################################################################
//hier werden Sensoren am I2C-Eingang aktiviert
const byte iomodus_baro = 0; //'0' =nc; '1' =BMP180,                   <<user IO-Shield-Plus<<
const byte iomodus_lux =  1; //'0' =nc; '1' =BH1750,                   <<user IO-Shield-Plus<<
const byte iomodus_280 = 1;  //'0' =nc; '1' =BME280,                   <<user IO-Shield-Plus<<
//#############################################################################################
//hier werden die Kennwerte fuer die Impulszaehler festgelegt
volatile unsigned long pulsecounter[6] = 
{ 0, //Zaehlerstand fuer D2 -Impulseingang bei Reset                    <<user IO-Shield20<<
 0, //Zaehlerstand fuer D3 -Impulseingang bei Reset                     <<user IO-Shield20<<
 0, //Zaehlerstand fuer D21-Impulseingang bei Reset                     <<user IO-Shield-Plus<< 
 0, //Zaehlerstand fuer D20-Impulseingang bei Reset                     <<user IO-Shield-Plus<< 
 0, //Zaehlerstand fuer D19-Impulseingang bei Reset                     <<user IO-Shield-Plus<< 
 0, //Zaehlerstand fuer D18-Impulseingang bei Reset                     <<user IO-Shield-Plus<< 
}; 
//hier wird der Teilerfaktor für die Impulszaehler festgelegt
const int pulsedivider[6] = 
{1, //Teilerfaktor D2 :                                                 <<user IO-Shield20<<
 1, //Teilerfaktor D3 :                                                 <<user IO-Shield20<<
 1, //Teilerfaktor D21 :                                                <<user IO-Shield-Plus<<
 1, //Teilerfaktor D20 :                                                <<user IO-Shield-Plus<<
 20, //Teilerfaktor D19 :                                              <<user IO-Shield-Plus<<
 20, //Teilerfaktor D18 :                                              <<user IO-Shield-Plus<<
}; 
//#############################################################################################
//#############################################################################################
//hier werden die anzeigetexte für lcd und tft display festgelegt 
String display_message[80] = {
"0","0",         //                              '0' =keine anzeige
"2 Status :",   //anzeigetext fuer port D02
"3 Status :",   //anzeigetext fuer port D03
"0","0","0","0","0","0",  // ports belegt durch lcd-shield     
"0",  // belegt durch ethernet W5100-shield, lcd-Shield PIN D10 abbiegen! 
"11 Status :",  //anzeigetext fuer port D11                             <<user IO-Shield-20<<
"12 Status :",  //anzeigetext fuer port D12                             <<user IO-Shield-20<<
"13 Status :",  //anzeigetext fuer port D13                             <<user IO-Shield-20<<
"14 Status :",  //anzeigetext fuer port D14 /TX3                        <<user IO-Shield-Plus<<
"15 Status :",  //anzeigetext fuer port D15 /RX3                        <<user IO-Shield-Plus<<
"16 Status :",  //anzeigetext fuer port D16 /TX2                        <<user IO-Shield-Plus<<
"17 Status :",  //anzeigetext fuer port D17 /RX2                        <<user IO-Shield-Plus<<
"Strom",  //anzeigetext fuer port D18 /TX1 /impulszaehler S03     <<user IO-Shield-Plus<<
"Solar",  //anzeigetext fuer port D19 /RX1 /impulszaehler S02     <<user IO-Shield-Plus<<
"20 I2C SDA:",  //anzeigetext fuer port D20 /SDA /impulszaehler S01     <<user IO-Shield-Plus<<
"21 I2C SCL:",  //anzeigetext fuer port D21 /SCL /impulszaehler S00     <<user IO-Shield-Plus<<
"22 Status :",  //anzeigetext fuer port D22                             <<user IO-Shield-Plus<<
"23 Status :",  //anzeigetext fuer port D23                             <<user IO-Shield-Plus<<
"24 weiss",     //anzeigetext fuer port D24                             <<user IO-Shield-Plus<<
"25 greun",     //anzeigetext fuer port D25                             <<user IO-Shield-Plus<<
"26 rot",       //anzeigetext fuer port D26                             <<user IO-Shield-Plus<<
"27 blau",      //anzeigetext fuer port D27                             <<user IO-Shield-Plus<<
"28 TuerK",     //anzeigetext fuer port D28                             <<user IO-Shield-Plus<<
"29 TuerH",     //anzeigetext fuer port D29                             <<user IO-Shield-Plus<<
"0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0",
"0",  // port belegt durch lcd-shield
"55 Status:",   //anzeigetext fuer port D55 /A1                         <<user IO-Shield-20<<
"56 Status:",   //anzeigetext fuer port D56 /A2                         <<user IO-Shield-20<<
"57 Status :",  //anzeigetext fuer port D57 /A3                         <<user IO-Shield-20<<
"58 Status :",  //anzeigetext fuer port D58 /A4                         <<user IO-Shield-20<<
"59 Status :",  //anzeigetext fuer port D59 /A5                         <<user IO-Shield-20<<
"0","0",
"TOfen",        //anzeigetext fuer port D62 /A8                         <<user IO-Shield-Plus<<
"TRaum",        //anzeigetext fuer port D63 /A9                         <<user IO-Shield-Plus<<
"TVL",          //anzeigetext fuer port D64 /A10                        <<user IO-Shield-Plus<<
"TRL",          //anzeigetext fuer port D65 /A11                        <<user IO-Shield-Plus<<
"TWW",          //anzeigetext fuer port D66 /A12                        <<user IO-Shield-Plus<<
"TAus",         //anzeigetext fuer port D67 /A13                        <<user IO-Shield-Plus<<
"68 in1",       //anzeigetext fuer port D68 /A14                        <<user IO-Shield-Plus<<
"69 in2",       //anzeigetext fuer port D69 /A15                        <<user IO-Shield-Plus<<
// die folgenden Anzeigetexte sind für Module mit mehreren Datenpunkten z.b. I2C-Module
"Druck/mB:",    //anzeigetext fuer I2C 
"Temp./C :",    //anzeigetext fuer I2C 
"Lux/lx",       //anzeigetext fuer I2C 
"Feucht/%:",    //anzeigetext fuer I2C
"rDruck:",      //anzeigetext fuer 
"Trend:",       //anzeigetext fuer 
"76 Status :",  //anzeigetext fuer 
"77 Status :",  //anzeigetext fuer 
"78 Status :",  //anzeigetext fuer 
"79 Status :"   //anzeigetext fuer   
};
//#############################################################################################
//#############################################################################################
//hier werden die Zugangsberechtigungen für den RDM6300 Rfid-Reader und FOBs festgelegt

//#############################################################################################
//#############################################################################################
//#############################################################################################

#include <SPI.h>
#include <Wire.h> 
#include <OneWire.h>   //für Temperatursensoren DS18B20
                       //http://www.hacktronics.com/code/OneWire.zip
#include <NewPing.h>   //für Ultraschallsensoren SR04
                       //https://arduino-new-ping.googlecode.com/files/NewPing_v1.5.zip
#include "DHT.h"       //für Temperatursensoren SHT22
                       //https://github.com/adafruit/DHT-sensor-library/archive/master.zip
#include <AS_BH1750.h> //für I2C-Luxmeter
                       //https://github.com/hexenmeister/AS_BH1750/archive/master.zip
#include <SFE_BMP180.h>//für I2C-Barometer
                       //https://github.com/sparkfun/BMP180_Breakout/archive/master.zip
#include <RCSwitch.h>  // läuft noch nicht!
#include <EEPROM.h>
#include <BME280_t.h>  //für I2C-Barometer BME280 Sensor

//#include <IRremote.h>// läuft noch nicht!

//der folgende Bereich ist bei verwendung w5100 auszukommentieren
//ausblenden mit " #if defined (5100)" funktioniert leider nicht!! 
/*
//Initialisierung des CC3000 Wifi auf dem IO-Shield-Plus  
#include <SFE_CC3000.h>// fuer cc3000 wifi
                 // http://github.com/sparkfun/SFE_CC3000_Library/archive/master.zip
#include <SFE_CC3000_Client.h>
// Pins
#define CC3000_INT 18  // int-Pin mit Wifi Shield ist D3, mit breakout auf IO-Shield-Plus D18
#define CC3000_EN 46   // en-Pin mit Wifi Shield ist D5, mit breakout auf IO-Shield-Plus  D46
#define CC3000_CS 53   // cs-Pin mit Wifi Shield ist D10, mit breakout auf IO-Shield-Plus D53
SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS);
SFE_CC3000_Client client = SFE_CC3000_Client(wifi);
unsigned int ap_security = WLAN_SEC_WPA2; // Security of network
unsigned int timeout = 30000; // Milliseconds
char server[] = "192,168,178,50"; // Remote host site
*/
#if defined (w5100)  //************************************************************************ 
//der folgende Bereich ist die Initialisierung des LAN bei Verwendung des LAN-Shields
#include <Ethernet.h> 
EthernetClient client;
EthernetServer server(80);
#endif  //************************************************************************************* 

#if defined(tft_display)  //*******************************************************************
//#include <Adafruit_GFX.h>    //Quelle: https://github.com/adafruit/Adafruit-GFX-Library
//#include <Adafruit_TFTLCD.h> //Quelle:   https://github.com/buhosoft/TFTLCD-Library
#include <stdint.h>
//#include "TouchScreen.h" 
#include <SPFD5408_Adafruit_GFX.h>   
#include <SPFD5408_Adafruit_TFTLCD.h> 
#include <SPFD5408_TouchScreen.h>  
//Quelle: http://www.smokeandwires.co.nz/blog/a-2-4-tft-touchscreen-shield-for-arduino/
//2,4"-display TouchScreen
#define YP A2  // must be an analog pin, use "An" notation!
#define XM A3  // must be an analog pin, use "An" notation!
#define YM 8   // can be a digital pin
#define XP 9   // can be a digital pin
//3,95"-display TouchScreen
//#define YP A1  // must be an analog pin, use "An" notation!
//#define XM A2  // must be an analog pin, use "An" notation 
//#define YM 7   // can be a digital pin
//#define XP 6   // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 330);
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0
#define tft_rotation 3 //3 oder 1 abhägig vom tft-shield typ               <<user-eingabe<< 
#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
int touch_y;
const byte zeilenzahl = 6;
int px,py,pz;
boolean touch, touch_alt;
unsigned long next_touch_time = 0;


//2,4'' display
const long int px_A = 934,  py_A = 882;  //touch-koordinaten oben-links                
const long int px_B = 213,  py_B = 818;  //touch-koordinaten oben-rechts              
const long int px_C = 936,  py_C = 117;  //touch-koordinaten unten-links              
#define schriftgroesse 3 
#define tft_type 1   // 1 ist 2,4''display   2 ist 3.95''display
 
//3,95'' display
//const long int px_A = 203,  py_A = 720;  //touch-koordinaten oben-links               
//const long int px_B = 189,  py_B = 85;  //touch-koordinaten oben-rechts             
//const long int px_C = 880,  py_C = 740;  //touch-koordinaten unten-links              
//#define schriftgroesse 4  
//#define tft_type 2   // 1 ist 2,4''display   2 ist 3.95''display

long int p_x, p_y ;   //normierte aktuelle touch-koordinaten: 
                      //oben links ist 0,0 und unten rechts ist 1000,1000
#endif  //*************************************************************************************

#if defined(lcd_display)  //*******************************************************************
//https://www.dfrobot.com/wiki/index.php?title=Arduino_LCD_KeyPad_Shield_%28SKU:_DFR0009%29
#include <LiquidCrystal.h> 
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // initialize library with numbers of the interface pins
const byte zeilenzahl = 2;
#endif  //*************************************************************************************

int x, x_alt;
byte zeile_pointer[6];
String zeile_data[6] = {"     ","     ","     ","     ","     ","     "};
String display_zeile_alt[6],display_zeile[6];
String taster;

char zeichen,buffer[50];
boolean fob_da =0;
String zeich, fob_hex, fob_dec,Name, lcd_rfid_message, oeffner, Value;
unsigned long fob_zahl,time_rfid3 = 0,time_rfid2 = 0; 
byte zeichen_zahl;

//********************************************************************************************* 
AS_BH1750 sensor; //Initialize BH1750 Luxmeter library
float lux;
long Lux;
int laenge;
const float ALTITUDE = 540.0; // eigene seehoehe in metern              <<user IO-Shield-Plus<<
SFE_BMP180 pressure;
char status;
double T,P,p0,F;
boolean reading = false;
String command = String(200);
String baro_string,baroT_string, lux_string;
//********************************************************************************************* 
boolean last_digital_value_D[80];
float last_value_D[80],last_IR_value,last_RF_value;
unsigned long next_Time[80];  
double last_baro_value,last_baroT_value;
boolean complete_loop =1; // wenn 1, dann einmal komplett durchlaufen
String befehl,sub_command = String(20),parameter = String(20),header = String(20);
int param,port_pin;
boolean port_data;
boolean value;
String I;
int analogwert;
//*********************************************************************************************
float tempNTC;
float temphNTC;
const float B_wert = 3950; //aus dem Datenblatt des NTC //<<user-eingabe<<
const float Tn = 298.15; //25°Celsius in °Kelvin 
const float Rv = 10000; //Vorwiderstand
const float Rn = 10000; //NTC-Widerstand bei 25°C
float Rt,temp_tur,humidity;
 
const float delta_onewire = 0.2; //          Deltas für Sendeauslösung 
const float delta_DHT = 0.2; //in °C 
const float delta_us = 3.0; // in cm
const float delta_analog = 2.0; // in inkrement
const float delta_ntc = 0.5; //in °C
const float delta_hntc = 20.0; //in °C
const float delta_lux = 5; //in lux
const float delta_counter = 5; //in counter inkrement
const double delta_baro = 5; //in mB
const double delta_baroT = 0.5; //in °C
//BME280******************************************************************************
float korrTemp = 0; // Korrekturwert fuer die Temperaturmessung BME280
float korrFeucht = 0; // Korrekturwert fuer die Feuchtigkeitsmessung BME20
float temp = 0, feucht = 0, druck = 0, reldruck = 0, altitude1 = 0;//BME280
String  temp_string, feucht_string, druck_string, reldruck_string;
double last_temp_value, last_feucht_value, last_druck_value, last_reldruck_value;
const double delta_feucht = 2.0; //in %    ab % ubertragen an CCU
#define MYALTITUDE  540.00 // Höhenmeter

//fuer Wettertrend********************************************************************

double p0_old, delta_p0, baro_wert_alt,p_mittel;//T,P
double p[5] = {1000.0,1000.0,1000.0,1000.0,1000.0};
double t[5] ={ 20.0,30.0,40.0,50.0,60.0 };
long baro_ctr = 0;
float Altitude = 199.0; // eigene seehoehe in metern             

//char status;
String wettertrend = "not valid";
String wettertrend_alt = "not_valid";

unsigned long next_time_baro = 0UL;
unsigned long delta_time_baro = 120000;
unsigned long baro_abtastzeit_alt = 0;
unsigned long baro_abtastzeit = 0;
unsigned long delta_baro_abtastzeit = 0;

 
BME280 <> BMESensor;
//************************************************************************************ 
long duration, cm; //variable für Ultraschallsensor
unsigned long time_sr04;
 
unsigned long next_full_loop = 0;
unsigned long delta_time = 3600000; // jede Stunde werden alle Inputs aktualisiert
unsigned long delta_tx = 500; //in ms, minimaler Abstand der Telegramme an die CCU
unsigned long next_tx = 0, time_wait = 0; 

int rf_key;
String rfkey;
RCSwitch mySwitch = RCSwitch();

unsigned zaehlwert;
unsigned last_zaehlwert[6] = {0,0,0,0,0,0};
//#############################################################################################
//#############################################################################################
void setup() 
{Serial.begin(9600); 
//+++++++ einrichtung der interrupts fuer impulszahler D2,D3,D18,D19,D20,D21
 if ((pulsedivider[0] > 0) && (iomodus_D[2] == 6)) 
   {pinMode(2, INPUT_PULLUP); attachInterrupt(0, ISR_0, FALLING);}
 if ((pulsedivider[1] > 0) && (iomodus_D[3] == 6)) 
   {pinMode(3, INPUT_PULLUP); attachInterrupt(1, ISR_1, FALLING);} 
 if ((pulsedivider[2] > 0) && (iomodus_D[21] == 6)) 
   {pinMode(21, INPUT_PULLUP); attachInterrupt(2, ISR_2, FALLING);}
 if ((pulsedivider[3] > 0) && (iomodus_D[20] == 6)) 
   {pinMode(20, INPUT_PULLUP); attachInterrupt(3, ISR_3, FALLING);}
 if ((pulsedivider[4] > 0) && (iomodus_D[19] == 6)) 
   {pinMode(19, INPUT_PULLUP); attachInterrupt(4, ISR_4, FALLING);}

 #if defined (w5100)  //************************************************************************* 
 if ((pulsedivider[5] > 0) && (iomodus_D[18] == 6))  //interrupt reserviert fuer cc3000
   {pinMode(18, INPUT_PULLUP); attachInterrupt(5, ISR_5, FALLING);}
 #endif  //*************************************************************************************

//+++++++ rfid initialisieren
 if ((iomodus_D[15] == 12) && (iomodus_D[14] == 12)){Serial3.begin(9600);}
 if ((iomodus_D[17] == 12) && (iomodus_D[16] == 12)){Serial2.begin(9600);}

#if defined (lcd_display)  //******************************************************************
//+++++++ lcd initialisieren
 lcd.begin(16, 2); delay(200);  //16 zeichen in 2 zeilen
 lcd.setCursor(0,0);
 lcd.print(" Homeduino 4.0  ");
#endif  //*************************************************************************************

#if defined (tft_display)  //******************************************************************
//+++++++ tft initialisieren
 tft.reset();
 //int identifier = tft.readID();  tft.begin(identifier);    // Orginal
   int identifier = 0x9341; tft.begin(identifier);           // geaendert
 Serial.print(" tft identifier:" ); Serial.println(identifier);   
 delay(100);
 tft.fillScreen(BLACK); tft.setRotation(tft_rotation);
 if (tft_type ==1) //2,4'' display
   {tft_print (1,"  Homeduino",4,YELLOW);
    tft_print (2,"     4.0",4,YELLOW);
    tft_print (5,"www.stall.biz",4,CYAN);
    tft.drawRect(0,0, 319, 240, GREEN);
   } 
  if (tft_type ==2)  //3,95'' display
   {tft_print (1,"   Homeduino",5,YELLOW);
    tft_print (2,"      4.0",5,YELLOW);
    tft_print (5," www.stall.biz",5,CYAN);
    tft.drawRect(5,5, 475, 310, GREEN);
   }   
#endif  //*************************************************************************************

for(int i=0; i<zeilenzahl; i++)
   {zeile_pointer[i] = EEPROM.read(i);  //anzeige-pointer aus eeprom holen
    if (zeile_pointer[i] >79) {zeile_pointer[i] = 0;}  //wenn eeprom erstes mal benutzt wird
   } 

#if defined (w5100)  //************************************************************************
//hier folgt die LAN Initialisierung 
char myIpString[24];
 if (Ethernet.begin(mac) == 0) // start the Ethernet connection:
   {Serial.println("Failed to configure Ethernet using DHCP"); Ethernet.begin(mac, homeduino);}
    delay(1000);// give the Ethernet shield a second to initialize:
    Serial.println("connecting..."); // if you get a connection, report back via serial:
 if (client.connect(ccu, 8181)) {}
   else {Serial.println("connection failed");} // if you didn't get a connection to the server:
 client.stop(); 
 IPAddress myIp = Ethernet.localIP();
 sprintf(myIpString, "%d.%d.%d.%d", myIp[0], myIp[1], myIp[2], myIp[3]); 
 I = myIpString;
 befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"IP"+"').State('"+ I + "')";
 set_sysvar(); 
 server.begin();
#endif  //*************************************************************************************

#if defined (cc3000)  //**********************************************************************
// hier folgt die CC3000 Initialisierung 
 ConnectionInfo connection_info;
 char myIpString[24]; 
 Serial.println("SparkFun CC3000 - WebClient");
 if ( wifi.init() ) {Serial.println("init complete");} 
 else {Serial.println("problem with init!");}
 // Connect using DHCP
 if (!wifi.connect(ap_ssid, ap_security, ap_password, timeout)) 
   {Serial.println("no connection to AP");}
 //build IP address
 if ( !wifi.getConnectionInfo(connection_info) ) {Serial.println("no connection details");} 
   else {sprintf(myIpString, "%d.%d.%d.%d", connection_info.ip_address[0], 
   connection_info.ip_address[1],connection_info.ip_address[2], connection_info.ip_address[3]); 
         I = myIpString;
        }
 befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"IP"+"').State('" + I + "')";
 set_sysvar(); 
 client.stop();
#endif  //*************************************************************************************

#if defined (lcd_display)  //****************************************************************** 
//bei erfolgreichem einloggen ausgabe ip-adresse 
lcd.setCursor(0,1);
lcd.print(myIpString);
delay(3000);
#endif  //*************************************************************************************

#if defined (tft_display) //*******************************************************************
//bei erfolgreichem einloggen ausgabe ip-adresse 
tft.fillScreen(BLACK);
if (tft_type ==1) //2,4'' display
  {tft.setCursor(8, 230); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(1);
   tft.print(Version + "   Homeduino IP: "); tft.print( myIpString);
  }
if (tft_type ==2) //3,95'' display
  {tft.setCursor(1, 300); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(2);
   tft.print(Version + " IP: "); tft.print( myIpString);
  }
#endif  //*************************************************************************************
for (int i = 0; i < 80; i++) {next_Time[i]=0;} //
 //delay(2000);
}
//#############################################################################################
//#############################################################################################
void loop() 
{complete_loop = 0;
 if (millis() > next_full_loop) //mindestens jede Stunde eine komplette Aktualisierung
   {complete_loop = 1; next_full_loop = millis() + delta_time; 
    if (next_full_loop < millis()) {complete_loop = 0;} //wichtig wegen Zahlensprung 
                                                        //von millis() alle 50 Tage
   } 
//*********************************************************************************************
 for (int i = 2; i < 70; i++) //behandlung aller Ports D2 bis D69 
 {while ((iomodus_D[i] == 0) || (iomodus_D[i] >29 )) {i++;}  // unbenutzte pins überspringen
  datenempfang(); //nach jeder Messung auf Datenempfang schalten
  display_data(); //display ausgeben und abfragen
 //******************************************************************************************** 
 if (iomodus_D[i] == 1) //behandlung digitaleingänge 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +1000;  //digitaleingänge nicht häufiger als alle 1000ms abfragen
       pinMode(i, INPUT_PULLUP); 
       digitalWrite(i, HIGH);
       value =digitalRead(i);
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) 
            {if (value ==0) {zeile_data[m] = "LOW";} else {zeile_data[m] = "HIGH";}}}
       if ((!value == last_digital_value_D[i]) || complete_loop) 
         {I = String(i);
          befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State("+value+")";
          //befehl="GET /xy.exe?antwort=dom.GetObject('"+display_message[i]+"').State("+value+")";
          set_sysvar();
          last_digital_value_D[i] = value;
         }
      } 
   }
//********************************************************************************************* 

 // one Wire Sensoren hier einfügen
 
//********************************************************************************************* 
 if (iomodus_D[i] == 4) //behandlung DHT temperatur- und feuchtesensoren
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +30000;  //DHT nicht häufiger als alle 30s abfragen 
       DHT dht(i, DHT22); //je nach verwendetem sensor "DHT11", "DHT22" (AM2302),"DHT 21" (AM2301)
       dht.begin();
       //delay(2000); // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
       time_wait = millis() +2000;                       //wahrend der 2s wartezeit, daten empfangen
       while (millis() < time_wait) {datenempfang();display_data;} //und display weiter bedienen 
       humidity = dht.readHumidity(); // Reed feuchtigkeit in %
       temp_tur = dht.readTemperature();// Read temperature as Celsius
       if (isnan(humidity) || isnan(temp_tur) ) // Check if any reads failed and 
         {//Serial.println("Failed to read from DHT sensor!");
          temp_tur = -1000;
         }
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = String(humidity,1);}
         }
       if (( humidity > (last_value_D[i] + delta_DHT))|| ( humidity < (last_value_D[i] - delta_DHT)) 
                                                  || complete_loop) 
         {I = String(i);
          //befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State("+humidity+")";
          befehl="GET /xy.exe?antwort=dom.GetObject('"+display_message[i]+"').State("+humidity+")";
          set_sysvar();
          //befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"_1').State("+temp_tur+")";
          befehl="GET /xy.exe?antwort=dom.GetObject('"+display_message[i]+"_1').State("+temp_tur+")";
          set_sysvar();
          last_value_D[i] = humidity;
        } 
     }
   } 

//******************************************************************************************** 
 
// Ultraschall hier einfügen
 
//********************************************************************************************* 
 if (iomodus_D[i] == 10) //behandlung analogeingänge 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +1000;  //analogeingänge nicht häufiger als alle 1000ms abfragen 
       analogwert =analogRead(i);
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = String(analogwert);}}
       if ((analogwert > (last_value_D[i] + delta_analog)) 
                || (analogwert < (last_value_D[i] - delta_analog)) || complete_loop) 
         {I = String(i);
          befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State("+analogwert+")";
          //befehl="GET /xy.exe?antwort=dom.GetObject('"+display_message[i]+"D"+I+"').State("+analogwert+")";
          set_sysvar();
          last_value_D[i] = analogwert;
         }
      }
   } 
//*********************************************************************************************
 if (iomodus_D[i] == 11) //behandlung NTC 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +1200000;  //NTC-eingänge nicht häufiger als alle 60s abfragen
       Rt = Rv/((1024.0/analogRead(i))- 1.0);
       tempNTC = (B_wert * Tn / ( B_wert + (Tn * log(Rt/Rn)))) -Tn +25.0 ;
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = String(tempNTC,1);}}
          if ((tempNTC > (last_value_D[i] + delta_ntc)) || (tempNTC < (last_value_D[i] - delta_ntc)) 
                                                   || complete_loop) 
            {I = String(i);
             //befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State("+tempNTC+")";
             befehl="GET /xy.exe?antwort=dom.GetObject('"+display_message[i]+"').State("+tempNTC+")";
             set_sysvar();
             last_value_D[i] = tempNTC;
            } 
      }
   }     
//*********************************************************************************************
if (iomodus_D[i] == 13) //behandlung HNTC 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +180000;  //HNTC-eingänge nicht häufiger als alle 180s abfragen
       Rt = Rv/((1024.0/analogRead(i))- 1.0);
       temphNTC = (B_wert * Tn / ( B_wert + (Tn * log(Rt/Rn)))) -Tn +25.0 ;
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = String(temphNTC,1);}}
          if ((temphNTC > (last_value_D[i] + delta_hntc)) || (temphNTC < (last_value_D[i] - delta_hntc)) 
                                                          || complete_loop) 
            {I = String(i);
             //befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State("+temphNTC+")";
             befehl="GET /xy.exe?antwort=dom.GetObject('"+display_message[i]+"').State("+temphNTC+")";
             set_sysvar();
             last_value_D[i] = temphNTC;
            } 
      }
   }     
//********************************************************************************************* 
 if (iomodus_D[i] == 6) //behandlung impulszahler D2,D3,D21,D20,D19,D18 
   {byte offset =23;
    if (i ==2) {offset = 4;} if (i ==3) {offset = 6;}
    zaehlwert = pulsecounter[offset - i ] / pulsedivider[offset - i ];
    for (int m=0; m < zeilenzahl; m++)
      {if (zeile_pointer[m] == i) {zeile_data[m] = String(zaehlwert);}}
       if ((pulsedivider[offset -i] > 0) && ((zaehlwert > (last_zaehlwert[offset - i]+ delta_counter) 
                           || complete_loop))) 
         {I = String(offset -i);
         // befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"imp"+I+"').State("+zaehlwert+")";
          befehl="GET /xy.exe?antwort=dom.GetObject('"+display_message[i]+"_imp"+I+"').State("+zaehlwert+")";
          set_sysvar();
          last_zaehlwert[offset - i] = zaehlwert;
         } 
   } 
//*********************************************************************************************
//behandlung I2C sensoren an pin 20(sda) und pin 21 (scl)
 if ((iomodus_D[i] == 8)&&(i == 20))
   {i++;  // da I2C Bus 2 eingaenge belegt//behandlung I2C sensoren an pin
  
//behandlung Luxmeter BH1750 an SCL pin21 und SDA pin 20 ***********************************
// for normal sensor resolution (1 lx resolution, 0-65535 lx, 120ms, no PowerDown) 
//use: sensor.begin(RESOLUTION_NORMAL, false); 
    if (iomodus_lux ==1)
      {if (millis() > next_Time[72])
         {next_Time[72] = next_Time[72] +30000;  //luxmeter nicht häufiger als alle 30s abfragen 
          if(!sensor.begin()) { Serial.println("Sensor not present"); }
          lux = sensor.readLightLevel(); //delay(1000);
          lux = map(lux,0,124000,0,64000) ; // den befehl map im www ansehen
          //Lux = (int)lux;
          Lux = (unsigned int)lux;
          //Serial.print("Helligkeit/lux: "); Serial.print(lux); Serial.println();
          lux_string = "      " + String(Lux);
          int laenge = lux_string.length();
          lux_string = lux_string.substring(laenge -6,laenge);
          for (int m=0; m < zeilenzahl; m++)
            {if (zeile_pointer[m] == 72) {zeile_data[m] = lux_string;}}
             if (((Lux > (last_value_D[72] + delta_lux)) || (Lux < (last_value_D[72] - delta_lux)) 
                                                         || complete_loop)) 
               {befehl="GET /xy.exe?antwort=dom.GetObject('" + hm_systemvariable+"lux"+"').State("+Lux+")";
               //{befehl="GET /xy.exe?antwort=dom.GetObject('" +display_message[i]+"lux"+"').State("+Lux+")";
                set_sysvar();
                last_value_D[72] = Lux;
               }
           } 
       } 
   //behandlung barometer BMP180 an SCL pin21 und SDA pin 20
    if (iomodus_baro ==1)
      {if (millis() > next_Time[70])
         {next_Time[70] = next_Time[70] +30000;  //barometer nicht häufiger als alle 30s abfragen 
          if (pressure.begin()) {status = pressure.startTemperature();}
          if (status) {delay(status); status = pressure.getTemperature(T);} //messung T
          if (status) {status = pressure.startPressure(3);} // //messung P mit resolution 0 bis 3
          if (status) {delay(status); status = pressure.getPressure(P,T);}
          if (status) {p0 = pressure.sealevel(P,ALTITUDE);} // umrechnung auf N.N.
//Serial.print("Hoehe/m: "); Serial.print(ALTITUDE); Serial.print(" Temperatur/C: "); 
//Serial.print(T); Serial.print(" Normaldruck /mb: "); Serial.println(p0); 
          baro_string = "     " + String(p0);
          laenge = baro_string.length();
          baro_string = baro_string.substring(laenge -7,laenge -1);
          baroT_string = "      " + String(T);
          laenge = baroT_string.length();
          baroT_string = baroT_string.substring(laenge -7,laenge -1);
          for (int m=0; m < zeilenzahl; m++) {if (zeile_pointer[m] == 70) {zeile_data[m] = baro_string;}}
          if ((p0 > (last_baro_value + delta_baro)) || (p0 < (last_baro_value - delta_baro)) 
                                                    || complete_loop) 
            {befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"baro"+"').State("+p0+")";
            //{befehl="GET /xy.exe?antwort=dom.GetObject('"+display_message[i]+"baro"+"').State("+p0+")";
             set_sysvar();
             last_baro_value = p0;
             last_value_D[70] = p0;
            }
          for (int m=0; m < zeilenzahl; m++) {if (zeile_pointer[m] == 71) {zeile_data[m] = baroT_string;}}  
          if ((T > (last_baroT_value + delta_baroT)) || (T < (last_baroT_value - delta_baroT)) 
                                                     || complete_loop) 
            {befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"baroT"+"').State("+T+")";
            //{befehl="GET /xy.exe?antwort=dom.GetObject('"+display_message[i]+"baroT"+"').State("+T+")";
             set_sysvar();
             last_baroT_value = T;
             last_value_D[71] = T;
            } 
         }
      } 
//BME280*****************************************************************************
//behandlung barometer BME280 an SCL pin21 und SDA pin 20
    if (iomodus_280 ==1)
      {if (millis() > next_Time[70])
         {next_Time[70] = next_Time[70] +60000;  //barometer nicht häufiger als alle 60s abfragen 
          (BMESensor.begin());}

          BMESensor.refresh();                                      // read current sensor data
          Serial.println(" ");
          temp = BMESensor.temperature + korrTemp;  // Auslesen der Werte aus dem BME280 und berrechnen der Werte
          feucht = BMESensor.humidity + korrFeucht;
          druck = BMESensor.pressure  / 100.0F;
          float relativepressure = BMESensor.seaLevelForAltitude(MYALTITUDE);
          //reldruck = relativepressure  / 100.0F;
          p[0] = relativepressure  / 100.0F;
          //altitude1 = BMESensor.pressureToAltitude(relativepressure);
          
//Serial.print("Hoehe/m: "); Serial.print(altitude1); Serial.print(" Temperatur/C: "); 
//Serial.print(temp); Serial.print(" Normaldruck /mb: "); Serial.println(relpressure1);
//Serial.print("Feuchte/%"); Serial.print(feucht); 

          temp_string = "     " + String(temp);
          laenge = temp_string.length();
          temp_string = temp_string.substring(laenge -7,laenge -1);
          
          feucht_string = "      " + String(feucht);
          laenge = feucht_string.length();
          feucht_string = feucht_string.substring(laenge -7,laenge -1);

          druck_string = "      " + String(druck);
          laenge = druck_string.length();
          druck_string = druck_string.substring(laenge -7,laenge -1);

          reldruck_string = "      " + String(reldruck);
          laenge = reldruck_string.length();
          reldruck_string = reldruck_string.substring(laenge -7,laenge -1);
          
          for (int m=0; m < zeilenzahl; m++) {if (zeile_pointer[m] == 71) {zeile_data[m] = temp_string;}}  
          if ((temp > (last_temp_value + delta_baroT)) || (temp < (last_baro_value - delta_baroT)) 
                                                    || complete_loop) 
            {befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"temp"+"').State("+temp+")";
            //{befehl="GET /xy.exe?antwort=dom.GetObject('"+display_message[i]+"temp"+"').State("+T+")";
             set_sysvar();
             last_temp_value = temp;
             last_value_D[71] = temp;
            }
            
          for (int m=0; m < zeilenzahl; m++) {if (zeile_pointer[m] == 73) {zeile_data[m] = feucht_string;}}  
          if ((feucht > (last_feucht_value + delta_feucht)) || (feucht < (last_feucht_value - delta_feucht)) 
                                                       || complete_loop) 
            {befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"feucht"+"').State("+feucht+")";
            //{befehl="GET /xy.exe?antwort=dom.GetObject('"+display_message[i]+"feucht"+"').State("+feucht+")";
             set_sysvar();
             last_feucht_value = feucht;
             last_value_D[73] = feucht;
             }
             
          for (int m=0; m < zeilenzahl; m++) {if (zeile_pointer[m] == 70) {zeile_data[m] = druck_string;}}  
          if ((druck > (last_druck_value + delta_baro)) || (druck < (last_druck_value - delta_baro)) 
                                                     || complete_loop)
            {befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"druck"+"').State("+druck+")";
            //{befehl="GET /xy.exe?antwort=dom.GetObject('"+display_message[i]+"druck"+"').State("+druck+")";
             set_sysvar();
             last_druck_value = druck;
             last_value_D[70] = druck;
            }

          /*for (int m=0; m < zeilenzahl; m++) {if (zeile_pointer[m] == 74) {zeile_data[m] = reldruck_string;}}  
          if ((reldruck > (last_reldruck_value + delta_baro)) || (reldruck < (last_reldruck_value - delta_baro)) 
                                                     || complete_loop) 
            {befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"reldruck"+"').State("+reldruck+")";
            //{befehl="GET /xy.exe?antwort=dom.GetObject('"+display_message[i]+"reldruck"+"').State("+reldruck+")";
             set_sysvar();
             last_druck_value = reldruck;
             last_value_D[74] = reldruck;
            ]*/
        
     
//BME280-Wettertrend'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

   {p[4] = p[3]; p[3] = p[2]; p[2] = p[1]; p[1] = p[0]; t[3] = t[2]; t[2] = t[1]; t[1] = t[0]; //Umspeichern 
      
   t[0] = ((float) (millis()) /1000); baro_ctr++;  //baro_ctr nur für beginn nach reset wichtig, damit "not valid" angezeigt wird
   
   //berechnung steigung mit linearer regression
   double A = 0; double B = 0; double C = 0; double D = 0;
   for ( int i = 0; i < 5; i++) {A +=  t[i] * p[i];   B += t[i];   C += p[i];   D += t[i]*t[i];}
   delta_p0 = 3600 * (5 * A - B * C) / (5 * D - B * B);    //delta_p0 in hPa/h
   delta_p0 = constrain(delta_p0, -5.0, 5.0);
  if (baro_ctr > 4) { baro_ctr = 5;
           wettertrend = "stark_fallend";
          if (delta_p0 > -1.0 ) {wettertrend = "fallend";}  
          if (delta_p0 > -0.2 ) {wettertrend = "stabil";}  
          if (delta_p0 > 0.2 ) {wettertrend = "steigend";}  
          if (delta_p0 > 1.0 ) {wettertrend = "stark_steigend";}   
         } else {wettertrend = "not valid";}
         
  p_mittel = C / 5;  // mittelwert der druckmessungen bilden       
     
     /*  Serial.println();
       Serial.print("Hoehe/m:  "); Serial.print(Altitude); Serial.print("  Temperatur/C: ");  Serial.print(temp_tur); 
       Serial.print("  Absolutdruck /mb: ");  Serial.print(P);Serial.print("  Druck NN /mb: ");  Serial.print(p_mittel); 
       Serial.print("  delta_p0: ");  Serial.print(delta_p0); Serial.print("  wettertrend: ");  Serial.println(wettertrend);
    */         
  if ((p_mittel > (baro_wert_alt + delta_baro)) || (p_mittel < (baro_wert_alt - delta_baro))|| (wettertrend_alt != wettertrend) || complete_loop)
         
          for (int m=0; m < zeilenzahl; m++) {if (zeile_pointer[m] == 74) {zeile_data[m] = p_mittel;}}
          {befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"reldruck"+"').State("+p_mittel+")";
          set_sysvar();
          befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"trend"+"').State("+wettertrend+")";
          set_sysvar();
          baro_wert_alt = p_mittel; wettertrend_alt = wettertrend;
        
          }      
        }
      } 
   }    
//*********************************************************************************************
 
// 433 MHz Modul hier einfügen

//******************************************************************************************* 

// Behandlung rfid3 tueroeffner an D22 und D23 des Mega einfügen
 
//******************************************************************************************** 

// Behandlung rfid-modul RDM6300

//**************************   ende loop  *****************************************************
 }
} 
//#############################################################################################
//#############################################################################################
//#############################  Unterprogramme   #############################################

void datenempfang() //Unterprogramm datenempfang: daten von ccu an homeduino senden
{command = ""; 

#if defined (w5100)  //************************************************************************
 EthernetClient client = server.available();   //mit W5100
#endif  //************************************************************************************* 

#if defined (cc3000)  //***********************************************************************
 SFE_CC3000_Client client = SFE_CC3000_Client(wifi);   //mit CC3000
#endif  //************************************************************************************* 

 if (client) // an http request ends with a blank line
   {boolean currentLineIsBlank = true;
    while (client.connected())
      {if (client.available()) 
         {char c = client.read();
          if (reading && c == ' ') reading =false;
          if (c == '?') reading = true; // beginn der Befehlssequenz 
          if (reading) 
            {if (command.length() < 100) //read char by char HTTP request
               {command = command + c; } //store characters to string
            } 
          if (c == '\n' && currentLineIsBlank) break;
          if (c == '\n') {currentLineIsBlank = true;} 
            else if (c != '\r') { currentLineIsBlank = false;}
         } 
       } 
     client.println(command);
     delay(1); 
     client.stop();
//*********************************************************************************************
    if (command.length() > 2) //behandlung Datenempfang von ccu: port auf 0/1 setzen 
      {Serial.println(command); //empfangenen befehl ausgeben
       client.print(command); //befehl dann dekodieren 
       int colonPosition = command.indexOf(':');
       sub_command = command.substring(2,colonPosition); //portpin erkennen
       Serial.print("D" + sub_command + " :");
       port_pin = sub_command.toInt();
       command = command.substring((colonPosition+1)); //Rest-command bilden
       if (((iomodus_D[port_pin] == 2)||(iomodus_D[port_pin] == 12)) && (command == "0")) 
         {for (int m=0; m < zeilenzahl; m++)
            {if (zeile_pointer[m] == port_pin) {zeile_data[m] = " LOW";}
            }
          pinMode(port_pin, OUTPUT); digitalWrite(port_pin, LOW); Serial.println(command);
         }
       if ((iomodus_D[port_pin] == 2) && (command == "1")) 
         {for (int m=0; m < zeilenzahl; m++)
            {if (zeile_pointer[m] == port_pin) {zeile_data[m] = " HIGH";}
            }
          pinMode(port_pin, OUTPUT); digitalWrite(port_pin, HIGH); Serial.println(command);}
          if ((iomodus_D[port_pin] == 7) && (port_pin ==4)) 
            {rf_send(command); Serial.println(command);} 
          if ((iomodus_D[port_pin] == 5) && (port_pin ==9)) 
            {ir_send(command); Serial.println(command);} 
      }
  } 
} 
//*********************************************************************************************
void set_sysvar() // subroutine HTTP request absetzen:
{//while (millis() < next_tx) {} //warten bis time > next_tx oder timeout
 next_tx = millis() +delta_tx;
 if (client.connect(ccu, 8181)) 
   {Serial.println(befehl);
    client.println(befehl);
    client.println();
    client.stop();
   } else {Serial.println("connection failed");}
}
//*********************************************************************************************
void rf_send(String rf_command) // subroutine rf telegramm senden
{
}
//*********************************************************************************************
void ir_send(String ir_command) // subroutine ir telegramm senden
{
}
//*********************************************************************************************
//hier sind die interrupt-service-routinen fuer die impulszaehler  //**************************
void ISR_0() //Interrupt an D2
{pulsecounter[0]++;}
void ISR_1() //Interrupt an D3
{pulsecounter[1]++;}
void ISR_2() //Interrupt an D21
{pulsecounter[2]++;}
void ISR_3() //Interrupt an D20
{pulsecounter[3]++;}
void ISR_4() //Interrupt an D19
{pulsecounter[4]++;}
void ISR_5() //Interrupt an D18 
{pulsecounter[5]++;}
//*********************************************************************************************
//Unterprogramm:  Converting from Hex (unsigned long) to Decimal: *****************************
//Quelle https://github.com/benrugg/Arduino-Hex-Decimal-Conversion/blob/master/hex_dec.ino
unsigned long hexToDec(String hexString) 
{unsigned long decValue = 0;
 int nextInt;
 for (int k = 0; k < hexString.length(); k++) 
   {nextInt = int(hexString.charAt(k));
    if (nextInt >= 48 && nextInt <= 57) nextInt = map(nextInt, 48, 57, 0, 9);
    if (nextInt >= 65 && nextInt <= 70) nextInt = map(nextInt, 65, 70, 10, 15);
    if (nextInt >= 97 && nextInt <= 102) nextInt = map(nextInt, 97, 102, 10, 15);
    nextInt = constrain(nextInt, 0, 15);
    decValue = (decValue * 16) + nextInt;
  }
 return decValue;
}

//*********************************************************************************************
void display_data() //gibt daten auf dem lcd oder tft display aus

//*********************************************************************************************
#if defined (lcd_display)  //behandlung lcd-display: erkennung des tasters und lcd-anzeige
{x = analogRead (0);  //abfrage A0
 if (x < (x_alt -100))  {tastererkennung();}
 x_alt = x; 
 for (int m = 0; m < zeilenzahl; m++)
   {while (zeile_data[m].length() < 5) {zeile_data[m] = " " + zeile_data[m];}
    if (display_message[zeile_pointer[m]] == "0") {zeile_data[m] = "                ";}
    display_zeile[m] =  display_message[zeile_pointer[m]] + zeile_data[m];
   
    if (display_zeile[m] != display_zeile_alt[m])  //datenausgabe auf display nur wenn aenderung 
      {lcd.setCursor(0,m); lcd.print (display_zeile[m]); display_zeile_alt[m] = display_zeile[m];}
   } 
} 
//*********************************************************************************************
void tastererkennung()
{if (x < 60) 
   {taster == "right"; 
    zeile_pointer[0]--;  if (zeile_pointer[0] ==1) {zeile_pointer[0] = 79;}
    while((iomodus_D[zeile_pointer[0]] ==0) || (iomodus_D[zeile_pointer[0]] >19))
         {zeile_pointer[0]--; if (zeile_pointer[0] ==1) {zeile_pointer[0] =79;} }
    EEPROM.write(0,zeile_pointer[0]);//delay(4);
   } 
   else if (x < 200) 
          {taster == "up";
           zeile_pointer[0]++;  if (zeile_pointer[0] ==80) {zeile_pointer[0] = 2;}
           while((iomodus_D[zeile_pointer[0]] ==0) || (iomodus_D[zeile_pointer[0]] >19))
               {zeile_pointer[0]++; if (zeile_pointer[0] ==80) {zeile_pointer[0] = 2;} }
           EEPROM.write(0,zeile_pointer[0]);//delay(4);
          } 
          else if (x < 400) 
                   {taster == "down";
                    zeile_pointer[1]++; if (zeile_pointer[1] ==80) {zeile_pointer[1] = 2;}
                    while((iomodus_D[zeile_pointer[1]] ==0) || (iomodus_D[zeile_pointer[1]] >19))
                         {zeile_pointer[1]++; if (zeile_pointer[1] ==80) {zeile_pointer[1] = 2;} } 
                    EEPROM.write(1,zeile_pointer[1]);//delay(4);     
                   } 
                  else if (x < 600)
                         {taster == "left";
                          zeile_pointer[1]--;
                          if (zeile_pointer[1] ==1) {zeile_pointer[1] = 79;}
                          while((iomodus_D[zeile_pointer[1]] ==0) || (iomodus_D[zeile_pointer[1]] >19))
                               {zeile_pointer[1]--; if (zeile_pointer[1] ==1) {zeile_pointer[1] =79;} }
                          EEPROM.write(1,zeile_pointer[1]);//delay(4);
                         } 
                         else if (x < 800)
                                {taster = "select";}
                                else {taster ="";}
}
#endif  //************************************************************************************* 

//*********************************************************************************************
#if defined (tft_display)  //behandlung tft toucheingabe und  display 2.4''
 {if (millis() > next_touch_time)  //touch-display abfragen
   {TSPoint p = ts.getPoint();// a point object holds x y and z coordinates
    px = p.x; py = p.y; pz =p.z;  
    pinMode(XM, OUTPUT);   pinMode(YP, OUTPUT);
    if (pz > MINPRESSURE && pz < MAXPRESSURE ) 
      {Serial.print("px : ");Serial.print( px); Serial.print("  py : " ); Serial.print(py);
       Serial.print("  pz : " ); Serial.print(pz);
       if (abs(px_B - px_A) > 100) {p_x = (1000 *(px- px_A))/(px_B -px_A); p_y = (1000 *(py - py_A))/(py_C -py_A);} 
         else {p_x = (1000 *(py -py_A))/(py_B - py_A); p_y = (1000 *(px - px_A)) /(px_C - px_A);}
       Serial.print("  p_x : ");Serial.print( p_x); Serial.print("  p_y : " ); Serial.print(p_y);
       if (p_y < 154) {touch_y = 0;}   //p_y = 1000 entspricht 6,5 Zeilen 
         else {if (p_y < 308) {touch_y = 1;}
                 else {if (p_y < 462) {touch_y = 2;}
                         else {if (p_y < 616) {touch_y = 3;}
                                 else {if (p_y < 770) {touch_y = 4;}
                                         else {touch_y = 5;}}}}}
       Serial.print("     touch_y "); Serial.print(touch_y); Serial.println();
       if (p_x < 500) {zeile_pointer_minus();}  //Serial.println(zeile_pointer[touch_y]);}
       if (p_x > 500) {zeile_pointer_plus(); }  //Serial.println(zeile_pointer[touch_y]);}
       touch_alt = touch;
      }
    for (int m = 0; m < zeilenzahl; m++)  //datenausgabe auf tft-display
      {while (zeile_data[m].length() < 7) {zeile_data[m] = " " + zeile_data[m];}
       display_zeile[m] =  display_message[zeile_pointer[m]] + zeile_data[m];
       if (display_zeile[m] != display_zeile_alt[m]) //displayausgabe nur wenn aenderung 
         {tft_print (m,display_zeile[m],schriftgroesse,WHITE); display_zeile_alt[m] = display_zeile[m];}
      }
   } 
}
//*********************************************************************************************
//mit diesem Unterprogramm wird auf dem tft display ein zeilen-display 6 x 16  emuliert
void tft_print (int line, String textline, int font_size, long int color)
{if (tft_type ==1)
   {tft.fillRect(0,38*line, 319, 38, BLACK); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(0, 38*line+6);              //und dann erst schreiben
   }
 if (tft_type ==2)
   {tft.fillRect(0,50*line, 479, 50, BLACK); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(5, 50*line+6);              //und dann erst schreiben
   }  
 tft.setTextColor(color);  
 tft.setTextSize(font_size);
 tft.print(textline);
}
//mit diesen Unterprogrammen wird der zeile_pointer im eeprom abgelegt
void zeile_pointer_plus()
{next_touch_time = millis() + 200; 
  zeile_pointer[touch_y]++;  if (zeile_pointer[touch_y] >79) {zeile_pointer[touch_y] = 2;}
 while((iomodus_D[zeile_pointer[touch_y]] ==0) || (iomodus_D[zeile_pointer[touch_y]] >19))
  {zeile_pointer[touch_y]++; if (zeile_pointer[touch_y] >79) {zeile_pointer[touch_y] = 2;} }
 EEPROM.write(touch_y,zeile_pointer[touch_y]);//delay(4);
}
void zeile_pointer_minus()
{next_touch_time = millis() + 200; 
  zeile_pointer[touch_y]--;  if (zeile_pointer[touch_y] <2) {zeile_pointer[touch_y] = 79;}
 while((iomodus_D[zeile_pointer[touch_y]] ==0) || (iomodus_D[zeile_pointer[touch_y]] >19))
   {zeile_pointer[touch_y]--; if (zeile_pointer[touch_y] <2) {zeile_pointer[touch_y] =79;}  }
 EEPROM.write(touch_y,zeile_pointer[touch_y]);//delay(4);
}      
#endif  //************************************************************************************* 



dondaik
Beiträge: 12929
Registriert: 16.01.2009, 18:48
Wohnort: Steingaden
Hat sich bedankt: 1604 Mal
Danksagung erhalten: 222 Mal

Re: Homeduino: universeller LAN/WLAN-Arduino für die Hausaut

Beitrag von dondaik » 11.05.2017, 21:51

:-) danke,
dann weiter mit viel erfolg !
-------
!!! der download der handbüchern auf den seiten von eq3 und das lesen der tips und tricks kann das hm-leben sehr erleichtern - das nutzen der suche nach schlagworten ebenso :mrgreen: !!!
wer schreibfehler findet darf sie behalten.

Ardubert Homedu
Beiträge: 142
Registriert: 17.07.2016, 10:40
Hat sich bedankt: 3 Mal
Danksagung erhalten: 1 Mal

Re: Homeduino: universeller LAN/WLAN-Arduino für die Hausaut

Beitrag von Ardubert Homedu » 27.06.2017, 10:41

Hallo,

Ist es auch nötig:
Vergrößerung des seriellen RX Puffers auf 256Byte in der Arduino IDE
auszuführen wenn nichts an das TFT gesendet werden soll??

kann man sagen das der neue Code mit den anpassungen Vers.5 von SciBee
so stabil läuft wie der 412 bzw 414??
Oder ist das jetzt die offiziell angekündigte v5??
Bei mir rennen einige Monatelang ohne jegliche kümmerei bis jetzt
sehr zuverlässig,, das möchte ich natürlich nicht aufs spiel setzen :wink: ....

mir geht es eigentlich nur um die Wlan anbindung ohne cc3000
und ich hab noch irgendwo ein par von diesen espModulen die
ich anfänglich mal bestellt habe für den HD, die aber ja dann
nicht fertig integriert waren.

mfg.

Flo

SciBee hat geschrieben:Hier nun eine überarbeitete Version des Codes.
Die Verbindung zur CCU ist nun stabiler und es können auch ganze Textzeilen an das Display gesendet werden.
Dazu ist aber eine Vergrößerung des seriellen RX Puffers auf 256Byte in der Arduino IDE nötig.
Wie das geht ist prinzipiell hier beschrieben: http://www.hobbytronics.co.uk/arduino-s ... uffer-size
Allerdings müssen ein paar Details angepasst werden. So muss man die HardwareSerial.h editieren und nicht die HardwareSerial.cpp und die liegt bei mir unter "C:\Users\[Benutzername]\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.17\cores\arduino" (vor der core-Kopie).

Code: Alles auswählen

#if !defined(SERIAL_TX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_TX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#endif
#endif
#if !defined(SERIAL_RX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_RX_BUFFER_SIZE 16
#else
#define SERIAL_RX_BUFFER_SIZE 256
#endif
#endif
#if (SERIAL_TX_BUFFER_SIZE>256)
Die Einträge müssen natürlich für den Mega und nicht für den Uno gemacht werden.
Dazu kopiert man unter dem Abschnitt "mega.name=Arduino/Genuino Mega or Mega 2560" in der boards.txt (C:\Users\[Benutzername]\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.17\boards.txt) folgenden Abschnitt rein nachdem man das ...\cores\arduino Verzeichnis nach ...\cores\arduino_256_serialbuffer kopiert hat:

Code: Alles auswählen

##############################################################

mega256.name=Arduino Mega 2560 265kB SerialBuffer

mega256.vid.0=0x2341
mega256.pid.0=0x0010
mega256.vid.1=0x2341
mega256.pid.1=0x0042
mega256.vid.2=0x2A03
mega256.pid.2=0x0010
mega256.vid.3=0x2A03
mega256.pid.3=0x0042
mega256.vid.4=0x2341
mega256.pid.4=0x0210
mega256.vid.5=0x2341
mega256.pid.5=0x0242

mega256.upload.tool=avrdude
mega256.upload.maximum_data_size=8192

mega256.bootloader.tool=avrdude
mega256.bootloader.low_fuses=0xFF
mega256.bootloader.unlock_bits=0x3F
mega256.bootloader.lock_bits=0x0F

mega256.build.f_cpu=16000000L
mega256.build.core=arduino_256_serialbuffer
mega256.build.variant=mega
# default board may be overridden by the cpu menu
mega256.build.board=AVR_MEGA2560

## Arduino/Genuino Mega w/ ATmega2560
## -------------------------
mega256.menu.cpu.atmega2560=ATmega2560 (Mega 2560)

mega256.menu.cpu.atmega2560.upload.protocol=wiring
mega256.menu.cpu.atmega2560.upload.maximum_size=253952
mega256.menu.cpu.atmega2560.upload.speed=115200

mega256.menu.cpu.atmega2560.bootloader.high_fuses=0xD8
mega256.menu.cpu.atmega2560.bootloader.extended_fuses=0xFD
mega256.menu.cpu.atmega2560.bootloader.file=stk500v2/stk500boot_v2_mega2560.hex

mega256.menu.cpu.atmega2560.build.mcu=atmega2560
mega256.menu.cpu.atmega2560.build.board=AVR_MEGA2560


##############################################################
Dann startet man die IDE neu und wählt als Board den neuen ATMega mit 256k SerialBuffer aus.
Ein Umprogrammieren des ESP-01 ist nicht nötig. Sowohl die Espressif wie auch die AI Tinker FW funktionieren bei mir.

Ich habe Eugen's erstes ESP-01 WiFi Shield mit dem Code getestet. Hat astrein funktioniert! Sogar bis 250kBaud - da hat dann aber der RX Puffer wieder nicht gereicht, weil der Mega zu langsam ist. Ich bin daher bei der Default Rate von 115200Baud geblieben.
Der Code ist für das Elegoo Display eingestellt. Wer andere Displays hat muss den Code eben an den entsprechenden Stellen modifizieren.

Code: Alles auswählen

const String Version = "hduino504_ESP_SciBee";  /*Stand: 12.03.2017 / Verfasser: Eugen Stall/SciBee
erprobt fuer Arduino Mega 2560 mit Arduino 1.6.13
hier ist immer die aktuelle V4.x Basis-Version:
http://www.stall.biz/project/homeduino-4-0-das-universelle-mess-und-aktormodul-fuer-die-hausautomation
das folgende homeduino-programm sendet messdaten zur ccu (homeduino als webclient) ...
und empfängt ausgabedaten für die homeduino-outputs (homeduino als webserver)

_________________            ________________
|port 8181 server|<---------<| client        |
|                |           |               |
| CCU            |           |     Homeduino | 
|                |           |               |
|          client|>--------->|server port 80 | 
|________________|           |_______________|

/Quellen:Arduino website plus http://arduino.cc/en/Tutorial/WebClient und ...
 http://tushev.org/articles/arduino/item/52-how-it-works-ds18b20-and-arduino und ...  

Intrudeced a command type parameter to adress different functions in the CCU/HD communication:
D controls Data operations e.g. control outputs - same behaviour as in versions < 5
T goes to text - displays a line of text in controlable size and color
C goes to Clock - sets the internal software clock. No additional hardware RTC required.

Example textline with a TFT display: 'http://123.456.789.123/?T0:This is a test,2,CYAN'
Syntax: http://[Homeduino_IP]/?T[linenumber 0...7]:[text with spaces],[fontsize 1...4],[textcolor] 
Maximum size is 100 characters including the fontsize, textline number and color value including the format commas
because of the tft_print textline String buffer. 
Remember: a 'Space' already consumes 3 characters because the browser translates it to '%20'!

Example setting the clock via browser: http://123.456.789.123/?C:27.05.2017,23:56:57 sets the internal clock of Homeduino at IP 123.456.789.123 to
Day: 27, Month: 05, Year: 2017, Hour: 23, Minute: 56, Second 57
You may use any separating character you like instead of dots or commas as the positions in the command are used.
the date is not increased automatically when midnight is over! This relies on the CCU clock. 
Update the clock via script every hour because the software clock in the HD is not very precise.

Example textline with LCD Display: 'http://123.456.789.123/?T0:0123456789ABCDEF' max. 16 characters
Syntax: http://[Homeduino_IP]/?T[linenumber 0...1]:[text with spaces] 
No fontsize or color parameters of course.

Example setting port D22 of Homeduino to "0" (Low) via browser: http://123.456.789.123/?D22:0
Same behaviour as before.

Example set a systemvariable in your CCU via browser:
http://123.456.789.123:8181/xy.exe?antwort=dom.GetObject('homeduino_001_IP').State('123.456.789.124')
which sets the varable named 'homeduino_001_IP' to the value '123.456.789.124'
 */
//#############################################################################################
//#############################################################################################
//Auswahl der verwendeten Shields: 
#define tft_display //"tft_display" oder "lcd_display"                         <<user-eingabe<< 
                    //"lcd_display" auch wenn kein display verwendet wird 
                    // TFT display details are defined starting near line 350.   <<user-eingabe<<
                    // Enable the sequence mating your TFT!!!

#define esp8266       //"cc3000"  Wifi-Modul or "w5100" ethernet shield or "esp8266" WiFi      <<user-eingabe<< 

//#define DEBUG //enable if you want to see more verbose output at the serial debug port
//#define ShowSeconds //enable if you want the clock to show seconds 12:34:56 elses it shows just 12:34

const byte ccu[4] = { 123, 456, 789, 123 };      //IP der CCU                                      <<user-eingabe<< 

//MAC-Adresse dieses Homeduinos ,bei mehreren Homeduinos MAC-.Adresse ändern!!:
// no need for a user specified MAC adress at ESP8266. ESP-01 has a preprogrammed MAC
const byte mac[6] = { 0x00, 0x10, 0x13, 0x00, 0x26, 0x07 };  //                                 <<user-eingabe<<

const byte homeduino[4] = { 123, 456, 789, 124 }; //IP des Homeduino,wenn DHCP versagt             <<user-eingabe<< 

const char ap_ssid[] = "myWLAN_SSID"; //SSID WLAN in Anführungszeichen                              <<user-eingabe<< 

const char ap_password[] = "myPassword"; //Passwort WLAN in Anführungszeichen         <<user-eingabe<< 

//xyz ist indiv. Bezeichnung dieses homeduino, keine sonderzeichen, öäüß...
const String homeduino_nummer = "001";  //                                                      <<user-eingabe<< 
const String hm_systemvariable = "homeduino_" + homeduino_nummer +"_";
//#############################################################################################
//#############################################################################################
//I/O-Kennung: hier wird die Funktion aller verwendbaren IO´s mit einer Kennziffer festgelegt 
//dabei haben alle IO´s die Standardfunktionen plus spez. Sonderfunktionen
//     Standardfunktionen sind:
//     '0' =andere Nutzg; '1' =dig_in; '2' =dig_out; '3' =1wire '4' =DHTxx; '5' =U_Schall; '17' = date and time; '18' =reserved line for text from CCU
//     6 textlines from CCU are activated in No 80...85 because there is no physical I/O beyond 79

const byte iomodus_D[87] = { 0,0,
 31, //D2 :      Std-fkt; '15' = IR_Rx??  '6' =ImpCount; '31' =tft;   <<user IO-Shield20<< 
 31, //D3 :      Std-fkt; '7' = 433_Rx??  '6' =ImpCount; '31' =tft;   <<user IO-Shield20<< 
 31, //D4 :      Std-fkt; '7' = 433_Tx??  '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D5 :      Std-fkt;                 '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D6 :      Std-fkt; '9' = buzzer    '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D7 :      Std-fkt;                 '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D8 :      Std-fkt;                 '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D9 :      Std-fkt; '16' = IR_Tx??  '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 0, //D10 :     Std-fkt; '20' = W5100 SS-Pin;
 0,  //D11 :     Std-fkt;  
 2,  //D12 :     Std-fkt;  
 2,  //D13 :     Std-fkt;
 0,  //D14/TX3 : Std-fkt; '0' =ESP8266;   '12' = rfid3;                <<user IO-Shield-Plus<< 
 0,  //D15/RX3 : Std-fkt; '0' =ESP8266;   '12' = rfid3;                <<user IO-Shield-Plus<< 
 0,  //D16/TX2 : Std-fkt; '0' =ESP8266;   '12' = rfid2;                <<user IO-Shield-Plus<< 
 0,  //D17/RX2 : Std-fkt; '0' =ESP8266;   '12' = rfid2;                <<user IO-Shield-Plus<< 
 0,  //D18/TX1 : Std-fkt; '6' =ImpCount;  '21' =CC3000                 <<user IO-Shield-Plus<< 
 0,  //D19/RX1 : Std-fkt; '6' =ImpCount;                               <<user IO-Shield-Plus<< 
 0,  //D20/SDA : Std-fkt; '6' =ImpCount;  '8' =I2C;                    <<user IO-Shield-Plus<< 
 0,  //D21/SCL : Std-fkt; '6' =ImpCount;  '8' =I2C;                    <<user IO-Shield-Plus<< 
 0,  //D22 :     Std-fkt; Resrved for ESP-01 reset;                        <<user IO-Shield-Plus<< 
 2,  //D23 :     Std-fkt; '12' = rfid2-oeffner;                        <<user IO-Shield-Plus<< 
 1,  //D24 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 0,  //D25 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 5,  //D26 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 0,  //D27 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 0,  //D28 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 4,  //D29 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 20, //MISO      '20' =W5100;  '21' =CC3000;   ICSP-Stecker
 20, //MOSI      '20' =W5100;  '21' =CC3000;   ICSP-Stecker
 20, //SCK       '20' =W5100;  '21' =CC3000;   ICSP-Stecker
 0, //SS                      '21' =CC3000;
 31, //D54 A0 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft; '30' =lcd; ser IO-Shield-20<< 
 31, //D55 A1 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft;         <<user IO-Shield-20<< 
 31, //D56 A2 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft;         <<user IO-Shield-20<< 
 31, //D57 A3 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft;         <<user IO-Shield-20<< 
 31, //D58 A4 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft;         <<user IO-Shield-20<< 
 0,  //D59 A5 :  Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-20<< 
 0,0,  
 0,  //D62 A8 :  Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D63 A9 :  Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D64 A10 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D65 A11 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D66 A12 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D67 A13 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D68 A14 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D69 A15 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;    '8' =I2C;                               <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;    '8' =I2C;                               <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;    '8' =I2C;                               <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;    '8' =I2C;                               <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 18, // '18' = reserved for text sent from CCU
 18, // '18' = reserved for text sent from CCU
 18, // '18' = reserved for text sent from CCU
 18, // '18' = reserved for text sent from CCU
 18, // '18' = reserved for text sent from CCU
 18, // '18' = reserved for text sent from CCU
 17  // '17' = reserved for date and time
}; 
//#############################################################################################
//hier werden Sensoren am I2C-Eingang aktiviert
const byte iomodus_baro = 0; //'0' =nc; '1' =BMP180,                   <<user IO-Shield-Plus<<
const byte iomodus_lux =  0; //'0' =nc; '1' =BH1750,                   <<user IO-Shield-Plus<<
//#############################################################################################
//hier werden die Kennwerte fuer die Impulszaehler festgelegt
volatile unsigned long pulsecounter[6] = 
{ 0, //Zaehlerstand fuer D2 -Impulseingang bei Reset                    <<user IO-Shield20<<
 0, //Zaehlerstand fuer D3 -Impulseingang bei Reset                     <<user IO-Shield20<<
 0, //Zaehlerstand fuer D21-Impulseingang bei Reset                     <<user IO-Shield-Plus<< 
 3, //Zaehlerstand fuer D20-Impulseingang bei Reset                     <<user IO-Shield-Plus<< 
 4711, //Zaehlerstand fuer D19-Impulseingang bei Reset                  <<user IO-Shield-Plus<< 
 5 //Zaehlerstand fuer D18-Impulseingang bei Reset                      <<user IO-Shield-Plus<< 
}; 
//hier wird der Teilerfaktor für die Impulszaehler festgelegt
const int pulsedivider[6] = 
{6, //Teilerfaktor D2 :                                                 <<user IO-Shield20<<
 1, //Teilerfaktor D3 :                                                 <<user IO-Shield20<<
 1, //Teilerfaktor D21 :                                                <<user IO-Shield-Plus<<
 1, //Teilerfaktor D20 :                                                <<user IO-Shield-Plus<<
 2, //Teilerfaktor D19 :                                                <<user IO-Shield-Plus<<
 1, //Teilerfaktor D18 :                                                <<user IO-Shield-Plus<<
}; 
//#############################################################################################
//#############################################################################################
//hier werden die anzeigetexte für das tft und lcd display festgelegt 
//Default message placeholder are at #80...#85
const String display_message[87] = {
"0","0",         //                              '0' =keine anzeige
"beweg tuer:    ",  //anzeigetext fuer port D02
"beweg gart:    ",  //anzeigetext fuer port D03
"0","0","0","0","0","0",  // ports belegt durch lcd-shield     
"0",  // belegt durch ethernet W5100-shield, lcd-Shield PIN D10 abbiegen! 
"11 Status :  ",  //anzeigetext fuer port D11                             <<user IO-Shield-20<<
"12 Status :  ",  //anzeigetext fuer port D12                             <<user IO-Shield-20<<
"13 Status :  ",  //anzeigetext fuer port D13                             <<user IO-Shield-20<<
"14 Status :  ",  //anzeigetext fuer port D14 /TX3                        <<user IO-Shield-Plus<<
"RFID Tuer :  ",  //anzeigetext fuer port D15 /RX3                        <<user IO-Shield-Plus<<
"16 Status :  ",  //anzeigetext fuer port D16 /TX2                        <<user IO-Shield-Plus<<
"RFID Gara :  ",  //anzeigetext fuer port D17 /RX2                        <<user IO-Shield-Plus<<
"18 Status :  ",  //anzeigetext fuer port D18 /TX1 /impulszaehler S03     <<user IO-Shield-Plus<<
"19 gas/m3 :  ",  //anzeigetext fuer port D19 /RX1 /impulszaehler S02     <<user IO-Shield-Plus<<
"21 I2C SDA:  ",  //anzeigetext fuer port D20 /SDA /impulszaehler S01     <<user IO-Shield-Plus<<
"21 I2C SCL:  ",  //anzeigetext fuer port D21 /SCL /impulszaehler S00     <<user IO-Shield-Plus<<
"22 ESP-01 :  ",  //anzeigetext fuer port D22                             <<user IO-Shield-Plus<<
"Ladegeraete:  ",  //anzeigetext fuer port D23                            <<user IO-Shield-Plus<<
"24 Bewegt :  ",  //anzeigetext fuer port D24                             <<user IO-Shield-Plus<<
"25 Status :  ",  //anzeigetext fuer port D25                             <<user IO-Shield-Plus<<
"26 Abstand:  ",  //anzeigetext fuer port D26                             <<user IO-Shield-Plus<<
"27 Status :  ",  //anzeigetext fuer port D27                             <<user IO-Shield-Plus<<
"28 DS18B20:  ",  //anzeigetext fuer port D28                             <<user IO-Shield-Plus<<
"29 T_DHT22:  ",  //anzeigetext fuer port D29                             <<user IO-Shield-Plus<<
"0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0",
"0",  // port belegt durch lcd-shield
"Temp_auss.:  ",  //anzeigetext fuer port D55 /A1                         <<user IO-Shield-20<<
"Temp_innen:  ",  //anzeigetext fuer port D56 /A2                         <<user IO-Shield-20<<
"57 Status :  ",  //anzeigetext fuer port D57 /A3                         <<user IO-Shield-20<<
"58 Status :  ",  //anzeigetext fuer port D58 /A4                         <<user IO-Shield-20<<
"59 Spg_A5 :  ",  //anzeigetext fuer port D59 /A5                         <<user IO-Shield-20<<
"0","0",
"62 Status :  ",  //anzeigetext fuer port D62 /A8                         <<user IO-Shield-Plus<<
"63 Status :  ",  //anzeigetext fuer port D63 /A9                         <<user IO-Shield-Plus<<
"64 Status :  ",  //anzeigetext fuer port D64 /A10                        <<user IO-Shield-Plus<<
"65 Status :  ",  //anzeigetext fuer port D65 /A11                        <<user IO-Shield-Plus<<
"66 Status :  ",  //anzeigetext fuer port D66 /A12                        <<user IO-Shield-Plus<<
"67 Status :  ",  //anzeigetext fuer port D67 /A13                        <<user IO-Shield-Plus<<
"68 Status :  ",  //anzeigetext fuer port D68 /A14                        <<user IO-Shield-Plus<<
"Abstand/cm:  ",  //anzeigetext fuer port D69 /A15                        <<user IO-Shield-Plus<<
// die folgenden Anzeigetexte sind für Module mit mehreren Datenpunkten z.b. I2C-Module
"L-Druck/mB:  ",  //anzeigetext fuer I2C 
"L-Temp./C :  ",  //anzeigetext fuer I2C 
"Lux/lx    :  ",   //anzeigetext fuer I2C 
"UV-Index  :  ",  //anzeigetext fuer I2C
"74 Status :  ",  //anzeigetext fuer 
"75 Status :  ",  //anzeigetext fuer 
"76 Status :  ",  //anzeigetext fuer 
"77 Status :  ",  //anzeigetext fuer 
"78 Status :  ",  //anzeigetext fuer 
"79 Status :  ",   //anzeigetext fuer   
"Text 1", //Anzeigetext 1 von CCU
"Text 2", //Anzeigetext 2 von CCU
"Text 3", //Anzeigetext 3 von CCU
"Text 4", //Anzeigetext 4 von CCU
"Text 5", //Anzeigetext 5 von CCU
"Text 6", //Anzeigetext 6 von CCU
"Zeit: " // Default text time and date
};
//#############################################################################################
//#############################################################################################
//hier werden die Zugangsberechtigungen für den RDM6300 Rfid-Reader und FOBs festgelegt
const byte fob_anzahl = 20;
const String fob[3*fob_anzahl] = {
"2381286","eugen","1",   // '0' = kein Tueroeffner                      <<user IO-Shield-Plus<<
"2381287","eugen","1",   // '1' = Tueroeffner1 D22                      <<user IO-Shield-Plus<<
"2381381","eugen","2",   // '2' = Tueroeffner2 D23                      <<user IO-Shield-Plus<<
"2380830","leonie","3",  // '3' = beide Tueroeffner                     <<user IO-Shield-Plus<<
"2409284","fabian","2"   //                                             <<user IO-Shield-Plus<<
"2409385","fabian","2"   //                                             <<user IO-Shield-Plus<<
"2409289","fabian","2"   //                                             <<user IO-Shield-Plus<<
"2519298","not used","0" //                                             <<user IO-Shield-Plus<<
"2519208","not used","0" //                                             <<user IO-Shield-Plus<<
"2519388","not used","0" //                                             <<user IO-Shield-Plus<<
"2519488","not used","0" //                                             <<user IO-Shield-Plus<<
"2511288","not used","0" //                                             <<user IO-Shield-Plus<<
"2529288","not used","0" //                                             <<user IO-Shield-Plus<<
"2619288","not used","0" //                                             <<user IO-Shield-Plus<<
"2719288","not used","0" //                                             <<user IO-Shield-Plus<<
"3519208","not used","0" //                                             <<user IO-Shield-Plus<<
"2519088","not used","0" //                                             <<user IO-Shield-Plus<<
"2519088","not used","0" //                                             <<user IO-Shield-Plus<<
"2510288","not used","0" //                                             <<user IO-Shield-Plus<<
"2510288","not used" "0" //                                             <<user IO-Shield-Plus<<
};
const unsigned long unlock_time1 = 5000; //oeffnungszeit rfid1 in ms    <<user IO-Shield-Plus<<
const unsigned long unlock_time2 = 5000; //oeffnungszeit rfid2 in ms    <<user IO-Shield-Plus<<
const boolean oeffner_polarity = 1;   // '1' normal, '0'  invers        <<user IO-Shield-Plus<<
//#############################################################################################
//#############################################################################################
//#############################################################################################

#include <SPI.h>
#include <Wire.h> 
#include <OneWire.h>   //für Temperatursensoren DS18B20
                       //http://www.hacktronics.com/code/OneWire.zip
#include <NewPing.h>   //für Ultraschallsensoren SR04
                       //https://arduino-new-ping.googlecode.com/files/NewPing_v1.5.zip
#include "DHT.h"       //für Temperatursensoren SHT22
                       //https://github.com/adafruit/DHT-sensor-library/archive/master.zip
#include <AS_BH1750.h> //für I2C-Luxmeter
                       //https://github.com/hexenmeister/AS_BH1750/archive/master.zip
#include <SFE_BMP180.h>//für I2C-Barometer
                       //https://github.com/sparkfun/BMP180_Breakout/archive/master.zip
#include <RCSwitch.h>  // läuft noch nicht!
#include <EEPROM.h>

#include <WiFiEsp.h>   //https://github.com/bportaluri/WiFiEsp
                       //für ESP-01 Modul

//#include <IRremote.h>// läuft noch nicht!

//der folgende Bereich ist bei verwendung w5100 auszukommentieren
//ausblenden mit " #if defined (5100)" funktioniert leider nicht!! 
/*
//Initialisierung des CC3000 Wifi auf dem IO-Shield-Plus  
#include <SFE_CC3000.h>// fuer cc3000 wifi
                 // http://github.com/sparkfun/SFE_CC3000_Library/archive/master.zip
#include <SFE_CC3000_Client.h>
// Pins
#define CC3000_INT 18  // int-Pin mit Wifi Shield ist D3, mit breakout auf IO-Shield-Plus D18
#define CC3000_EN 46   // en-Pin mit Wifi Shield ist D5, mit breakout auf IO-Shield-Plus  D46
#define CC3000_CS 53   // cs-Pin mit Wifi Shield ist D10, mit breakout auf IO-Shield-Plus D53
SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS);
SFE_CC3000_Client client = SFE_CC3000_Client(wifi);
unsigned int ap_security = WLAN_SEC_WPA2; // Security of network
unsigned int timeout = 30000; // Milliseconds
char server[] = "192,168,178,50"; // Remote host site
*/
#if defined (w5100)  //************************************************************************ 
//der folgende Bereich ist die Initialisierung des LAN bei Verwendung des LAN-Shields
#include <Ethernet.h> 
EthernetClient client;
EthernetServer server(80);
#endif  //************************************************************************************* 

#if defined (esp8266)
    WiFiEspClient client;
    WiFiEspServer server(80);
#endif 
    unsigned long reqCount = 0;

#if defined(tft_display)  //*******************************************************************
#include <Adafruit_GFX.h>    //Quelle: https://github.com/adafruit/Adafruit-GFX-Library
#include <Adafruit_TFTLCD.h> //Quelle:   https://github.com/buhosoft/TFTLCD-Library
#include <stdint.h>
#include "TouchScreen.h"      
//Quelle: http://www.smokeandwires.co.nz/blog/a-2-4-tft-touchscreen-shield-for-arduino/

#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0
#define tft_rotation 3 //3 oder 1 abhägig vom tft-shield typ  Achtung! bei 3 und IL9327 Offset beobachtet   <<user-eingabe<< 
#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin


Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
int touch_y;
const byte zeilenzahl = 6; //set 6 for ...x240 displays, set 8 for ...x320 displays 
int px,py,pz;
unsigned long next_touch_time = 0; 
int fontgroesse;
int espbyte = 0;
boolean centertouch = 1;
boolean receivingcommand = false;

//2,4'' display 320x240
/*
const long int px_A = 901,  py_A = 183;  //touch-koordinaten oben-links                
const long int px_B = 192,  py_B = 189;  //touch-koordinaten oben-rechts              
const long int px_C = 936,  py_C = 860;  //touch-koordinaten unten-links              
#define schriftgroesse 3 
#define tft_type 1   // 1 ist 2,4''display   2 ist 3.95''display
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 330);
*/
/*
//3,95'' display 480x320
const long int px_A = 302, py_A = 890;  //touch-koordinaten oben-links               
const long int px_B =280,  py_B = 115;  //touch-koordinaten oben-rechts             
const long int px_C =842,  py_C = 900;  //touch-koordinaten unten-links              
#define schriftgroesse 4  
#define tft_type 2   // 1 ist 2,4''display   2 ist 3.95''display
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 330);
*/
/*
//3,5'' display 400x240 controller: IL9327
const long int px_A = 946,  py_A = 135;  //touch-koordinaten oben-links                
const long int px_B = 76,   py_B = 118;  //touch-koordinaten oben-rechts              
const long int px_C = 953,  py_C = 893;  //touch-koordinaten unten-links              
#define schriftgroesse 3 
#define tft_type 3   // 1 ist 2,4''display   2 ist 3.95''display   3 ist 3,5" Display
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 330);
*/
/*
//3,5'' display 480x320 controller: IL9341
const long int px_A = 980,  py_A = 110;  //touch-koordinaten oben-links                
const long int px_B = 83,   py_B = 127;  //touch-koordinaten oben-rechts              
const long int px_C = 957,  py_C = 909;  //touch-koordinaten unten-links              
#define schriftgroesse 3 
#define tft_type 4   // 1 ist 2,4''display   2 ist 3.95''display   3 ist 3,5" Display
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 330);
*/

//2,8'' display 320x240 Elegoo controller: IL9341
//https://www.amazon.de/gp/product/B01EUVJYME?ref%5F=pe%5F386171%5F51767411%5FTE%5Fdp%5F2&pldnSite=1
const long int px_A = 148,  py_A = 96;  //touch-koordinaten oben-links                
const long int px_B = 135,  py_B = 914;  //touch-koordinaten oben-rechts              
const long int px_C = 913,  py_C = 103;  //touch-koordinaten unten-links              
#define schriftgroesse 2 
#define tft_type 5   // 1 ist 2,4''display   2 ist 3.95''display   3 ist 3,5" Display
#define YP A3 // must be an analog pin, use "An" notation!
#define XM A2 // must be an analog pin, use "An" notation!
#define YM 9  // can be a digital pin
#define XP 8  // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);


// color definitions for e.g. ILI9327 TFT, tft_type == 3 or 5
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

// color definitions for e.g. ILI9341 TFT tft_type == 4
//#define BLACK   0xFFFF  
//#define BLUE    0xFFE0 
//#define RED     0x07FF 
//#define GREEN   0xF81F 
//#define CYAN    0xF800 
//#define MAGENTA 0x07E0 
//#define YELLOW  0x001F 
//#define WHITE   0x0000 

#define default_color WHITE //standard text color on TFTs   <-- User Eingabe


long int p_x, p_y ;   //normierte aktuelle touch-koordinaten: 
                      //oben links ist 0,0 und unten rechts ist 1000,1000
#endif  //*************************************************************************************

#if defined(lcd_display)  //*******************************************************************
//https://www.dfrobot.com/wiki/index.php?title=Arduino_LCD_KeyPad_Shield_%28SKU:_DFR0009%29
#include <LiquidCrystal.h> 
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // initialize library with numbers of the interface pins
const byte zeilenzahl = 2;
#endif  //*************************************************************************************

int x, x_alt;
byte zeile_pointer[8];
String zeile_data[8] = {"     ","     ","     ","     ","     ","     ","     ","     "};
String display_zeile_alt[8],display_zeile[8];
int text_line;
String text_content = "";
long int text_farbe;
String taster;

char zeichen,buffer[50];
boolean fob_da =0;
String zeich, fob_hex, fob_dec,Name, lcd_rfid_message, oeffner, Value;
unsigned long fob_zahl,time_rfid3 = 0,time_rfid2 = 0; 
byte zeichen_zahl;

//********************************************************************************************* 
AS_BH1750 sensor; //Initialize BH1750 Luxmeter library
float lux;
long Lux;
int laenge;
const float ALTITUDE = 299.0; // eigene seehoehe in metern              <<user IO-Shield-Plus<<
SFE_BMP180 pressure;
char status;
double T,P,p0;
boolean reading = false;
String command = "";

String baro_string,baroT_string, lux_string;
//********************************************************************************************* 
boolean last_digital_value_D[88];
float last_value_D[88],last_IR_value,last_RF_value;
unsigned long next_Time[88];  
double last_baro_value,last_baroT_value;
boolean complete_loop =1; // wenn 1, dann einmal komplett durchlaufen
String befehl,sub_command = String(20),parameter = String(20),header = String(20);
int param,port_pin;
boolean port_data;
boolean value;
String I;
int analogwert;
//********************************************************************************************* 
float tempNTC;
const float B_wert = 3950; //aus dem Datenblatt des NTC //<<user-eingabe<<
const float Tn = 298.15; //25°Celsius in °Kelvin 
const float Rv = 10000; //Vorwiderstand
const float Rn = 10000; //NTC-Widerstand bei 25°C
float Rt,temp_tur,humidity;
 
const float delta_onewire = 0.2; //Deltas für Sendeauslösung 
const float delta_DHT = 0.2; //in °C 
const float delta_us = 5.0; // in cm
const float delta_analog = 2.0; // in inkrement
const float delta_ntc = 0.5; //in °C
const float delta_lux = 15; //in lux
const float delta_counter = 5; //in counter inkrement
const double delta_baro = 0.5; //in mB
const double delta_baroT = 0.5; //in °C
 
long duration, cm; //variable für Ultraschallsensor
unsigned long time_sr04;
 
unsigned long next_full_loop = 0;
unsigned long delta_time = 3600000; // jede Stunde werden alle Inputs aktualisiert
unsigned long delta_tx = 200; //in ms, minimaler Abstand der Telegramme an die CCU
unsigned long next_tx = 0, time_wait = 0; 

int rf_key;
String rfkey;
RCSwitch mySwitch = RCSwitch();

unsigned zaehlwert;
unsigned last_zaehlwert[6] = {0,0,0,0,0,0};

unsigned long previousMillis = 0,  years = 0;
unsigned int seconds = 0, minutes = 0, hours = 0, days = 0, months = 0;
//#############################################################################################
//#############################################################################################
void setup() 
{Serial.begin(115200); 
 command.reserve(100); // reserve memory for the CCU text to avoid memory fragmentation and buffer overruns. Remember: Space becomes %20 (3 characters) instead of one character
                       // %20 is replaced by ' ' AFTER transmission
text_content.reserve(60);
previousMillis = millis();
 
//+++++++ einrichtung der interrupts fuer impulszahler D2,D3,D18,D19,D20,D21
 if ((pulsedivider[0] > 0) && (iomodus_D[2] == 6)) 
   {pinMode(2, INPUT_PULLUP); attachInterrupt(0, ISR_0, FALLING);}
 if ((pulsedivider[1] > 0) && (iomodus_D[3] == 6)) 
   {pinMode(3, INPUT_PULLUP); attachInterrupt(1, ISR_1, FALLING);} 
 if ((pulsedivider[2] > 0) && (iomodus_D[21] == 6)) 
   {pinMode(21, INPUT_PULLUP); attachInterrupt(2, ISR_2, FALLING);}
 if ((pulsedivider[3] > 0) && (iomodus_D[20] == 6)) 
   {pinMode(20, INPUT_PULLUP); attachInterrupt(3, ISR_3, FALLING);}
 if ((pulsedivider[4] > 0) && (iomodus_D[19] == 6)) 
   {pinMode(19, INPUT_PULLUP); attachInterrupt(4, ISR_4, FALLING);}

 #if defined (w5100)  //************************************************************************* 
 if ((pulsedivider[5] > 0) && (iomodus_D[18] == 6))  //interrupt reserviert fuer cc3000
   {pinMode(18, INPUT_PULLUP); attachInterrupt(5, ISR_5, FALLING);}
 #endif  //*************************************************************************************

//+++++++ rfid initialisieren
// if ((iomodus_D[15] == 12) && (iomodus_D[14] == 12)){Serial3.begin(9600);}
// if ((iomodus_D[17] == 12) && (iomodus_D[16] == 12)){Serial2.begin(9600);}

#if defined (lcd_display)  //******************************************************************
//+++++++ lcd initialisieren
 lcd.begin(16, 2); delay(200);  //16 zeichen in 2 zeilen
 lcd.setCursor(0,0);
 lcd.print(F(" Homeduino 5.04 "));
 #endif  //*************************************************************************************

#if defined (tft_display)  //******************************************************************
//+++++++ tft initialisieren
 tft.reset();
 int identifier = tft.readID();  
 if (identifier == 0)
  {Serial.print(F("Unknown LCD driver chip: "));
    Serial.println(identifier, HEX);
    Serial.print(F("I try use ILI9341 LCD driver "));
    identifier = 0x9341;
  }
 tft.begin(identifier);
 Serial.print(F("TFT identifier:" )); Serial.println(identifier, HEX);   
 delay(100);
 tft.fillScreen(BLACK); tft.setRotation(tft_rotation);
 if (tft_type ==1) //2,4'' display 320x240
   {tft_print (1,"  Homeduino",4,YELLOW);
    tft_print (2,"     5.04",4,YELLOW);
    tft_print (5,"www.stall.biz",4,CYAN);
    tft.drawRect(0,0, 319, 240, GREEN);
   } 
  if (tft_type ==2)  //3,95'' display 480x320
   {tft_print (1,"   Homeduino",5,YELLOW);
    tft_print (2,"      5.04",5,YELLOW);
    tft_print (5," www.stall.biz",5,CYAN);
    tft.drawRect(5,5, 475, 310, GREEN);
   }   
if (tft_type ==3) //3,5'' display 400x240
   {tft_print (1,"  Homeduino",5,YELLOW);
    tft_print (2,"     5.04",5,YELLOW);
    String wlan_ssid = " Connecting to WLAN: " + String::String(ap_ssid);
    tft_print (4,wlan_ssid,2,WHITE);
    tft_print (5,"  www.stall.biz",4,CYAN);
    tft.drawRect(0,0, 399, 239, GREEN);
   } 
if (tft_type ==4) //3,5'' display 480x320
   {tft.fillScreen((BLACK));
    tft_print (1,"   Homeduino",5,(YELLOW));
    tft_print (2,"      5.04",5,(YELLOW));
    String wlan_ssid = " Connecting to WLAN: " + String::String(ap_ssid);
    tft_print (4,wlan_ssid,2,(WHITE));
    tft_print (5,"   www.stall.biz",4,CYAN);
    tft.drawRect(0,0, 480, 320, (GREEN));
//
  #ifdef DEBUG
    Serial.println(F("Printing colored rectangles to check the color definitions:"));
    Serial.println(F("BLACK, BLUE, RED, GREEN, CYAN, MAGENTA, YELLOW, WHITE"));
    tft.fillRect(125,280, 20, 20, (BLACK));
    tft.fillRect(155,280, 20, 20, (BLUE));
    tft.fillRect(185,280, 20, 20, (RED));
    tft.fillRect(215,280, 20, 20, (GREEN));
    tft.fillRect(245,280, 20, 20, (CYAN));
    tft.fillRect(275,280, 20, 20, (MAGENTA));
    tft.fillRect(305,280, 20, 20, (YELLOW));
    tft.fillRect(335,280, 20, 20, (WHITE));
  #endif    
   } 
if (tft_type ==5) //2,8'' Elegoo display 320x240
   {tft.fillScreen((BLACK));
    tft_print (1," Homeduino",5,(YELLOW));
    tft_print (2,"   5.04",5,(YELLOW));
    String wlan_ssid = " Connecting to WLAN: " + String::String(ap_ssid);
    tft_print (4,wlan_ssid,1,(WHITE));
    tft_print (3,"  www.stall.biz",3,CYAN);
    tft.drawRect(0,0, 320, 240, (GREEN));
//
  #ifdef DEBUG
    Serial.println(F("Printing colored rectangles to check the color definitions:"));
    Serial.println(F("BLACK, BLUE, RED, GREEN, CYAN, MAGENTA, YELLOW, WHITE"));
    tft.fillRect(45,210, 20, 20, (BLACK));
    tft.fillRect(75,210, 20, 20, (BLUE));
    tft.fillRect(105,210, 20, 20, (RED));
    tft.fillRect(135,210, 20, 20, (GREEN));
    tft.fillRect(165,210, 20, 20, (CYAN));
    tft.fillRect(195,210, 20, 20, (MAGENTA));
    tft.fillRect(225,210, 20, 20, (YELLOW));
    tft.fillRect(255,210, 20, 20, (WHITE));
  #endif    
   } 

#endif  //*************************************************************************************

for(int i=0; i<zeilenzahl; i++)
   {zeile_pointer[i] = EEPROM.read(i);  //anzeige-pointer aus eeprom holen
    if (zeile_pointer[i] >86) {zeile_pointer[i] = 0;}  //wenn eeprom erstes mal benutzt wird
   } 

#if defined (w5100)  //************************************************************************
//hier folgt die LAN Initialisierung 
char myIpString[24];
 if (Ethernet.begin(mac) == 0) // start the Ethernet connection:
   {Serial.println(F("Failed to configure Ethernet using DHCP")); Ethernet.begin(mac, homeduino);}
    delay(1000);// give the Ethernet shield a second to initialize:
    Serial.println(F("connecting...")); // if you get a connection, report back via serial:
 if (client.connect(ccu, 8181)) {}
   else {Serial.println(F("connection failed"));} // if you didn't get a connection to the server:
 client.stop(); 
 IPAddress myIp = Ethernet.localIP();
 sprintf(myIpString, "%d.%d.%d.%d", myIp[0], myIp[1], myIp[2], myIp[3]); 
 I = myIpString;
 befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"IP"+"').State('"+ I + "')";
 set_sysvar(); 
 server.begin();
#endif  //*************************************************************************************

#if defined (cc3000)  //**********************************************************************
// hier folgt die CC3000 Initialisierung 
 ConnectionInfo connection_info;
 char myIpString[24]; 
 Serial.println(F("SparkFun CC3000 - WebClient"));
 if ( wifi.init() ) {Serial.println(F("init complete"));} 
 else {Serial.println(F("problem with init!"));}
 // Connect using DHCP
 if (!wifi.connect(ap_ssid, ap_security, ap_password, timeout)) 
   {Serial.println(F("no connection to AP"));}
 //build IP address
 if ( !wifi.getConnectionInfo(connection_info) ) {Serial.println(F("no connection details"));} 
   else {sprintf(myIpString, "%d.%d.%d.%d", connection_info.ip_address[0], 
   connection_info.ip_address[1],connection_info.ip_address[2], connection_info.ip_address[3]); 
         I = myIpString;
        }
 befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"IP"+"').State('" + I + "')";
 set_sysvar(); 
 client.stop();
#endif  //*************************************************************************************

#if defined (esp8266)  //**********************************************************************
// Starting ESP8266 Init 
    #ifdef DEBUG
        Serial.print(F("SERIAL_TX_BUFFER_SIZE: ")); Serial.println(SERIAL_TX_BUFFER_SIZE);
        Serial.print(F("SERIAL_RX_BUFFER_SIZE: ")); Serial.println(SERIAL_RX_BUFFER_SIZE);
    #endif
       char myIpString[24]; 
       pinMode(22,OUTPUT); digitalWrite(22,1); // Reset-Pin auf 1 setzen
       Serial3.begin(115200); // Standard baudrate for current ESP-01 modules with Espressif firmware. Old ones use 9600 baud
        // initialize ESP module to different baudrate. HANDLE WITH CARE!!! Only enable next lines if you know what you are doing!
/*        Serial3.write("AT+UART_DEF=115200,8,1,0,0\r\n"); //Modify default baudrate of 115200 (current Espressif FW) to reduce ESP Timeout Problems
        Auf_OK_warten(); //Only throws OK when the module is reconfigured for the first time. On subsequent boots a Timeout occurs because the comm-rate already IS @ the target rate
        Serial3.end();
        delay(3000); 
        Serial3.begin(115200); 
*/        
       Serial.println(F("Resetting ESP-01 module"));
       digitalWrite(22,0); delay(100); digitalWrite(22,1); delay(1000);//reset-Impuls ausgeben und Bootmeldungen abwarten
       Serial.println(F("Espressif ESP8266 - WebClient"));

        Serial3.write("AT\r\n");
        Auf_OK_warten(); //wait until reset is completed and ESP-01 responds again

      // initialize ESP module
        WiFi.init(&Serial3);
      
       // check for the presence of the shield
        if (WiFi.status() == WL_NO_SHIELD) {
          Serial.println(F("WiFi shield not present"));
          tft_print (4," No WLAN shield! STOP!!!",2,(RED));
          tft_print (3,"",3,BLACK);
            if (tft_type ==5) //2,8'' Elegoo display 320x240
            {tft.drawRect(0,0, 320, 240, (RED));}
          // don't continue
          while (true);
        }

            // attempt to connect to WiFi network
          while ( status != WL_CONNECTED) {
            Serial.print(F("Attempting to connect to WPA SSID: "));
            Serial.println(ap_ssid); 
            tft_print (4,"     WLAN shield ok - trying to connect...",1,(MAGENTA));
            if (tft_type ==5) {tft.drawRect(0,0, 320, 240, (MAGENTA));}               //2,8'' Elegoo display 320x240
            // Connect to WPA/WPA2 network
            status = WiFi.begin(ap_ssid, ap_password);
            }

              // you're connected now, so print out the data
            Serial.println(F("You're connected to the network"));
            
             // print the SSID of the network you're attached to
              Serial.print(F("SSID: "));
              Serial.println(WiFi.SSID());
            
              // print your WiFi shield's IP address
              IPAddress ip = WiFi.localIP();
              Serial.print(F("IP Address: "));
              Serial.println(ip);
              sprintf(myIpString, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
              I = myIpString;
              // print my MAC address
              byte mac[6];
              WiFi.macAddress(mac);
              char buf[20];
              sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]);
              Serial.print(F("MAC address: "));
              Serial.println(buf);
#if defined DEBUG
              Serial.print(F("String IP Address: "));
              Serial.println(myIpString);
#endif
              // print the received signal strength
              long rssi = WiFi.RSSI();
              Serial.print(F("Signal strength (RSSI):"));
              Serial.print(rssi);
              Serial.println(F(" dBm"));
              delay(6000); //let the Wifi connection establish itself
              Serial.println(F("Announcing my IP"));
              befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"IP"+"').State('"+ I + "')";
              set_sysvar(); 
              server.begin();
       
#endif  //*************************************************************************************


#if defined (lcd_display)  //****************************************************************** 
    //bei erfolgreichem einloggen ausgabe ip-adresse 
    lcd.setCursor(0,1);
    lcd.print(myIpString);
    delay(3000);
#endif  //*************************************************************************************

#if defined (tft_display) //*******************************************************************
//bei erfolgreichem einloggen ausgabe ip-adresse 
tft.fillScreen(BLACK);
if (tft_type ==1) //2,4'' display
  {tft.setCursor(8, 230); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(1);
   tft.print(Version + "   Homeduino IP: "); tft.print(myIpString);
  }
if (tft_type ==2) //3,95'' display 480x320
  {tft.setCursor(1, 300); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(2);
   tft.print(Version + " IP: "); tft.print( myIpString);
  }
if (tft_type ==3) //3,5'' display 400x240
  {tft.setCursor(0, 230); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(1);
   tft.print(Version + "   " + hm_systemvariable); tft.print( myIpString);
//   Serial.print(Version + "   Homeduino IP: "); Serial.print( myIpString); tft.print("   Nr.: " + homeduino_nummer);
  }
if (tft_type ==4) //3,5'' display 480x320
  {tft.setCursor(0, 310); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(1);
   tft.print(Version + "   " + hm_systemvariable); tft.print( myIpString);
//   Serial.print(Version + "   Homeduino IP: "); Serial.print( myIpString); tft.print("   Nr.: " + homeduino_nummer);
  }
if (tft_type ==5) //2,8'' Elegoo display 320x240
  {tft.setCursor(0, 230); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(1);
   tft.print(Version + "   " + hm_systemvariable); tft.print( myIpString);
//   Serial.print(Version + "   Homeduino IP: "); Serial.print( myIpString); tft.print("   Nr.: " + homeduino_nummer);
  }

#endif  //*************************************************************************************
for (int i = 0; i < 87; i++) {next_Time[i]=0;} //
 //delay(2000);
}
//#############################################################################################
//#############################################################################################
void loop() 
{
/* Enable following sequence to see the available character map.   
  tft.setCursor(0, 0); 
   tft.setTextColor(WHITE);  
   tft.setTextSize(3);
  for (int m = 0; m < 256; m++)
   {tft.print(char(m));}
  while (true); //end of character map sequence
*/   
  complete_loop = 0;
 if (millis() > next_full_loop) //mindestens jede Stunde eine komplette Aktualisierung
   {complete_loop = 1; next_full_loop = millis() + delta_time; 
    if (next_full_loop < millis()) {complete_loop = 0;} //wichtig wegen Zahlensprung 
                                                        //von millis() alle 50 Tage
   } 

//*********************************************************************************************
 for (int i = 2; i < 87; i++) //behandlung aller Ports D2 bis D69 und der Texte
 {while ((iomodus_D[i] == 0) || (iomodus_D[i] >29 )) {i++;}  // unbenutzte pins überspringen
// Serial.print("i: "); Serial.println(i);
  datenempfang(); //nach jeder Messung auf Datenempfang schalten
  display_data(); //display ausgeben und abfragen
  clockservice(); //update the clock
 //******************************************************************************************** 
 if (iomodus_D[i] == 1) //behandlung digitaleingänge 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +1000;  //digitaleingänge nicht häufiger als alle 1000ms abfragen
       pinMode(i, INPUT_PULLUP); 
       digitalWrite(i, HIGH);
       value =digitalRead(i);
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) 
            {if (value ==0) {zeile_data[m] = "LOW";} else {zeile_data[m] = "HIGH";}}}
       if ((!value == last_digital_value_D[i]) || complete_loop) 
         {I = String(i);
           befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+value+"')";
          set_sysvar();
          last_digital_value_D[i] = value;
         }
      } 
   }
   datenempfang();
//********************************************************************************************* 
 if (iomodus_D[i] == 3) //behandlung onewire 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +10000;  //onewire nicht häufiger als alle 10s abfragen 
       pinMode(i, INPUT_PULLUP);
       digitalWrite(i,HIGH);
       OneWire ds(i); 
       #define DS18S20_ID 0x10
       #define DS18B20_ID 0x28 
       byte present = 0;   byte data[12];    byte addr[8];
       temp_tur = 1000.0;
       if (!ds.search(addr)) { ds.reset_search(); temp_tur = -1000.0; } //find a device
       if ((OneWire::crc8( addr, 7) != addr[7]) && (temp_tur > -1000.0)) {temp_tur = -1000.0; }
       if ((addr[0] != DS18S20_ID && addr[0] != DS18B20_ID)&& (temp_tur > -1000.0)) 
         {temp_tur = -1000.0;}
       if (temp_tur > -1000.0) 
         {ds.reset(); 
          ds.select(addr); 
          ds.write(0x44, 1); // Start conversion
          //delay(850); // Wait some time...
          time_wait = millis() +850;                                  //wahrend der 2s wartezeit, daten empfangen, clock
          while (millis() < time_wait) {datenempfang();display_data;clockservice();} //und display weiter bedienen 
          present = ds.reset(); 
          ds.select(addr);
          ds.write(0xBE); // Issue Read scratchpad command
          for ( int k = 0; k < 9; k++) { data[k] = ds.read(); } // Receive 9 bytes
          temp_tur = ( (data[1] << 8) + data[0] )*0.0625; // Calculate temperature value 18B20
          //temp_tur = ( (data[1] << 8) + data[0] )*0.5 // Calculate temperature value 18S20
         }
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = String(temp_tur,1);}
         }
       if ((temp_tur > (last_value_D[i] + delta_onewire)) 
                            || (temp_tur < (last_value_D[i] - delta_onewire)) || complete_loop) 
         {I = String(i);
           befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+temp_tur+"')";
          set_sysvar();
          last_value_D[i] = temp_tur;
         }
      }   
  }
  datenempfang();
//********************************************************************************************* 
 if (iomodus_D[i] == 4) //behandlung DHT temperatur- und feuchtesensoren
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +30000;  //DHT nicht häufiger als alle 30s abfragen 
       DHT dht(i, DHT22); //je nach verwendetem sensor "DHT11", "DHT22" (AM2302),"DHT 21" (AM2301)
       dht.begin();
       //delay(2000); // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
       time_wait = millis() +2000;                                 //wahrend der 2s wartezeit, daten empfangen, clock
       while (millis() < time_wait) {datenempfang();display_data;clockservice();} //und display weiter bedienen 
       humidity = dht.readHumidity(); // Read temperature as Celsius
       temp_tur = dht.readTemperature(); 
       if (isnan(humidity) || isnan(temp_tur) ) // Check if any reads failed and 
         {//Serial.println("Failed to read from DHT sensor!");
          temp_tur = -1000;
         }
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = (String(temp_tur,1) + (char(247)) + "C/" + String(humidity,1) + "%");}
         }
       if ((temp_tur > (last_value_D[i] + delta_DHT))|| (temp_tur < (last_value_D[i] - delta_DHT)) 
                                                  || complete_loop) 
         {I = String(i);
          befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+temp_tur+"')";
          set_sysvar();
           befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"_1').State('"+humidity+"')";
          set_sysvar();
          last_value_D[i] = temp_tur;
        } 
     }
   } 
 //******************************************************************************************** 
 if (iomodus_D[i] == 5) //behandlung ultraschallsensoren 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +2000;  //ultraschall nicht häufiger als alle 2s abfragen 
 //achtung: zu beachten 
 //bei verwendung der US-Sensoren beim IO-Shield-Plus sind die 150-Ohm-Schutzwiderstände 
 //zu überbrücken (Jumper setzen!), entsprechend beim IO-Shield20 der Jumper 4-5 zu setzen!! 
       NewPing sonar(i, i, 200); // NewPing setup of pin and maximum distance.
       unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
       int cm = uS / US_ROUNDTRIP_CM;
       if (cm == 0) {}
       else {
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = (String(cm) + "cm");}} // display_value[i] = (String(cm) + "cm");} }
          if ((cm > (last_value_D[i] + delta_us)) || (cm < (last_value_D[i] - delta_us)) || complete_loop) 
            {I = String(i);
              befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+cm+"')";
             set_sysvar();
             last_value_D[i] = cm;
            }
       } 
      }
   }
   datenempfang();
//********************************************************************************************* 
 if (iomodus_D[i] == 10) //behandlung analogeingänge 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +1000;  //analogeingänge nicht häufiger als alle 1000ms abfragen 
       analogwert =analogRead(i);
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = String(analogwert);}}
       if ((analogwert > (last_value_D[i] + delta_analog)) 
                || (analogwert < (last_value_D[i] - delta_analog)) || complete_loop) 
         {I = String(i);
         Serial.print(F("i6: ")); Serial.println(i);
           befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State6("+analogwert+")";
          set_sysvar();
          last_value_D[i] = analogwert;
         }
      }
   } 
   datenempfang();
//*********************************************************************************************
 if (iomodus_D[i] == 11) //behandlung NTC 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +10000;  //NTC-eingänge nicht häufiger als alle 10s abfragen
       Rt = Rv/((1024.0/analogRead(i))- 1.0);
       tempNTC = (B_wert * Tn / ( B_wert + (Tn * log(Rt/Rn)))) -Tn +25.0 ;
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = String(tempNTC,1);}}
          if ((tempNTC > (last_value_D[i] + delta_ntc)) || (tempNTC < (last_value_D[i] - delta_ntc)) 
                                                   || complete_loop) 
            {I = String(i);
              befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+tempNTC+"')";
             set_sysvar();
             last_value_D[i] = tempNTC;
            } 
      }
   }    
   datenempfang(); 
//********************************************************************************************* 
 if (iomodus_D[i] == 6) //behandlung impulszahler D2,D3,D21,D20,D19,D18 
   {byte offset =23;
    if (i ==2) {offset = 4;} if (i ==3) {offset = 6;}
    zaehlwert = pulsecounter[offset - i ] / pulsedivider[offset - i ];
    for (int m=0; m < zeilenzahl; m++)
      {if (zeile_pointer[m] == i) {zeile_data[m] = String(zaehlwert);}}
       if ((pulsedivider[offset -i] > 0) && ((zaehlwert > (last_zaehlwert[offset - i]+ delta_counter) 
                           || complete_loop))) 
         {I = String(offset -i);
           befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"imp"+I+"').State('"+zaehlwert+"')";
          set_sysvar();
          last_zaehlwert[offset - i] = zaehlwert;
         } 
   }
   datenempfang(); 
//*********************************************************************************************
//behandlung I2C sensoren an pin 20(sda) und pin 21 (scl)
 if ((iomodus_D[i] == 8)&&(i == 20))
   {i++;  // da I2C Bus 2 eingaenge belegt
  
//behandlung Luxmeter BH1750 an SCL pin21 und SDA pin 20 ***********************************
// for normal sensor resolution (1 lx resolution, 0-65535 lx, 120ms, no PowerDown) 
//use: sensor.begin(RESOLUTION_NORMAL, false); 
    if (iomodus_lux ==1)
      {if (millis() > next_Time[72])
         {next_Time[72] = next_Time[72] +5000;  //luxmeter nicht häufiger als alle 5s abfragen 
          if(!sensor.begin()) { Serial.println(F("Sensor not present")); }
          lux = sensor.readLightLevel(); //delay(1000);
          Lux = (int)lux;
          //Serial.print(F("Helligkeit/lux: ")); Serial.print(lux); Serial.println();
          lux_string = "      " + String(Lux);
          int laenge = lux_string.length();
          lux_string = lux_string.substring(laenge -6,laenge);
          for (int m=0; m < zeilenzahl; m++)
            {if (zeile_pointer[m] == 72) {zeile_data[m] = lux_string;}}
             if (((Lux > (last_value_D[72] + delta_lux)) || (Lux < (last_value_D[72] - delta_lux)) 
                                                || complete_loop)) 
               {befehl="GET /xy.exe?antwort=dom.GetObject('" + hm_systemvariable+"lux"+"').State('"+Lux+"')";
                set_sysvar();
                last_value_D[72] = Lux;
               }
         } 
       } 
   datenempfang(); 
       
   //behandlung barometer BMP180 an SCL pin21 und SDA pin 20
    if (iomodus_baro ==1)
      {if (millis() > next_Time[70])
         {next_Time[70] = next_Time[70] +30000;  //barometer nicht häufiger als alle 30s abfragen 
          if (pressure.begin()) {status = pressure.startTemperature();}
          if (status) {delay(status); status = pressure.getTemperature(T);} //messung T
          if (status) {status = pressure.startPressure(3);} // //messung P mit resolution 0 bis 3
          if (status) {delay(status); status = pressure.getPressure(P,T);}
          if (status) {p0 = pressure.sealevel(P,ALTITUDE);} // umrechnung auf N.N.
//Serial.print("Hoehe/m: "); Serial.print(ALTITUDE); Serial.print(" Temperatur/C: "); 
//Serial.print(T); Serial.print(" Normaldruck /mb: "); Serial.println(p0); 
          baro_string = "     " + String(p0);
          laenge = baro_string.length();
          baro_string = baro_string.substring(laenge -7,laenge -1);
          baroT_string = "      " + String(T);
          laenge = baroT_string.length();
          baroT_string = baroT_string.substring(laenge -7,laenge -1);
          for (int m=0; m < zeilenzahl; m++) {if (zeile_pointer[m] == 70) {zeile_data[m] = baro_string;}}
          if ((p0 > (last_baro_value + delta_baro)) || (p0 < (last_baro_value - delta_baro)) 
                                                || complete_loop) 
            {befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"baro"+"').State('"+p0+"')";
             set_sysvar();
             last_baro_value = p0;
             last_value_D[70] = p0;
            }
          for (int m=0; m < zeilenzahl; m++) {if (zeile_pointer[m] == 71) {zeile_data[m] = baroT_string;}}  
          if ((T > (last_baroT_value + delta_baroT)) || (p0 < (last_baroT_value - delta_baroT)) 
                                                     || complete_loop) 
            {befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"baroT"+"').State('"+T+"')";
             set_sysvar();
             last_baroT_value = T;
             last_value_D[71] = T;
            } 
         }
      } 
      datenempfang();
  }  
//*********************************************************************************************
 if (iomodus_D[3] == 7) //behandlung 433Mhz-rx 
   {if (mySwitch.available()) 
      {int value = mySwitch.getReceivedValue();
       if (value == 0) {client.print(F("Unknown encoding"));} 
          else {Serial.print(F("Pin D3 received : "));
                Serial.print (mySwitch.getReceivedValue() );
                Serial.print (F(" / "));
                Serial.print( mySwitch.getReceivedBitlength() );
                Serial.print(F("bit Protocol: "));
                Serial.println( mySwitch.getReceivedProtocol() + " \n\r" );
               }
      mySwitch.resetAvailable();
     }
   } 
   datenempfang();
  //******************************************************************************************* 
 if ((iomodus_D[i] == 12) && (i==22))  //behandlung rfid3 tueroeffner an D22 des Mega
   {pinMode(i,OUTPUT);
    if (millis()< time_rfid3)         //D22-als normal-Ausgang für tueröffner schalten
      {Value = " AUF"; 
       if (oeffner_polarity) {digitalWrite(i, HIGH);} else {digitalWrite(i,LOW);}
       }
         else {Value = "  ZU"; if (!oeffner_polarity) 
                               {digitalWrite(i, HIGH);} else {digitalWrite(i,LOW);}}
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = Value;}}
    }
  if ((iomodus_D[i] == 12) && (i==23))  //behandlung rfid2 tueroeffner  an D23 des Mega
    {pinMode(i,OUTPUT);
     if (millis()< time_rfid2)         //D23-als normal-Ausgang für tueröffner schalten
       {Value = " AUF"; if (oeffner_polarity) 
                          {digitalWrite(i, HIGH);} 
                          else {digitalWrite(i,LOW);}}
       else {Value = "  ZU"; if (!oeffner_polarity) {digitalWrite(i, HIGH);} 
                                                    else {digitalWrite(i,LOW);}} 
     for (int m=0; m < zeilenzahl; m++)
       {if (zeile_pointer[m] == i) {zeile_data[m] = Value;}
       }
    }
    datenempfang();
 //******************************************************************************************** 
if (iomodus_D[i] == 18)  //Behandlung reine Texte von CCU
    {for (int m=0; m < zeilenzahl; m++)
       {if (zeile_pointer[m] == i) {zeile_data[m] = "";} 
       }
    }
 //******************************************************************************************** 
if (iomodus_D[i] == 17)  //Behandlung Uhrzeit von CCU
    {clockservice();
      for (int m=0; m < zeilenzahl; m++)
       {String min10 = ""; String hours10 = ""; String seconds10 = ""; String days10 = ""; String months10 = "";
        if (zeile_pointer[m] == i) { //add leading zeros
           if (seconds < 10)  {seconds10 = "0";}
           if (minutes < 10) {min10 = "0";}
           if (hours < 10)  {hours10 = "0";}
           if (days < 10)  {days10 = "0";}
           if (months < 10)  {months10 = "0";}
 
#if defined (tft_display)
    #if defined (ShowSeconds)
           zeile_data[m] = (days10 + String(days) + "." + months10 + String(months) + "." + String(years) + "  " + hours10 + String(hours) + ":" + min10 + String(minutes) + ":" + seconds10 + String(seconds)); 
    #else            
           zeile_data[m] = (days10 + String(days) + "." + months10 + String(months) + "." + String(years) + "     " + hours10 + String(hours) + ":" + min10 + String(minutes));
    #endif           
#endif
#if defined (lcd_display)
    #if defined (ShowSeconds)
           zeile_data[m] = (days10 + String(days) + "." + months10 + String(months) + "  " + hours10 + String(hours) + ":" + min10 + String(minutes) + ":" + seconds10 + String(seconds)); 
    #else            
           zeile_data[m] = (days10 + String(days) + "." + months10 + String(months) + "   " + hours10 + String(hours) + ":" + min10 + String(minutes));
    #endif           
#endif

        }
      }
    }
    datenempfang();
 //******************************************************************************************** 
/*  if (iomodus_D[i] == 12) //behandlung rfid-modul RDM6300 
    {int m = 0; fob_zahl=0;  fob_hex ="";
     if (i == 15){while((Serial3.available()>0)&&(m <11 ))  //behandlung rfid3
                       {fob_da=1;  m++;  zeichen = Serial3.read();
                        if (m>4)  //die ersten 4 zeichen ignorieren
                          {fob_hex += zeichen; fob_zahl = hexToDec(fob_hex);}
                        if (m > 10) //Datenübertragung fertig, dann buffer leeren 
                          {while(Serial3.available()>0) {zeichen = Serial3.read();}}
             }
         }    
     if (i == 17){while((Serial2.available()>0)&&(m <11 ))//behandlung rfid2
                      {fob_da=1;  m++;  zeichen = Serial2.read();
                       if (m>4)  //die ersten 4 zeichen ignorieren
                         {fob_hex += zeichen; fob_zahl = hexToDec(fob_hex);}
                       if (m > 10) //Datenübertragung fertig, dann buffer leeren 
                         {while(Serial2.available()>0) {zeichen = Serial2.read();}}
            }
           }
     if (fob_da)
       {fob_dec = ""; 
        sprintf(buffer,"%lu", fob_zahl); //zahl umwandeln in string
        for(int k = 0; k<7; k++) {fob_dec += buffer[k];} 
        Name = "";  //gueltigen namen und oeffner aus tabelle ermitteln  
        for (int k = 0; k < fob_anzahl; k++) {if (fob_dec == fob[3*k]) 
                                                {Name += fob[(3*k)+1];
                                                 oeffner= fob[(3*k)+2]; 
                                                 break;
                                                }
                                              }
        if ((Name != "") && ((oeffner =="1") ||(oeffner =="3"))) 
          {time_rfid3 = millis() + unlock_time1;}
        if ((Name != "") && ((oeffner =="2") ||(oeffner =="3")))  
          {time_rfid2 = millis() + unlock_time2;}
        if (Name == "") {Name = fob_dec;}
        lcd_rfid_message = Name + "          "; //lcd mmeldung modifizieren für rfid
        lcd_rfid_message = lcd_rfid_message.substring(0,9);
         
        for (int n=0; n < zeilenzahl; n++)
          {if (zeile_pointer[n] == i) 
             {display_message[i]= lcd_rfid_message; zeile_data[n] = fob_dec;}
          }
           
     //Serial.println(Name + " " + fob_dec);
        I = String(i);
        befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+Name+"')";
        set_sysvar();
        fob_da =0;
       }
     delay(500);  
    }
*/
//**************************   ende loop  *****************************************************
 }
} 
//#############################################################################################
//#############################################################################################
//#############################  Unterprogramme   #############################################

void datenempfang() //Unterprogramm datenempfang: daten von ccu an homeduino senden
{command = ""; 

#if defined (w5100)  //************************************************************************
 EthernetClient client = server.available();   //mit W5100
#endif  //************************************************************************************* 

#if defined (cc3000)  //***********************************************************************
 SFE_CC3000_Client client = SFE_CC3000_Client(wifi);   //mit CC3000
#endif  //************************************************************************************* 

#if defined (esp8266)  //***********************************************************************
  WiFiEspClient client = server.available();   //using ESP8266 (ESP-01 module)
#endif  //************************************************************************************* 

  if (client)  {
    receivingcommand = false;
    Serial.println(F("New client"));
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    unsigned long breakMillis = millis();
    while (client.connected())
    { //Serial.println(F("Client still connected"));
      if ((millis() - breakMillis) > 500) {sendHttpResponse(client); break;}
      if (client.available())
      {
        char c = client.read(); 
//        Serial.write(c);
        breakMillis = millis();
          if (reading && c == ' ') {reading =false;}
          if (c == '?') {reading = true; receivingcommand = true;} // beginn der Befehlssequenz 
          if (reading) 
            { if (command.length() < 100) //read char by char HTTP request
               {command = command + c;} // Serial.println(command);} //store characters to string
            } 
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
         if (c == '\n' && currentLineIsBlank) {sendHttpResponse(client);break;}
          if (c == '\n') {currentLineIsBlank = true;} 
            else if (c != '\r') { currentLineIsBlank = false;}
      }
    }
    delay(10);        // give the web browser time to receive the data
    client.stop();    // close the connection:
    Serial.println(F("Client disconnected"));
  }
  
    if (command.length() > 2) //behandlung Datenempfang von ccu: port auf 0/1 setzen or write textline or set clock
        {

#if defined (tft_display) //**************************************************
       String commandType = command.substring(1,2); // detect command type: "D" for data, "T" for text, "C" for clock (date, time)
          if (commandType == ("D")) {
             int colonPosition = command.indexOf(':');
             sub_command = command.substring(2,colonPosition); //portpin erkennen
             Serial.print("D" + sub_command + " :");
             port_pin = sub_command.toInt();
             command = command.substring((colonPosition+1)); //Rest-command bilden
              SetOutputPort (); //If command adresses an output port toggle it
                if ((iomodus_D[port_pin] == 7) && (port_pin ==4)) 
                  {rf_send(command); Serial.println(command);} 
                if ((iomodus_D[port_pin] == 5) && (port_pin ==9)) 
                  {ir_send(command); Serial.println(command);} 
          }
          if (commandType == ("T")) {
//            Serial.println(command);
             int colonPosition = command.indexOf(':');
             sub_command = command.substring(2,3 ); //select textline erkennen value 0-7 for line 1-8
             text_line = sub_command.toInt();
             String text_content_full = command.substring((colonPosition+1)); //isolate remaining text 
             char text_content_array[text_content_full.length() + 1]; // copy text to char array and split by separator comma in segments
             text_content_full.toCharArray(text_content_array, text_content_full.length() + 1);
             char* token = strtok(text_content_array, ",");
             char* text_content_char = token;
//             Serial.println(text_content_char);
             token= strtok(0, ",");
             char* text_size = token;
             token = strtok(0, ",");
             char* text_color_char = token;
             text_content = ((char*)text_content_char);
//             text_content_char = (text_content_char + '\0');
             String text_content = String(text_content_char);
//             Serial.println(text_content);
             text_content.replace("%20", " "); // %20 = HTML for Space. Enable formatting texts with spaces
             fontgroesse = atoi( text_size );
             String text_color = ((char*) text_color_char );
             if (text_color == "BLACK") {text_farbe = BLACK;}
             if (text_color == "BLUE") {text_farbe = BLUE;}
             if (text_color == "RED") {text_farbe = RED;}
             if (text_color == "GREEN") {text_farbe = GREEN;}
             if (text_color == "CYAN") {text_farbe = CYAN;}
             if (text_color == "MAGENTA") {text_farbe = MAGENTA;}
             if (text_color == "YELLOW") {text_farbe = YELLOW;}
             if (text_color == "WHITE") {text_farbe = WHITE;}
      #ifdef DEBUG
                    Serial.print(F("Zeile: "));Serial.println(text_line);
                    Serial.print(F("Text: "));Serial.println(text_content);
                    Serial.print(F("Groesse: "));Serial.println(text_size);
                    Serial.print(F("Farbe: "));Serial.println(text_color);
                    freeRam();
      #endif   

             tft_print (text_line,text_content,fontgroesse,text_farbe); 
          }
         if (commandType == ("C")) {
             command.replace("%20", " "); // %20 = HTML for space. Formatting Time / Date with Spaces possible
             Serial.print(F("C-Command received: ")); Serial.println(command);
             int colonPosition = command.indexOf(':');
             sub_command = command.substring((colonPosition + 1),(colonPosition + 3)); 
             days = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 4),(colonPosition + 6)); 
             months = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 7),(colonPosition + 11)); 
             years = (sub_command.toInt());

             sub_command = command.substring((colonPosition + 12),(colonPosition + 14)); 
             hours = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 15),(colonPosition + 17)); 
             minutes = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 18),(colonPosition + 20)); 
             seconds = (sub_command.toInt());
          } 
   #endif
   
   #if defined (lcd_display)
        String commandType = command.substring(1,2); // Kommandotyp abfragen: "D" für Daten oder "T" für Text
//       Serial.println("Kommandotyp: " + commandType);
          if (commandType == ("D")) {
      int colonPosition = command.indexOf(':');
       sub_command = command.substring(2,colonPosition); //portpin erkennen
       Serial.print("D" + sub_command + " :");
       port_pin = sub_command.toInt();
       command = command.substring((colonPosition+1)); //Rest-command bilden
          SetOutputPort (); //If command adresses an output port toggle it
          if ((iomodus_D[port_pin] == 7) && (port_pin ==4)) 
            {rf_send(command); Serial.println(command);} 
          if ((iomodus_D[port_pin] == 5) && (port_pin ==9)) 
            {ir_send(command); Serial.println(command);} 
          }
 
         if (commandType == ("T")) {
             int colonPosition = command.indexOf(':');
             sub_command = command.substring(2,3 ); //Textzeile erkennen Werte 0-1 für Zeile 1-2
             text_line = sub_command.toInt();
             String text_content_full = command.substring((colonPosition+1)); //Restlichen Text isolieren max. 22 Zeichen
                #ifdef DEBUG
                    Serial.print(F("Text: "));Serial.println(text_content_full);
                #endif   
             text_content_full.replace("%20", " "); // %20 = HTML für Space. Formatierung des Textes mit Spaces ermöglichen
             lcd.setCursor(0,text_line);
             lcd.print("                "); // delete 16 characters per line
             lcd.setCursor(0,text_line);
             lcd.print(text_content_full);
          }

        if (commandType == ("C")) {
             command.replace("%20", " "); // %20 = HTML for space. Formatting Time / Date with Spaces possible
             Serial.print(F("C-Command received: ")); Serial.println(command);
             int colonPosition = command.indexOf(':');
             sub_command = command.substring((colonPosition + 1),(colonPosition + 3)); 
             days = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 4),(colonPosition + 6)); 
             months = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 7),(colonPosition + 11)); 
             years = (sub_command.toInt());

             sub_command = command.substring((colonPosition + 12),(colonPosition + 14)); 
             hours = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 15),(colonPosition + 17)); 
             minutes = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 18),(colonPosition + 20)); 
             seconds = (sub_command.toInt());
          } 
          
      #endif
      }
  } 
//*********************************************************************************************
void set_sysvar() // subroutine HTTP request absetzen:
{while (millis() < next_tx) {} //warten bis time > next_tx oder timeout
 next_tx = millis() +delta_tx;
 if (client.connect(ccu, 8181)) 
   {byte transmitbytes = 0;
    unsigned long breakMillis = millis();
    Serial.println(befehl);
    transmitbytes = client.println(befehl);
    while (transmitbytes != (befehl.length() + 2)) {
      Serial.println(F("Transmission failed! Retrying..."));
      delay(10);
      transmitbytes = client.println(befehl);
      if ((millis() - breakMillis) > 100) {Serial.println(F("Transmission failed 10 times!!! Check the WLAN connection to your CCU!")); break;}
      }
    client.println();
    client.flush();
    client.stop();
   } else {Serial.println(F("connection failed"));}
}

//*********************************************************************************************
void rf_send(String rf_command) // subroutine rf telegramm senden
{
}
//*********************************************************************************************
void ir_send(String ir_command) // subroutine ir telegramm senden
{
}
//*********************************************************************************************
//hier sind die interrupt-service-routinen fuer die impulszaehler  //**************************
void ISR_0() //Interrupt an D2
{pulsecounter[0]++;}
void ISR_1() //Interrupt an D3
{pulsecounter[1]++;}
void ISR_2() //Interrupt an D21
{pulsecounter[2]++;}
void ISR_3() //Interrupt an D20
{pulsecounter[3]++;}
void ISR_4() //Interrupt an D19
{pulsecounter[4]++;}
void ISR_5() //Interrupt an D18 
{pulsecounter[5]++;}
//*********************************************************************************************
//Unterprogramm:  Converting from Hex (unsigned long) to Decimal: *****************************
//Quelle https://github.com/benrugg/Arduino-Hex-Decimal-Conversion/blob/master/hex_dec.ino
unsigned long hexToDec(String hexString) 
{unsigned long decValue = 0;
 int nextInt;
 for (int k = 0; k < hexString.length(); k++) 
   {nextInt = int(hexString.charAt(k));
    if (nextInt >= 48 && nextInt <= 57) nextInt = map(nextInt, 48, 57, 0, 9);
    if (nextInt >= 65 && nextInt <= 70) nextInt = map(nextInt, 65, 70, 10, 15);
    if (nextInt >= 97 && nextInt <= 102) nextInt = map(nextInt, 97, 102, 10, 15);
    nextInt = constrain(nextInt, 0, 15);
    decValue = (decValue * 16) + nextInt;
  }
 return decValue;
}

//*********************************************************************************************
void display_data() //gibt daten auf dem lcd oder tft display aus

//*********************************************************************************************
#if defined (lcd_display)  //behandlung lcd-display: erkennung des tasters und lcd-anzeige
{x = analogRead (0);  //abfrage A0
 if (x < (x_alt -100))  {tastererkennung();}
 x_alt = x; 
 for (int m = 0; m < zeilenzahl; m++)
   {while (zeile_data[m].length() < 5) {zeile_data[m] = " " + zeile_data[m];}
    if (display_message[zeile_pointer[m]] == "0") {zeile_data[m] = "                ";}
    display_zeile[m] =  display_message[zeile_pointer[m]] + zeile_data[m];
   
    if (display_zeile[m] != display_zeile_alt[m])  //datenausgabe auf display nur wenn aenderung 
      {lcd.setCursor(0,m); lcd.print (display_zeile[m]); display_zeile_alt[m] = display_zeile[m];}
   } 
} 
//*********************************************************************************************
void tastererkennung()
{if (x < 60) 
   {taster == "right"; 
    zeile_pointer[0]--;  if (zeile_pointer[0] ==1) {zeile_pointer[0] = 87;}
    while((iomodus_D[zeile_pointer[0]] ==0) || (iomodus_D[zeile_pointer[0]] >19))
         {zeile_pointer[0]--; if (zeile_pointer[0] ==1) {zeile_pointer[0] =87;} }
    EEPROM.write(0,zeile_pointer[0]);//delay(4);
   } 
   else if (x < 200) 
          {taster == "up";
           zeile_pointer[0]++;  if (zeile_pointer[0] ==87) {zeile_pointer[0] = 2;}
           while((iomodus_D[zeile_pointer[0]] ==0) || (iomodus_D[zeile_pointer[0]] >19))
               {zeile_pointer[0]++; if (zeile_pointer[0] ==87) {zeile_pointer[0] = 2;} }
           EEPROM.write(0,zeile_pointer[0]);//delay(4);
          } 
          else if (x < 400) 
                   {taster == "down";
                    zeile_pointer[1]++; if (zeile_pointer[1] ==87) {zeile_pointer[1] = 2;}
                    while((iomodus_D[zeile_pointer[1]] ==0) || (iomodus_D[zeile_pointer[1]] >19))
                         {zeile_pointer[1]++; if (zeile_pointer[1] ==87) {zeile_pointer[1] = 2;} } 
                    EEPROM.write(1,zeile_pointer[1]);//delay(4);     
                   } 
                  else if (x < 600)
                         {taster == "left";
                          zeile_pointer[1]--;
                          if (zeile_pointer[1] ==1) {zeile_pointer[1] = 87;}
                          while((iomodus_D[zeile_pointer[1]] ==0) || (iomodus_D[zeile_pointer[1]] >19))
                               {zeile_pointer[1]--; if (zeile_pointer[1] ==1) {zeile_pointer[1] =87;} }
                          EEPROM.write(1,zeile_pointer[1]);//delay(4);
                         } 
                         else if (x < 800)
                                {taster = "select";}
                                else {taster ="";}
}
#endif  //************************************************************************************* 

//*********************************************************************************************
#if defined (tft_display)  //behandlung tft toucheingabe und  display 2.4''
 {if (millis() > next_touch_time)  //touch-display abfragen
   {TSPoint p = ts.getPoint();// a point object holds x y and z coordinates
    px = p.x; py = p.y; pz =p.z;  
    pinMode(XM, OUTPUT);   pinMode(YP, OUTPUT);
    if (pz > MINPRESSURE && pz < MAXPRESSURE ) 
      {
#ifdef DEBUG
       Serial.print(F("px : "));Serial.print( px); Serial.print(F("  py : " )); Serial.print(py);
       Serial.print(F("  pz : " )); Serial.print(pz);
#endif       
       if (abs(px_B - px_A) > 100) {p_x = (1000 *(px- px_A))/(px_B -px_A); p_y = (1000 *(py - py_A))/(py_C -py_A);} 
         else {p_x = (1000 *(py -py_A))/(py_B - py_A); p_y = (1000 *(px - px_A)) /(px_C - px_A);}
       Serial.print(F("  p_x : "));Serial.print( p_x); Serial.print(F("  p_y : " )); Serial.print(p_y);

    if (tft_type != 4) {
       if (p_y < 154) {touch_y = 0;}   //p_y = 1000 entspricht 6,5 Zeilen 
         else {if (p_y < 308) {touch_y = 1;}
                 else {if (p_y < 462) {touch_y = 2;}
                         else {if (p_y < 616) {touch_y = 3;}
                                 else {if (p_y < 770) {touch_y = 4;}
                                         else {touch_y = 5;}}}}}}

    if (tft_type == 4) {
       if (p_y < 106) {touch_y = 0;}   //p_y = 1000 entspricht 8,5 Zeilen 
         else {if (p_y < 212) {touch_y = 1;}
                 else {if (p_y < 370) {touch_y = 2;}
                         else {if (p_y < 500) {touch_y = 3;}
                                 else {if (p_y < 590) {touch_y = 4;}
                                        else {if (p_y < 690) {touch_y = 5;}
                                              else {if (p_y < 790) {touch_y = 6;}
                                                  else {touch_y = 7;}}}}}}}}


       Serial.print(F("     touch_y ")); Serial.print(touch_y); Serial.println();
       centertouch = 1;
       if (p_x < 333) {zeile_pointer_minus();  Serial.println(zeile_pointer[touch_y]); centertouch = 0;}
       if (p_x > 666) {zeile_pointer_plus();  Serial.println(zeile_pointer[touch_y]); centertouch = 0;} //reserve center area for other action
       if ((centertouch) && ((iomodus_D[zeile_pointer[touch_y]]) == 2)) {
        port_pin = zeile_pointer[touch_y];
#ifdef DEBUG
        Serial.print (F("iomodus_D[zeile_pointer[touch_y]] Touch Mitte - Modus: ")); Serial.println (iomodus_D[port_pin]); 
        Serial.print (F("Port_Pin: D")); Serial.println(port_pin);
        Serial.print(F("Status des Ausgangs: ")); Serial.println(digitalRead(port_pin));
#endif
        next_touch_time = millis() + 200;
        if (((iomodus_D[port_pin]) == 2) && (digitalRead(port_pin) == LOW)) {
            command = "1"; SetOutputPort ();} 
          else {
            command = "0"; SetOutputPort ();} //toggle output pin
        centertouch = 0;}
      }
      for (int m = 0; m < zeilenzahl; m++)  //datenausgabe auf tft-display
      {while (zeile_data[m].length() < 7) {zeile_data[m] = " " + zeile_data[m];}
       display_zeile[m] =  display_message[zeile_pointer[m]] + zeile_data[m];
       if (display_zeile[m] != display_zeile_alt[m]) //displayausgabe nur wenn aenderung 
         {tft_print (m,display_zeile[m],schriftgroesse,default_color); display_zeile_alt[m] = display_zeile[m];
        }
      }
   } 
}
//*********************************************************************************************
//mit diesem Unterprogramm wird auf dem tft display ein zeilen-display 6 x 16 bis 8 x 26 emuliert
void tft_print (int line, String textline, int font_size, long int color)
{if (tft_type ==1)
   {tft.fillRect(0,38*line, 319, 38, BLACK); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(0, 38*line+6);              //und dann erst schreiben
   }
 if (tft_type ==2)
   {tft.fillRect(0,50*line, 479, 50, BLACK); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(5, 50*line+6);              //und dann erst schreiben
   }  
if (tft_type ==3)
   {tft.fillRect(0,38*line, 399, 38, BLACK); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(0, 38*line+6);              //und dann erst schreiben
   }
if (tft_type ==4)
   {tft.fillRect(0,38*line, 479, 38, (BLACK)); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(0, 38*line+6);              //und dann erst schreiben
   }
if (tft_type ==5)
   {tft.fillRect(0,38*line, 320, 38, (BLACK)); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(0, 38*line+6);              //und dann erst schreiben
   }
 tft.setTextColor(color);  
 tft.setTextSize(font_size);
 tft.print(textline);
}

//mit diesen Unterprogrammen wird der zeile_pointer im eeprom abgelegt
void zeile_pointer_plus()
{next_touch_time = millis() + 200; 
  zeile_pointer[touch_y]++; if (zeile_pointer[touch_y] >86) {zeile_pointer[touch_y] = 2;}
 while((iomodus_D[zeile_pointer[touch_y]] ==0) || (iomodus_D[zeile_pointer[touch_y]] >19))
  {zeile_pointer[touch_y]++; if (zeile_pointer[touch_y] >86) {zeile_pointer[touch_y] = 2;} }
 EEPROM.write(touch_y,zeile_pointer[touch_y]);//delay(4);
}
void zeile_pointer_minus()
{next_touch_time = millis() + 200; 
  zeile_pointer[touch_y]--; if (zeile_pointer[touch_y] <2) {zeile_pointer[touch_y] = 86;}
 while((iomodus_D[zeile_pointer[touch_y]] ==0) || (iomodus_D[zeile_pointer[touch_y]] >19))
   {zeile_pointer[touch_y]--; if (zeile_pointer[touch_y] <2) {zeile_pointer[touch_y] =86;}  }
 EEPROM.write(touch_y,zeile_pointer[touch_y]);//delay(4);
}      
#endif  //************************************************************************************* 

/* just needed in case you want to communicate with the ESP-01 without using the ESPwifi lib */
   void Auf_OK_warten()
{ Serial3.flush(); 
  boolean Ook = false;
  boolean Kok = false;
  unsigned long Counter = 0;
  
  while(!Kok)
  {
    if (Serial3.available())     espbyte = Serial3.read();
    if (espbyte == 79) Ook = true;
    if (espbyte == 75) Kok = true;
    Counter++;
    if (Counter > 200000){Serial.print(F("Timeout while communicating with ESP-01 module!\n\r")); break;}
  }
  if (Ook && Kok) Serial.println();
}

//*************************************************************************************
      int freeRam () { //just for debugging
          extern int __heap_start, *__brkval; 
          int v; 
          int fr = (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
          Serial.print(F("Free ram: "));
          Serial.println(fr);
       }
//*************************************************************************************
      void SetOutputPort () {
               if (((iomodus_D[port_pin] == 2)||(iomodus_D[port_pin] == 12)) && (command == "0")) 
               {for (int m=0; m < zeilenzahl; m++)
                  {if (zeile_pointer[m] == port_pin) {zeile_data[m] = " Aus";} // display_value[port_pin] = " LOW";}
                  }
                pinMode(port_pin, OUTPUT); digitalWrite(port_pin, LOW); Serial.println(command);
               }
             if ((iomodus_D[port_pin] == 2) && (command == "1")) 
               {for (int m=0; m < zeilenzahl; m++)
                  {if (zeile_pointer[m] == port_pin) {zeile_data[m] = "   An";} // display_value[port_pin] = " HIGH";}
                  }
                pinMode(port_pin, OUTPUT); digitalWrite(port_pin, HIGH); Serial.println(command);}
          String I = String(port_pin);
          befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+command+"')";
          set_sysvar();
       }
 
//*************************************************************************************
      void clockservice () {
        if ((millis() - previousMillis) >= 998) { //should be 1000. Different value for compensation and depends on quartz and program precision
              previousMillis = millis(); // save current time to previousMillis
                seconds = ++seconds;
             if (seconds == 60) {
                 seconds = 0;
                 minutes = ++minutes;}
             if (minutes == 60) {
                 minutes = 0; 
                 hours = ++hours;}
             if (hours == 24) {hours = 0;}
        }
      }

//*************************************************************************************
void sendHttpResponse(WiFiEspClient client)
    {
    if (receivingcommand == true) {
          clockservice();
          Serial.println(F("Sending command response"));
          // send a standard http response header
          // use \r\n instead of many println statements to speedup data send
          client.print(F( "HTTP/1.1 200 OK\r\n"
                          "Content-Type: text/html\r\n"
                          "Connection: close\r\n"             // the connection will be closed after completion of the response
//                          "Refresh: 10\r\n"                   // refresh the page automatically every 10 sec. Useful for tests if you compare command to received command
                          "\r\n"));
          client.print(F("<!DOCTYPE HTML>\r\n"
                         "<html>\r\n"
                         "<h1>Welcome at "));
          client.print(hm_systemvariable);
          client.print(F( "</h1>\r\n"
                          "Requests received: "));
          client.print(++reqCount);
          client.print(F( "<br>\r\n"
                          "<br>\r\n"
                          "Command received: "));
          client.print(command);
          client.print(F( "<br>\r\n"
                          "<br>\r\n"
                          "Command length: "));
          client.print(command.length());
          client.print(F( " out of a maximum of 100"
                          "<br>\r\n"
                          "<br>\r\n"
                          "</html>\r\n"));
          client.flush();
          next_tx = millis() +delta_tx;
          clockservice();
          receivingcommand = false;
         }
         else {
              Serial.println(F("Sending 404 response after invalid request"));
              client.print(F("HTTP/1.1 404 \r\n" //shortest possible answer
              "\r\n"));
              next_tx = millis() +delta_tx;
              }
    }

Ardubert Homedu
Beiträge: 142
Registriert: 17.07.2016, 10:40
Hat sich bedankt: 3 Mal
Danksagung erhalten: 1 Mal

Re: Homeduino: universeller LAN/WLAN-Arduino für die Hausaut

Beitrag von Ardubert Homedu » 02.07.2017, 22:43

Hallo,,

Scetch von SciBee am Testgerät versucht...

Mein verschwendeter Abend bescherte mir folgende Mysterien :shock:

Wenn der ESP am Mega angeschlossen ist Lässt sich kein Scetch hochladen,,,
Auch wenn das TFT aufgesteckt ist lässt sich keiner Hochladen... :shock:

Hochladen geht also nur mit nem NACKTEN Mega :!:
War sonst nie ein Problem...

Die Verbindung zum Router scheint zu laufen,
ist mir jetzt aber zu spät Sensoren anzuschließen und
bis zur CCU2 zu testen... mach ich evtl. morgen Abend..

mit meiner bestehenden IDE für meine Homeduinos läuft der Scetch auch nicht
durch ist auch nicht in den griff zu bekommen.... 165

Hab mit der Neuen IDE auch ewig gebraucht bis es mal durch lief... 183

Ist es normal das die Verbindung ins WLAN ca 2 Minuten dauert?
solange bleibt ca das TFT auf dem ersten Bildschirm...

Jemand ne Idee?? Stell mich sicher wieder weng doof an...

mfg. Flo

Ardubert Homedu
Beiträge: 142
Registriert: 17.07.2016, 10:40
Hat sich bedankt: 3 Mal
Danksagung erhalten: 1 Mal

Re: Homeduino: universeller LAN/WLAN-Arduino für die Hausaut

Beitrag von Ardubert Homedu » 03.07.2017, 23:40

Hat das sonst keiner am Laufen??

Mit dem 504 Scetch klapperts bei mir an allen Ecken.... :shock:

mfg. Flo

Ardubert Homedu
Beiträge: 142
Registriert: 17.07.2016, 10:40
Hat sich bedankt: 3 Mal
Danksagung erhalten: 1 Mal

Re: Homeduino: universeller LAN/WLAN-Arduino für die Hausaut

Beitrag von Ardubert Homedu » 04.07.2017, 22:33

Hallo zusammen,,,

Nach ewigem probieren und mal ausgeschlafen an die Sache rann gehen :lol:
Funktioniert nun der Scetch 8)

das der Upload probleme gemacht hat lag wohl irgendwie an meinem USB Port..
der gleiche den ich sonst auch immer benutze,, aber wenn ich nicht zusätzlich
ein Netzteil an der DC Buchse habe, kann ich nur Ohne TFT und Ohne ESP + gedöns
Hochladen... keine Ahnung :shock:

Das ich keine Daten in die CCU2 bekommen habe Lag daran das in dem Scetch noch
die Änderungen gefehlt haben wegen dem FW Update...

Das habe ich jetzt eingetragen...

hier der Scetch, der nun auch mit ESP-01 und CCU2 läuft
Display usw. natürlich anpassen.

Code: Alles auswählen

const String Version = "hduino504_ESP_SciBee";  /*Stand: 12.03.2017 / Verfasser: Eugen Stall/SciBee
erprobt fuer Arduino Mega 2560 mit Arduino 1.6.13
hier ist immer die aktuelle V4.x Basis-Version:
http://www.stall.biz/project/homeduino-4-0-das-universelle-mess-und-aktormodul-fuer-die-hausautomation
das folgende homeduino-programm sendet messdaten zur ccu (homeduino als webclient) ...
und empfängt ausgabedaten für die homeduino-outputs (homeduino als webserver)

_________________            ________________
|port 8181 server|<---------<| client        |
|                |           |               |
| CCU            |           |     Homeduino | 
|                |           |               |
|          client|>--------->|server port 80 | 
|________________|           |_______________|

/Quellen:Arduino website plus http://arduino.cc/en/Tutorial/WebClient und ...
 http://tushev.org/articles/arduino/item/52-how-it-works-ds18b20-and-arduino und ...  

Intrudeced a command type parameter to adress different functions in the CCU/HD communication:
D controls Data operations e.g. control outputs - same behaviour as in versions < 5
T goes to text - displays a line of text in controlable size and color
C goes to Clock - sets the internal software clock. No additional hardware RTC required.

Example textline with a TFT display: 'http://123.456.789.123/?T0:This is a test,2,CYAN'
Syntax: http://[Homeduino_IP]/?T[linenumber 0...7]:[text with spaces],[fontsize 1...4],[textcolor] 
Maximum size is 100 characters including the fontsize, textline number and color value including the format commas
because of the tft_print textline String buffer. 
Remember: a 'Space' already consumes 3 characters because the browser translates it to '%20'!

Example setting the clock via browser: http://123.456.789.123/?C:27.05.2017,23:56:57 sets the internal clock of Homeduino at IP 123.456.789.123 to
Day: 27, Month: 05, Year: 2017, Hour: 23, Minute: 56, Second 57
You may use any separating character you like instead of dots or commas as the positions in the command are used.
the date is not increased automatically when midnight is over! This relies on the CCU clock. 
Update the clock via script every hour because the software clock in the HD is not very precise.

Example textline with LCD Display: 'http://123.456.789.123/?T0:0123456789ABCDEF' max. 16 characters
Syntax: http://[Homeduino_IP]/?T[linenumber 0...1]:[text with spaces] 
No fontsize or color parameters of course.

Example setting port D22 of Homeduino to "0" (Low) via browser: http://123.456.789.123/?D22:0
Same behaviour as before.

Example set a systemvariable in your CCU via browser:
http://123.456.789.123:8181/xy.exe?antwort=dom.GetObject('homeduino_001_IP').State('123.456.789.124')
which sets the varable named 'homeduino_001_IP' to the value '123.456.789.124'
 */
//#############################################################################################
//#############################################################################################
//Auswahl der verwendeten Shields: 
#define tft_display //"tft_display" oder "lcd_display"                         <<user-eingabe<< 
                    //"lcd_display" auch wenn kein display verwendet wird 
                    // TFT display details are defined starting near line 350.   <<user-eingabe<<
                    // Enable the sequence mating your TFT!!!

#define esp8266       //"cc3000"  Wifi-Modul or "w5100" ethernet shield or "esp8266" WiFi      <<user-eingabe<< 

//#define DEBUG //enable if you want to see more verbose output at the serial debug port
//#define ShowSeconds //enable if you want the clock to show seconds 12:34:56 elses it shows just 12:34

const byte ccu[4] = { 192, 168, 0, 100 };      //IP der CCU                                      <<user-eingabe<< 

//MAC-Adresse dieses Homeduinos ,bei mehreren Homeduinos MAC-.Adresse ändern!!:
// no need for a user specified MAC adress at ESP8266. ESP-01 has a preprogrammed MAC
const byte mac[6] = { 0x00, 0x10, 0x13, 0x00, 0x26, 0x07 };  //                                 <<user-eingabe<<

const byte homeduino[4] = { 192, 168, 0, 100 }; //IP des Homeduino,wenn DHCP versagt             <<user-eingabe<< 

const char ap_ssid[] = "myWLAN_SSID"; //SSID WLAN in Anführungszeichen                              <<user-eingabe<< 

const char ap_password[] = "myPassword"; //Passwort WLAN in Anführungszeichen         <<user-eingabe<< 

//xyz ist indiv. Bezeichnung dieses homeduino, keine sonderzeichen, öäüß...
const String homeduino_nummer = "001";  //                                                      <<user-eingabe<< 
const String hm_systemvariable = "homeduino_" + homeduino_nummer +"_";
//#############################################################################################
//#############################################################################################
//I/O-Kennung: hier wird die Funktion aller verwendbaren IO´s mit einer Kennziffer festgelegt 
//dabei haben alle IO´s die Standardfunktionen plus spez. Sonderfunktionen
//     Standardfunktionen sind:
//     '0' =andere Nutzg; '1' =dig_in; '2' =dig_out; '3' =1wire '4' =DHTxx; '5' =U_Schall; '17' = date and time; '18' =reserved line for text from CCU
//     6 textlines from CCU are activated in No 80...85 because there is no physical I/O beyond 79

const byte iomodus_D[87] = { 0,0,
 31, //D2 :      Std-fkt; '15' = IR_Rx??  '6' =ImpCount; '31' =tft;   <<user IO-Shield20<< 
 31, //D3 :      Std-fkt; '7' = 433_Rx??  '6' =ImpCount; '31' =tft;   <<user IO-Shield20<< 
 31, //D4 :      Std-fkt; '7' = 433_Tx??  '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D5 :      Std-fkt;                 '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D6 :      Std-fkt; '9' = buzzer    '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D7 :      Std-fkt;                 '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D8 :      Std-fkt;                 '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 31, //D9 :      Std-fkt; '16' = IR_Tx??  '30' =lcd;     '31' =tft;   <<user IO-Shield20<< 
 0,  //D10 :     Std-fkt; '20' = W5100 SS-Pin;
 0,  //D11 :     Std-fkt;  
 0,  //D12 :     Std-fkt;  
 0,  //D13 :     Std-fkt;
 0,  //D14/TX3 : Std-fkt; '0' =ESP8266;   '12' = rfid3;                <<user IO-Shield-Plus<< 
 0,  //D15/RX3 : Std-fkt; '0' =ESP8266;   '12' = rfid3;                <<user IO-Shield-Plus<< 
 0,  //D16/TX2 : Std-fkt; '0' =ESP8266;   '12' = rfid2;                <<user IO-Shield-Plus<< 
 0,  //D17/RX2 : Std-fkt; '0' =ESP8266;   '12' = rfid2;                <<user IO-Shield-Plus<< 
 0,  //D18/TX1 : Std-fkt; '6' =ImpCount;  '21' =CC3000                 <<user IO-Shield-Plus<< 
 0,  //D19/RX1 : Std-fkt; '6' =ImpCount;                               <<user IO-Shield-Plus<< 
 0,  //D20/SDA : Std-fkt; '6' =ImpCount;  '8' =I2C;                    <<user IO-Shield-Plus<< 
 0,  //D21/SCL : Std-fkt; '6' =ImpCount;  '8' =I2C;                    <<user IO-Shield-Plus<< 
 0,  //D22 :     Std-fkt; Resrved for ESP-01 reset;                        <<user IO-Shield-Plus<< 
 0,  //D23 :     Std-fkt; '12' = rfid2-oeffner;                        <<user IO-Shield-Plus<< 
 0,  //D24 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 0,  //D25 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 0,  //D26 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 4,  //D27 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 0,  //D28 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 2,  //D29 :     Std-fkt;                                              <<user IO-Shield-Plus<< 
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 20, //MISO      '20' =W5100;  '21' =CC3000;   ICSP-Stecker
 20, //MOSI      '20' =W5100;  '21' =CC3000;   ICSP-Stecker
 20, //SCK       '20' =W5100;  '21' =CC3000;   ICSP-Stecker
 0, //SS                      '21' =CC3000;
 31, //D54 A0 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft; '30' =lcd; ser IO-Shield-20<< 
 31, //D55 A1 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft;         <<user IO-Shield-20<< 
 31, //D56 A2 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft;         <<user IO-Shield-20<< 
 31, //D57 A3 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft;         <<user IO-Shield-20<< 
 31, //D58 A4 :  Std-fkt; '10' =analog; '11' =NTC; '31' =tft;         <<user IO-Shield-20<< 
 0,  //D59 A5 :  Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-20<< 
 0,0,  
 0,  //D62 A8 :  Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D63 A9 :  Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D64 A10 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D65 A11 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D66 A12 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D67 A13 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D68 A14 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  //D69 A15 : Std-fkt; '10' =analog; '11' =NTC;                    <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;    '8' =I2C;                               <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;    '8' =I2C;                               <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;    '8' =I2C;                               <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;    '8' =I2C;                               <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 0,  // '0' =andere Nutzg;                                            <<user IO-Shield-Plus<< 
 18, // '18' = reserved for text sent from CCU
 18, // '18' = reserved for text sent from CCU
 18, // '18' = reserved for text sent from CCU
 18, // '18' = reserved for text sent from CCU
 18, // '18' = reserved for text sent from CCU
 18, // '18' = reserved for text sent from CCU
 17  // '17' = reserved for date and time
}; 
//#############################################################################################
//hier werden Sensoren am I2C-Eingang aktiviert
const byte iomodus_baro = 0; //'0' =nc; '1' =BMP180,                   <<user IO-Shield-Plus<<
const byte iomodus_lux =  0; //'0' =nc; '1' =BH1750,                   <<user IO-Shield-Plus<<
//#############################################################################################
//hier werden die Kennwerte fuer die Impulszaehler festgelegt
volatile unsigned long pulsecounter[6] = 
{ 0, //Zaehlerstand fuer D2 -Impulseingang bei Reset                    <<user IO-Shield20<<
 0, //Zaehlerstand fuer D3 -Impulseingang bei Reset                     <<user IO-Shield20<<
 0, //Zaehlerstand fuer D21-Impulseingang bei Reset                     <<user IO-Shield-Plus<< 
 3, //Zaehlerstand fuer D20-Impulseingang bei Reset                     <<user IO-Shield-Plus<< 
 4711, //Zaehlerstand fuer D19-Impulseingang bei Reset                  <<user IO-Shield-Plus<< 
 5 //Zaehlerstand fuer D18-Impulseingang bei Reset                      <<user IO-Shield-Plus<< 
}; 
//hier wird der Teilerfaktor für die Impulszaehler festgelegt
const int pulsedivider[6] = 
{6, //Teilerfaktor D2 :                                                 <<user IO-Shield20<<
 1, //Teilerfaktor D3 :                                                 <<user IO-Shield20<<
 1, //Teilerfaktor D21 :                                                <<user IO-Shield-Plus<<
 1, //Teilerfaktor D20 :                                                <<user IO-Shield-Plus<<
 2, //Teilerfaktor D19 :                                                <<user IO-Shield-Plus<<
 1, //Teilerfaktor D18 :                                                <<user IO-Shield-Plus<<
}; 
//#############################################################################################
//#############################################################################################
//hier werden die anzeigetexte für das tft und lcd display festgelegt 
//Default message placeholder are at #80...#85
const String display_message[87] = {
"0","0",         //                              '0' =keine anzeige
"beweg tuer:    ",  //anzeigetext fuer port D02
"beweg gart:    ",  //anzeigetext fuer port D03
"0","0","0","0","0","0",  // ports belegt durch lcd-shield     
"0",  // belegt durch ethernet W5100-shield, lcd-Shield PIN D10 abbiegen! 
"11 Status :  ",  //anzeigetext fuer port D11                             <<user IO-Shield-20<<
"12 Status :  ",  //anzeigetext fuer port D12                             <<user IO-Shield-20<<
"13 Status :  ",  //anzeigetext fuer port D13                             <<user IO-Shield-20<<
"14 Status :  ",  //anzeigetext fuer port D14 /TX3                        <<user IO-Shield-Plus<<
"RFID Tuer :  ",  //anzeigetext fuer port D15 /RX3                        <<user IO-Shield-Plus<<
"16 Status :  ",  //anzeigetext fuer port D16 /TX2                        <<user IO-Shield-Plus<<
"RFID Gara :  ",  //anzeigetext fuer port D17 /RX2                        <<user IO-Shield-Plus<<
"18 Status :  ",  //anzeigetext fuer port D18 /TX1 /impulszaehler S03     <<user IO-Shield-Plus<<
"19 gas/m3 :  ",  //anzeigetext fuer port D19 /RX1 /impulszaehler S02     <<user IO-Shield-Plus<<
"21 I2C SDA:  ",  //anzeigetext fuer port D20 /SDA /impulszaehler S01     <<user IO-Shield-Plus<<
"21 I2C SCL:  ",  //anzeigetext fuer port D21 /SCL /impulszaehler S00     <<user IO-Shield-Plus<<
"22 ESP-01 :  ",  //anzeigetext fuer port D22                             <<user IO-Shield-Plus<<
"Ladegeraete:  ",  //anzeigetext fuer port D23                            <<user IO-Shield-Plus<<
"24 Bewegt :  ",  //anzeigetext fuer port D24                             <<user IO-Shield-Plus<<
"25 Status :  ",  //anzeigetext fuer port D25                             <<user IO-Shield-Plus<<
"26 Abstand: 123456789",  //anzeigetext fuer port D26                             <<user IO-Shield-Plus<<
"DHT22 V 123456789:  ",  //anzeigetext fuer port D27                             <<user IO-Shield-Plus<<
"28 DS18B20:  ",  //anzeigetext fuer port D28                             <<user IO-Shield-Plus<<
"Dig Out  :  ",  //anzeigetext fuer port D29                             <<user IO-Shield-Plus<<
"0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0",
"0",  // port belegt durch lcd-shield
"Temp_auss.:  ",  //anzeigetext fuer port D55 /A1                         <<user IO-Shield-20<<
"Temp_innen:  ",  //anzeigetext fuer port D56 /A2                         <<user IO-Shield-20<<
"57 Status :  ",  //anzeigetext fuer port D57 /A3                         <<user IO-Shield-20<<
"58 Status :  ",  //anzeigetext fuer port D58 /A4                         <<user IO-Shield-20<<
"59 Spg_A5 :  ",  //anzeigetext fuer port D59 /A5                         <<user IO-Shield-20<<
"0","0",
"62 Status :  ",  //anzeigetext fuer port D62 /A8                         <<user IO-Shield-Plus<<
"63 Status :  ",  //anzeigetext fuer port D63 /A9                         <<user IO-Shield-Plus<<
"64 Status :  ",  //anzeigetext fuer port D64 /A10                        <<user IO-Shield-Plus<<
"65 Status :  ",  //anzeigetext fuer port D65 /A11                        <<user IO-Shield-Plus<<
"66 Status :  ",  //anzeigetext fuer port D66 /A12                        <<user IO-Shield-Plus<<
"67 Status :  ",  //anzeigetext fuer port D67 /A13                        <<user IO-Shield-Plus<<
"68 Status :  ",  //anzeigetext fuer port D68 /A14                        <<user IO-Shield-Plus<<
"Abstand/cm:  ",  //anzeigetext fuer port D69 /A15                        <<user IO-Shield-Plus<<
// die folgenden Anzeigetexte sind für Module mit mehreren Datenpunkten z.b. I2C-Module
"L-Druck/mB:  ",  //anzeigetext fuer I2C 
"L-Temp./C :  ",  //anzeigetext fuer I2C 
"Lux/lx    :  ",   //anzeigetext fuer I2C 
"UV-Index  :  ",  //anzeigetext fuer I2C
"74 Status :  ",  //anzeigetext fuer 
"75 Status :  ",  //anzeigetext fuer 
"76 Status :  ",  //anzeigetext fuer 
"77 Status :  ",  //anzeigetext fuer 
"78 Status :  ",  //anzeigetext fuer 
"79 Status :  ",   //anzeigetext fuer   
"Text 1", //Anzeigetext 1 von CCU
"Text 2", //Anzeigetext 2 von CCU
"Text 3", //Anzeigetext 3 von CCU
"Text 4", //Anzeigetext 4 von CCU
"Text 5", //Anzeigetext 5 von CCU
"Text 6", //Anzeigetext 6 von CCU
"Zeit: " // Default text time and date
};
//#############################################################################################
//#############################################################################################
//hier werden die Zugangsberechtigungen für den RDM6300 Rfid-Reader und FOBs festgelegt
const byte fob_anzahl = 20;
const String fob[3*fob_anzahl] = {
"2381286","eugen","1",   // '0' = kein Tueroeffner                      <<user IO-Shield-Plus<<
"2381287","eugen","1",   // '1' = Tueroeffner1 D22                      <<user IO-Shield-Plus<<
"2381381","eugen","2",   // '2' = Tueroeffner2 D23                      <<user IO-Shield-Plus<<
"2380830","leonie","3",  // '3' = beide Tueroeffner                     <<user IO-Shield-Plus<<
"2409284","fabian","2"   //                                             <<user IO-Shield-Plus<<
"2409385","fabian","2"   //                                             <<user IO-Shield-Plus<<
"2409289","fabian","2"   //                                             <<user IO-Shield-Plus<<
"2519298","not used","0" //                                             <<user IO-Shield-Plus<<
"2519208","not used","0" //                                             <<user IO-Shield-Plus<<
"2519388","not used","0" //                                             <<user IO-Shield-Plus<<
"2519488","not used","0" //                                             <<user IO-Shield-Plus<<
"2511288","not used","0" //                                             <<user IO-Shield-Plus<<
"2529288","not used","0" //                                             <<user IO-Shield-Plus<<
"2619288","not used","0" //                                             <<user IO-Shield-Plus<<
"2719288","not used","0" //                                             <<user IO-Shield-Plus<<
"3519208","not used","0" //                                             <<user IO-Shield-Plus<<
"2519088","not used","0" //                                             <<user IO-Shield-Plus<<
"2519088","not used","0" //                                             <<user IO-Shield-Plus<<
"2510288","not used","0" //                                             <<user IO-Shield-Plus<<
"2510288","not used" "0" //                                             <<user IO-Shield-Plus<<
};
const unsigned long unlock_time1 = 5000; //oeffnungszeit rfid1 in ms    <<user IO-Shield-Plus<<
const unsigned long unlock_time2 = 5000; //oeffnungszeit rfid2 in ms    <<user IO-Shield-Plus<<
const boolean oeffner_polarity = 1;   // '1' normal, '0'  invers        <<user IO-Shield-Plus<<
//#############################################################################################
//#############################################################################################
//#############################################################################################

#include <SPI.h>
#include <Wire.h> 
#include <OneWire.h>   //für Temperatursensoren DS18B20
                       //http://www.hacktronics.com/code/OneWire.zip
#include <NewPing.h>   //für Ultraschallsensoren SR04
                       //https://arduino-new-ping.googlecode.com/files/NewPing_v1.5.zip
#include "DHT.h"       //für Temperatursensoren SHT22
                       //https://github.com/adafruit/DHT-sensor-library/archive/master.zip
#include <AS_BH1750.h> //für I2C-Luxmeter
                       //https://github.com/hexenmeister/AS_BH1750/archive/master.zip
#include <SFE_BMP180.h>//für I2C-Barometer
                       //https://github.com/sparkfun/BMP180_Breakout/archive/master.zip
#include <RCSwitch.h>  // läuft noch nicht!
#include <EEPROM.h>

#include <WiFiEsp.h>   //https://github.com/bportaluri/WiFiEsp
                       //für ESP-01 Modul

//#include <IRremote.h>// läuft noch nicht!

//der folgende Bereich ist bei verwendung w5100 auszukommentieren
//ausblenden mit " #if defined (5100)" funktioniert leider nicht!! 
/*
//Initialisierung des CC3000 Wifi auf dem IO-Shield-Plus  
#include <SFE_CC3000.h>// fuer cc3000 wifi
                 // http://github.com/sparkfun/SFE_CC3000_Library/archive/master.zip
#include <SFE_CC3000_Client.h>
// Pins
#define CC3000_INT 18  // int-Pin mit Wifi Shield ist D3, mit breakout auf IO-Shield-Plus D18
#define CC3000_EN 46   // en-Pin mit Wifi Shield ist D5, mit breakout auf IO-Shield-Plus  D46
#define CC3000_CS 53   // cs-Pin mit Wifi Shield ist D10, mit breakout auf IO-Shield-Plus D53
SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS);
SFE_CC3000_Client client = SFE_CC3000_Client(wifi);
unsigned int ap_security = WLAN_SEC_WPA2; // Security of network
unsigned int timeout = 30000; // Milliseconds
char server[] = "192,168,178,50"; // Remote host site
*/
#if defined (w5100)  //************************************************************************ 
//der folgende Bereich ist die Initialisierung des LAN bei Verwendung des LAN-Shields
#include <Ethernet.h> 
EthernetClient client;
EthernetServer server(80);
#endif  //************************************************************************************* 

#if defined (esp8266)
    WiFiEspClient client;
    WiFiEspServer server(80);
#endif 
    unsigned long reqCount = 0;

#if defined(tft_display)  //*******************************************************************
#include <Adafruit_GFX.h>    //Quelle: https://github.com/adafruit/Adafruit-GFX-Library
#include <Adafruit_TFTLCD.h> //Quelle:   https://github.com/buhosoft/TFTLCD-Library
#include <stdint.h>
#include "TouchScreen.h"      
//Quelle: http://www.smokeandwires.co.nz/blog/a-2-4-tft-touchscreen-shield-for-arduino/

#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0
#define tft_rotation 3 //3 oder 1 abhägig vom tft-shield typ  Achtung! bei 3 und IL9327 Offset beobachtet   <<user-eingabe<< 
#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin


Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
int touch_y;
const byte zeilenzahl = 6; //set 6 for ...x240 displays, set 8 for ...x320 displays 
int px,py,pz;
unsigned long next_touch_time = 0; 
int fontgroesse;
int espbyte = 0;
boolean centertouch = 1;
boolean receivingcommand = false;

//2,4'' display 320x240
/*
const long int px_A = 901,  py_A = 183;  //touch-koordinaten oben-links                
const long int px_B = 192,  py_B = 189;  //touch-koordinaten oben-rechts              
const long int px_C = 936,  py_C = 860;  //touch-koordinaten unten-links              
#define schriftgroesse 3 
#define tft_type 1   // 1 ist 2,4''display   2 ist 3.95''display
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 330);
*/

//3,95'' display 480x320
const long int px_A = 188, py_A = 792;  //touch-koordinaten oben-links               
const long int px_B = 154,  py_B = 106;  //touch-koordinaten oben-rechts             
const long int px_C = 890,  py_C = 873;  //touch-koordinaten unten-links             
#define schriftgroesse 2  
#define tft_type 2   // 1 ist 2,4''display   2 ist 3.95''display
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 330);

/*
//3,5'' display 400x240 controller: IL9327
const long int px_A = 946,  py_A = 135;  //touch-koordinaten oben-links                
const long int px_B = 76,   py_B = 118;  //touch-koordinaten oben-rechts              
const long int px_C = 953,  py_C = 893;  //touch-koordinaten unten-links              
#define schriftgroesse 3 
#define tft_type 3   // 1 ist 2,4''display   2 ist 3.95''display   3 ist 3,5" Display
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 330);
*/
/*
//3,5'' display 480x320 controller: IL9341
const long int px_A = 980,  py_A = 110;  //touch-koordinaten oben-links                
const long int px_B = 83,   py_B = 127;  //touch-koordinaten oben-rechts              
const long int px_C = 957,  py_C = 909;  //touch-koordinaten unten-links              
#define schriftgroesse 3 
#define tft_type 4   // 1 ist 2,4''display   2 ist 3.95''display   3 ist 3,5" Display
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 330);
*/
/*
//2,8'' display 320x240 Elegoo controller: IL9341
//https://www.amazon.de/gp/product/B01EUVJYME?ref%5F=pe%5F386171%5F51767411%5FTE%5Fdp%5F2&pldnSite=1
const long int px_A = 148,  py_A = 96;  //touch-koordinaten oben-links                
const long int px_B = 135,  py_B = 914;  //touch-koordinaten oben-rechts              
const long int px_C = 913,  py_C = 103;  //touch-koordinaten unten-links              
#define schriftgroesse 2 
#define tft_type 5   // 1 ist 2,4''display   2 ist 3.95''display   3 ist 3,5" Display
#define YP A3 // must be an analog pin, use "An" notation!
#define XM A2 // must be an analog pin, use "An" notation!
#define YM 9  // can be a digital pin
#define XP 8  // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
*/

// color definitions for e.g. ILI9327 TFT, tft_type == 3 or 5
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

// color definitions for e.g. ILI9341 TFT tft_type == 4
//#define BLACK   0xFFFF  
//#define BLUE    0xFFE0 
//#define RED     0x07FF 
//#define GREEN   0xF81F 
//#define CYAN    0xF800 
//#define MAGENTA 0x07E0 
//#define YELLOW  0x001F 
//#define WHITE   0x0000 

#define default_color WHITE //standard text color on TFTs   <-- User Eingabe


long int p_x, p_y ;   //normierte aktuelle touch-koordinaten: 
                      //oben links ist 0,0 und unten rechts ist 1000,1000
#endif  //*************************************************************************************

#if defined(lcd_display)  //*******************************************************************
//https://www.dfrobot.com/wiki/index.php?title=Arduino_LCD_KeyPad_Shield_%28SKU:_DFR0009%29
#include <LiquidCrystal.h> 
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // initialize library with numbers of the interface pins
const byte zeilenzahl = 2;
#endif  //*************************************************************************************

int x, x_alt;
byte zeile_pointer[8];
String zeile_data[8] = {"     ","     ","     ","     ","     ","     ","     ","     "};
String display_zeile_alt[8],display_zeile[8];
int text_line;
String text_content = "";
long int text_farbe;
String taster;

char zeichen,buffer[50];
boolean fob_da =0;
String zeich, fob_hex, fob_dec,Name, lcd_rfid_message, oeffner, Value;
unsigned long fob_zahl,time_rfid3 = 0,time_rfid2 = 0; 
byte zeichen_zahl;

//********************************************************************************************* 
AS_BH1750 sensor; //Initialize BH1750 Luxmeter library
float lux;
long Lux;
int laenge;
const float ALTITUDE = 299.0; // eigene seehoehe in metern              <<user IO-Shield-Plus<<
SFE_BMP180 pressure;
char status;
double T,P,p0;
boolean reading = false;
String command = "";

String baro_string,baroT_string, lux_string;
//********************************************************************************************* 
boolean last_digital_value_D[88];
float last_value_D[88],last_IR_value,last_RF_value;
unsigned long next_Time[88];  
double last_baro_value,last_baroT_value;
boolean complete_loop =1; // wenn 1, dann einmal komplett durchlaufen
String befehl,sub_command = String(20),parameter = String(20),header = String(20);
int param,port_pin;
boolean port_data;
boolean value;
String I;
int analogwert;
//********************************************************************************************* 
float tempNTC;
const float B_wert = 3950; //aus dem Datenblatt des NTC //<<user-eingabe<<
const float Tn = 298.15; //25°Celsius in °Kelvin 
const float Rv = 10000; //Vorwiderstand
const float Rn = 10000; //NTC-Widerstand bei 25°C
float Rt,temp_tur,humidity;
 
const float delta_onewire = 0.2; //Deltas für Sendeauslösung 
const float delta_DHT = 0.2; //in °C 
const float delta_us = 5.0; // in cm
const float delta_analog = 2.0; // in inkrement
const float delta_ntc = 0.5; //in °C
const float delta_lux = 15; //in lux
const float delta_counter = 5; //in counter inkrement
const double delta_baro = 0.5; //in mB
const double delta_baroT = 0.5; //in °C
 
long duration, cm; //variable für Ultraschallsensor
unsigned long time_sr04;
 
unsigned long next_full_loop = 0;
unsigned long delta_time = 3600000; // jede Stunde werden alle Inputs aktualisiert
unsigned long delta_tx = 200; //in ms, minimaler Abstand der Telegramme an die CCU
unsigned long next_tx = 0, time_wait = 0; 

int rf_key;
String rfkey;
RCSwitch mySwitch = RCSwitch();

unsigned zaehlwert;
unsigned last_zaehlwert[6] = {0,0,0,0,0,0};

unsigned long previousMillis = 0,  years = 0;
unsigned int seconds = 0, minutes = 0, hours = 0, days = 0, months = 0;
//#############################################################################################
//#############################################################################################
void setup() 
{Serial.begin(115200); 
 command.reserve(100); // reserve memory for the CCU text to avoid memory fragmentation and buffer overruns. Remember: Space becomes %20 (3 characters) instead of one character
                       // %20 is replaced by ' ' AFTER transmission
text_content.reserve(60);
previousMillis = millis();
 
//+++++++ einrichtung der interrupts fuer impulszahler D2,D3,D18,D19,D20,D21
 if ((pulsedivider[0] > 0) && (iomodus_D[2] == 6)) 
   {pinMode(2, INPUT_PULLUP); attachInterrupt(0, ISR_0, FALLING);}
 if ((pulsedivider[1] > 0) && (iomodus_D[3] == 6)) 
   {pinMode(3, INPUT_PULLUP); attachInterrupt(1, ISR_1, FALLING);} 
 if ((pulsedivider[2] > 0) && (iomodus_D[21] == 6)) 
   {pinMode(21, INPUT_PULLUP); attachInterrupt(2, ISR_2, FALLING);}
 if ((pulsedivider[3] > 0) && (iomodus_D[20] == 6)) 
   {pinMode(20, INPUT_PULLUP); attachInterrupt(3, ISR_3, FALLING);}
 if ((pulsedivider[4] > 0) && (iomodus_D[19] == 6)) 
   {pinMode(19, INPUT_PULLUP); attachInterrupt(4, ISR_4, FALLING);}

 #if defined (w5100)  //************************************************************************* 
 if ((pulsedivider[5] > 0) && (iomodus_D[18] == 6))  //interrupt reserviert fuer cc3000
   {pinMode(18, INPUT_PULLUP); attachInterrupt(5, ISR_5, FALLING);}
 #endif  //*************************************************************************************

//+++++++ rfid initialisieren
// if ((iomodus_D[15] == 12) && (iomodus_D[14] == 12)){Serial3.begin(9600);}
// if ((iomodus_D[17] == 12) && (iomodus_D[16] == 12)){Serial2.begin(9600);}

#if defined (lcd_display)  //******************************************************************
//+++++++ lcd initialisieren
 lcd.begin(16, 2); delay(200);  //16 zeichen in 2 zeilen
 lcd.setCursor(0,0);
 lcd.print(F(" Homeduino 5.04 "));
 #endif  //*************************************************************************************

#if defined (tft_display)  //******************************************************************
//+++++++ tft initialisieren
 tft.reset();
 int identifier = tft.readID();  
 if (identifier == 0)
  {Serial.print(F("Unknown LCD driver chip: "));
    Serial.println(identifier, HEX);
    Serial.print(F("I try use ILI9341 LCD driver "));
    identifier = 0x9341;
  }
 tft.begin(identifier);
 Serial.print(F("TFT identifier:" )); Serial.println(identifier, HEX);   
 delay(100);
 tft.fillScreen(BLACK); tft.setRotation(tft_rotation);
 if (tft_type ==1) //2,4'' display 320x240
   {tft_print (1,"  Homeduino",4,YELLOW);
    tft_print (2,"     5.04",4,YELLOW);
    tft_print (5,"www.stall.biz",4,CYAN);
    tft.drawRect(0,0, 319, 240, GREEN);
   } 
  if (tft_type ==2)  //3,95'' display 480x320
   {tft_print (1,"   Homeduino",5,YELLOW);
    tft_print (2,"      5.04",5,YELLOW);
    tft_print (5," www.stall.biz",5,CYAN);
    tft.drawRect(5,5, 475, 310, GREEN);
   }   
if (tft_type ==3) //3,5'' display 400x240
   {tft_print (1,"  Homeduino",5,YELLOW);
    tft_print (2,"     5.04",5,YELLOW);
    String wlan_ssid = " Connecting to WLAN: " + String::String(ap_ssid);
    tft_print (4,wlan_ssid,2,WHITE);
    tft_print (5,"  www.stall.biz",4,CYAN);
    tft.drawRect(0,0, 399, 239, GREEN);
   } 
if (tft_type ==4) //3,5'' display 480x320
   {tft.fillScreen((BLACK));
    tft_print (1,"   Homeduino",5,(YELLOW));
    tft_print (2,"      5.04",5,(YELLOW));
    String wlan_ssid = " Connecting to WLAN: " + String::String(ap_ssid);
    tft_print (4,wlan_ssid,2,(WHITE));
    tft_print (5,"   www.stall.biz",4,CYAN);
    tft.drawRect(0,0, 480, 320, (GREEN));
//
  #ifdef DEBUG
    Serial.println(F("Printing colored rectangles to check the color definitions:"));
    Serial.println(F("BLACK, BLUE, RED, GREEN, CYAN, MAGENTA, YELLOW, WHITE"));
    tft.fillRect(125,280, 20, 20, (BLACK));
    tft.fillRect(155,280, 20, 20, (BLUE));
    tft.fillRect(185,280, 20, 20, (RED));
    tft.fillRect(215,280, 20, 20, (GREEN));
    tft.fillRect(245,280, 20, 20, (CYAN));
    tft.fillRect(275,280, 20, 20, (MAGENTA));
    tft.fillRect(305,280, 20, 20, (YELLOW));
    tft.fillRect(335,280, 20, 20, (WHITE));
  #endif    
   } 
if (tft_type ==5) //2,8'' Elegoo display 320x240
   {tft.fillScreen((BLACK));
    tft_print (1," Homeduino",5,(YELLOW));
    tft_print (2,"   5.04",5,(YELLOW));
    String wlan_ssid = " Connecting to WLAN: " + String::String(ap_ssid);
    tft_print (4,wlan_ssid,1,(WHITE));
    tft_print (3,"  www.stall.biz",3,CYAN);
    tft.drawRect(0,0, 320, 240, (GREEN));
//
  #ifdef DEBUG
    Serial.println(F("Printing colored rectangles to check the color definitions:"));
    Serial.println(F("BLACK, BLUE, RED, GREEN, CYAN, MAGENTA, YELLOW, WHITE"));
    tft.fillRect(45,210, 20, 20, (BLACK));
    tft.fillRect(75,210, 20, 20, (BLUE));
    tft.fillRect(105,210, 20, 20, (RED));
    tft.fillRect(135,210, 20, 20, (GREEN));
    tft.fillRect(165,210, 20, 20, (CYAN));
    tft.fillRect(195,210, 20, 20, (MAGENTA));
    tft.fillRect(225,210, 20, 20, (YELLOW));
    tft.fillRect(255,210, 20, 20, (WHITE));
  #endif    
   } 

#endif  //*************************************************************************************

for(int i=0; i<zeilenzahl; i++)
   {zeile_pointer[i] = EEPROM.read(i);  //anzeige-pointer aus eeprom holen
    if (zeile_pointer[i] >86) {zeile_pointer[i] = 0;}  //wenn eeprom erstes mal benutzt wird
   } 

#if defined (w5100)  //************************************************************************
//hier folgt die LAN Initialisierung 
char myIpString[24];
 if (Ethernet.begin(mac) == 0) // start the Ethernet connection:
   {Serial.println(F("Failed to configure Ethernet using DHCP")); Ethernet.begin(mac, homeduino);}
    delay(1000);// give the Ethernet shield a second to initialize:
    Serial.println(F("connecting...")); // if you get a connection, report back via serial:
 if (client.connect(ccu, 8181)) {}
   else {Serial.println(F("connection failed"));} // if you didn't get a connection to the server:
 client.stop(); 
 IPAddress myIp = Ethernet.localIP();
 sprintf(myIpString, "%d.%d.%d.%d", myIp[0], myIp[1], myIp[2], myIp[3]); 
 I = myIpString;
 befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"IP"+"').State('"+ I + "')";
 set_sysvar(); 
 server.begin();
#endif  //*************************************************************************************

#if defined (cc3000)  //**********************************************************************
// hier folgt die CC3000 Initialisierung 
 ConnectionInfo connection_info;
 char myIpString[24]; 
 Serial.println(F("SparkFun CC3000 - WebClient"));
 if ( wifi.init() ) {Serial.println(F("init complete"));} 
 else {Serial.println(F("problem with init!"));}
 // Connect using DHCP
 if (!wifi.connect(ap_ssid, ap_security, ap_password, timeout)) 
   {Serial.println(F("no connection to AP"));}
 //build IP address
 if ( !wifi.getConnectionInfo(connection_info) ) {Serial.println(F("no connection details"));} 
   else {sprintf(myIpString, "%d.%d.%d.%d", connection_info.ip_address[0], 
   connection_info.ip_address[1],connection_info.ip_address[2], connection_info.ip_address[3]); 
         I = myIpString;
        }
 befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"IP"+"').State('" + I + "')";
 set_sysvar(); 
 client.stop();
#endif  //*************************************************************************************

#if defined (esp8266)  //**********************************************************************
// Starting ESP8266 Init 
    #ifdef DEBUG
        Serial.print(F("SERIAL_TX_BUFFER_SIZE: ")); Serial.println(SERIAL_TX_BUFFER_SIZE);
        Serial.print(F("SERIAL_RX_BUFFER_SIZE: ")); Serial.println(SERIAL_RX_BUFFER_SIZE);
    #endif
       char myIpString[24]; 
       pinMode(22,OUTPUT); digitalWrite(22,1); // Reset-Pin auf 1 setzen
       Serial3.begin(115200); // Standard baudrate for current ESP-01 modules with Espressif firmware. Old ones use 9600 baud
        // initialize ESP module to different baudrate. HANDLE WITH CARE!!! Only enable next lines if you know what you are doing!
/*        Serial3.write("AT+UART_DEF=115200,8,1,0,0\r\n"); //Modify default baudrate of 115200 (current Espressif FW) to reduce ESP Timeout Problems
        Auf_OK_warten(); //Only throws OK when the module is reconfigured for the first time. On subsequent boots a Timeout occurs because the comm-rate already IS @ the target rate
        Serial3.end();
        delay(3000); 
        Serial3.begin(115200); 
*/        
       Serial.println(F("Resetting ESP-01 module"));
       digitalWrite(22,0); delay(100); digitalWrite(22,1); delay(1000);//reset-Impuls ausgeben und Bootmeldungen abwarten
       Serial.println(F("Espressif ESP8266 - WebClient"));

        Serial3.write("AT\r\n");
        Auf_OK_warten(); //wait until reset is completed and ESP-01 responds again

      // initialize ESP module
        WiFi.init(&Serial3);
      
       // check for the presence of the shield
        if (WiFi.status() == WL_NO_SHIELD) {
          Serial.println(F("WiFi shield not present"));
          tft_print (4," No WLAN shield! STOP!!!",2,(RED));
          tft_print (3,"",3,BLACK);
            if (tft_type ==5) //2,8'' Elegoo display 320x240
            {tft.drawRect(0,0, 320, 240, (RED));}
          // don't continue
          while (true);
        }

            // attempt to connect to WiFi network
          while ( status != WL_CONNECTED) {
            Serial.print(F("Attempting to connect to WPA SSID: "));
            Serial.println(ap_ssid); 
            tft_print (4,"     WLAN shield ok - trying to connect...",1,(MAGENTA));
            if (tft_type ==5) {tft.drawRect(0,0, 320, 240, (MAGENTA));}               //2,8'' Elegoo display 320x240
            // Connect to WPA/WPA2 network
            status = WiFi.begin(ap_ssid, ap_password);
            }

              // you're connected now, so print out the data
            Serial.println(F("You're connected to the network"));
            
             // print the SSID of the network you're attached to
              Serial.print(F("SSID: "));
              Serial.println(WiFi.SSID());
            
              // print your WiFi shield's IP address
              IPAddress ip = WiFi.localIP();
              Serial.print(F("IP Address: "));
              Serial.println(ip);
              sprintf(myIpString, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
              I = myIpString;
              // print my MAC address
              byte mac[6];
              WiFi.macAddress(mac);
              char buf[20];
              sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]);
              Serial.print(F("MAC address: "));
              Serial.println(buf);
#if defined DEBUG
              Serial.print(F("String IP Address: "));
              Serial.println(myIpString);
#endif
              // print the received signal strength
              long rssi = WiFi.RSSI();
              Serial.print(F("Signal strength (RSSI):"));
              Serial.print(rssi);
              Serial.println(F(" dBm"));
              delay(6000); //let the Wifi connection establish itself
              Serial.println(F("Announcing my IP"));
              befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"IP"+"').State('"+ I + "')";
              set_sysvar(); 
              server.begin();
       
#endif  //*************************************************************************************


#if defined (lcd_display)  //****************************************************************** 
    //bei erfolgreichem einloggen ausgabe ip-adresse 
    lcd.setCursor(0,1);
    lcd.print(myIpString);
    delay(3000);
#endif  //*************************************************************************************

#if defined (tft_display) //*******************************************************************
//bei erfolgreichem einloggen ausgabe ip-adresse 
tft.fillScreen(BLACK);
if (tft_type ==1) //2,4'' display
  {tft.setCursor(8, 230); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(1);
   tft.print(Version + "   Homeduino IP: "); tft.print(myIpString);
  }
if (tft_type ==2) //3,95'' display 480x320
  {tft.setCursor(1, 300); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(2);
   tft.print(Version + " IP: "); tft.print( myIpString);
  }
if (tft_type ==3) //3,5'' display 400x240
  {tft.setCursor(0, 230); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(1);
   tft.print(Version + "   " + hm_systemvariable); tft.print( myIpString);
//   Serial.print(Version + "   Homeduino IP: "); Serial.print( myIpString); tft.print("   Nr.: " + homeduino_nummer);
  }
if (tft_type ==4) //3,5'' display 480x320
  {tft.setCursor(0, 310); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(1);
   tft.print(Version + "   " + hm_systemvariable); tft.print( myIpString);
//   Serial.print(Version + "   Homeduino IP: "); Serial.print( myIpString); tft.print("   Nr.: " + homeduino_nummer);
  }
if (tft_type ==5) //2,8'' Elegoo display 320x240
  {tft.setCursor(0, 230); //fusszeile
   tft.setTextColor(GREEN);  
   tft.setTextSize(1);
   tft.print(Version + "   " + hm_systemvariable); tft.print( myIpString);
//   Serial.print(Version + "   Homeduino IP: "); Serial.print( myIpString); tft.print("   Nr.: " + homeduino_nummer);
  }

#endif  //*************************************************************************************
for (int i = 0; i < 87; i++) {next_Time[i]=0;} //
 //delay(2000);
}
//#############################################################################################
//#############################################################################################
void loop() 
{
/* Enable following sequence to see the available character map.   
  tft.setCursor(0, 0); 
   tft.setTextColor(WHITE);  
   tft.setTextSize(3);
  for (int m = 0; m < 256; m++)
   {tft.print(char(m));}
  while (true); //end of character map sequence
*/   
  complete_loop = 0;
 if (millis() > next_full_loop) //mindestens jede Stunde eine komplette Aktualisierung
   {complete_loop = 1; next_full_loop = millis() + delta_time; 
    if (next_full_loop < millis()) {complete_loop = 0;} //wichtig wegen Zahlensprung 
                                                        //von millis() alle 50 Tage
   } 

//*********************************************************************************************
 for (int i = 2; i < 87; i++) //behandlung aller Ports D2 bis D69 und der Texte
 {while ((iomodus_D[i] == 0) || (iomodus_D[i] >29 )) {i++;}  // unbenutzte pins überspringen
// Serial.print("i: "); Serial.println(i);
  datenempfang(); //nach jeder Messung auf Datenempfang schalten
  display_data(); //display ausgeben und abfragen
  clockservice(); //update the clock
 //******************************************************************************************** 
 if (iomodus_D[i] == 1) //behandlung digitaleingänge 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +1000;  //digitaleingänge nicht häufiger als alle 1000ms abfragen
       pinMode(i, INPUT_PULLUP); 
       digitalWrite(i, HIGH);
       value =digitalRead(i);
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) 
            {if (value ==0) {zeile_data[m] = "LOW";} else {zeile_data[m] = "HIGH";}}}
       if ((!value == last_digital_value_D[i]) || complete_loop) 
         {I = String(i);
           befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+value+"')";
          set_sysvar();
          last_digital_value_D[i] = value;
         }
      } 
   }
   datenempfang();
//********************************************************************************************* 
 if (iomodus_D[i] == 3) //behandlung onewire 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +10000;  //onewire nicht häufiger als alle 10s abfragen 
       pinMode(i, INPUT_PULLUP);
       digitalWrite(i,HIGH);
       OneWire ds(i); 
       #define DS18S20_ID 0x10
       #define DS18B20_ID 0x28 
       byte present = 0;   byte data[12];    byte addr[8];
       temp_tur = 1000.0;
       if (!ds.search(addr)) { ds.reset_search(); temp_tur = -1000.0; } //find a device
       if ((OneWire::crc8( addr, 7) != addr[7]) && (temp_tur > -1000.0)) {temp_tur = -1000.0; }
       if ((addr[0] != DS18S20_ID && addr[0] != DS18B20_ID)&& (temp_tur > -1000.0)) 
         {temp_tur = -1000.0;}
       if (temp_tur > -1000.0) 
         {ds.reset(); 
          ds.select(addr); 
          ds.write(0x44, 1); // Start conversion
          //delay(850); // Wait some time...
          time_wait = millis() +850;                                  //wahrend der 2s wartezeit, daten empfangen, clock
          while (millis() < time_wait) {datenempfang();display_data;clockservice();} //und display weiter bedienen 
          present = ds.reset(); 
          ds.select(addr);
          ds.write(0xBE); // Issue Read scratchpad command
          for ( int k = 0; k < 9; k++) { data[k] = ds.read(); } // Receive 9 bytes
          temp_tur = ( (data[1] << 8) + data[0] )*0.0625; // Calculate temperature value 18B20
          //temp_tur = ( (data[1] << 8) + data[0] )*0.5 // Calculate temperature value 18S20
         }
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = String(temp_tur,1);}
         }
       if ((temp_tur > (last_value_D[i] + delta_onewire)) 
                            || (temp_tur < (last_value_D[i] - delta_onewire)) || complete_loop) 
         {I = String(i);
           befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+temp_tur+"')";
          set_sysvar();
          last_value_D[i] = temp_tur;
         }
      }   
  }
  datenempfang();
//********************************************************************************************* 
 if (iomodus_D[i] == 4) //behandlung DHT temperatur- und feuchtesensoren
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +30000;  //DHT nicht häufiger als alle 30s abfragen 
       DHT dht(i, DHT22); //je nach verwendetem sensor "DHT11", "DHT22" (AM2302),"DHT 21" (AM2301)
       dht.begin();
       //delay(2000); // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
       time_wait = millis() +2000;                                 //wahrend der 2s wartezeit, daten empfangen, clock
       while (millis() < time_wait) {datenempfang();display_data;clockservice();} //und display weiter bedienen 
       humidity = dht.readHumidity(); // Read temperature as Celsius
       temp_tur = dht.readTemperature(); 
       if (isnan(humidity) || isnan(temp_tur) ) // Check if any reads failed and 
         {//Serial.println("Failed to read from DHT sensor!");
          temp_tur = -1000;
         }
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = (String(temp_tur,1) + (char(247)) + "C/" + String(humidity,1) + "%");}
         }
       if ((temp_tur > (last_value_D[i] + delta_DHT))|| (temp_tur < (last_value_D[i] - delta_DHT)) 
                                                  || complete_loop) 
         {I = String(i);
          befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+temp_tur+"')";
          set_sysvar();
           befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"_1').State('"+humidity+"')";
          set_sysvar();
          last_value_D[i] = temp_tur;
        } 
     }
   } 
 //******************************************************************************************** 
 if (iomodus_D[i] == 5) //behandlung ultraschallsensoren 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +2000;  //ultraschall nicht häufiger als alle 2s abfragen 
 //achtung: zu beachten 
 //bei verwendung der US-Sensoren beim IO-Shield-Plus sind die 150-Ohm-Schutzwiderstände 
 //zu überbrücken (Jumper setzen!), entsprechend beim IO-Shield20 der Jumper 4-5 zu setzen!! 
       NewPing sonar(i, i, 200); // NewPing setup of pin and maximum distance.
       unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
       int cm = uS / US_ROUNDTRIP_CM;
       if (cm == 0) {}
       else {
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = (String(cm) + "cm");}} // display_value[i] = (String(cm) + "cm");} }
          if ((cm > (last_value_D[i] + delta_us)) || (cm < (last_value_D[i] - delta_us)) || complete_loop) 
            {I = String(i);
              befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+cm+"')";
             set_sysvar();
             last_value_D[i] = cm;
            }
       } 
      }
   }
   datenempfang();
//********************************************************************************************* 
 if (iomodus_D[i] == 10) //behandlung analogeingänge 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +1000;  //analogeingänge nicht häufiger als alle 1000ms abfragen 
       analogwert =analogRead(i);
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = String(analogwert);}}
       if ((analogwert > (last_value_D[i] + delta_analog)) 
                || (analogwert < (last_value_D[i] - delta_analog)) || complete_loop) 
         {I = String(i);
         Serial.print(F("i6: ")); Serial.println(i);
           befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State6("+analogwert+")";
          set_sysvar();
          last_value_D[i] = analogwert;
         }
      }
   } 
   datenempfang();
//*********************************************************************************************
 if (iomodus_D[i] == 11) //behandlung NTC 
   {if (millis() > next_Time[i])
      {next_Time[i] = next_Time[i] +10000;  //NTC-eingänge nicht häufiger als alle 10s abfragen
       Rt = Rv/((1024.0/analogRead(i))- 1.0);
       tempNTC = (B_wert * Tn / ( B_wert + (Tn * log(Rt/Rn)))) -Tn +25.0 ;
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = String(tempNTC,1);}}
          if ((tempNTC > (last_value_D[i] + delta_ntc)) || (tempNTC < (last_value_D[i] - delta_ntc)) 
                                                   || complete_loop) 
            {I = String(i);
              befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+tempNTC+"')";
             set_sysvar();
             last_value_D[i] = tempNTC;
            } 
      }
   }    
   datenempfang(); 
//********************************************************************************************* 
 if (iomodus_D[i] == 6) //behandlung impulszahler D2,D3,D21,D20,D19,D18 
   {byte offset =23;
    if (i ==2) {offset = 4;} if (i ==3) {offset = 6;}
    zaehlwert = pulsecounter[offset - i ] / pulsedivider[offset - i ];
    for (int m=0; m < zeilenzahl; m++)
      {if (zeile_pointer[m] == i) {zeile_data[m] = String(zaehlwert);}}
       if ((pulsedivider[offset -i] > 0) && ((zaehlwert > (last_zaehlwert[offset - i]+ delta_counter) 
                           || complete_loop))) 
         {I = String(offset -i);
           befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"imp"+I+"').State('"+zaehlwert+"')";
          set_sysvar();
          last_zaehlwert[offset - i] = zaehlwert;
         } 
   }
   datenempfang(); 
//*********************************************************************************************
//behandlung I2C sensoren an pin 20(sda) und pin 21 (scl)
 if ((iomodus_D[i] == 8)&&(i == 20))
   {i++;  // da I2C Bus 2 eingaenge belegt
  
//behandlung Luxmeter BH1750 an SCL pin21 und SDA pin 20 ***********************************
// for normal sensor resolution (1 lx resolution, 0-65535 lx, 120ms, no PowerDown) 
//use: sensor.begin(RESOLUTION_NORMAL, false); 
    if (iomodus_lux ==1)
      {if (millis() > next_Time[72])
         {next_Time[72] = next_Time[72] +5000;  //luxmeter nicht häufiger als alle 5s abfragen 
          if(!sensor.begin()) { Serial.println(F("Sensor not present")); }
          lux = sensor.readLightLevel(); //delay(1000);
          Lux = (int)lux;
          //Serial.print(F("Helligkeit/lux: ")); Serial.print(lux); Serial.println();
          lux_string = "      " + String(Lux);
          int laenge = lux_string.length();
          lux_string = lux_string.substring(laenge -6,laenge);
          for (int m=0; m < zeilenzahl; m++)
            {if (zeile_pointer[m] == 72) {zeile_data[m] = lux_string;}}
             if (((Lux > (last_value_D[72] + delta_lux)) || (Lux < (last_value_D[72] - delta_lux)) 
                                                || complete_loop)) 
               {befehl="GET /xy.exe?antwort=dom.GetObject('" + hm_systemvariable+"lux"+"').State('"+Lux+"')";
                set_sysvar();
                last_value_D[72] = Lux;
               }
         } 
       } 
   datenempfang(); 
       
   //behandlung barometer BMP180 an SCL pin21 und SDA pin 20
    if (iomodus_baro ==1)
      {if (millis() > next_Time[70])
         {next_Time[70] = next_Time[70] +30000;  //barometer nicht häufiger als alle 30s abfragen 
          if (pressure.begin()) {status = pressure.startTemperature();}
          if (status) {delay(status); status = pressure.getTemperature(T);} //messung T
          if (status) {status = pressure.startPressure(3);} // //messung P mit resolution 0 bis 3
          if (status) {delay(status); status = pressure.getPressure(P,T);}
          if (status) {p0 = pressure.sealevel(P,ALTITUDE);} // umrechnung auf N.N.
//Serial.print("Hoehe/m: "); Serial.print(ALTITUDE); Serial.print(" Temperatur/C: "); 
//Serial.print(T); Serial.print(" Normaldruck /mb: "); Serial.println(p0); 
          baro_string = "     " + String(p0);
          laenge = baro_string.length();
          baro_string = baro_string.substring(laenge -7,laenge -1);
          baroT_string = "      " + String(T);
          laenge = baroT_string.length();
          baroT_string = baroT_string.substring(laenge -7,laenge -1);
          for (int m=0; m < zeilenzahl; m++) {if (zeile_pointer[m] == 70) {zeile_data[m] = baro_string;}}
          if ((p0 > (last_baro_value + delta_baro)) || (p0 < (last_baro_value - delta_baro)) 
                                                || complete_loop) 
            {befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"baro"+"').State('"+p0+"')";
             set_sysvar();
             last_baro_value = p0;
             last_value_D[70] = p0;
            }
          for (int m=0; m < zeilenzahl; m++) {if (zeile_pointer[m] == 71) {zeile_data[m] = baroT_string;}}  
          if ((T > (last_baroT_value + delta_baroT)) || (p0 < (last_baroT_value - delta_baroT)) 
                                                     || complete_loop) 
            {befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"baroT"+"').State('"+T+"')";
             set_sysvar();
             last_baroT_value = T;
             last_value_D[71] = T;
            } 
         }
      } 
      datenempfang();
  }  
//*********************************************************************************************
 if (iomodus_D[3] == 7) //behandlung 433Mhz-rx 
   {if (mySwitch.available()) 
      {int value = mySwitch.getReceivedValue();
       if (value == 0) {client.print(F("Unknown encoding"));} 
          else {Serial.print(F("Pin D3 received : "));
                Serial.print (mySwitch.getReceivedValue() );
                Serial.print (F(" / "));
                Serial.print( mySwitch.getReceivedBitlength() );
                Serial.print(F("bit Protocol: "));
                Serial.println( mySwitch.getReceivedProtocol() + " \n\r" );
               }
      mySwitch.resetAvailable();
     }
   } 
   datenempfang();
  //******************************************************************************************* 
 if ((iomodus_D[i] == 12) && (i==22))  //behandlung rfid3 tueroeffner an D22 des Mega
   {pinMode(i,OUTPUT);
    if (millis()< time_rfid3)         //D22-als normal-Ausgang für tueröffner schalten
      {Value = " AUF"; 
       if (oeffner_polarity) {digitalWrite(i, HIGH);} else {digitalWrite(i,LOW);}
       }
         else {Value = "  ZU"; if (!oeffner_polarity) 
                               {digitalWrite(i, HIGH);} else {digitalWrite(i,LOW);}}
       for (int m=0; m < zeilenzahl; m++)
         {if (zeile_pointer[m] == i) {zeile_data[m] = Value;}}
    }
  if ((iomodus_D[i] == 12) && (i==23))  //behandlung rfid2 tueroeffner  an D23 des Mega
    {pinMode(i,OUTPUT);
     if (millis()< time_rfid2)         //D23-als normal-Ausgang für tueröffner schalten
       {Value = " AUF"; if (oeffner_polarity) 
                          {digitalWrite(i, HIGH);} 
                          else {digitalWrite(i,LOW);}}
       else {Value = "  ZU"; if (!oeffner_polarity) {digitalWrite(i, HIGH);} 
                                                    else {digitalWrite(i,LOW);}} 
     for (int m=0; m < zeilenzahl; m++)
       {if (zeile_pointer[m] == i) {zeile_data[m] = Value;}
       }
    }
    datenempfang();
 //******************************************************************************************** 
if (iomodus_D[i] == 18)  //Behandlung reine Texte von CCU
    {for (int m=0; m < zeilenzahl; m++)
       {if (zeile_pointer[m] == i) {zeile_data[m] = "";} 
       }
    }
 //******************************************************************************************** 
if (iomodus_D[i] == 17)  //Behandlung Uhrzeit von CCU
    {clockservice();
      for (int m=0; m < zeilenzahl; m++)
       {String min10 = ""; String hours10 = ""; String seconds10 = ""; String days10 = ""; String months10 = "";
        if (zeile_pointer[m] == i) { //add leading zeros
           if (seconds < 10)  {seconds10 = "0";}
           if (minutes < 10) {min10 = "0";}
           if (hours < 10)  {hours10 = "0";}
           if (days < 10)  {days10 = "0";}
           if (months < 10)  {months10 = "0";}
 
#if defined (tft_display)
    #if defined (ShowSeconds)
           zeile_data[m] = (days10 + String(days) + "." + months10 + String(months) + "." + String(years) + "  " + hours10 + String(hours) + ":" + min10 + String(minutes) + ":" + seconds10 + String(seconds)); 
    #else            
           zeile_data[m] = (days10 + String(days) + "." + months10 + String(months) + "." + String(years) + "     " + hours10 + String(hours) + ":" + min10 + String(minutes));
    #endif           
#endif
#if defined (lcd_display)
    #if defined (ShowSeconds)
           zeile_data[m] = (days10 + String(days) + "." + months10 + String(months) + "  " + hours10 + String(hours) + ":" + min10 + String(minutes) + ":" + seconds10 + String(seconds)); 
    #else            
           zeile_data[m] = (days10 + String(days) + "." + months10 + String(months) + "   " + hours10 + String(hours) + ":" + min10 + String(minutes));
    #endif           
#endif

        }
      }
    }
    datenempfang();
 //******************************************************************************************** 
/*  if (iomodus_D[i] == 12) //behandlung rfid-modul RDM6300 
    {int m = 0; fob_zahl=0;  fob_hex ="";
     if (i == 15){while((Serial3.available()>0)&&(m <11 ))  //behandlung rfid3
                       {fob_da=1;  m++;  zeichen = Serial3.read();
                        if (m>4)  //die ersten 4 zeichen ignorieren
                          {fob_hex += zeichen; fob_zahl = hexToDec(fob_hex);}
                        if (m > 10) //Datenübertragung fertig, dann buffer leeren 
                          {while(Serial3.available()>0) {zeichen = Serial3.read();}}
             }
         }    
     if (i == 17){while((Serial2.available()>0)&&(m <11 ))//behandlung rfid2
                      {fob_da=1;  m++;  zeichen = Serial2.read();
                       if (m>4)  //die ersten 4 zeichen ignorieren
                         {fob_hex += zeichen; fob_zahl = hexToDec(fob_hex);}
                       if (m > 10) //Datenübertragung fertig, dann buffer leeren 
                         {while(Serial2.available()>0) {zeichen = Serial2.read();}}
            }
           }
     if (fob_da)
       {fob_dec = ""; 
        sprintf(buffer,"%lu", fob_zahl); //zahl umwandeln in string
        for(int k = 0; k<7; k++) {fob_dec += buffer[k];} 
        Name = "";  //gueltigen namen und oeffner aus tabelle ermitteln  
        for (int k = 0; k < fob_anzahl; k++) {if (fob_dec == fob[3*k]) 
                                                {Name += fob[(3*k)+1];
                                                 oeffner= fob[(3*k)+2]; 
                                                 break;
                                                }
                                              }
        if ((Name != "") && ((oeffner =="1") ||(oeffner =="3"))) 
          {time_rfid3 = millis() + unlock_time1;}
        if ((Name != "") && ((oeffner =="2") ||(oeffner =="3")))  
          {time_rfid2 = millis() + unlock_time2;}
        if (Name == "") {Name = fob_dec;}
        lcd_rfid_message = Name + "          "; //lcd mmeldung modifizieren für rfid
        lcd_rfid_message = lcd_rfid_message.substring(0,9);
         
        for (int n=0; n < zeilenzahl; n++)
          {if (zeile_pointer[n] == i) 
             {display_message[i]= lcd_rfid_message; zeile_data[n] = fob_dec;}
          }
           
     //Serial.println(Name + " " + fob_dec);
        I = String(i);
        befehl="GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+Name+"')";
        set_sysvar();
        fob_da =0;
       }
     delay(500);  
    }
*/
//**************************   ende loop  *****************************************************
 }
} 
//#############################################################################################
//#############################################################################################
//#############################  Unterprogramme   #############################################

void datenempfang() //Unterprogramm datenempfang: daten von ccu an homeduino senden
{command = ""; 

#if defined (w5100)  //************************************************************************
 EthernetClient client = server.available();   //mit W5100
#endif  //************************************************************************************* 

#if defined (cc3000)  //***********************************************************************
 SFE_CC3000_Client client = SFE_CC3000_Client(wifi);   //mit CC3000
#endif  //************************************************************************************* 

#if defined (esp8266)  //***********************************************************************
  WiFiEspClient client = server.available();   //using ESP8266 (ESP-01 module)
#endif  //************************************************************************************* 

  if (client)  {
    receivingcommand = false;
    Serial.println(F("New client"));
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    unsigned long breakMillis = millis();
    while (client.connected())
    { //Serial.println(F("Client still connected"));
      if ((millis() - breakMillis) > 500) {sendHttpResponse(client); break;}
      if (client.available())
      {
        char c = client.read(); 
//        Serial.write(c);
        breakMillis = millis();
          if (reading && c == ' ') {reading =false;}
          if (c == '?') {reading = true; receivingcommand = true;} // beginn der Befehlssequenz 
          if (reading) 
            { if (command.length() < 100) //read char by char HTTP request
               {command = command + c;} // Serial.println(command);} //store characters to string
            } 
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
         if (c == '\n' && currentLineIsBlank) {sendHttpResponse(client);break;}
          if (c == '\n') {currentLineIsBlank = true;} 
            else if (c != '\r') { currentLineIsBlank = false;}
      }
    }
    delay(10);        // give the web browser time to receive the data
    client.stop();    // close the connection:
    Serial.println(F("Client disconnected"));
  }
  
    if (command.length() > 2) //behandlung Datenempfang von ccu: port auf 0/1 setzen or write textline or set clock
        {

#if defined (tft_display) //**************************************************
       String commandType = command.substring(1,2); // detect command type: "D" for data, "T" for text, "C" for clock (date, time)
          if (commandType == ("D")) {
             int colonPosition = command.indexOf(':');
             sub_command = command.substring(2,colonPosition); //portpin erkennen
             Serial.print("D" + sub_command + " :");
             port_pin = sub_command.toInt();
             command = command.substring((colonPosition+1)); //Rest-command bilden
              SetOutputPort (); //If command adresses an output port toggle it
                if ((iomodus_D[port_pin] == 7) && (port_pin ==4)) 
                  {rf_send(command); Serial.println(command);} 
                if ((iomodus_D[port_pin] == 5) && (port_pin ==9)) 
                  {ir_send(command); Serial.println(command);} 
          }
          if (commandType == ("T")) {
//            Serial.println(command);
             int colonPosition = command.indexOf(':');
             sub_command = command.substring(2,3 ); //select textline erkennen value 0-7 for line 1-8
             text_line = sub_command.toInt();
             String text_content_full = command.substring((colonPosition+1)); //isolate remaining text 
             char text_content_array[text_content_full.length() + 1]; // copy text to char array and split by separator comma in segments
             text_content_full.toCharArray(text_content_array, text_content_full.length() + 1);
             char* token = strtok(text_content_array, ",");
             char* text_content_char = token;
//             Serial.println(text_content_char);
             token= strtok(0, ",");
             char* text_size = token;
             token = strtok(0, ",");
             char* text_color_char = token;
             text_content = ((char*)text_content_char);
//             text_content_char = (text_content_char + '\0');
             String text_content = String(text_content_char);
//             Serial.println(text_content);
             text_content.replace("%20", " "); // %20 = HTML for Space. Enable formatting texts with spaces
             fontgroesse = atoi( text_size );
             String text_color = ((char*) text_color_char );
             if (text_color == "BLACK") {text_farbe = BLACK;}
             if (text_color == "BLUE") {text_farbe = BLUE;}
             if (text_color == "RED") {text_farbe = RED;}
             if (text_color == "GREEN") {text_farbe = GREEN;}
             if (text_color == "CYAN") {text_farbe = CYAN;}
             if (text_color == "MAGENTA") {text_farbe = MAGENTA;}
             if (text_color == "YELLOW") {text_farbe = YELLOW;}
             if (text_color == "WHITE") {text_farbe = WHITE;}
      #ifdef DEBUG
                    Serial.print(F("Zeile: "));Serial.println(text_line);
                    Serial.print(F("Text: "));Serial.println(text_content);
                    Serial.print(F("Groesse: "));Serial.println(text_size);
                    Serial.print(F("Farbe: "));Serial.println(text_color);
                    freeRam();
      #endif   

             tft_print (text_line,text_content,fontgroesse,text_farbe); 
          }
         if (commandType == ("C")) {
             command.replace("%20", " "); // %20 = HTML for space. Formatting Time / Date with Spaces possible
             Serial.print(F("C-Command received: ")); Serial.println(command);
             int colonPosition = command.indexOf(':');
             sub_command = command.substring((colonPosition + 1),(colonPosition + 3)); 
             days = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 4),(colonPosition + 6)); 
             months = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 7),(colonPosition + 11)); 
             years = (sub_command.toInt());

             sub_command = command.substring((colonPosition + 12),(colonPosition + 14)); 
             hours = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 15),(colonPosition + 17)); 
             minutes = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 18),(colonPosition + 20)); 
             seconds = (sub_command.toInt());
          } 
   #endif
   
   #if defined (lcd_display)
        String commandType = command.substring(1,2); // Kommandotyp abfragen: "D" für Daten oder "T" für Text
//       Serial.println("Kommandotyp: " + commandType);
          if (commandType == ("D")) {
      int colonPosition = command.indexOf(':');
       sub_command = command.substring(2,colonPosition); //portpin erkennen
       Serial.print("D" + sub_command + " :");
       port_pin = sub_command.toInt();
       command = command.substring((colonPosition+1)); //Rest-command bilden
          SetOutputPort (); //If command adresses an output port toggle it
          if ((iomodus_D[port_pin] == 7) && (port_pin ==4)) 
            {rf_send(command); Serial.println(command);} 
          if ((iomodus_D[port_pin] == 5) && (port_pin ==9)) 
            {ir_send(command); Serial.println(command);} 
          }
 
         if (commandType == ("T")) {
             int colonPosition = command.indexOf(':');
             sub_command = command.substring(2,3 ); //Textzeile erkennen Werte 0-1 für Zeile 1-2
             text_line = sub_command.toInt();
             String text_content_full = command.substring((colonPosition+1)); //Restlichen Text isolieren max. 22 Zeichen
                #ifdef DEBUG
                    Serial.print(F("Text: "));Serial.println(text_content_full);
                #endif   
             text_content_full.replace("%20", " "); // %20 = HTML für Space. Formatierung des Textes mit Spaces ermöglichen
             lcd.setCursor(0,text_line);
             lcd.print("                "); // delete 16 characters per line
             lcd.setCursor(0,text_line);
             lcd.print(text_content_full);
          }

        if (commandType == ("C")) {
             command.replace("%20", " "); // %20 = HTML for space. Formatting Time / Date with Spaces possible
             Serial.print(F("C-Command received: ")); Serial.println(command);
             int colonPosition = command.indexOf(':');
             sub_command = command.substring((colonPosition + 1),(colonPosition + 3)); 
             days = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 4),(colonPosition + 6)); 
             months = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 7),(colonPosition + 11)); 
             years = (sub_command.toInt());

             sub_command = command.substring((colonPosition + 12),(colonPosition + 14)); 
             hours = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 15),(colonPosition + 17)); 
             minutes = (sub_command.toInt());
             sub_command = command.substring((colonPosition + 18),(colonPosition + 20)); 
             seconds = (sub_command.toInt());
          } 
          
      #endif
      }
  } 
//*********************************************************************************************
void set_sysvar() // subroutine HTTP request absetzen:
{while (millis() < next_tx) {} //warten bis time > next_tx oder timeout
 next_tx = millis() +delta_tx;  
   
  befehl += " HTTP/1.1\r\nHost:";  //zusaetzlich wegen neuer CCU-firmware
  befehl += ccu[4];
  befehl += "\r\nConnection: close\r\n\r\n";
                                                    
 if (client.connect(ccu, 8181)) 
   {byte transmitbytes = 0;
    unsigned long breakMillis = millis();
    Serial.println(befehl);
    transmitbytes = client.println(befehl);
    while (transmitbytes != (befehl.length() + 2)) {
      Serial.println(F("Transmission failed! Retrying..."));
      delay(10);
      transmitbytes = client.println(befehl);
      if ((millis() - breakMillis) > 100) {Serial.println(F("Transmission failed 10 times!!! Check the WLAN connection to your CCU!")); break;}
      }
    client.println();
    client.flush();
    client.stop();
   } else {Serial.println(F("connection failed"));}
}

//*********************************************************************************************
void rf_send(String rf_command) // subroutine rf telegramm senden
{
}
//*********************************************************************************************
void ir_send(String ir_command) // subroutine ir telegramm senden
{
}
//*********************************************************************************************
//hier sind die interrupt-service-routinen fuer die impulszaehler  //**************************
void ISR_0() //Interrupt an D2
{pulsecounter[0]++;}
void ISR_1() //Interrupt an D3
{pulsecounter[1]++;}
void ISR_2() //Interrupt an D21
{pulsecounter[2]++;}
void ISR_3() //Interrupt an D20
{pulsecounter[3]++;}
void ISR_4() //Interrupt an D19
{pulsecounter[4]++;}
void ISR_5() //Interrupt an D18 
{pulsecounter[5]++;}
//*********************************************************************************************
//Unterprogramm:  Converting from Hex (unsigned long) to Decimal: *****************************
//Quelle https://github.com/benrugg/Arduino-Hex-Decimal-Conversion/blob/master/hex_dec.ino
unsigned long hexToDec(String hexString) 
{unsigned long decValue = 0;
 int nextInt;
 for (int k = 0; k < hexString.length(); k++) 
   {nextInt = int(hexString.charAt(k));
    if (nextInt >= 48 && nextInt <= 57) nextInt = map(nextInt, 48, 57, 0, 9);
    if (nextInt >= 65 && nextInt <= 70) nextInt = map(nextInt, 65, 70, 10, 15);
    if (nextInt >= 97 && nextInt <= 102) nextInt = map(nextInt, 97, 102, 10, 15);
    nextInt = constrain(nextInt, 0, 15);
    decValue = (decValue * 16) + nextInt;
  }
 return decValue;
}

//*********************************************************************************************
void display_data() //gibt daten auf dem lcd oder tft display aus

//*********************************************************************************************
#if defined (lcd_display)  //behandlung lcd-display: erkennung des tasters und lcd-anzeige
{x = analogRead (0);  //abfrage A0
 if (x < (x_alt -100))  {tastererkennung();}
 x_alt = x; 
 for (int m = 0; m < zeilenzahl; m++)
   {while (zeile_data[m].length() < 5) {zeile_data[m] = " " + zeile_data[m];}
    if (display_message[zeile_pointer[m]] == "0") {zeile_data[m] = "                ";}
    display_zeile[m] =  display_message[zeile_pointer[m]] + zeile_data[m];
   
    if (display_zeile[m] != display_zeile_alt[m])  //datenausgabe auf display nur wenn aenderung 
      {lcd.setCursor(0,m); lcd.print (display_zeile[m]); display_zeile_alt[m] = display_zeile[m];}
   } 
} 
//*********************************************************************************************
void tastererkennung()
{if (x < 60) 
   {taster == "right"; 
    zeile_pointer[0]--;  if (zeile_pointer[0] ==1) {zeile_pointer[0] = 87;}
    while((iomodus_D[zeile_pointer[0]] ==0) || (iomodus_D[zeile_pointer[0]] >19))
         {zeile_pointer[0]--; if (zeile_pointer[0] ==1) {zeile_pointer[0] =87;} }
    EEPROM.write(0,zeile_pointer[0]);//delay(4);
   } 
   else if (x < 200) 
          {taster == "up";
           zeile_pointer[0]++;  if (zeile_pointer[0] ==87) {zeile_pointer[0] = 2;}
           while((iomodus_D[zeile_pointer[0]] ==0) || (iomodus_D[zeile_pointer[0]] >19))
               {zeile_pointer[0]++; if (zeile_pointer[0] ==87) {zeile_pointer[0] = 2;} }
           EEPROM.write(0,zeile_pointer[0]);//delay(4);
          } 
          else if (x < 400) 
                   {taster == "down";
                    zeile_pointer[1]++; if (zeile_pointer[1] ==87) {zeile_pointer[1] = 2;}
                    while((iomodus_D[zeile_pointer[1]] ==0) || (iomodus_D[zeile_pointer[1]] >19))
                         {zeile_pointer[1]++; if (zeile_pointer[1] ==87) {zeile_pointer[1] = 2;} } 
                    EEPROM.write(1,zeile_pointer[1]);//delay(4);     
                   } 
                  else if (x < 600)
                         {taster == "left";
                          zeile_pointer[1]--;
                          if (zeile_pointer[1] ==1) {zeile_pointer[1] = 87;}
                          while((iomodus_D[zeile_pointer[1]] ==0) || (iomodus_D[zeile_pointer[1]] >19))
                               {zeile_pointer[1]--; if (zeile_pointer[1] ==1) {zeile_pointer[1] =87;} }
                          EEPROM.write(1,zeile_pointer[1]);//delay(4);
                         } 
                         else if (x < 800)
                                {taster = "select";}
                                else {taster ="";}
}
#endif  //************************************************************************************* 

//*********************************************************************************************
#if defined (tft_display)  //behandlung tft toucheingabe und  display 2.4''
 {if (millis() > next_touch_time)  //touch-display abfragen
   {TSPoint p = ts.getPoint();// a point object holds x y and z coordinates
    px = p.x; py = p.y; pz =p.z;  
    pinMode(XM, OUTPUT);   pinMode(YP, OUTPUT);
    if (pz > MINPRESSURE && pz < MAXPRESSURE ) 
      {
#ifdef DEBUG
       Serial.print(F("px : "));Serial.print( px); Serial.print(F("  py : " )); Serial.print(py);
       Serial.print(F("  pz : " )); Serial.print(pz);
#endif       
       if (abs(px_B - px_A) > 100) {p_x = (1000 *(px- px_A))/(px_B -px_A); p_y = (1000 *(py - py_A))/(py_C -py_A);} 
         else {p_x = (1000 *(py -py_A))/(py_B - py_A); p_y = (1000 *(px - px_A)) /(px_C - px_A);}
       Serial.print(F("  p_x : "));Serial.print( p_x); Serial.print(F("  p_y : " )); Serial.print(p_y);

    if (tft_type != 4) {
       if (p_y < 154) {touch_y = 0;}   //p_y = 1000 entspricht 6,5 Zeilen 
         else {if (p_y < 308) {touch_y = 1;}
                 else {if (p_y < 462) {touch_y = 2;}
                         else {if (p_y < 616) {touch_y = 3;}
                                 else {if (p_y < 770) {touch_y = 4;}
                                         else {touch_y = 5;}}}}}}

    if (tft_type == 4) {
       if (p_y < 106) {touch_y = 0;}   //p_y = 1000 entspricht 8,5 Zeilen 
         else {if (p_y < 212) {touch_y = 1;}
                 else {if (p_y < 370) {touch_y = 2;}
                         else {if (p_y < 500) {touch_y = 3;}
                                 else {if (p_y < 590) {touch_y = 4;}
                                        else {if (p_y < 690) {touch_y = 5;}
                                              else {if (p_y < 790) {touch_y = 6;}
                                                  else {touch_y = 7;}}}}}}}}


       Serial.print(F("     touch_y ")); Serial.print(touch_y); Serial.println();
       centertouch = 1;
       if (p_x < 333) {zeile_pointer_minus();  Serial.println(zeile_pointer[touch_y]); centertouch = 0;}
       if (p_x > 666) {zeile_pointer_plus();  Serial.println(zeile_pointer[touch_y]); centertouch = 0;} //reserve center area for other action
       if ((centertouch) && ((iomodus_D[zeile_pointer[touch_y]]) == 2)) {
        port_pin = zeile_pointer[touch_y];
#ifdef DEBUG
        Serial.print (F("iomodus_D[zeile_pointer[touch_y]] Touch Mitte - Modus: ")); Serial.println (iomodus_D[port_pin]); 
        Serial.print (F("Port_Pin: D")); Serial.println(port_pin);
        Serial.print(F("Status des Ausgangs: ")); Serial.println(digitalRead(port_pin));
#endif
        next_touch_time = millis() + 200;
        if (((iomodus_D[port_pin]) == 2) && (digitalRead(port_pin) == LOW)) {
            command = "1"; SetOutputPort ();} 
          else {
            command = "0"; SetOutputPort ();} //toggle output pin
        centertouch = 0;}
      }
      for (int m = 0; m < zeilenzahl; m++)  //datenausgabe auf tft-display
      {while (zeile_data[m].length() < 7) {zeile_data[m] = " " + zeile_data[m];}
       display_zeile[m] =  display_message[zeile_pointer[m]] + zeile_data[m];
       if (display_zeile[m] != display_zeile_alt[m]) //displayausgabe nur wenn aenderung 
         {tft_print (m,display_zeile[m],schriftgroesse,default_color); display_zeile_alt[m] = display_zeile[m];
        }
      }
   } 
}
//*********************************************************************************************
//mit diesem Unterprogramm wird auf dem tft display ein zeilen-display 6 x 16 bis 8 x 26 emuliert
void tft_print (int line, String textline, int font_size, long int color)
{if (tft_type ==1)
   {tft.fillRect(0,38*line, 319, 38, BLACK); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(0, 38*line+6);              //und dann erst schreiben
   }
 if (tft_type ==2)
   {tft.fillRect(0,50*line, 479, 50, BLACK); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(5, 50*line+6);              //und dann erst schreiben
   }  
if (tft_type ==3)
   {tft.fillRect(0,38*line, 399, 38, BLACK); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(0, 38*line+6);              //und dann erst schreiben
   }
if (tft_type ==4)
   {tft.fillRect(0,38*line, 479, 38, (BLACK)); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(0, 38*line+6);              //und dann erst schreiben
   }
if (tft_type ==5)
   {tft.fillRect(0,38*line, 320, 38, (BLACK)); //x0,y0, width,heights  //zeile loeschen
    tft.setCursor(0, 38*line+6);              //und dann erst schreiben
   }
 tft.setTextColor(color);  
 tft.setTextSize(font_size);
 tft.print(textline);
}

//mit diesen Unterprogrammen wird der zeile_pointer im eeprom abgelegt
void zeile_pointer_plus()
{next_touch_time = millis() + 200; 
  zeile_pointer[touch_y]++; if (zeile_pointer[touch_y] >86) {zeile_pointer[touch_y] = 2;}
 while((iomodus_D[zeile_pointer[touch_y]] ==0) || (iomodus_D[zeile_pointer[touch_y]] >19))
  {zeile_pointer[touch_y]++; if (zeile_pointer[touch_y] >86) {zeile_pointer[touch_y] = 2;} }
 EEPROM.write(touch_y,zeile_pointer[touch_y]);//delay(4);
}
void zeile_pointer_minus()
{next_touch_time = millis() + 200; 
  zeile_pointer[touch_y]--; if (zeile_pointer[touch_y] <2) {zeile_pointer[touch_y] = 86;}
 while((iomodus_D[zeile_pointer[touch_y]] ==0) || (iomodus_D[zeile_pointer[touch_y]] >19))
   {zeile_pointer[touch_y]--; if (zeile_pointer[touch_y] <2) {zeile_pointer[touch_y] =86;}  }
 EEPROM.write(touch_y,zeile_pointer[touch_y]);//delay(4);
}      
#endif  //************************************************************************************* 

/* just needed in case you want to communicate with the ESP-01 without using the ESPwifi lib */
   void Auf_OK_warten()
{ Serial3.flush(); 
  boolean Ook = false;
  boolean Kok = false;
  unsigned long Counter = 0;
  
  while(!Kok)
  {
    if (Serial3.available())     espbyte = Serial3.read();
    if (espbyte == 79) Ook = true;
    if (espbyte == 75) Kok = true;
    Counter++;
    if (Counter > 200000){Serial.print(F("Timeout while communicating with ESP-01 module!\n\r")); break;}
  }
  if (Ook && Kok) Serial.println();
}

//*************************************************************************************
      int freeRam () { //just for debugging
          extern int __heap_start, *__brkval; 
          int v; 
          int fr = (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
          Serial.print(F("Free ram: "));
          Serial.println(fr);
       }
//*************************************************************************************
      void SetOutputPort () {
               if (((iomodus_D[port_pin] == 2)||(iomodus_D[port_pin] == 12)) && (command == "0")) 
               {for (int m=0; m < zeilenzahl; m++)
                  {if (zeile_pointer[m] == port_pin) {zeile_data[m] = " Aus";} // display_value[port_pin] = " LOW";}
                  }
                pinMode(port_pin, OUTPUT); digitalWrite(port_pin, LOW); Serial.println(command);
               }
             if ((iomodus_D[port_pin] == 2) && (command == "1")) 
               {for (int m=0; m < zeilenzahl; m++)
                  {if (zeile_pointer[m] == port_pin) {zeile_data[m] = "   An";} // display_value[port_pin] = " HIGH";}
                  }
                pinMode(port_pin, OUTPUT); digitalWrite(port_pin, HIGH); Serial.println(command);}
          String I = String(port_pin);
          befehl = "GET /xy.exe?antwort=dom.GetObject('"+hm_systemvariable+"D"+I+"').State('"+command+"')";
          set_sysvar();
       }
 
//*************************************************************************************
      void clockservice () {
        if ((millis() - previousMillis) >= 998) { //should be 1000. Different value for compensation and depends on quartz and program precision
              previousMillis = millis(); // save current time to previousMillis
                seconds = ++seconds;
             if (seconds == 60) {
                 seconds = 0;
                 minutes = ++minutes;}
             if (minutes == 60) {
                 minutes = 0; 
                 hours = ++hours;}
             if (hours == 24) {hours = 0;}
        }
      }

//*************************************************************************************
void sendHttpResponse(WiFiEspClient client)
    {
    if (receivingcommand == true) {
          clockservice();
          Serial.println(F("Sending command response"));
          // send a standard http response header
          // use \r\n instead of many println statements to speedup data send
          client.print(F( "HTTP/1.1 200 OK\r\n"
                          "Content-Type: text/html\r\n"
                          "Connection: close\r\n"             // the connection will be closed after completion of the response
//                          "Refresh: 10\r\n"                   // refresh the page automatically every 10 sec. Useful for tests if you compare command to received command
                          "\r\n"));
          client.print(F("<!DOCTYPE HTML>\r\n"
                         "<html>\r\n"
                         "<h1>Welcome at "));
          client.print(hm_systemvariable);
          client.print(F( "</h1>\r\n"
                          "Requests received: "));
          client.print(++reqCount);
          client.print(F( "<br>\r\n"
                          "<br>\r\n"
                          "Command received: "));
          client.print(command);
          client.print(F( "<br>\r\n"
                          "<br>\r\n"
                          "Command length: "));
          client.print(command.length());
          client.print(F( " out of a maximum of 100"
                          "<br>\r\n"
                          "<br>\r\n"
                          "</html>\r\n"));
          client.flush();
          next_tx = millis() +delta_tx;
          clockservice();
          receivingcommand = false;
         }
         else {
              Serial.println(F("Sending 404 response after invalid request"));
              client.print(F("HTTP/1.1 404 \r\n" //shortest possible answer
              "\r\n"));
              next_tx = millis() +delta_tx;
              }
    }

Das mit dem RX Puffer habe ich nicht gemacht...
deswegen noch mal die Frage,, ist das nötig? oder nur wenn
Text zum Homeduino gesendet wird?!

mfg. Flo

Antworten

Zurück zu „HomeMatic Tipps & Tricks - keine Fragen!“