Homeduino 3.0 … das ultimative IO-Modul für die Hausautomation

,
Print Friendly, PDF & Email

[google-translator]

Wichtiger Hinweis: Es gibt mittlerweile eine neue Softwareversion:   Homduino 4.0

Für die Ungeduldigen ist hier die erste vorläufige Version der Homeduino 3.0 Software veröffentlicht. An der Software wird noch gearbeitet und einige Funktionalitäten für  Infrarot- und 433Mhz-Module fehlen noch. Darüberhinaus ist auch noch eine LCD-Anzeige geplant.

Unterstützt werden das IO-Shield20 und das IO-Shield-Plus

Hier die Installationshinweise:

1. Installation der Arduino 1.6.3 IDE

2. Kopieren der zusätzlichen Libraries in das Library-Verzeichnis:
https://www.stall.biz/wp-content/uploads/2015/04/homeduino_libraries30.zip

3. Ausführen der aktuellen Version : (mit W5100-Ethernet-Shield oder CC3000 Shield )

Anmerkung 07.05.2015:  Die aktuelle Version homeduino30_03 ist noch nicht komplett getestet !!

Rückmeldungen erwünscht .

Beide folgenden Versionen (W5100 mit LAN und CC3000 mit WLAN) könnte man in einem Sketch mit sog. „conditional compilation“ zusammenfassen, aber leider gibt es damit noch Fehlermeldungen, die aktuell (noch) nicht beseitigt werden konnten. Deshalb hier aktuell noch zwei Versionen:

 

 Hier die LAN-Version:

[codesyntax lang=“text“ title=“Betaversion Homeduino 3.0 Sketch mit LAN W5100-Shield“]

