hi
du bist gut, dass ist aber nicht so einfach.
Also folgende Situation.
Impuls Eingang S00 bis S02 funktionieren wie sie sollen, nur S03 geht nicht. Es hat sich elektrisch aber nichts daran geändert...
Die Eingänge D2 bis D12 gehen wohl als Analog Onewire oder als Digitaler Eingang ohne Probleme.
Die Eingänge A0 bis A5 auf dem IO Shield und die Eingänge A8 bis A15 auf dem 2 IO Shield Plus gehen nicht.
Ich weiß echt nicht wo ich jetzt anpacken soll.
Ich habe schon verschiedene Sensoren umgehängt und abgehängt um defekte auszuschließen aber das war alles nicht zielführend.
Zur Hardware ich habe noch die erste Generation des IO Shields plus.
Früher als alles ging sah mein Sketch so aus:
Code: Alles auswählen
/*Ver.: "homeduino30_03_LAN.ino / Stand: 2015.05.11 / Verfasser: Eugen Stall
LAN-Version mit W5100 Shield
hier ist immer die aktuelle Version:
http://www.stall.biz/?project=der-homeduino-2-0-als-vielseitiges-lanwlan-sensormodul-fur-die-homematic&preview=true&preview_id=1115&preview_nonce=9162dd6679
das folgende homeduino-programm sendet messdaten zur ccu (homeduino als webclient) ...
und empfängt ausgabedaten für die homeduino-outputs (homeduino als webserver)
____________________ ___________________
| |
server port 8181 |<------------<| client
| |
CCU | | Homeduino
| |
client |>------------>| server port 80
____________________| |___________________
erprobt fuer Arduino Mega 2560 mit Arduino 1.6.3
diese Software steuert referenziert die signale an den Arduino-pins mit entsprechenden systemvariablen in der Homematic ccu
mit dem Befehl: http://<ip der ccu>:8181/GET /xy.exe?antwort=dom.GetObject('<systemvariable>').State(" + value + ")"
/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 ...
*/
#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 <IRremote.h> // läuft noch nicht!
//Kommunikationsweg festlegen
#define com_mode 0 //"0" W5100, "1" CC300 Breakout <<user-eingabe<<
/*
//der folgende Bereich ist die 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 ist D18
#define CC3000_EN 46 // en-Pin mit Wifi Shield ist D5, mit breakout auf IO-Shield-Plus ist D46
#define CC3000_CS 53 // cs-Pin mit Wifi Shield ist D10, mit breakout auf IO-Shield-Plus ist D53
SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS);
SFE_CC3000_Client client = SFE_CC3000_Client(wifi);
// Constants
char ap_ssid[] = "ssid"; // SSID Name des WLAN in Anführungszeichen <<user-eingabe<<
char ap_password[] = "passwort"; // Passwort des WLAN in Anführungszeichen <<user-eingabe<<
unsigned int ap_security = WLAN_SEC_WPA2; // Security of network
unsigned int timeout = 30000; // Milliseconds
//char server[] = "192,168,178,50"; // Remote host site
*/
//der folgende Bereich ist die Initialisierung des LAN bei Verwendung des LAN-Shields
#include <Ethernet.h>
EthernetClient client;
EthernetServer server(80);
byte ccu[] = { 192, 168, 178, 7 }; //das ist die IP der CCU <<user-eingabe<<
byte mac[] = { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }; //bei mehreren homeduinos ändern!! <<user-eingabe<<
byte homeduino[] = { 192, 168, 178, 103 }; //das ist feste IP dieses Homeduino, <<user-eingabe<<
//wenn DHCP versagt
String homeduino_nummer = "1"; //indiv. Bezeichnung dieses homeduino <<user-eingabe<<
//das ist bel. String ohne
//sonderzeichen und öäüß...
String hm_systemvariable = "homeduino_" + homeduino_nummer +"_";
//Input-Kennung: hier wird die Funktion aller verwendbaren IO´s mit einer Kennziffer festgelegt
//dabei haben alle IO´s die Standardfunktionen plus spez. Sonderfunktionen
byte iomodus_D[70] =
{ 0, //D0 : '0' = andere Nutzg;
0, //D1 : '0' = andere Nutzg;
//Standardfkt:'0' =andere Nutzg; '1' =dig_input; '2' =dig_output; '3' =1wire '4' =DHTxx; '5' =U_Schall
//++++++++++++++ hier folgt die Festlegung der digitalen Pinfunktionen für das IO-Shield20 +++++++++++++++++
6, //D2 : Standardfkt; '5' = IR_Rx?? '6' =ImpCount; <<user-eingabe für IO-Shield20<<
6, //D3 : Standardfkt; '7' = 433_Rx?? '6' =ImpCount; <<user-eingabe für IO-Shield20<<
0, //D4 : Standardfkt; '7' = 433_Tx?? '0' =W5100/SS-Pin <<user-eingabe für IO-Shield20<<
1, //D5 : Standardfkt; <<user-eingabe für IO-Shield20<<
1, //D6 : Standardfkt; '9' = buzzer <<user-eingabe für IO-Shield20<<
1, //D7 : Standardfkt; <<user-eingabe für IO-Shield20<<
3, //D8 : Standardfkt; <<user-eingabe für IO-Shield20<<
3, //D9 : Standardfkt; '5' = IR_Tx?? <<user-eingabe für IO-Shield20<<
0, //D10 : '0' =andere Nutzg;'0' =W5100 '2' = digital in;
0, //D11 : '0' =andere Nutzg;'0' =W5100 '2' = digital in;
0, //D12 : '0' =andere Nutzg;'0' =W5100 '2' = digital in;
0, //D13 : '0' =andere Nutzg;'0' =W5100 '2' = digital in;
//++++++++++++++ hier folgt die Festlegung der digitalen Pinfunktionen für das IO-Shield_Plus ++++++++++++++
0, //D14 : Standardfkt; '7' =ESP8266; <user-eingabe für IO-Shield-Plus20<<
0, //D15 : Standardfkt; '7' =ESP8266; <user-eingabe für IO-Shield-Plus20<<
0, //D16 : Standardfkt; '7' =ESP8266; <user-eingabe für IO-Shield-Plus20<<
0, //D17 : Standardfkt; '7' =ESP8266; <user-eingabe für IO-Shield-Plus20<<
6, //D18 : Standardfkt; '6' =ImpCount; '0' =CC3000 <user-eingabe für IO-Shield-Plus20<<
6, //D19 : Standardfkt; '6' =ImpCount; <user-eingabe für IO-Shield-Plus20<<
6, //D20 : Standardfkt; '6' =ImpCount; '8' =I2C;SDA <user-eingabe für IO-Shield-Plus20<<
6, //D21 : Standardfkt; '6' =ImpCount; '8' =I2C;SCL <user-eingabe für IO-Shield-Plus20<<
0, //D22 : Standardfkt; <user-eingabe für IO-Shield-Plus20<<
0, //D23 : Standardfkt; <user-eingabe für IO-Shield-Plus20<<
0, //D24 : Standardfkt; <user-eingabe für IO-Shield-Plus20<<
0, //D25 : Standardfkt; <user-eingabe für IO-Shield-Plus20<<
0, //D26 : Standardfkt; <user-eingabe für IO-Shield-Plus20<<
0, //D27 : Standardfkt; <user-eingabe für IO-Shield-Plus20<<
0, //D28 : Standardfkt; <user-eingabe für IO-Shield-Plus20<<
0, //D29 : Standardfkt; <user-eingabe für IO-Shield-Plus20<<
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
//hier wird die Funktion der Eingänge A0 bis A15 festgelegt
//++++++++++++++ hier folgt die Festlegung der analogen Pinfunktionen für das IO-Shield20 ++++++++++++++++++
0, //D54 A0 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<<
3, //D55 A1 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<<
3, //D56 A2 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<<
3, //D57 A3 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<<
3, //D58 A4 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<<
3, //D59 A5 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<<
0, //D60 A6 : "0" =andere Nutzg;
0, //D61 A7 : "0" =andere Nutzg;
//++++++++++++++ hier folgt die Festlegung der analogen Pinfunktionen für das IO-Shield_Plus +++++++++++++++
3, //D62 A8 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<<
0, //D63 A9 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<<
0, //D64 A10 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<<
0, //D65 A11 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<<
0, //D66 A12 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<<
0, //D67 A13 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<<
0, //D68 A14 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<<
0 //D69 A15 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<<
};
//hier werden Sensoren am I2C-Eingang aktiviert
byte iomodus_baro = 0; //'0' =nc; '1' =BMP180, dann auch oben I2C setzen <<user-eingabe für IO-Shield-Plus<<
byte iomodus_lux = 0; //'0' =nc; '1' =BH1750, dann auch oben I2C setzen <<user-eingabe für IO-Shield-Plus<<
//hier werden die Kennwerte fuer die Impulszaehler festgelegt
unsigned zaehlwert;
unsigned last_zaehlwert[6] = {0,0,0,0,0,0};
volatile unsigned long pulsecounter[6] =
{ 100, //Zaehlerstand fuer D2 -Impulseingang bei Reset <<user-eingabe für IO-Shield20<<
200, //Zaehlerstand fuer D3 -Impulseingang bei Reset <<user-eingabe für IO-Shield20<<
0, //Zaehlerstand fuer D21-Impulseingang bei Reset <<user-eingabe für IO-Shield-Plus<<
0, //Zaehlerstand fuer D20-Impulseingang bei Reset <<user-eingabe für IO-Shield-Plus<<
0, //Zaehlerstand fuer D19-Impulseingang bei Reset <<user-eingabe für IO-Shield-Plus<<
600 //Zaehlerstand fuer D18-Impulseingang bei Reset <<user-eingabe für IO-Shield-Plus<<
};
//hier wird der Teilerfaktor für die Impulszaehler festgelegt
int pulsedivider[6] =
{ 1, //Teilerfaktor D2 : <<user-eingabe für IO-Shield20<<
1, //Teilerfaktor D3 : <<user-eingabe für IO-Shield20<<
1, //Teilerfaktor D21 : <<user-eingabe für IO-Shield-Plus<<
1, //Teilerfaktor D20 : <<user-eingabe für IO-Shield-Plus<<
1, //Teilerfaktor D19 : <<user-eingabe für IO-Shield-Plus<<
1, //Teilerfaktor D18 : <<user-eingabe für IO-Shield-Plus<<
};
//hier werden die zuletzt gesendeten sytemvariablen gespeichert
boolean last_digital_value_D[70];
float last_value_D[70];
float last_IR_value;
float last_RF_value;
float last_lux_value;
double last_baro_value;
double last_baroT_value;
boolean complete_loop =1; // wenn 1, dann einmal komplett durchlaufen
String header = String(20);
String befehl;
String sub_command = String(20);
String parameter = String(20);
int param;
int port_pin;
boolean port_data;
boolean value;
String I;
int analogwert;
float tempNTC;
float B_wert = 3950; //aus dem Datenblatt des NTC //<<user-eingabe<<
float Tn = 298.15; //25°Celsius in °Kelvin
float Rv = 10000; //Vorwiderstand
float Rn = 10000; //NTC-Widerstand bei 25°C
float Rt ;
float temp_tur;
float humidity;
float delta_onewire = 0.2; //Deltas für Sendeauslösung
float delta_DHT = 0.2; //in °C
float delta_us = 3.0; // in cm
float delta_analog = 2.0; // in inkrement
float delta_ntc = 0.5; //in °C
float delta_lux = 20; //in lux
float delta_counter = 5; //in counter inkrement
double delta_baro = 0.2; //in mB
double delta_baroT = 0.5; //in °C
long duration, cm; //variable für Ultraschallsensor
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;
unsigned long time_DHT = 0;
int rf_key;
String rfkey;
RCSwitch mySwitch = RCSwitch();
//**************************************************************************************************
AS_BH1750 sensor; //Initialize BH1750 Luxmeter library
#define ALTITUDE 299.0 // eigene seehoehe in metern <<user-eingabe für IO-Shield-Plus<<
SFE_BMP180 pressure;
char status;
double T,P,p0;
boolean reading = false;
String command = String(200);
//**************************************************************************************************
//**************************************************************************************************
void setup()
{Serial.begin(115200);
//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 com_mode == 0
if ((pulsedivider[5] > 0) && (iomodus_D[18] == 6)) {pinMode(18, INPUT_PULLUP); attachInterrupt(5, ISR_5, FALLING);}
#endif
//+++++++ hier folgt die LAN Initialisierung
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();
char myIpString[24]; //IP auslesen
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();
/*
//+++++++ hier folgt die CC3000 Initialisierung
ConnectionInfo connection_info;
int i;
byte IP_ADDR_LEN =4;
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");}
// Gather connection details and print IP address
if ( !wifi.getConnectionInfo(connection_info) ) {Serial.println("no connection details");}
else {for (i = 0; i < IP_ADDR_LEN; i++)
{Serial.print(connection_info.ip_address[i]);
if ( i < IP_ADDR_LEN - 1 ) {Serial.print(".");}
}
Serial.println(" ist aktuelle IP-Adresse");
}
if (client.connect(ccu, 8181)) {} // Make a TCP connection to remote host
else {Serial.println("connection failed");} // if you didn't get a connection to the server:
client.stop();
*/
}
//**************************************************************************************************
//**************************************************************************************************
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
{if (i== 30) {i = 54;} // unbenutzte pins überspringen
//**************************************************************************************************
if (iomodus_D[i] == 1) //behandlung digitaleingänge
{pinMode(i, INPUT_PULLUP);
digitalWrite(i, HIGH);
value =digitalRead(i);
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;
}
}
//**************************************************************************************************
if (iomodus_D[i] == 3) //behandlung onewire
{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...
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
}
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;
}
}
//**************************************************************************************************
if (iomodus_D[i] == 4) //behandlung DHT temperatur- und feuchtesensoren
{DHT dht(i, DHT22); //je nach verwendetem sensor "DHT11" oder "DHT22" (AM2302) oder "DHT 21" (AM2301)
dht.begin();
//delay(2000); // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
time_DHT = millis() +2000;
while (millis() < time_DHT) {datenempfang();} //wahrend der 2s wartezeit, daten empfangen
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;
}
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 achtung: zu beachten
//bei verwendung der US-Sensoren beim IO-Shield-Plus sind die 150-Ohm-Schutzwiderstände
//zu überbrücken , entsprechend beim IO-Shield20 der digitale 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 > (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;
}
}
//**************************************************************************************************
if (iomodus_D[i] == 10) //behandlung analogeingänge
{analogwert =analogRead(i);
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 + ")";
set_sysvar();
last_value_D[i] = analogwert;
}
}
//**************************************************************************************************
if (iomodus_D[i] == 11) //behandlung NTC
{Rt = Rv/((1024.0/analogRead(i))- 1.0);
tempNTC = (B_wert * Tn / ( B_wert + (Tn * log(Rt/Rn)))) -Tn +25.0 ;
if ((tempNTC > (last_value_D[70] + delta_ntc)) || (tempNTC < (last_value_D[70] - 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;
}
}
//**************************************************************************************************
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 ];
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;
}
}
//**************************************************************************************************
//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_D[20] == 1) && (iomodus_D[21] == 1) && (iomodus_lux ==1))
{if(!sensor.begin()) { Serial.println("Sensor not present"); }
float lux = sensor.readLightLevel(); delay(1000);
Serial.print("Helligkeit/lux: "); Serial.print(lux); Serial.println();
if ((lux > (last_lux_value + delta_lux)) || (lux < (last_lux_value - delta_lux)) || complete_loop)
{befehl = "GET /xy.exe?antwort=dom.GetObject('" + hm_systemvariable + "lux" + "').State(" + lux + ")";
set_sysvar();
last_lux_value = lux;
}
}
//**************************************************************************************************
//behandlung barometer BMP180 an SCL pin21 und SDA pin 20
if ((iomodus_D[20] == 8) && (iomodus_D[21] == 8)&& (iomodus_baro ==1))
{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);
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;
}
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;
}
}
}
//**************************************************************************************************
if (iomodus_D[3] == 7) //behandlung 433Mhz-rx
{if (mySwitch.available())
{int value = mySwitch.getReceivedValue();
if (value == 0) {client.print("Unknown encoding");}
else {Serial.print("Pin D3 received : ");
Serial.print (mySwitch.getReceivedValue() );
Serial.print (" / ");
Serial.print( mySwitch.getReceivedBitlength() );
Serial.print("bit Protocol: ");
Serial.println( mySwitch.getReceivedProtocol() + " \n\r" );
}
mySwitch.resetAvailable();
}
}
//**************************************************************************************************
datenempfang();
}
//##############################################################
//##############################################################
void datenempfang() //Unterprogramm datenempfang: daten von ccu an homeduino
{command = "";
EthernetClient client = server.available(); //mit W5100
//SFE_CC3000_Client client = SFE_CC3000_Client(wifi); //mit CC3000
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)
{//read char by char HTTP request
if (command.length() < 100)
{ //store characters to string
command = command + c;
}
}
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: port auf 0 / 1 setzen
{Serial.println(command); //empfangenen befehl ausgeben
client.print(command);
//befehl 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) && (command == "0"))
{pinMode(port_pin, OUTPUT); digitalWrite(port_pin, LOW); Serial.println(command);}
if ((iomodus_D[port_pin] == 2) && (command == "1"))
{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();
}
}
//##############################################################
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]++;}
Und jetzt sieht es so aus:
Code: Alles auswählen
//Ver.: "homeduino_20_11_1.ino / Stand: 2017.03.19 / Verfasser: Eugen Stall
//hier ist immer die aktuelle Version:
//https://www.stall.biz/?project=der-homeduino-2-0-als-vielseitiges-lanwlan-sensormodul-fur-die-homematic&preview=true&preview_id=1115&preview_nonce=9162dd6679
//fuer Arduino Mega 2560, UNO, Duemilanove mit Arduino 1.5.8
//diese Software steuert referenziert die signale an den Arduino-pins mit entsprechenden systemvariablen in der Homematic ccu
//mit dem Befehl: http://<ip der ccu>:8181/GET /xy.exe?antwort=dom.GetObject('<systemvariable>').State(" + value + ")"
//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 ...
#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
//+++++++ der folgende Bereich ist die Initialisierung des LAN bei Verwndung des LAN-Shields
#define com_mode 0
#include <Ethernet.h>
EthernetClient client;
//+++++++
/*
//+++++++ der folgende Bereich ist die Initialisierung des CC3000 Wifi auf dem IO-Shield-Plus
#define com_mode 1
#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 ist D18
#define CC3000_EN 46 // en -Pin mit Wifi Shield ist D5, mit breakout auf IO-Shield-Plus ist D46
#define CC3000_CS 53 // cs -Pin mit Wifi Shield ist D10, mit breakout auf IO-Shield-Plus ist D53
SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS);
SFE_CC3000_Client client = SFE_CC3000_Client(wifi);
// Constants
char ap_ssid[] = "ssid"; // SSID Name des WLAN in Anführungszeichen <<user-eingabe<<
char ap_password[] = "passwort"; // Passwort des WLAN in Anführungszeichen <<user-eingabe<<
unsigned int ap_security = WLAN_SEC_WPA2; // Security of network
unsigned int timeout = 30000; // Milliseconds
//char server[] = "192,168,178,50"; // Remote host site
//+++++++
*/
char ccu_ip[31] = "192.168.178.7"; //myCCUIP"; //das ist die IP der CCU <<user-eingabe<<
byte mac[] = { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }; //muss nur bei mehreren homeduinos individuell geändert werden ! <<user-eingabe<<
byte homeduino[] = { 192, 168, 178, 103 }; //das ist die feste IP dieses Homeduino, wenn DHCP versagt <<user-eingabe<<
String homeduino_nummer = "1"; // indiv. Bezeichnung für diese homeduino-box <<user-eingabe<<
String hm_systemvariable = "homeduino_" + homeduino_nummer +"_";
//Input-Kennung: hier wird die Funktion der Eingänge D2 bis D29 festgelegt
byte iomodus_D[30] =
{ 0, //D0 : '0' = andere Nutzung;
0, //D1 : '0' = andere Nutzung;
//++++++++++++++ hier folgt die Festlegung der digitalen Pinfunktionen für das IO-Shield20 +++++++++++++++++++++++++++++++++
6, //D2 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield20<<
//'4' = Ultraschall; '5' = Infrarot;
6, //D3 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield20<<
//'4' = Ultraschall; '7' = 433Mhz_Rx
0, //D4 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield20<<
//'4' = Ultraschall;
2, //D5 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield20<<
//'4' = Ultraschall;
2, //D6 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield20<<
//'4' = Ultraschall;
2, //D7 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield20<<
//'4' = Ultraschall;
1, //D8 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield20<<
//'4' = Ultraschall;
1, //D9 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield20<<
//'4' = Ultraschall;
0, //D10 : '0' = andere Nutzung; '2' = digital in;
0, //D11 : '0' = andere Nutzung; '2' = digital in;
0, //D12 : '0' = andere Nutzung; '2' = digital in;
0, //D13 : '0' = andere Nutzung; '2' = digital in;
//++++++++++++++ hier folgt die Festlegung der digitalen Pinfunktionen für das IO-Shield_Plus +++++++++++++++++++++++++++++++++
0, //D14 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield-Plus<<
//'4' = Ultraschall; '7' = ESP8266;
0, //D15 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield-Plus<<
//'4' = Ultraschall; '7' = ESP8266;
0, //D16 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield-Plus<<
//'4' = Ultraschall; '7' = ESP8266;
0, //D17 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield-Plus<<
//'4' = Ultraschall; '7' = ESP8266;
6, //D18 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield-Plus<<
//'4' = Ultraschall; '6' = Impulszaehler; '0' = CC3000
6, //D19 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield-Plus<<
//'4' = Ultraschall; '6' = Impulszaehler;
6, //D20 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield-Plus<<
//'4' = Ultraschall; '6' = Impulszaehler; '8' = I2C;
6, //D21 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield-Plus<<
//'4' = Ultraschall; '6' = Impulszaehler; '8' = I2C;
0, //D22 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield-Plus<<
//'4' = Ultraschall;
0, //D23 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield-Plus<<
//'4' = Ultraschall;
0, //D24 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield-Plus<<
//'4' = Ultraschall;
0, //D25 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield-Plus<<
//'4' = Ultraschall;
0, //D26 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield-Plus<<
//'4' = Ultraschall;
0, //D27 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield-Plus<<
//'4' = Ultraschall;
0, //D28 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield-Plus<<
//'4' = Ultraschall;
0, //D29 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '3' = DHTxx; <<user-eingabe für I/O-Shield-Plus<<
//'4' = Ultraschall;
};
//hier wird die Funktion der Eingänge A0 bis A15 festgelegt
byte iomodus_A[16] =
{
//++++++++++++++ hier folgt die Festlegung der analogen Pinfunktionen für das IO-Shield20 +++++++++++++++++++++++++++++++++
0, //A0 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '11' = NTC; <<user-eingabe für I/O-Shield20<<
//'10' = analog in;
1, //A1 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '11' = NTC; <<user-eingabe für I/O-Shield20<<
//'10' = analog in;
1, //A2 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '11' = NTC; <<user-eingabe für I/O-Shield20<<
//'10' = analog in;
1, //A3 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '11' = NTC; <<user-eingabe für I/O-Shield20<<
//'10' = analog in;
1, //A4 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '11' = NTC; <<user-eingabe für I/O-Shield20<<
//'10' = analog in;
1, //A5 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '11' = NTC; <<user-eingabe für I/O-Shield20<<
//'10' = analog in;
0, //A6 : "0" = andere Nutzung;
0, //A7 : "0" = andere Nutzung;
//++++++++++++++ hier folgt die Festlegung der analogen Pinfunktionen für das IO-Shield_Plus +++++++++++++++++++++++++++++++++
1, //A8 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '11' = NTC; <<user-eingabe für I/O-Shield-Plus<<
//'10' = analog in;
0, //A9 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '11' = NTC; <<user-eingabe für I/O-Shield-Plus<<
//'10' = analog in;
0, //A10 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '11' = NTC; <<user-eingabe für I/O-Shield-Plus<<
//'10' = analog in;
0, //A11 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '11' = NTC; <<user-eingabe für I/O-Shield-Plus<<
//'10' = analog in;
0, //A12 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '11' = NTC; <<user-eingabe für I/O-Shield-Plus<<
//'10' = analog in;
0, //A13 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '11' = NTC; <<user-eingabe für I/O-Shield-Plus<<
//'10' = analog in;
0, //A14 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '11' = NTC; <<user-eingabe für I/O-Shield-Plus<<
//'10' = analog in;
0, //A15 : '0' = andere Nutzung; '1' = 1wire; '2' = digital in; '11' = NTC; <<user-eingabe für I/O-Shield-Plus<<
//'10' = analog in;
};
//hier werden Sensoren am I2C-Eingang aktiviert
byte iomodus_baro = 0; //"0" = N.C.; "1" = BMP180, wenn aktiviert, dann auch oben I2C aktivieren <<user-eingabe für I/O-Shield-Plus<<
byte iomodus_lux = 0; //"0" = N.C.; "1" = BH1750, wenn aktiviert, dann auch oben I2C aktivieren <<user-eingabe für I/O-Shield-Plus<<
//hier werden die Kennwerte fuer die Impulszaehler festgelegt
unsigned zaehlwert;
unsigned last_zaehlwert[6] = {0,0,0,0,0,0};
volatile unsigned long pulsecounter[6] =
{ 4713,
0,
0, //Zaehlerstand fuer D21-Impulseingang bei Reset <<user-eingabe für I/O-Shield-Plus<<
0, //Zaehlerstand fuer D20-Impulseingang bei Reset <<user-eingabe für I/O-Shield-Plus<<
0, //Zaehlerstand fuer D19-Impulseingang bei Reset <<user-eingabe für I/O-Shield-Plus<<
0, //Zaehlerstand fuer D18-Impulseingang bei Reset <<user-eingabe für I/O-Shield-Plus<<
};
//hier wird der Teilerfaktor für die Impulszaehler festgelegt
int pulsedivider[6] =
{ 1,
1,
1, //Teilerfaktor fuer D21 : wenn 0, dann keine Zaehlfunktion, sonst Teilfaktor <<user-eingabe für I/O-Shield-Plus<<
1, //Teilerfaktor fuer D20 : wenn 0, dann keine Zaehlfunktion, sonst Teilfaktor <<user-eingabe für I/O-Shield-Plus<<
1, //Teilerfaktor fuer D19 : wenn 0, dann keine Zaehlfunktion, sonst Teilfaktor <<user-eingabe für I/O-Shield-Plus<<
1, //Teilerfaktor fuer D18 : wenn 0, dann keine Zaehlfunktion, sonst Teilfaktor <<user-eingabe für I/O-Shield-Plus<<
};
//hier werden die zuletzt gesendeten sytemvariablen gespeichert
boolean last_digitalin_value_D[30];
float last_digital_value_D[30];
boolean last_digitalin_value_A[16];
float last_analogin_value_A[16];
float last_IR_value;
float last_RF_value;
float last_lux_value;
double last_baro_value;
double last_baroT_value;
boolean complete_loop =1; // wenn 1, dann einmal komplett durchlaufen
boolean value;
String befehl;
String I;
int analogwert;
float tempNTC;
float B_wert = 3950; //aus dem Datenblatt des NTC //<<user-eingabe<<
float Tn = 298.15; //25°Celsius in °Kelvin
float Rv = 10000; //Vorwiderstand
float Rn = 10000; //NTC-Widerstand bei 25°C
float Rt ;
float temp_tur;
float humidity;
float delta_onewire = 0.2; //Deltas für Sendeauslösung
float delta_sht = 0.2;
float delta_us = 2;
float delta_analog = 2;
float delta_ntc = 0.2;
float delta_lux = 20;
double delta_baro = 0.2;
double delta_baroT = 0.5;
long duration, cm; //variable für Ultraschallsensor
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;
boolean ccu_presence;
//**************************************************************************************************
AS_BH1750 sensor; //Initialize BH1750 Luxmeter library
#define ALTITUDE 299.0 // seehoehe in metern
SFE_BMP180 pressure;
char status;
double T,P,p0;
//**************************************************************************************************
//**************************************************************************************************
void setup()
{Serial.begin(115200);
//+++++++ hier folgt die LAN Initialisierung
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_ip, 8181)) {}
else {Serial.println("connection failed");} // if you didn't get a connection to the server:
client.stop();
char myIpString[24]; //IP auslesen
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();
//+++++++
/*
//+++++++ hier folgt die CC3000 Initialisierung
ConnectionInfo connection_info;
int i;
byte IP_ADDR_LEN =4;
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");}
// Gather connection details and print IP address
if ( !wifi.getConnectionInfo(connection_info) ) {Serial.println("no connection details");}
else {for (i = 0; i < IP_ADDR_LEN; i++)
{Serial.print(connection_info.ip_address[i]);
if ( i < IP_ADDR_LEN - 1 ) {Serial.print(".");}
}
Serial.println(" ist aktuelle IP-Adresse");
}
if (client.connect(ccu, 8181)) {} // Make a TCP connection to remote host
else {Serial.println("connection failed");} // if you didn't get a connection to the server:
client.stop();
//+++++++
*/
//einrichtung der interrupts fuer impulszahler D18,D19,D20,D21
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 ((pulsedivider[5] > 0) && (iomodus_D[18] == 6) && (com_mode == 0)) {pinMode(18, INPUT_PULLUP); attachInterrupt(5, ISR_5, FALLING);}
}
//**************************************************************************************************
//**************************************************************************************************
void loop()
{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 < 30; i++) //behandlung digitaleingänge D2 bis D29
{if (iomodus_D[i] == 2)
{pinMode(i, INPUT_PULLUP);
digitalWrite(i, HIGH);
value =digitalRead(i);
if ((!value == last_digitalin_value_D[i]) || complete_loop)
{I = String(i);
befehl = "GET /xy.exe?antwort=dom.GetObject('" + hm_systemvariable + "D" + I + "').State(" + value + ")";
set_sysvar();
last_digitalin_value_D[i] = value;
}
}
}
//**************************************************************************************************
for (int i = 0; i < 16; i++) //behandlung zur verwendung digitaleingänge an analogen Eingängen A0 bis A15
{if (iomodus_A[i] == 2)
{pinMode(i + 54, INPUT_PULLUP);
digitalWrite(i + 54, HIGH);
value =digitalRead(i+54); //achtung beim uno sind 14 zu addieren, beim mega 54
if ((!value == last_digitalin_value_A[i]) || complete_loop)
{I = String(i);
befehl = "GET /xy.exe?antwort=dom.GetObject('" + hm_systemvariable + "A" + I + "').State(" + value + ")";
set_sysvar();
last_digitalin_value_A[i] = value;
}
}
}
//**************************************************************************************************
for (int i = 2; i < 30; i++) //behandlung onewire an D2 bis D29
{if (iomodus_D[i] == 1)
{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...
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
}
if ((temp_tur > (last_digital_value_D[i] + delta_onewire)) || (temp_tur < (last_digital_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_digital_value_D[i] = temp_tur;
}
}
}
//**************************************************************************************************
for (int i = 0; i < 16; i++) //behandlung onewire an A0 bis A15
{if (iomodus_A[i] == 1)
{pinMode(i + 54, INPUT_PULLUP);
digitalWrite(i + 54, HIGH);
OneWire ds(i+ 54);
#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...
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
}
if ((temp_tur > (last_analogin_value_A[i] + delta_onewire)) || (temp_tur < (last_analogin_value_A[i] - delta_onewire)) || complete_loop)
{
I = String(i);
befehl = "GET /xy.exe?antwort=dom.GetObject('" + hm_systemvariable + "A" + I + "').State(" + temp_tur + ")";
set_sysvar();
last_analogin_value_A[i] = temp_tur;
}
}
}
//**************************************************************************************************
for (int i = 2; i < 30; i++) //behandlung DHT22 D2 bis D29
{if (iomodus_D[i] == 3)
{DHT dht(i, DHT22); //je nach verwendetem sensor "DHT11" oder "DHT22" (AM2302) oder "DHT 21" (AM2301)
dht.begin();
delay(2000); // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
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;}
if ((temp_tur > (last_digital_value_D[i] + delta_sht)) || (temp_tur < (last_digital_value_D[i] - delta_sht)) || 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_digital_value_D[i] = temp_tur;
}
}
}
//**************************************************************************************************
for (int i = 2; i < 30; i++) //behandlung Ultraschallsensor D2 bis D29
{if (iomodus_D[i] == 4)
{ 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 > (last_digital_value_D[i] + delta_us)) || (cm < (last_digital_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_digital_value_D[i] = cm;
}
}
}
//**************************************************************************************************
for (int i = 0; i < 16; i++) //behandlung analogeingänge A0 bis A15
{if (iomodus_A[i] == 10)
{analogwert =analogRead(i);
if ((analogwert > (last_analogin_value_A[i] + delta_analog)) || (analogwert < (last_analogin_value_A[i] - delta_analog)) || complete_loop)
{I = String(i);
befehl = "GET /xy.exe?antwort=dom.GetObject('" + hm_systemvariable + "A" + I + "').State(" + analogwert + ")";
set_sysvar();
last_analogin_value_A[i] = analogwert;
}
}
}
//**************************************************************************************************
for (int i = 0; i < 16; i++) //behandlung NTC an A0 bis A15
{if (iomodus_A[i] == 11)
{Rt = Rv/((1024.0/analogRead(i))- 1.0);
tempNTC = (B_wert * Tn / ( B_wert + (Tn * log(Rt/Rn)))) -Tn +25.0 ;
if ((tempNTC > (last_analogin_value_A[i] + delta_ntc)) || (tempNTC < (last_analogin_value_A[i] - delta_ntc)) || complete_loop)
{I = String(i);
befehl = "GET /xy.exe?antwort=dom.GetObject('" + hm_systemvariable + "A" + I + "').State(" + tempNTC + ")";
set_sysvar();
last_analogin_value_A[i] = tempNTC;
}
}
}
//**************************************************************************************************
//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_D[20] == 1) && (iomodus_D[21] == 1) && (iomodus_lux ==1))
{if(!sensor.begin()) { /*Serial.println("Sensor not present");*/}
float lux = sensor.readLightLevel(); delay(1000);
if ((lux > (last_lux_value + delta_lux)) || (lux < (last_lux_value - delta_lux)) || complete_loop)
{befehl = "GET /xy.exe?antwort=dom.GetObject('" + hm_systemvariable + "lux" + "').State(" + lux + ")";
set_sysvar();
last_lux_value = lux;
}
}
//**************************************************************************************************
//behandlung barometer BMP180 an SCL pin21 und SDA pin 20
if ((iomodus_D[20] == 1) && (iomodus_D[21] == 1)&& (iomodus_baro ==1))
{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);
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;
}
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;
}
}
//**************************************************************************************************
for (int i = 2; i < 5; i++) //behandlung impulszahler D21,D20,D19,D18
{zaehlwert = pulsecounter[i] / pulsedivider[i];
if ( (pulsedivider[i] > 0) && ((zaehlwert > (last_zaehlwert[i]) || complete_loop)))
{I = String(i);
befehl = "GET /xy.exe?antwort=dom.GetObject('" + hm_systemvariable + "imp" + I + "').State(" + zaehlwert + ")";
set_sysvar();
last_zaehlwert[i] = zaehlwert;
}
}
//**************************************************************************************************
complete_loop = 0;
}
//##############################################################
// subroutine HTTP request absetzen:
void set_sysvar()
{ //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_ip;
befehl += "\r\nConnection: close\r\n\r\n";
if (client.connect(ccu_ip, 8181))
{Serial.print("sent to ccu : "); Serial.print(befehl); yield();
client.print(befehl);
delay(10); client.stop();
ccu_presence = 1;
} else {Serial.println("keine verbindung zur ccu"); ccu_presence = 0; return;}
}
//##############################################################
//hier sind die interrupt-service-routinen fuer die impulszaehler
void ISR_2() //Interrupt an D21
{pulsecounter[2]++;}
void ISR_3() //Interrupt an D20
{pulsecounter[3]++;}
void ISR_4() //Interrupt an D19
{pulsecounter[4]++;}
#if com_mode == 0
void ISR_5() //Interrupt an D18
{pulsecounter[5]++;}
#endif