/*Ver.: "homeduino30_03_LAN.ino / Stand: 2015.05.11 / Verfasser: Eugen Stall

LAN-Version mit W5100 Shield

hier ist immer die aktuelle Version:
Home
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, 50 }; //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, 52 }; //das ist feste IP dieses Homeduino, <<user-eingabe<< //wenn DHCP versagt String homeduino_nummer = "xyz"; //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 +++++++++++++++++ 2, //D2 : Standardfkt; '5' = IR_Rx?? '6' =ImpCount; <<user-eingabe für IO-Shield20<< 2, //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<< 2, //D5 : Standardfkt; <<user-eingabe für IO-Shield20<< 0, //D6 : Standardfkt; '9' = buzzer <<user-eingabe für IO-Shield20<< 0, //D7 : Standardfkt; <<user-eingabe für IO-Shield20<< 0, //D8 : Standardfkt; <<user-eingabe für IO-Shield20<< 1, //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 ++++++++++++++ 3, //D14 : Standardfkt; '7' =ESP8266; <user-eingabe für IO-Shield-Plus20<< 2, //D15 : Standardfkt; '7' =ESP8266; <user-eingabe für IO-Shield-Plus20<< 2, //D16 : Standardfkt; '7' =ESP8266; <user-eingabe für IO-Shield-Plus20<< 2, //D17 : Standardfkt; '7' =ESP8266; <user-eingabe für IO-Shield-Plus20<< 0, //D18 : Standardfkt; '6' =ImpCount; '0' =CC3000 <user-eingabe für IO-Shield-Plus20<< 3, //D19 : Standardfkt; '6' =ImpCount; <user-eingabe für IO-Shield-Plus20<< 1, //D20 : Standardfkt; '6' =ImpCount; '8' =I2C;SDA <user-eingabe für IO-Shield-Plus20<< 1, //D21 : Standardfkt; '6' =ImpCount; '8' =I2C;SCL <user-eingabe für IO-Shield-Plus20<< 1, //D22 : Standardfkt; <user-eingabe für IO-Shield-Plus20<< 1, //D23 : Standardfkt; <user-eingabe für IO-Shield-Plus20<< 1, //D24 : Standardfkt; <user-eingabe für IO-Shield-Plus20<< 1, //D25 : Standardfkt; <user-eingabe für IO-Shield-Plus20<< 1, //D26 : Standardfkt; <user-eingabe für IO-Shield-Plus20<< 1, //D27 : Standardfkt; <user-eingabe für IO-Shield-Plus20<< 1, //D28 : Standardfkt; <user-eingabe für IO-Shield-Plus20<< 1, //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 ++++++++++++++++++ 3, //D54 A0 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 2, //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<< 0, //D57 A3 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 0, //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 +++++++++++++++ 1, //D62 A8 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 1, //D63 A9 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 1, //D64 A10 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 1, //D65 A11 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 1, //D66 A12 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 1, //D67 A13 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 1, //D68 A14 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 1 //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] = { 0, //Zaehlerstand fuer D2 -Impulseingang bei Reset <<user-eingabe für IO-Shield20<< 0, //Zaehlerstand fuer D3 -Impulseingang bei Reset <<user-eingabe für IO-Shield20<< 4711, //Zaehlerstand fuer D21-Impulseingang bei Reset <<user-eingabe für IO-Shield-Plus<< 3, //Zaehlerstand fuer D20-Impulseingang bei Reset <<user-eingabe für IO-Shield-Plus<< 4, //Zaehlerstand fuer D19-Impulseingang bei Reset <<user-eingabe für IO-Shield-Plus<< 5 //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]++;}

[/codesyntax]

 

 

Und hier die Wifi-Version :

[codesyntax lang=“text“ title=“Betaversion Homeduino 3.0 Sketch mit CC3000 Wifi Breakout“]

/*Ver.: "homeduino30_03_wifi.ino / Stand: 2015.05.07 / Verfasser: Eugen Stall

Wifi-Version mit CC3000-Breakout

hier ist immer die aktuelle Version:
Home
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 1 //"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, 50 }; //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, 52 }; //das ist feste IP dieses Homeduino, <<user-eingabe<< //wenn DHCP versagt String homeduino_nummer = "xyz"; //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 +++++++++++++++++ 2, //D2 : Standardfkt; '5' = IR_Rx?? '6' =ImpCount; <<user-eingabe für IO-Shield20<< 2, //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<< 2, //D5 : Standardfkt; <<user-eingabe für IO-Shield20<< 0, //D6 : Standardfkt; '9' = buzzer <<user-eingabe für IO-Shield20<< 0, //D7 : Standardfkt; <<user-eingabe für IO-Shield20<< 0, //D8 : Standardfkt; <<user-eingabe für IO-Shield20<< 1, //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 ++++++++++++++ 3, //D14 : Standardfkt; '7' =ESP8266; <user-eingabe für IO-Shield-Plus20<< 2, //D15 : Standardfkt; '7' =ESP8266; <user-eingabe für IO-Shield-Plus20<< 2, //D16 : Standardfkt; '7' =ESP8266; <user-eingabe für IO-Shield-Plus20<< 2, //D17 : Standardfkt; '7' =ESP8266; <user-eingabe für IO-Shield-Plus20<< 0, //D18 : Standardfkt; '6' =ImpCount; '0' =CC3000 <user-eingabe für IO-Shield-Plus20<< 3, //D19 : Standardfkt; '6' =ImpCount; <user-eingabe für IO-Shield-Plus20<< 1, //D20 : Standardfkt; '6' =ImpCount; '8' =I2C;SDA <user-eingabe für IO-Shield-Plus20<< 1, //D21 : Standardfkt; '6' =ImpCount; '8' =I2C;SCL <user-eingabe für IO-Shield-Plus20<< 1, //D22 : Standardfkt; <user-eingabe für IO-Shield-Plus20<< 1, //D23 : Standardfkt; <user-eingabe für IO-Shield-Plus20<< 1, //D24 : Standardfkt; <user-eingabe für IO-Shield-Plus20<< 1, //D25 : Standardfkt; <user-eingabe für IO-Shield-Plus20<< 1, //D26 : Standardfkt; <user-eingabe für IO-Shield-Plus20<< 1, //D27 : Standardfkt; <user-eingabe für IO-Shield-Plus20<< 1, //D28 : Standardfkt; <user-eingabe für IO-Shield-Plus20<< 1, //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 ++++++++++++++++++ 3, //D54 A0 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 2, //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<< 0, //D57 A3 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 0, //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 +++++++++++++++ 1, //D62 A8 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 1, //D63 A9 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 1, //D64 A10 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 1, //D65 A11 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 1, //D66 A12 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 1, //D67 A13 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 1, //D68 A14 : Standardfkt; '10' =anal_Inp '11' =NTC <<user-eingabe für IO-Shield-Plus20<< 1 //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] = { 0, //Zaehlerstand fuer D2 -Impulseingang bei Reset <<user-eingabe für IO-Shield20<< 0, //Zaehlerstand fuer D3 -Impulseingang bei Reset <<user-eingabe für IO-Shield20<< 4711, //Zaehlerstand fuer D21-Impulseingang bei Reset <<user-eingabe für IO-Shield-Plus<< 3, //Zaehlerstand fuer D20-Impulseingang bei Reset <<user-eingabe für IO-Shield-Plus<< 4, //Zaehlerstand fuer D19-Impulseingang bei Reset <<user-eingabe für IO-Shield-Plus<< 5 //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]++;}

[/codesyntax]

 

 

Damit ist es jetzt möglich, auch Daten von der CCU  an den Homeduino zu senden, um beispielsweise einen beliebigen Port zu setzen. Der Weg zurück erfolgt automatisch, indem bei Veränderung der Sensorsignale die korrespondierenden Systemvariablen gesetzt werden.

Eine detaillierte Anleitung und Beschreibung erfolgt später. Wichtig: Gegenüber den bisherigen Versionen wurde aus verschiedenen Gründen die Portbezeichnung und die Port-Funktionskennung geändert. Mein aktueller Homeduino heißt homeduino_xyz. Wichtig bei der richtigen Benennung der verwendeten Systemvariablen !

 

Ein Beispiel für ein HM-Skript, mit dem man einen Ausgang auf dem Homeduino schalten kann ist hier:

 

[codesyntax lang=“text“ title=“HM-Skript zum Schalten von D9″]

var send_data = "homeduino_xyz/D9:0"; !##########################
!beim  "homeduino_xyz"  Pin D9 auf 0 / 1 setzen #####  Stand 12.04.2015  stall.biz  
integer word_position = send_data.Find("/");
var h_duino = send_data.Substr(0, word_position) + "_IP";
h_duino = dom.GetObject(h_duino).State();
send_data = "http://" + h_duino + "/?" + send_data.Substr(word_position+1, 30);
string stdout;
string stderr;

!verwendung system.Exec
!system.Exec("wget -q -O - '"#send_data#"'", &stdout, &stderr);

!verwendung CUxD
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("wget -q -O - '"#send_data#"'");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
stdout = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();

!fehler behandlung fehlt noch
boolean fehler = 1;
if (stdout.Length() >0) {fehler =0;} 
dom.GetObject("CUxD.CUX2801001:1.SYSLOG").State("eine Statusmeldung");

[/codesyntax]

 

Wichtig:
Die neue Homeduino 3.0 Software ist sowohl für das
>>> Basis-Shield  IO-Shield20 als auch für das …
>>> Ergänzungs-Shield IO-Shield-Plus geeignet!

Rückmeldungen und Erfahrungen sind willkommen.

Haftungs- und Sicherheitshinweise

Beim Nachbau müssen natürlich alle wichtigen einschlägigen Sicherheitsvorschriften für den Umgang mit gefährlichen Spannungen  eingehalten werden. Fundierte theoretische und praktische Fachkenntnisse der Elektrotechnik und für den Umgang mit gefährlichen Spannungen sind unverzichtbar!!

Durch eine unsachgemäße Installation gefährden Sie ihr Leben und das Leben ihrer Mitmenschen! Darüberhinaus riskieren Sie erhebliche Sachschäden , welche durch Brand etc. hervorgerufen werden können ! Für alle Personen- und Sachschäden durch falsche Installation etc. ist nicht der Hersteller sondern nur der Betreiber verantwortlich.

Ich verweise hier unbedingt auf  die  „Sicherheitshinweise und Haftungsausschluss„-Seite dieses Blogs.

 

 

 

Skills

Posted on

13. April 2015