├── DoorLockLuxMotion └── DoorLockLuxMotion.ino ├── DoorWindow └── DoorWindow.ino ├── MyEsp8266Gateway ├── .gitignore ├── GatewayUtil.h └── MyEsp8266Gateway.ino ├── MyEthernetGateway └── MyEthernetGateway.ino ├── MyEthernetGateway_ENC28J60 └── MyEthernetGateway_ENC28J60.ino ├── MySerialGateway └── MySerialGateway.ino ├── README.md ├── Schematic ├── MySensors_PIR │ └── v1.1 │ │ ├── MySensors_PIR.brd │ │ ├── MySensors_PIR.sch │ │ ├── board_ms_pir_up_rev1.1_eagle.png │ │ ├── gerber_ms_pir_up_rev1.1_bottom.png │ │ ├── gerber_ms_pir_up_rev1.1_top.png │ │ └── schematic_ms_pir_up_rev1.1.png └── lbr │ ├── Sensors_PIR_Lux.lbr │ └── nrf24L01+.lbr ├── TempHumLuxMotion └── TempHumLuxMotion.ino ├── TempHumLuxMotionBat └── TempHumLuxMotionBat.ino ├── WDT_Reset_Test └── WDT_Reset_Test.ino └── WriteDesiredNodeID └── WriteDesiredNodeID.ino /DoorLockLuxMotion/DoorLockLuxMotion.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | //#include 7 | #include 8 | #include 9 | 10 | //-------- define these in your sketch, if applicable ---------------------------------------------------------- 11 | // You can reduce the memory footprint of this handler by declaring that there will be no pin change interrupts 12 | // on any one or two of the three ports. If only a single port remains, the handler will be declared inline 13 | // reducing the size and latency of the handler. 14 | //#define NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts 15 | //#define NO_PORTC_PINCHANGES // to indicate that port c will not be used for pin change interrupts 16 | //#define NO_PORTD_PINCHANGES // to indicate that port d will not be used for pin change interrupts 17 | // if there is only one PCInt vector in use the code can be inlined 18 | // reducing latency and code size 19 | // define DISABLE_PCINT_MULTI_SERVICE below to limit the handler to servicing a single interrupt per invocation. 20 | //#define DISABLE_PCINT_MULTI_SERVICE 21 | //-------- define the above in your sketch, if applicable ------------------------------------------------------ 22 | 23 | #define VERSION "1.1" 24 | 25 | #define MYDEBUG 0 26 | #define REPEATER 0 27 | #define USE_WATCHDOG 1 28 | 29 | //----------------------------------------------------------------------------------------------- 30 | #define MAX_U_LONG 4294967295; 31 | 32 | // Sensor-Child-IDs 33 | #define CHILD_ID_LIGHT 1 34 | #define CHILD_ID_MOTION 2 35 | 36 | #define CHILD_ID_DOOR 5 37 | #define CHILD_ID_LOCK 6 38 | 39 | // receive Controller command 40 | #define CHILD_CCMD_ID 100 41 | 42 | // Sensors PIN Config 43 | #define MOT_SENSOR_PIN 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) 44 | // remove INTERRUPT definition to disable interrupts 45 | #define INTERRUPT MOT_SENSOR_PIN-2 // Usually the interrupt = pin -2 (on uno/nano anyway) 46 | #define INTERRUPT_MODE CHANGE 47 | 48 | // Use pin change interrupts for DOOR and LOCK contacts 49 | // remove PC_INTERRUPT definition to disable pinchange interrupts 50 | #define PC_INTERRUPT dummy 51 | 52 | #if defined (PC_INTERRUPT) 53 | #include 54 | #endif 55 | 56 | #define DOOR_SENSOR_PIN 6 57 | #define LOCK_SENSOR_PIN 7 58 | 59 | // LED pins 60 | //#define PIN_LED_RED 6 61 | #define PIN_LED_GREEN 5 62 | 63 | #define PIN_LED_A_B A0 64 | #define PIN_LED_A_G A1 65 | #define PIN_LED_A_Y A2 66 | #define PIN_LED_A_R A3 67 | 68 | // Send time limits 69 | #define TIME_MAX_REPLAY_LUX 600000 // Maximum time to send values (Lux) even if not changed 70 | #define TIME_MIN_REPLAY_LUX 1000 // Minimum time to send values (Lux) even if changed 71 | #define TIME_MIN_REPLAY_MOT 1000 // Minimum time to send values (Motion) even if changed 72 | 73 | #define TIME_MAX_REPLAY_DOOR 600000 // Maximum time to send door status even if not changed 74 | #define TIME_MIN_REPLAY_DOOR 70 75 | #define TIME_MAX_REPLAY_LOCK 600000 // Maximum time to send lock status even if not changed 76 | #define TIME_MIN_REPLAY_LOCK 70 77 | 78 | // Sleep time between Distance reads (in milliseconds), remove to disable 79 | //#define SLEEP_TIME 50 80 | 81 | // Ideen: Parameter aus der Ferne aendern und in EEPROM speichern: MIN/MAX Time, Sende-Grenzwerte, LED-Benutzung 82 | 83 | //----------------------------------------------------------------------------------------------- 84 | 85 | MySensor gw; 86 | 87 | //BH1750 lightSensor; 88 | AS_BH1750A lightSensor; 89 | 90 | MyMessage msgLux(CHILD_ID_LIGHT, V_LIGHT_LEVEL); 91 | float lastLux = -1; 92 | 93 | MyMessage msgMot(CHILD_ID_MOTION, V_TRIPPED); 94 | uint16_t lastMot = 0; 95 | 96 | MyMessage msgDoor(CHILD_ID_DOOR, V_TRIPPED); 97 | uint16_t lastDoor = 0; 98 | 99 | MyMessage msgLock(CHILD_ID_LOCK, V_LOCK_STATUS); 100 | uint16_t lastLock = 0; 101 | 102 | boolean metric = true; 103 | 104 | // Sensoren vorhanden? 105 | boolean mot_present = true; // can not be autodetected 106 | boolean door_present = true; // can not be autodetected 107 | boolean lock_present = true; // can not be autodetected 108 | boolean lux_present = false; // can be autodetected 109 | 110 | // LEDs 111 | #include 112 | AS_Blink ledR(PIN_LED_A_R, cMillis); 113 | AS_Blink ledG(PIN_LED_A_G, cMillis); 114 | AS_Blink ledB(PIN_LED_A_B, cMillis); 115 | AS_Blink ledY(PIN_LED_A_Y, cMillis); 116 | 117 | //----------------------------------------------------------------------------------------------- 118 | 119 | void setup() 120 | { 121 | // configure Watchdog - startet das Device im Falle eines Freezes neu 122 | #if USE_WATCHDOG > 0 123 | // Damit Watchdog korrekt funktioniert, muss bei mehreren Boards (z.B. Pro MiniU) ein anderer Bootloader installiert werden. Z.B. Optiboot 124 | // s. http://sysmagazine.com/posts/189744/ oder Originalpost: http://habrahabr.ru/post/189744/ 125 | wdt_disable(); 126 | // set watchdog 127 | wdt_enable(WDTO_8S); 128 | //wdt_reset(); 129 | #endif 130 | 131 | // configure pins for the status LEDs 132 | //pinMode(PIN_LED_RED, OUTPUT); 133 | pinMode(PIN_LED_GREEN, OUTPUT); 134 | 135 | // Test the LEDs 136 | //digitalWrite(PIN_LED_RED,1); // LED red 137 | //delay(100); 138 | digitalWrite(PIN_LED_GREEN, 1); // LED green 139 | delay(100); 140 | ledG.setOn(); 141 | delay(100); 142 | ledY.setOn(); 143 | delay(100); 144 | ledR.setOn(); 145 | delay(100); 146 | ledB.setOn(); 147 | 148 | // configure MySesnsors system 149 | #if REPEATER == 1 150 | // The third argument enables repeater mode. 151 | // Keep node awake all time (no slepping!). Pump the radio network by calling process() in your loop(). The MySensors library will take care of all routing in the background. 152 | gw.begin(incomingMessage, AUTO, true); 153 | #else 154 | // Normal Node 155 | gw.begin(incomingMessage, AUTO, false); 156 | #endif 157 | 158 | // autodetect and initialize sensors 159 | 160 | // autodetect BH1750 161 | if (!lightSensor.begin(RESOLUTION_AUTO_HIGH,false)) { 162 | lux_present = false; 163 | #if MYDEBUG > 0 164 | Serial.println("LightSensor not found"); 165 | #endif 166 | } else { 167 | lux_present = true; 168 | #if MYDEBUG > 0 169 | Serial.println("LightSensor found"); 170 | #endif 171 | } 172 | 173 | // sets right mode for the sensor pins 174 | pinMode(MOT_SENSOR_PIN, INPUT); 175 | pinMode(DOOR_SENSOR_PIN, INPUT_PULLUP); 176 | digitalWrite(DOOR_SENSOR_PIN, HIGH); 177 | pinMode(LOCK_SENSOR_PIN, INPUT_PULLUP); 178 | digitalWrite(LOCK_SENSOR_PIN, HIGH); 179 | 180 | // Send the sketch version information to the gateway and Controller 181 | //gw.sendSketchInfo("Temp+Hum+Lux+Motion", "1.0"); 182 | const char *sketch_name = "Door+Lock/Motion+Lux sensor ("; 183 | //+(mot_present?"M ":""+lux_present?"L ":""+dht_present?"T H":""); 184 | if (mot_present) { 185 | sketch_name = strcat(const_cast(sketch_name), "M"); 186 | } 187 | if (lux_present) { 188 | sketch_name = strcat(const_cast(sketch_name), "L"); 189 | } 190 | if (door_present) { 191 | sketch_name = strcat(const_cast(sketch_name), "d"); 192 | } 193 | if (lock_present) { 194 | sketch_name = strcat(const_cast(sketch_name), "l"); 195 | } 196 | sketch_name = strcat(const_cast(sketch_name), ")"); 197 | 198 | #if MYDEBUG > 0 199 | Serial.print("Sketch: "); 200 | Serial.print(sketch_name); 201 | Serial.print(" Version: "); 202 | Serial.println(VERSION); 203 | #endif 204 | 205 | gw.sendSketchInfo(sketch_name, VERSION); 206 | 207 | // Register all sensors to gw (they will be created as child devices) 208 | if (mot_present) { 209 | gw.present(CHILD_ID_MOTION, S_MOTION); 210 | } 211 | 212 | if (door_present) { 213 | gw.present(CHILD_ID_DOOR, S_DOOR); 214 | } 215 | 216 | if (lock_present) { 217 | gw.present(CHILD_ID_LOCK, S_LOCK); 218 | } 219 | 220 | if (lux_present) { 221 | gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL); 222 | } 223 | 224 | gw.present(CHILD_CCMD_ID, S_CUSTOM); 225 | 226 | //metric = gw.getConfig().isMetric; 227 | 228 | // attach interupts (if any used) 229 | #if defined (INTERRUPT) 230 | if(mot_present) { 231 | attachInterrupt(INTERRUPT, sendMot, INTERRUPT_MODE); 232 | } 233 | #endif 234 | #if defined (PC_INTERRUPT) 235 | //PCintPort::attachInterrupt(DOOR_SENSOR_PIN, &sendDoor, CHANGE); 236 | //PCintPort::attachInterrupt(LOCK_SENSOR_PIN, &sendLock, CHANGE); 237 | // Beide obere PCInts zu aktivieren führte zum Aufhängen, daher beides in einer Methode 238 | PCintPort::attachInterrupt(LOCK_SENSOR_PIN, &sendDoorAndLock, CHANGE); 239 | #endif 240 | 241 | // turn the LEDs off 242 | ledG.setOff(); 243 | delay(100); 244 | ledY.setOff(); 245 | delay(100); 246 | ledR.setOff(); 247 | delay(100); 248 | ledB.setOff(); 249 | //delay(100); 250 | //digitalWrite(PIN_LED_RED,0); // LED red 251 | delay(100); 252 | digitalWrite(PIN_LED_GREEN, 0); // LED green 253 | 254 | 255 | #if USE_WATCHDOG > 0 256 | // set watchdog 257 | //wdt_enable(WDTO_4S); 258 | wdt_reset(); 259 | #endif 260 | 261 | // TEST ONLY! 262 | ledG.setBlinkInterval(250); 263 | ledY.setBlinkInterval(800); 264 | ledR.setBlinkInterval(100); 265 | ledB.setBlinkInterval(800); 266 | } 267 | 268 | void sendDoorAndLock() { 269 | #if MYDEBUG > 0 270 | Serial.println("PC_INT handler activated"); 271 | #endif 272 | 273 | sendDoor(); 274 | sendLock(); 275 | } 276 | 277 | void loop() 278 | { 279 | #if USE_WATCHDOG > 0 280 | // watchdog reset 281 | wdt_reset(); 282 | #endif 283 | 284 | // Blink 285 | blink(); 286 | 287 | // send sensor events 288 | if (mot_present) { 289 | sendMot(); 290 | } 291 | 292 | // Blink 293 | blink(); 294 | 295 | if (door_present) { 296 | sendDoor(); 297 | } 298 | 299 | // Blink 300 | blink(); 301 | 302 | if (lock_present) { 303 | sendLock(); 304 | } 305 | 306 | // Blink 307 | blink(); 308 | 309 | if (lux_present) { 310 | sendLux(); 311 | } 312 | 313 | #if defined (SLEEP_TIME) 314 | // Sleep until interrupt comes in on motion sensor. Send update every X minutes. 315 | // Auchtung! Wird Zeitprobleme geben, Korrektur notwendig. 316 | sleep(INTERRUPT, CHANGE, SLEEP_TIME); 317 | #endif 318 | 319 | #if REPEATER == 1 320 | // process radio messages (use for repeater and aktor nodes) 321 | gw.process(); 322 | #endif 323 | 324 | // Blink 325 | blink(); 326 | } 327 | 328 | void blink() { 329 | ledR.blink(); 330 | ledG.blink(); 331 | ledB.blink(); 332 | ledY.blink(); 333 | } 334 | 335 | //----------------------------------------------------------------------------------------------- 336 | // TODO: ggf. nach MSUtils verlagern 337 | unsigned long timeCorrection = 0; 338 | unsigned long cMillis() { 339 | return millis() + timeCorrection; 340 | } 341 | 342 | void sleep(unsigned long ms) { 343 | gw.sleep(ms); 344 | timeCorrection += ms; 345 | } 346 | 347 | bool sleep(uint8_t interrupt, uint8_t mode, unsigned long ms) { 348 | bool ret = gw.sleep(interrupt, mode, ms); 349 | if (ret) { 350 | // interrupted 351 | // Statistisch dürfe im Mittel dir Hälfte der Zeit ein akzeptabler Wert bei Interrupts sein 352 | timeCorrection += (ms / 2); 353 | } else { 354 | timeCorrection += ms; 355 | } 356 | return ret; 357 | } 358 | 359 | //----------------------------------------------------------------------------------------------- 360 | 361 | unsigned long lastTimeLux = cMillis() + TIME_MIN_REPLAY_LUX + 1; 362 | //boolean luxReadingRunning=false; 363 | void sendLux() 364 | { 365 | unsigned long time = cMillis(); 366 | 367 | // Zeitdifferenz zum letzten Senden 368 | unsigned long delayTime = 0; 369 | // Auf Ueberlauf pruefen 370 | if (time < lastTimeLux) 371 | { 372 | // Ueberlauf: Delay ist Zeit zum MaxWert plus Zeit ab Null 373 | delayTime = MAX_U_LONG - lastTimeLux + time; 374 | } else { 375 | // Kein Ueberlauf: einfache Differenz 376 | delayTime = time - lastTimeLux; 377 | } 378 | 379 | #if MYDEBUG > 1 380 | Serial.print("TimeDiff: "); 381 | Serial.println(delayTime); 382 | #endif 383 | 384 | // Mindestabstand beachten 385 | if (delayTime < TIME_MIN_REPLAY_LUX) 386 | { 387 | return; 388 | } 389 | 390 | 391 | // Senden, nur wenn sich der Wert geändert hat 392 | // Nach verstreichen eines definierten Intervals soll in jedem Fall gesendet werden 393 | 394 | boolean sendAnyway = delayTime >= TIME_MAX_REPLAY_LUX; 395 | 396 | lightSensor.startMeasurementAsync(cMillis); 397 | while(!lightSensor.isMeasurementReady()) { 398 | //delay(lightSensor.nextDelay()); 399 | unsigned long x = lightSensor.nextDelay(); 400 | unsigned long st=cMillis(); 401 | while(cMillis() 0 409 | Serial.print("Lux: "); 410 | Serial.println(lux); 411 | #endif 412 | 413 | float diff = abs(lux - lastLux); 414 | boolean doSend = false; 415 | // Weil exponentielle Funktion, mehrere Stufen (vereinfacht) 416 | if (lastLux < 1) { 417 | doSend = diff > 0.5; 418 | } else if (lastLux < 5) { 419 | doSend = diff > 1; 420 | } else if (lastLux < 10) { 421 | doSend = diff > 2; 422 | } else if (lastLux < 100) { 423 | doSend = diff > 10; 424 | } else if (lastLux < 1000) { 425 | doSend = diff > 100; 426 | } else if (lastLux < 10000) { 427 | doSend = diff > 1000; 428 | } else { 429 | doSend = diff > 10000; 430 | } 431 | 432 | if (sendAnyway || doSend) { 433 | //gw.send(msgLux.set(lux)); 434 | gw.send(msgLux.set(lux, 2)); 435 | lastLux = lux; 436 | // Zeit merken 437 | lastTimeLux = cMillis(); 438 | 439 | 440 | Serial.print("->Lux: "); 441 | Serial.println(lux); 442 | } 443 | } 444 | 445 | unsigned long lastTimeDoor = 0; 446 | boolean doorStatus = false; 447 | void sendDoor() { 448 | unsigned long time = cMillis(); 449 | 450 | // Zeitdifferenz zum letzten Senden 451 | unsigned long delayTime = 0; 452 | // Auf Ueberlauf pruefen 453 | if (time < lastTimeDoor) 454 | { 455 | // Ueberlauf: Delay ist Zeit zum MaxWert plus Zeit ab Null 456 | delayTime = MAX_U_LONG - lastTimeDoor + time; 457 | } else { 458 | // Kein Ueberlauf: einfache Differenz 459 | delayTime = time - lastTimeDoor; 460 | } 461 | 462 | // Mindestabstand beachten 463 | if (delayTime < TIME_MIN_REPLAY_DOOR) 464 | { 465 | return; 466 | } 467 | 468 | // Senden, nur wenn sich der Wert geändert hat 469 | // Nach verstreichen eines definierten Intervals soll in jedem Fall gesendet werden 470 | 471 | boolean sendAnyway = delayTime >= TIME_MAX_REPLAY_DOOR; 472 | 473 | boolean newDoorStatus = digitalRead(DOOR_SENSOR_PIN) == HIGH; 474 | 475 | #if MYDEBUG > 0 476 | Serial.print("Door: "); 477 | Serial.println(newDoorStatus ? "off" : "on"); 478 | #endif 479 | 480 | if (newDoorStatus != doorStatus || sendAnyway) { 481 | doorStatus = newDoorStatus; 482 | gw.send(msgDoor.set(newDoorStatus ? "0" : "1")); // Send value to gw 483 | // Zeit merken 484 | lastTimeDoor = cMillis(); 485 | } 486 | } 487 | 488 | unsigned long lastTimeLock = 0; 489 | boolean lockStatus = false; 490 | void sendLock() { 491 | unsigned long time = cMillis(); 492 | 493 | // Zeitdifferenz zum letzten Senden 494 | unsigned long delayTime = 0; 495 | // Auf Ueberlauf pruefen 496 | if (time < lastTimeLock) 497 | { 498 | // Ueberlauf: Delay ist Zeit zum MaxWert plus Zeit ab Null 499 | delayTime = MAX_U_LONG - lastTimeLock + time; 500 | } else { 501 | // Kein Ueberlauf: einfache Differenz 502 | delayTime = time - lastTimeLock; 503 | } 504 | 505 | // Mindestabstand beachten 506 | if (delayTime < TIME_MIN_REPLAY_LOCK) 507 | { 508 | return; 509 | } 510 | 511 | // Senden, nur wenn sich der Wert geändert hat 512 | // Nach verstreichen eines definierten Intervals soll in jedem Fall gesendet werden 513 | 514 | boolean sendAnyway = delayTime >= TIME_MAX_REPLAY_LOCK; 515 | 516 | boolean newLockStatus = digitalRead(LOCK_SENSOR_PIN) == HIGH; 517 | 518 | #if MYDEBUG > 0 519 | Serial.print("Lock: "); 520 | Serial.println(newLockStatus ? "off" : "on"); 521 | #endif 522 | 523 | if (newLockStatus != lockStatus || sendAnyway) { 524 | lockStatus = newLockStatus; 525 | gw.send(msgLock.set(newLockStatus ? "0" : "1")); // Send value to gw 526 | // Zeit merken 527 | lastTimeLock = cMillis(); 528 | } 529 | } 530 | 531 | unsigned long lastTimeMot = cMillis() + TIME_MIN_REPLAY_MOT + 1; 532 | void sendMot() 533 | { 534 | unsigned long time = cMillis(); 535 | 536 | // Zeitdifferenz zum letzten Senden 537 | unsigned long delayTime = 0; 538 | // Auf Ueberlauf pruefen 539 | if (time < lastTimeMot) 540 | { 541 | // Ueberlauf: Delay ist Zeit zum MaxWert plus Zeit ab Null 542 | delayTime = MAX_U_LONG - lastTimeMot + time; 543 | } else { 544 | // Kein Ueberlauf: einfache Differenz 545 | delayTime = time - lastTimeMot; 546 | } 547 | // Mindestabstand beachten 548 | if (delayTime < TIME_MIN_REPLAY_MOT) 549 | { 550 | return; 551 | } 552 | 553 | // Read digital motion value 554 | boolean tripped = digitalRead(MOT_SENSOR_PIN) == HIGH; 555 | digitalWrite(PIN_LED_GREEN, tripped ? 1 : 0); //TEST TODO 556 | 557 | #if MYDEBUG > 0 558 | Serial.print("Motion: "); 559 | Serial.println(tripped); 560 | #endif 561 | 562 | if (tripped && !lastMot) // muss zwischendurch mal 'false' werden 563 | { 564 | //gw.send(msgMot.set(tripped?"1":"0")); // Send tripped value to gw 565 | gw.send(msgMot.set("1")); // Send tripped value to gw 566 | // Zeit merken 567 | lastTimeMot = cMillis(); 568 | } 569 | 570 | lastMot = tripped; 571 | } 572 | 573 | int controllerCmd = 0; 574 | void incomingMessage(const MyMessage &message) { 575 | // We only expect one type of message from controller. But we better check anyway. 576 | if (message.isAck()) { 577 | Serial.println("This is an ack from gateway"); 578 | } 579 | 580 | if (message.type == V_VAR1) { 581 | // new controller command 582 | controllerCmd = message.getInt(); 583 | // Format xyzzzz => x => LED-Nr. (), y => State (0->off, 1->on, 2->blink, 3->PIR-State, 4->door/lock state), zzzz => Blink interval *10ms (100 = 1000ms) 584 | 585 | 586 | // Zustände LEDs (Door/Lock, Windows...) 587 | // Green: on -> Door closed and locked; blinking slow -> door closed but not locked; blinking fast-> door is open 588 | // Yellow: reserved 589 | // Red: alarm (reserved) 590 | // Blue: on -> all Windows closed; blinking slow -> at least one windows is tilted, all other are closed; blinking fast -> at least one window ist open; off -> unknown 591 | 592 | 593 | // Write some debug info 594 | Serial.print("Incoming change for sensor:"); 595 | Serial.print(message.sensor); 596 | Serial.print(", New status: "); 597 | Serial.println(message.getInt()); 598 | } 599 | } 600 | 601 | -------------------------------------------------------------------------------- /DoorWindow/DoorWindow.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define SKETCH_NAME "Door Window Sensor" 5 | #define VERSION "1.2" 6 | 7 | #define DEBUG 1 8 | #define REPEATER 0 9 | #define USE_WATCHDOG 0 10 | 11 | //----------------------------------------------------------------------------------------------- 12 | #define MAX_U_LONG 4294967295; 13 | 14 | // Sensor-Child-IDs 15 | #define CHILD_ID_DOOR_WIN 1 16 | 17 | // Switch pin 18 | #define SWITCH_PIN 3 // Arduino Digital I/O pin for button/reed switch or IR-Sensor 19 | #define INTERRUPT SWITCH_PIN-2 // Usually the interrupt = pin -2 (on uno/nano anyway) 20 | #define INTERRUPT_MODE CHANGE 21 | 22 | // LED pins 23 | #define PIN_LED 7 24 | 25 | // Send time limits 26 | #define TIME_MAX_REPLAY_DOOR_WIN 600000 // Maximum time to send values even if not changed 27 | #define TIME_MIN_REPLAY_DOOR_WIN 100 // Minimum time to send values even if changed 28 | 29 | // Aufpassen bei SleepTime wg. Watchdog! 30 | #define SLEEP_TIME 1000 // Sleep time between Distance reads (in milliseconds) (be careful with watchdogbe careful with watchdog (if used)!) 31 | 32 | //----------------------------------------------------------------------------------------------- 33 | 34 | MySensor gw; 35 | 36 | MyMessage msg(CHILD_ID_DOOR_WIN, V_TRIPPED); 37 | uint16_t lastVal=0; 38 | 39 | void setup() 40 | { 41 | #if USE_WATCHDOG > 0 42 | // Damit Watchdog korrekt funktioniert, muss bei mehreren Boards (z.B. Pro MiniU) ein anderer Bootloader installiert werden. Z.B. Optiboot 43 | // s. http://sysmagazine.com/posts/189744/ oder Originalpost: http://habrahabr.ru/post/189744/ 44 | wdt_disable(); 45 | // set watchdog 46 | wdt_enable(WDTO_8S); 47 | //wdt_reset(); 48 | #endif 49 | 50 | #if DEBUG > 0 51 | Serial.print("Sketch: "); 52 | Serial.print(SKETCH_NAME); 53 | Serial.print(" Version: "); 54 | Serial.println(VERSION); 55 | #endif 56 | 57 | // initialize repeater or normal node 58 | #if REPEATER == 1 59 | // The third argument enables repeater mode. 60 | // Keep node awake all time (no slepping!). Pump the radio network by calling process() in your loop(). The MySensors library will take care of all routing in the background. 61 | gw.begin(NULL, AUTO, true); 62 | #else 63 | // Normal Node 64 | gw.begin(); 65 | #endif 66 | 67 | // Setup the buttons 68 | //pinMode(SWITCH_PIN, INPUT); 69 | // Activate internal pull-ups 70 | pinMode(SWITCH_PIN, INPUT_PULLUP); 71 | digitalWrite(SWITCH_PIN, HIGH); 72 | 73 | // Define LED pins 74 | pinMode(PIN_LED, OUTPUT); 75 | digitalWrite(PIN_LED,0); // LED off 76 | 77 | // Send the sketch version information to the gateway and Controller 78 | gw.sendSketchInfo(SKETCH_NAME, VERSION); 79 | 80 | // Register binary input sensor to sensor_node (they will be created as child devices) 81 | // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. 82 | // If S_LIGHT is used, remember to update variable type you send in. See "msg" above. 83 | gw.present(CHILD_ID_DOOR_WIN, S_DOOR); 84 | 85 | //metric = gw.getConfig().isMetric; 86 | 87 | #if defined (INTERRUPT) 88 | attachInterrupt(INTERRUPT, sendMsg, INTERRUPT_MODE); 89 | #endif 90 | 91 | #if USE_WATCHDOG > 0 92 | // set watchdog 93 | //wdt_enable(WDTO_2S); 94 | wdt_reset(); 95 | #endif 96 | } 97 | 98 | void loop() 99 | { 100 | #if USE_WATCHDOG > 0 101 | // watchdog reset 102 | wdt_reset(); 103 | #endif 104 | 105 | #if PIN_LED > 0 106 | // switch led off 107 | digitalWrite(PIN_LED,0); 108 | sendMsg(); 109 | #endif 110 | 111 | #if defined (SLEEP_TIME) 112 | // Sleep until interrupt comes in on motion sensor. Send update every X minutes. 113 | // Auchtung! Wird Zeitprobleme geben, Korrektur notwendig. 114 | gw.sleep(INTERRUPT, CHANGE, SLEEP_TIME); 115 | #endif 116 | 117 | #if REPEATER == 1 118 | // process radio messages (use for repeater and aktor nodes) 119 | gw.process(); 120 | #endif 121 | } 122 | 123 | //----------------------------------------------------------------------------------------------- 124 | 125 | unsigned long lastTime=cMillis()+TIME_MIN_REPLAY_DOOR_WIN+1; 126 | void sendMsg() 127 | { 128 | unsigned long time = cMillis(); 129 | 130 | // Zeitdifferenz zum letzten Senden 131 | unsigned long delayTime = 0; 132 | // Auf Ueberlauf pruefen 133 | if(time= TIME_MAX_REPLAY_DOOR_WIN; 149 | 150 | // Read digital motion value 151 | boolean tripped = digitalRead(SWITCH_PIN) == HIGH; 152 | 153 | if(sendAnyway || tripped != lastVal) 154 | { 155 | #if PIN_LED > 0 156 | // switch led on 157 | digitalWrite(PIN_LED,1); 158 | #endif 159 | 160 | #if DEBUG > 0 161 | Serial.print("Value: "); 162 | Serial.println(tripped); 163 | #endif 164 | 165 | gw.send(msg.set(tripped?"1":"0")); // Send tripped value to gw 166 | // Zeit merken 167 | lastTime=cMillis(); 168 | } 169 | 170 | lastVal = tripped; 171 | } 172 | 173 | //----------------------------------------------------------------------------------------------- 174 | // TODO: ggf. nach MSUtils verlagern 175 | unsigned long timeCorrection = 0; 176 | unsigned long cMillis() { 177 | return millis()+timeCorrection; 178 | } 179 | 180 | void sleep(unsigned long ms) { 181 | gw.sleep(ms); 182 | timeCorrection += ms; 183 | } 184 | 185 | bool sleep(uint8_t interrupt, uint8_t mode, unsigned long ms) { 186 | bool ret = gw.sleep(interrupt,mode, ms); 187 | if(ret) { 188 | // interrupted 189 | // Statistisch dürfe im Mittel die Hälfte der Zeit ein akzeptabler Wert bei Interrupts sein 190 | timeCorrection += (ms/2); 191 | } else { 192 | timeCorrection += ms; 193 | } 194 | return ret; 195 | } 196 | 197 | //----------------------------------------------------------------------------------------------- 198 | 199 | -------------------------------------------------------------------------------- /MyEsp8266Gateway/.gitignore: -------------------------------------------------------------------------------- 1 | /MySecret.h 2 | -------------------------------------------------------------------------------- /MyEsp8266Gateway/GatewayUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef __GATEWAYUTIL_H__ 2 | #define __GATEWAYUTIL_H__ 3 | 4 | #ifdef ARDUINO 5 | 6 | static uint8_t inclusionTime = 1; // Number of minutes inclusion mode is enabled 7 | static uint8_t pinInclusion = 3; // Input pin that should trigger inclusion mode 8 | 9 | #define MAX_RECEIVE_LENGTH 100 // Max buffersize needed for messages coming from controller 10 | #define MAX_SEND_LENGTH 120 // Max buffersize needed for messages destined for controller 11 | 12 | 13 | typedef struct 14 | { 15 | char string[MAX_RECEIVE_LENGTH]; 16 | uint8_t idx; 17 | } inputBuffer; 18 | 19 | static volatile boolean buttonTriggeredInclusion; 20 | static boolean inclusionMode; // Keeps track on inclusion mode 21 | bool inclusionButtonSupported = false; 22 | void (*serial)(const char *fmt, ... ); 23 | 24 | MyParserSerial parser; 25 | 26 | void setInclusionMode(boolean newMode); 27 | 28 | char convBuf[MAX_PAYLOAD*2+1]; 29 | unsigned long inclusionStartTime; 30 | 31 | 32 | void startInclusionInterrupt() { 33 | buttonTriggeredInclusion = true; 34 | } 35 | 36 | void setupGateway(uint8_t _inc, uint8_t _incTime, void (* _serial)(const char *, ... )) { 37 | inclusionMode = 0; 38 | buttonTriggeredInclusion = false; 39 | serial = _serial; 40 | 41 | inclusionTime = _incTime; 42 | inclusionButtonSupported = (_inc != 255); 43 | if (inclusionButtonSupported) 44 | { 45 | pinInclusion = _inc; 46 | 47 | // Setup digital in that triggers inclusion mode 48 | pinMode(pinInclusion, INPUT_PULLUP); 49 | 50 | // Add interrupt for inclusion button to pin 51 | attachInterrupt(pinInclusion, startInclusionInterrupt, FALLING); 52 | } 53 | } 54 | 55 | void incomingMessage(const MyMessage &message) { 56 | // if (mGetCommand(message) == C_PRESENTATION && inclusionMode) { 57 | // gw.rxBlink(3); 58 | // } else { 59 | // gw.rxBlink(1); 60 | // } 61 | // Pass along the message from sensors to serial line 62 | serial(PSTR("%d;%d;%d;%d;%d;%s\n"),message.sender, message.sensor, mGetCommand(message), mGetAck(message), message.type, message.getString(convBuf)); 63 | } 64 | 65 | 66 | 67 | void checkButtonTriggeredInclusion() { 68 | if (inclusionButtonSupported) 69 | { 70 | if (buttonTriggeredInclusion) { 71 | // Ok, someone pressed the inclusion button on the gateway 72 | // start inclusion mode for 1 munute. 73 | #ifdef DEBUG 74 | serial(PSTR("0;0;%d;0;%d;Inclusion started by button.\n"), C_INTERNAL, I_LOG_MESSAGE); 75 | #endif 76 | buttonTriggeredInclusion = false; 77 | setInclusionMode(true); 78 | } 79 | } 80 | } 81 | 82 | void checkInclusionFinished() { 83 | if (inclusionMode && millis()-inclusionStartTime>60000UL*inclusionTime) { 84 | // inclusionTimeInMinutes minute(s) has passed.. stop inclusion mode 85 | setInclusionMode(false); 86 | } 87 | } 88 | 89 | void parseAndSend(MySensor &gw, char *commandBuffer) { 90 | boolean ok; 91 | MyMessage &msg = gw.getLastMessage(); 92 | 93 | if (parser.parse(msg, commandBuffer)) { 94 | uint8_t command = mGetCommand(msg); 95 | 96 | if (msg.destination==GATEWAY_ADDRESS && command==C_INTERNAL) { 97 | // Handle messages directed to gateway 98 | if (msg.type == I_VERSION) { 99 | // Request for version 100 | serial(PSTR("0;0;%d;0;%d;%s\n"), C_INTERNAL, I_VERSION, LIBRARY_VERSION); 101 | } else if (msg.type == I_INCLUSION_MODE) { 102 | // Request to change inclusion mode 103 | setInclusionMode(atoi(msg.data) == 1); 104 | } 105 | } else { 106 | #ifdef WITH_LEDS_BLINKING 107 | gw.txBlink(1); 108 | #endif 109 | ok = gw.sendRoute(msg); 110 | if (!ok) { 111 | #ifdef WITH_LEDS_BLINKING 112 | gw.errBlink(1); 113 | #endif 114 | } 115 | } 116 | } 117 | } 118 | 119 | void setInclusionMode(boolean newMode) { 120 | if (newMode != inclusionMode) { 121 | inclusionMode = newMode; 122 | // Send back mode change on serial line to ack command 123 | serial(PSTR("0;0;%d;0;%d;%d\n"), C_INTERNAL, I_INCLUSION_MODE, inclusionMode?1:0); 124 | 125 | if (inclusionMode) { 126 | inclusionStartTime = millis(); 127 | } 128 | } 129 | } 130 | 131 | 132 | #else 133 | #error This example is only for use on Arduino. 134 | #endif // ARDUINO 135 | 136 | #endif 137 | -------------------------------------------------------------------------------- /MyEsp8266Gateway/MyEsp8266Gateway.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * The MySensors Arduino library handles the wireless radio link and protocol 3 | * between your home built sensors/actuators and HA controller of choice. 4 | * The sensors forms a self healing radio network with optional repeaters. Each 5 | * repeater and gateway builds a routing tables in EEPROM which keeps track of the 6 | * network topology allowing messages to be routed to nodes. 7 | * 8 | * Created by Henrik Ekblad 9 | * Copyright (C) 2013-2015 Sensnology AB 10 | * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors 11 | * 12 | * Documentation: http://www.mysensors.org 13 | * Support Forum: http://forum.mysensors.org 14 | * 15 | * This program is free software; you can redistribute it and/or 16 | * modify it under the terms of the GNU General Public License 17 | * version 2 as published by the Free Software Foundation. 18 | * 19 | ******************************* 20 | * 21 | * REVISION HISTORY 22 | * Version 1.0.1 - Hexenmeister - quick fix: line endings for FHEM 23 | * Version 1.0 - Henrik EKblad 24 | * Contribution by a-lurker and Anticimex, 25 | * Contribution by Norbert Truchsess 26 | * Contribution by Ivo Pullens (ESP8266 support) 27 | * 28 | * DESCRIPTION 29 | * The EthernetGateway sends data received from sensors to the WiFi link. 30 | * The gateway also accepts input on ethernet interface, which is then sent out to the radio network. 31 | * 32 | * VERA CONFIGURATION: 33 | * Enter "ip-number:port" in the ip-field of the Arduino GW device. This will temporarily override any serial configuration for the Vera plugin. 34 | * E.g. If you want to use the defualt values in this sketch enter: 192.168.178.66:5003 35 | * 36 | * LED purposes: 37 | * - To use the feature, uncomment WITH_LEDS_BLINKING in MyConfig.h 38 | * - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved 39 | * - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly 40 | * - ERR (red) - fast blink on error during transmission error or recieve crc error 41 | * 42 | * See http://www.mysensors.org/build/ethernet_gateway for wiring instructions. 43 | * The ESP8266 however requires different wiring: 44 | * nRF24L01+ ESP8266 45 | * VCC VCC 46 | * CE GPIO4 47 | * CSN/CS GPIO15 48 | * SCK GPIO14 49 | * MISO GPIO12 50 | * MOSI GPIO13 51 | * 52 | * Not all ESP8266 modules have all pins available on their external interface. 53 | * This code has been tested on an ESP-12 module. 54 | * The ESP8266 requires a certain pin configuration to download code, and another one to run code: 55 | * - Connect REST (reset) via 10K pullup resistor to VCC, and via switch to GND ('reset switch') 56 | * - Connect GPIO15 via 10K pulldown resistor to GND 57 | * - Connect CH_PD via 10K resistor to VCC 58 | * - Connect GPIO2 via 10K resistor to VCC 59 | * - Connect GPIO0 via 10K resistor to VCC, and via switch to GND ('bootload switch') 60 | * 61 | * Inclusion mode button: 62 | * - Connect GPIO5 via switch to GND ('inclusion switch') 63 | * 64 | * Hardware SHA204 signing is currently not supported! 65 | * 66 | * Make sure to fill in your ssid and WiFi password below for ssid & pass. 67 | */ 68 | #define NO_PORTB_PINCHANGES 69 | 70 | #include 71 | 72 | #include 73 | #include 74 | #include 75 | #include 76 | #include 77 | #include 78 | #include 79 | 80 | #include 81 | #include 82 | #include 83 | #include "GatewayUtil.h" 84 | 85 | #include "MySecret.h" 86 | 87 | // create a new MySecret.h file with following content: 88 | // -cut------------------------------------------> 89 | // #define MY_WLAN_SSID "MyWLAN_SSID" // SSID 90 | // #define MY_WLAN_PASS "my_very_secret_password" // Password 91 | // <-cut------------------------------------------ 92 | // (and you do not check them into the repository!) 93 | 94 | const char *ssid = MY_WLAN_SSID; // cannot be longer than 32 characters! 95 | const char *pass = MY_WLAN_PASS; // 96 | 97 | #define INCLUSION_MODE_TIME 1 // Number of minutes inclusion mode is enabled 98 | #define INCLUSION_MODE_PIN 5 // Digital pin used for inclusion mode button 99 | 100 | #define RADIO_CE_PIN 4 // radio chip enable 101 | #define RADIO_SPI_SS_PIN 15 // radio SPI serial select 102 | 103 | #ifdef WITH_LEDS_BLINKING 104 | #define RADIO_ERROR_LED_PIN 7 // Error led pin 105 | #define RADIO_RX_LED_PIN 8 // Receive led pin 106 | #define RADIO_TX_LED_PIN 9 // the PCB, on board LED 107 | #endif 108 | 109 | 110 | // NRFRF24L01 radio driver (set low transmit power by default) 111 | MyTransportNRF24 transport(RADIO_CE_PIN, RADIO_SPI_SS_PIN, RF24_PA_LEVEL_GW); 112 | //MyTransportRFM69 transport; 113 | 114 | 115 | // Message signing driver (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h) 116 | #ifdef MY_SIGNING_FEATURE 117 | MySigningNone signer; 118 | //MySigningAtsha204Soft signer; 119 | #endif 120 | 121 | // Hardware profile 122 | MyHwESP8266 hw; 123 | 124 | // Construct MySensors library (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h) 125 | // To use LEDs blinking, uncomment WITH_LEDS_BLINKING in MyConfig.h 126 | MySensor gw(transport, hw 127 | #ifdef MY_SIGNING_FEATURE 128 | , signer 129 | #endif 130 | #ifdef WITH_LEDS_BLINKING 131 | , RADIO_RX_LED_PIN, RADIO_TX_LED_PIN, RADIO_ERROR_LED_PIN 132 | #endif 133 | ); 134 | 135 | 136 | #define IP_PORT 5003 // The port you want to open 137 | #define MAX_SRV_CLIENTS 5 // how many clients should be able to telnet to this ESP8266 138 | 139 | // a R/W server on the port 140 | static WiFiServer server(IP_PORT); 141 | static WiFiClient clients[MAX_SRV_CLIENTS]; 142 | static bool clientsConnected[MAX_SRV_CLIENTS]; 143 | static inputBuffer inputString[MAX_SRV_CLIENTS]; 144 | 145 | #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 146 | 147 | #define USE_STATIC_IP 0 148 | #define STATIC_IP 192, 168, 0, 222 149 | #define STATIC_GATEWAY 192, 168, 0, 1 150 | #define STATIC_DNS 192, 168, 0, 1 151 | #define STATIC_SUBNET 255, 255, 255, 0 152 | 153 | void output(const char *fmt, ... ) 154 | { 155 | char serialBuffer[MAX_SEND_LENGTH]; 156 | va_list args; 157 | va_start (args, fmt ); 158 | vsnprintf_P(serialBuffer, MAX_SEND_LENGTH, fmt, args); 159 | va_end (args); 160 | Serial.print(serialBuffer); 161 | for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) 162 | { 163 | if (clients[i] && clients[i].connected()) 164 | { 165 | // Serial.print("Client "); Serial.print(i); Serial.println(" write"); 166 | clients[i].write((uint8_t*)serialBuffer, strlen(serialBuffer)); 167 | } 168 | } 169 | } 170 | 171 | void setup() 172 | { 173 | // Setup console 174 | hw_init(); 175 | 176 | Serial.println(); Serial.println(); 177 | Serial.println("ESP8266 MySensors Gateway"); 178 | Serial.print("Connecting to "); Serial.println(ssid); 179 | 180 | WiFi.mode (WIFI_STA); // turn off AP mode 181 | 182 | (void)WiFi.begin(ssid, pass); 183 | 184 | #if USE_STATIC_IP > 0 185 | IPAddress ip(STATIC_IP); 186 | IPAddress gateway(STATIC_GATEWAY); 187 | IPAddress dns(STATIC_DNS); 188 | IPAddress subnet(STATIC_SUBNET); 189 | WiFi.config(ip, dns, gateway, subnet); 190 | #endif 191 | 192 | while (WiFi.status() != WL_CONNECTED) 193 | { 194 | delay(500); 195 | Serial.print("."); 196 | } 197 | Serial.println("Connected!"); 198 | Serial.print("IP: "); Serial.println(WiFi.localIP()); 199 | Serial.flush(); 200 | 201 | setupGateway(INCLUSION_MODE_PIN, INCLUSION_MODE_TIME, output); 202 | Serial.println("GateWay setup done!");Serial.flush(); 203 | 204 | // Initialize gateway at maximum PA level, channel 70 and callback for write operations 205 | gw.begin(incomingMessage, 0, true, 0); 206 | 207 | Serial.println("MySensors init done!");Serial.flush(); 208 | 209 | // start listening for clients 210 | server.begin(); 211 | server.setNoDelay(true); 212 | 213 | Serial.println("Server ready!");Serial.flush(); 214 | } 215 | 216 | 217 | void loop() { 218 | gw.process(); 219 | 220 | checkButtonTriggeredInclusion(); 221 | checkInclusionFinished(); 222 | 223 | // Go over list of clients and stop any that are no longer connected. 224 | // If the server has a new client connection it will be assigned to a free slot. 225 | bool allSlotsOccupied = true; 226 | for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) 227 | { 228 | if (!clients[i].connected()) 229 | { 230 | if (clientsConnected[i]) 231 | { 232 | Serial.print("Client "); Serial.print(i); Serial.println(" disconnected"); 233 | clients[i].stop(); 234 | } 235 | //check if there are any new clients 236 | if (server.hasClient()) 237 | { 238 | clients[i] = server.available(); 239 | inputString[i].idx = 0; 240 | Serial.print("Client "); Serial.print(i); Serial.println(" connected"); 241 | output(PSTR("0;0;%d;0;%d;Gateway startup complete.\n"), C_INTERNAL, I_GATEWAY_READY); 242 | } 243 | } 244 | bool connected = clients[i].connected(); 245 | clientsConnected[i] = connected; 246 | allSlotsOccupied &= connected; 247 | } 248 | if (allSlotsOccupied && server.hasClient()) 249 | { 250 | //no free/disconnected spot so reject 251 | Serial.println("No free slot available"); 252 | WiFiClient c = server.available(); 253 | c.stop(); 254 | } 255 | 256 | // Loop over clients connect and read available data 257 | for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) 258 | { 259 | while(clients[i].connected() && clients[i].available()) 260 | { 261 | char inChar = clients[i].read(); 262 | if ( inputString[i].idx < MAX_RECEIVE_LENGTH - 1 ) 263 | { 264 | // if newline then command is complete 265 | if (inChar == '\n') 266 | { 267 | // a command was issued by the client 268 | // we will now try to send it to the actuator 269 | inputString[i].string[inputString[i].idx] = 0; 270 | 271 | // echo the string to the serial port 272 | Serial.print("Client "); Serial.print(i); Serial.print(": "); Serial.println(inputString[i].string); 273 | 274 | parseAndSend(gw, strcat(inputString[i].string,"\n")); 275 | 276 | // clear the string: 277 | inputString[i].idx = 0; 278 | // Finished with this client's message. Next loop() we'll see if there's more to read. 279 | break; 280 | } else { 281 | // add it to the inputString: 282 | inputString[i].string[inputString[i].idx++] = inChar; 283 | } 284 | } else { 285 | // Incoming message too long. Throw away 286 | Serial.print("Client "); Serial.print(i); Serial.println(": Message too long"); 287 | inputString[i].idx = 0; 288 | // Finished with this client's message. Next loop() we'll see if there's more to read. 289 | break; 290 | } 291 | } 292 | } 293 | } 294 | 295 | 296 | 297 | -------------------------------------------------------------------------------- /MyEthernetGateway/MyEthernetGateway.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2013 Henrik Ekblad 4 | * 5 | * Contribution by a-lurker 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * version 2 as published by the Free Software Foundation. 10 | * 11 | * DESCRIPTION 12 | * The EthernetGateway sends data received from sensors to the ethernet link. 13 | * The gateway also accepts input on ethernet interface, which is then sent out to the radio network. 14 | * 15 | * The GW code is designed for Arduino 328p / 16MHz. ATmega168 does not have enough memory to run this program. 16 | * 17 | * 18 | * COMPILING WIZNET (W5100) ETHERNET MODULE 19 | * > Edit RF24_config.h in (libraries\MySensors\utility) to enable softspi (remove // before "#define SOFTSPI"). 20 | * 21 | * COMPILING ENC28J60 ETHERNET MODULE 22 | * > Use Arduino IDE 1.5.7 (or later) 23 | * > Disable DEBUG in Sensor.h before compiling this sketch. Othervise the sketch will probably not fit in program space when downloading. 24 | * > Remove Ethernet.h include below and include UIPEthernet.h 25 | * > Remove DigitalIO include 26 | * Note that I had to disable UDP and DHCP support in uipethernet-conf.h to reduce space. (which means you have to choose a static IP for that module) 27 | * 28 | * VERA CONFIGURATION: 29 | * Enter "ip-number:port" in the ip-field of the Arduino GW device. This will temporarily override any serial configuration for the Vera plugin. 30 | * E.g. If you want to use the defualt values in this sketch enter: 192.168.0.25:5003 31 | * 32 | * LED purposes: 33 | * - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved 34 | * - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly 35 | * - ERR (red) - fast blink on error during transmission error or recieve crc error 36 | * 37 | * See http://www.mysensors.org/build/ethernet_gateway for wiring instructions. 38 | * 39 | */ 40 | 41 | #include // This include can be removed when using UIPEthernet module 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | // Use this if you have attached a Ethernet ENC28J60 shields 48 | //#include 49 | 50 | // Use this fo WizNET W5100 module and Arduino Ethernet Shield 51 | #include 52 | 53 | // The W5100 ethernet module has problems sharing SPI with radio. To solve this you have to wire the radio a little differently and use a soft-spi fix in the NRF24L01 code. 54 | // To enable soft-spi you just have to edit RF24_config.h which can be found in your XXX/libraries/MySensors/utility folder. Just remove the commented slashes (//) before "#define SOFTSPI". 55 | // 56 | // NOTE: This fix must be reverted back when you have compiled and uploaded code to your gateway. 57 | // The normal sensors don't need SOFTSPI enabled and if you leave this in, you can't use the wiring guides for the sensors on this site. 58 | 59 | 60 | #define INCLUSION_MODE_TIME 1 // Number of minutes inclusion mode is enabled 61 | #define INCLUSION_MODE_PIN 3 // Digital pin used for inclusion mode button 62 | 63 | #define RADIO_CE_PIN 5 // radio chip enable 64 | #define RADIO_SPI_SS_PIN 6 // radio SPI serial select 65 | #define RADIO_ERROR_LED_PIN 7 // Error led pin 66 | #define RADIO_RX_LED_PIN 8 // Receive led pin 67 | #define RADIO_TX_LED_PIN 9 // the PCB, on board LED 68 | 69 | #define IP_PORT 5003 // The port you want to open 70 | IPAddress myIp (192, 168, 0, 25); // Configure your static ip-address here COMPILE ERROR HERE? Use Arduino IDE 1.5.7 or later! 71 | 72 | // The MAC address can be anything you want but should be unique on your network. 73 | // Newer boards have a MAC address printed on the underside of the PCB, which you can (optionally) use. 74 | // Note that most of the Ardunio examples use "DEAD BEEF FEED" for the MAC address. 75 | byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x10 }; 76 | 77 | // a R/W server on the port 78 | EthernetServer server = EthernetServer(IP_PORT); 79 | 80 | // No blink or button functionality. Use the vanilla constructor. 81 | MyGateway gw(RADIO_CE_PIN, RADIO_SPI_SS_PIN, INCLUSION_MODE_TIME); 82 | 83 | // Uncomment this constructor if you have leds and include button attached to your gateway 84 | //MyGateway gw(RADIO_CE_PIN, RADIO_SPI_SS_PIN, INCLUSION_MODE_TIME, INCLUSION_MODE_PIN, RADIO_RX_LED_PIN, RADIO_TX_LED_PIN, RADIO_ERROR_LED_PIN); 85 | 86 | 87 | char inputString[MAX_RECEIVE_LENGTH] = ""; // A string to hold incoming commands from serial/ethernet interface 88 | int inputPos = 0; 89 | 90 | void setup() 91 | { 92 | // Initialize gateway at maximum PA level, channel 70 and callback for write operations 93 | gw.begin(RF24_PA_LEVEL_GW, RF24_CHANNEL, RF24_DATARATE, writeEthernet); 94 | 95 | Ethernet.begin(mac, myIp); 96 | 97 | // give the Ethernet interface a second to initialize 98 | delay(1000); 99 | 100 | // start listening for clients 101 | server.begin(); 102 | } 103 | 104 | // This will be called when data should be written to ethernet 105 | void writeEthernet(char *writeBuffer) { 106 | server.write(writeBuffer); 107 | } 108 | 109 | 110 | void loop() 111 | { 112 | // if an incoming client connects, there will be 113 | // bytes available to read via the client object 114 | EthernetClient client = server.available(); 115 | 116 | if (client) { 117 | // if got 1 or more bytes 118 | if (client.available()) { 119 | // read the bytes incoming from the client 120 | char inChar = client.read(); 121 | 122 | if (inputPos 4 | * 5 | * Contribution by a-lurker 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * version 2 as published by the Free Software Foundation. 10 | * 11 | * DESCRIPTION 12 | * The EthernetGateway sends data received from sensors to the ethernet link. 13 | * The gateway also accepts input on ethernet interface, which is then sent out to the radio network. 14 | * 15 | * The GW code is designed for Arduino 328p / 16MHz. ATmega168 does not have enough memory to run this program. 16 | * 17 | * 18 | * COMPILING WIZNET (W5100) ETHERNET MODULE 19 | * > Edit RF24_config.h in (libraries\MySensors\utility) to enable softspi (remove // before "#define SOFTSPI"). 20 | * 21 | * COMPILING ENC28J60 ETHERNET MODULE 22 | * > Use Arduino IDE 1.5.7 (or later) 23 | * > Disable DEBUG in Sensor.h before compiling this sketch. Othervise the sketch will probably not fit in program space when downloading. 24 | * > Remove Ethernet.h include below and include UIPEthernet.h 25 | * > Remove DigitalIO include 26 | * Note that I had to disable UDP and DHCP support in uipethernet-conf.h to reduce space. (which means you have to choose a static IP for that module) 27 | * 28 | * VERA CONFIGURATION: 29 | * Enter "ip-number:port" in the ip-field of the Arduino GW device. This will temporarily override any serial configuration for the Vera plugin. 30 | * E.g. If you want to use the defualt values in this sketch enter: 192.168.178.66:5003 31 | * 32 | * LED purposes: 33 | * - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved 34 | * - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly 35 | * - ERR (red) - fast blink on error during transmission error or recieve crc error 36 | * 37 | * See http://www.mysensors.org/build/ethernet_gateway for wiring instructions. 38 | * 39 | */ 40 | 41 | #include // This include can be removed when using UIPEthernet module 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | // Use this if you have attached a Ethernet ENC28J60 shields 48 | #include 49 | 50 | // Use this fo WizNET W5100 module and Arduino Ethernet Shield 51 | //#include 52 | 53 | 54 | #define INCLUSION_MODE_TIME 1 // Number of minutes inclusion mode is enabled 55 | #define INCLUSION_MODE_PIN 3 // Digital pin used for inclusion mode button 56 | 57 | #define RADIO_CE_PIN 5 // radio chip enable 58 | #define RADIO_SPI_SS_PIN 6 // radio SPI serial select 59 | #define RADIO_ERROR_LED_PIN 7 // Error led pin 60 | #define RADIO_RX_LED_PIN 8 // Receive led pin 61 | #define RADIO_TX_LED_PIN 9 // the PCB, on board LED 62 | 63 | #define IP_PORT 5003 // The port you want to open 64 | IPAddress myIp (192, 168, 0, 25); // Configure your static ip-address here COMPILE ERROR HERE? Use Arduino IDE 1.5.7 or later! 65 | 66 | // The MAC address can be anything you want but should be unique on your network. 67 | // Newer boards have a MAC address printed on the underside of the PCB, which you can (optionally) use. 68 | // Note that most of the Ardunio examples use "DEAD BEEF FEED" for the MAC address. 69 | byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x20 }; 70 | 71 | // a R/W server on the port 72 | EthernetServer server = EthernetServer(IP_PORT); 73 | 74 | // No blink or button functionality. Use the vanilla constructor. 75 | MyGateway gw(RADIO_CE_PIN, RADIO_SPI_SS_PIN, INCLUSION_MODE_TIME); 76 | 77 | // Uncomment this constructor if you have leds and include button attached to your gateway 78 | //MyGateway gw(RADIO_CE_PIN, RADIO_SPI_SS_PIN, INCLUSION_MODE_TIME, INCLUSION_MODE_PIN, RADIO_RX_LED_PIN, RADIO_TX_LED_PIN, RADIO_ERROR_LED_PIN); 79 | 80 | 81 | char inputString[MAX_RECEIVE_LENGTH] = ""; // A string to hold incoming commands from serial/ethernet interface 82 | int inputPos = 0; 83 | 84 | void setup() 85 | { 86 | // Damit Watchdog korrekt funktioniert, muss bei mehreren Boards (z.B. Pro MiniU) ein anderer Bootloader installiert werden. Z.B. Optiboot 87 | // s. http://sysmagazine.com/posts/189744/ oder Originalpost: http://habrahabr.ru/post/189744/ 88 | wdt_disable(); 89 | // set watchdog 90 | wdt_enable(WDTO_8S); 91 | //wdt_reset(); 92 | 93 | // Initialize gateway at maximum PA level, channel 70 and callback for write operations 94 | gw.begin(RF24_PA_LEVEL_GW, RF24_CHANNEL, RF24_DATARATE, writeEthernet); 95 | 96 | Ethernet.begin(mac, myIp); 97 | 98 | // give the Ethernet interface a second to initialize 99 | delay(1000); 100 | 101 | // start listening for clients 102 | server.begin(); 103 | 104 | // set watchdog 105 | wdt_enable(WDTO_2S); 106 | } 107 | 108 | // This will be called when data should be written to ethernet 109 | void writeEthernet(char *writeBuffer) { 110 | server.write(writeBuffer); 111 | } 112 | 113 | 114 | void loop() 115 | { 116 | // watchdog reset 117 | wdt_reset(); 118 | 119 | // if an incoming client connects, there will be 120 | // bytes available to read via the client object 121 | EthernetClient client = server.available(); 122 | 123 | if (client) { 124 | // if got 1 or more bytes 125 | if (client.available()) { 126 | // read the bytes incoming from the client 127 | char inChar = client.read(); 128 | 129 | if (inputPos 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * version 2 as published by the Free Software Foundation. 7 | * 8 | * DESCRIPTION 9 | * The ArduinoGateway prints data received from sensors on the serial link. 10 | * The gateway accepts input on seral which will be sent out on radio network. 11 | * 12 | * The GW code is designed for Arduino Nano 328p / 16MHz 13 | * 14 | * Wire connections (OPTIONAL): 15 | * - Inclusion button should be connected between digital pin 3 and GND 16 | * - RX/TX/ERR leds need to be connected between +5V (anode) and digital ping 6/5/4 with resistor 270-330R in a series 17 | * 18 | * LEDs (OPTIONAL): 19 | * - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved 20 | * - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly 21 | * - ERR (red) - fast blink on error during transmission error or recieve crc error 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #define INCLUSION_MODE_TIME 1 // Number of minutes inclusion mode is enabled 30 | #define INCLUSION_MODE_PIN 3 // Digital pin used for inclusion mode button 31 | 32 | 33 | MyGateway gw(DEFAULT_CE_PIN, DEFAULT_CS_PIN, INCLUSION_MODE_TIME, INCLUSION_MODE_PIN, 6, 5, 4); 34 | 35 | char inputString[MAX_RECEIVE_LENGTH] = ""; // A string to hold incoming commands from serial/ethernet interface 36 | int inputPos = 0; 37 | boolean commandComplete = false; // whether the string is complete 38 | 39 | void setup() 40 | { 41 | // Damit Watchdog korrekt funktioniert, muss bei mehreren Boards (z.B. Pro MiniU) ein anderer Bootloader installiert werden. Z.B. Optiboot 42 | // s. http://sysmagazine.com/posts/189744/ oder Originalpost: http://habrahabr.ru/post/189744/ 43 | wdt_disable(); 44 | // set watchdog 45 | wdt_enable(WDTO_8S); 46 | //wdt_reset(); 47 | 48 | gw.begin(); 49 | 50 | // set watchdog 51 | wdt_enable(WDTO_2S); 52 | } 53 | 54 | 55 | void loop() 56 | { 57 | // watchdog reset 58 | wdt_reset(); 59 | 60 | gw.processRadioMessage(); 61 | if (commandComplete) { 62 | // A command wass issued from serial interface 63 | // We will now try to send it to the actuator 64 | gw.parseAndSend(inputString); 65 | commandComplete = false; 66 | inputPos = 0; 67 | } 68 | } 69 | 70 | 71 | /* 72 | SerialEvent occurs whenever a new data comes in the 73 | hardware serial RX. This routine is run between each 74 | time loop() runs, so using delay inside loop can delay 75 | response. Multiple bytes of data may be available. 76 | */ 77 | void serialEvent() { 78 | while (Serial.available()) { 79 | // get the new byte: 80 | char inChar = (char)Serial.read(); 81 | // if the incoming character is a newline, set a flag 82 | // so the main loop can do something about it: 83 | if (inputPos 5 | http://www.s6z.de/cms/index.php/homeautomation/mysensors/63-up-bewegungsmelder-in-eigenbau
6 | http://www.s6z.de/cms/index.php/homeautomation/mysensors/66-mysensors-up-sensor-platine
7 | http://www.s6z.de/cms/index.php/homeautomation/mysensors/67-up-sensor-pir-temp-hum-lux-in-eigenbau
8 | -------------------------------------------------------------------------------- /Schematic/MySensors_PIR/v1.1/board_ms_pir_up_rev1.1_eagle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexenmeister/MySensors_MyDevices/a7c4930ae3d61a49df69fa5fc35925fadc7c8a93/Schematic/MySensors_PIR/v1.1/board_ms_pir_up_rev1.1_eagle.png -------------------------------------------------------------------------------- /Schematic/MySensors_PIR/v1.1/gerber_ms_pir_up_rev1.1_bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexenmeister/MySensors_MyDevices/a7c4930ae3d61a49df69fa5fc35925fadc7c8a93/Schematic/MySensors_PIR/v1.1/gerber_ms_pir_up_rev1.1_bottom.png -------------------------------------------------------------------------------- /Schematic/MySensors_PIR/v1.1/gerber_ms_pir_up_rev1.1_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexenmeister/MySensors_MyDevices/a7c4930ae3d61a49df69fa5fc35925fadc7c8a93/Schematic/MySensors_PIR/v1.1/gerber_ms_pir_up_rev1.1_top.png -------------------------------------------------------------------------------- /Schematic/MySensors_PIR/v1.1/schematic_ms_pir_up_rev1.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexenmeister/MySensors_MyDevices/a7c4930ae3d61a49df69fa5fc35925fadc7c8a93/Schematic/MySensors_PIR/v1.1/schematic_ms_pir_up_rev1.1.png -------------------------------------------------------------------------------- /Schematic/lbr/Sensors_PIR_Lux.lbr: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | <b>Sensors</b> 151 | <p> 152 | Alexander Schulz (aka Hexenmeister)<br> 153 | Hannover / Germany<br> 154 | http://www.s6z.de<br><br> 155 | <author>Created by Alexander Schulz</author></p><br> 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | >NAME 198 | 199 | 200 | 201 | 202 | 203 | GY-302 204 | 205 | 206 | 207 | 208 | 209 | (BH1750) 210 | 211 | 212 | VCC 213 | GND 214 | SCL 215 | SDA 216 | ADR 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | >NAME 244 | 245 | 246 | 247 | HC-SR501 248 | 249 | 250 | 251 | 252 | PIR 253 | 254 | VCC 255 | OUT 256 | GND 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | >NAME 266 | 267 | 268 | 269 | 270 | 271 | GY-302 272 | BH1750 273 | 274 | 275 | 276 | 277 | 278 | 279 | >NAME 280 | 281 | 282 | 283 | HC-SR510 284 | PIR 285 | 286 | 287 | 288 | 289 | <b>GY-302 / BH1750</b> 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | <b>PIR Module HC-SR501</b> 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | -------------------------------------------------------------------------------- /Schematic/lbr/nrf24L01+.lbr: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | <b>nRF24L01 Transceiver</b> 151 | <p> 152 | Alexander Schulz (aka Hexenmeister)<br> 153 | Hannover / Germany<br> 154 | http://www.s6z.de<br><br> 155 | <author>Created by Alexander Schulz</author></p><br> 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | NRF24L01+ 255 | 256 | 257 | 258 | 259 | GND 260 | VCC 261 | CE 262 | CSN 263 | SCK 264 | MOSI 265 | MISO 266 | IRQ 267 | >NAME 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | nRF24L01+ 291 | 292 | 293 | 294 | 295 | >NAME 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | VCC 305 | GND 306 | CE 307 | CSN 308 | SCK 309 | MOSI 310 | MISO 311 | IRQ 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | nRF24L01+ 337 | >NAME 338 | 339 | 340 | 341 | 342 | <b>nRF24L01+ Transceiver Module</b> 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | -------------------------------------------------------------------------------- /TempHumLuxMotion/TempHumLuxMotion.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | //#include 6 | #include 7 | #include 8 | 9 | #define VERSION "1.2" 10 | 11 | #define DEBUG 0 12 | #define REPEATER 1 13 | 14 | //----------------------------------------------------------------------------------------------- 15 | #define MAX_U_LONG 4294967295; 16 | 17 | // Sensor-Child-IDs 18 | #define CHILD_ID_LIGHT 1 19 | #define CHILD_ID_MOTION 2 20 | #define CHILD_ID_TEMP 3 21 | #define CHILD_ID_HUM 4 22 | 23 | // Sensors PIN Config 24 | #define HUMIDITY_SENSOR_DIGITAL_PIN 4 // The digital input you attached DHT sensot 25 | #define MOT_SENSOR_PIN 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) 26 | #define INTERRUPT MOT_SENSOR_PIN-2 // Usually the interrupt = pin -2 (on uno/nano anyway) 27 | #define INTERRUPT_MODE CHANGE 28 | 29 | // LED pins 30 | //#define PIN_LED_RED 6 31 | #define PIN_LED_GREEN 5 32 | 33 | // Send time limits 34 | #define TIME_MAX_REPLAY_LUX 600000 // Maximum time to send values (Lux) even if not changed 35 | #define TIME_MAX_REPLAY_TH 600000 // Maximum time to send values (TH) even if not changed 36 | #define TIME_MIN_REPLAY_LUX 1000 // Minimum time to send values (Lux) even if changed 37 | #define TIME_MIN_REPLAY_TH 60000 // Minimum time to send values (TH) even if changed 38 | #define TIME_MIN_REPLAY_MOT 1000 // Minimum time to send values (Motion) even if changed 39 | 40 | #define MAX_DIFF_T 1 // Send immediately when the difference is greater than X degree 41 | #define MAX_DIFF_H 5 // Send immediately when the difference is greater than X percent 42 | 43 | 44 | //unsigned long SLEEP_TIME = 1000; // Sleep time between Distance reads (in milliseconds) 45 | // Aufpassen bei SleepTime wg. Watchdog! 46 | #define SLEEP_TIME 1000 // Sleep time between Distance reads (in milliseconds) (be careful with watchdogbe careful with watchdog (if used)!) 47 | 48 | 49 | // Ideen: Parameter aus der Ferne aendern und in EEPROM speichern: MIN/MAX Time, Sende-Grenzwerte, LED-Benutzung 50 | 51 | //----------------------------------------------------------------------------------------------- 52 | 53 | MySensor gw; 54 | 55 | //BH1750 lightSensor; 56 | AS_BH1750 lightSensor; 57 | 58 | MyMessage msgLux(CHILD_ID_LIGHT, V_LIGHT_LEVEL); 59 | float lastLux=-1; 60 | 61 | MyMessage msgMot(CHILD_ID_MOTION, V_TRIPPED); 62 | uint16_t lastMot=0; 63 | 64 | boolean metric = true; 65 | 66 | DHT dht; 67 | float lastTemp=-999; 68 | float lastHum=-1; 69 | 70 | MyMessage msgHum(CHILD_ID_HUM, V_HUM); 71 | MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); 72 | 73 | //----------------------------------------------------------------------------------------------- 74 | boolean mot_present = true; // can not be autodetected 75 | boolean dht_present = false; 76 | boolean lux_present = false; 77 | //----------------------------------------------------------------------------------------------- 78 | 79 | void setup() 80 | { 81 | #if REPEATER == 1 82 | // The third argument enables repeater mode. 83 | // Keep node awake all time (no slepping!). Pump the radio network by calling process() in your loop(). The MySensors library will take care of all routing in the background. 84 | gw.begin(NULL, AUTO, true); 85 | #else 86 | // Normal Node 87 | gw.begin(); 88 | #endif 89 | 90 | // Init Sensors 91 | 92 | // autodetect DHT 93 | dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 94 | // warm up 95 | delay(dht.getMinimumSamplingPeriod()); 96 | float temperature = dht.getTemperature(); 97 | dht_present=!isnan(temperature); 98 | #if DEBUG > 0 99 | if(!dht_present) { 100 | Serial.println("LightSensor not found"); 101 | } else { 102 | Serial.println("LightSensor found"); 103 | } 104 | #endif 105 | 106 | // autodetect BH1750 107 | if(!lightSensor.begin()) { 108 | lux_present = false; 109 | #if DEBUG > 0 110 | Serial.println("LightSensor not found"); 111 | #endif 112 | } else { 113 | lux_present = true; 114 | #if DEBUG > 0 115 | Serial.println("LightSensor found"); 116 | #endif 117 | } 118 | 119 | // sets the motion sensor digital pin as input 120 | pinMode(MOT_SENSOR_PIN, INPUT); 121 | 122 | // Define LED pins 123 | //pinMode(PIN_LED_RED, OUTPUT); 124 | pinMode(PIN_LED_GREEN, OUTPUT); 125 | //digitalWrite(PIN_LED_RED,0); // LED red 126 | digitalWrite(PIN_LED_GREEN,0); // LED green 127 | 128 | // Send the sketch version information to the gateway and Controller 129 | //gw.sendSketchInfo("Temp+Hum+Lux+Motion", "1.0"); 130 | const char *sketch_name = "Universal sensor ("; 131 | //+(mot_present?"M ":""+lux_present?"L ":""+dht_present?"T H":""); 132 | if(mot_present) { sketch_name = strcat(const_cast(sketch_name),"M"); } 133 | if(lux_present) { sketch_name = strcat(const_cast(sketch_name),"L"); } 134 | if(dht_present) { sketch_name = strcat(const_cast(sketch_name),"TH"); } 135 | sketch_name = strcat(const_cast(sketch_name),")"); 136 | 137 | #if DEBUG > 0 138 | Serial.print("Sketch: "); 139 | Serial.print(sketch_name); 140 | Serial.print(" Version: "); 141 | Serial.println(VERSION); 142 | #endif 143 | 144 | gw.sendSketchInfo(sketch_name, VERSION); 145 | 146 | // Register all sensors to gw (they will be created as child devices) 147 | if(mot_present) { 148 | gw.present(CHILD_ID_MOTION, S_MOTION); 149 | } 150 | 151 | if(lux_present) { 152 | gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL); 153 | } 154 | 155 | if(dht_present) { 156 | gw.present(CHILD_ID_HUM, S_HUM); 157 | gw.present(CHILD_ID_TEMP, S_TEMP); 158 | } 159 | 160 | //metric = gw.getConfig().isMetric; 161 | 162 | #if defined (INTERRUPT) 163 | if(mot_present) { 164 | attachInterrupt(INTERRUPT, sendMot, INTERRUPT_MODE); 165 | } 166 | #endif 167 | } 168 | 169 | void loop() 170 | { 171 | // send sensor events 172 | if(mot_present) { 173 | sendMot(); 174 | } 175 | 176 | if(lux_present) { 177 | sendLux(); 178 | } 179 | 180 | if(dht_present) { 181 | sendTH(); 182 | } 183 | 184 | #if defined (SLEEP_TIME) 185 | // Sleep until interrupt comes in on motion sensor. Send update every X minutes. 186 | // Auchtung! Wird Zeitprobleme geben, Korrektur notwendig. 187 | gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME); 188 | #endif 189 | 190 | #if REPEATER == 1 191 | // process radio messages (use for repeater and aktor nodes) 192 | gw.process(); 193 | #endif 194 | } 195 | 196 | //----------------------------------------------------------------------------------------------- 197 | 198 | unsigned long lastTimeTH=millis()+TIME_MIN_REPLAY_TH+1; 199 | void sendTH() 200 | { 201 | unsigned long time = millis(); 202 | 203 | // Zeitdifferenz zum letzten Senden 204 | unsigned long delayTime = 0; 205 | 206 | // Auf Ueberlauf pruefen 207 | if(time 1 217 | Serial.print("TimeDiff: "); 218 | Serial.println(delayTime); 219 | #endif 220 | 221 | // Mindestabstand beachten 222 | if(delayTime= TIME_MAX_REPLAY_TH; 231 | 232 | // DHT22 braucht 2 Sekunden 233 | // delay(dht.getMinimumSamplingPeriod()); 234 | 235 | float temperature = dht.getTemperature(); 236 | if (isnan(temperature)) { 237 | #if DEBUG > 0 238 | Serial.println("Failed reading temperature from DHT"); 239 | #endif 240 | } 241 | else if (sendAnyway || (abs(temperature - lastTemp) > MAX_DIFF_T)) 242 | { 243 | lastTemp = temperature; 244 | if (!metric) { 245 | temperature = dht.toFahrenheit(temperature); 246 | } 247 | 248 | #if DEBUG > 0 249 | Serial.print("T: "); 250 | Serial.println(temperature); 251 | #endif 252 | 253 | gw.send(msgTemp.set(temperature, 1)); 254 | lastTimeTH=millis(); 255 | } 256 | 257 | float humidity = dht.getHumidity(); 258 | if (isnan(humidity)) { 259 | #if DEBUG > 0 260 | Serial.println("Failed reading humidity from DHT"); 261 | #endif 262 | } 263 | else if (sendAnyway || abs(humidity - lastHum) > MAX_DIFF_H) 264 | { 265 | lastHum = humidity; 266 | 267 | #if DEBUG > 0 268 | Serial.print("H: "); 269 | Serial.println(humidity); 270 | #endif 271 | 272 | gw.send(msgHum.set(humidity, 1)); 273 | lastTimeTH=millis(); 274 | } 275 | } 276 | 277 | 278 | unsigned long lastTimeLux=millis()+TIME_MIN_REPLAY_LUX+1; 279 | void sendLux() 280 | { 281 | 282 | // Prüfen, ob Sensor antwortet 283 | if(!lightSensor.isPresent()) { 284 | #if DEBUG > 0 285 | Serial.println("LightSensor not found"); 286 | #endif 287 | return; 288 | } 289 | 290 | unsigned long time = millis(); 291 | 292 | // Zeitdifferenz zum letzten Senden 293 | unsigned long delayTime = 0; 294 | // Auf Ueberlauf pruefen 295 | if(time 1 305 | Serial.print("TimeDiff: "); 306 | Serial.println(delayTime); 307 | #endif 308 | 309 | // Mindestabstand beachten 310 | if(delayTime= TIME_MAX_REPLAY_LUX; 320 | 321 | //uint16_t lux = lightSensor.readLightLevel();// Get Lux value 322 | float lux = lightSensor.readLightLevel();// Get Lux value 323 | 324 | #if DEBUG > 0 325 | Serial.print("Lux: "); 326 | Serial.println(lux); 327 | #endif 328 | 329 | float diff = abs(lux - lastLux); 330 | boolean doSend = false; 331 | // Weil exponentielle Funktion, mehrere Stufen 332 | if(lastLux<1) { 333 | doSend = diff>0.5; 334 | } else if (lastLux<5) { 335 | doSend = diff>1; 336 | } else if (lastLux<10) { 337 | doSend = diff>2; 338 | } else if (lastLux<100) { 339 | doSend = diff>10; 340 | } else if (lastLux<1000) { 341 | doSend = diff>100; 342 | } else if (lastLux<10000) { 343 | doSend = diff>1000; 344 | } else { 345 | doSend = diff>10000; 346 | } 347 | 348 | 349 | // Senden, wenn Abweichung > als 1% ist. 350 | //uint16_t aDiff = abs(lux - lastLux); 351 | //uint16_t pAbw = (min(lux,lastLux)/100); 352 | 353 | //#if DEBUG > 1 354 | //Serial.print("aDiff: "); 355 | //Serial.println(aDiff); 356 | //Serial.print("pAbw: "); 357 | //Serial.println(pAbw); 358 | //#endif 359 | 360 | //if (sendAnyway || aDiff > pAbw) { 361 | if (sendAnyway || doSend) { 362 | //gw.send(msgLux.set(lux)); 363 | gw.send(msgLux.set(lux,2)); 364 | lastLux = lux; 365 | // Zeit merken 366 | lastTimeLux=millis(); 367 | } 368 | } 369 | 370 | unsigned long lastTimeMot=millis()+TIME_MIN_REPLAY_MOT+1; 371 | void sendMot() 372 | { 373 | unsigned long time = millis(); 374 | 375 | // Zeitdifferenz zum letzten Senden 376 | unsigned long delayTime = 0; 377 | // Auf Ueberlauf pruefen 378 | if(time 0 397 | Serial.print("Motion: "); 398 | Serial.println(tripped); 399 | #endif 400 | 401 | if(tripped && !lastMot) // muss zwischendurch mal 'false' werden 402 | { 403 | //gw.send(msgMot.set(tripped?"1":"0")); // Send tripped value to gw 404 | gw.send(msgMot.set("1")); // Send tripped value to gw 405 | // Zeit merken 406 | lastTimeMot=millis(); 407 | } 408 | 409 | lastMot = tripped; 410 | } 411 | 412 | -------------------------------------------------------------------------------- /TempHumLuxMotionBat/TempHumLuxMotionBat.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | //#include 6 | #include 7 | #include 8 | 9 | #define VERSION "1.2" 10 | 11 | #define DEBUG 1 12 | #define REPEATER 0 13 | 14 | //----------------------------------------------------------------------------------------------- 15 | #define MAX_U_LONG 4294967295; 16 | 17 | // Sensor-Child-IDs 18 | #define CHILD_ID_LIGHT 1 19 | #define CHILD_ID_MOTION 2 20 | #define CHILD_ID_TEMP 3 21 | #define CHILD_ID_HUM 4 22 | 23 | // Sensors PIN Config 24 | #define HUMIDITY_SENSOR_DIGITAL_PIN 4 // The digital input you attached DHT sensot 25 | #define MOT_SENSOR_PIN 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) 26 | #define INTERRUPT MOT_SENSOR_PIN-2 // Usually the interrupt = pin -2 (on uno/nano anyway) 27 | 28 | // LED pins 29 | //#define PIN_LED_RED 6 30 | #define PIN_LED_GREEN 5 31 | 32 | // Send time limits 33 | #define TIME_MAX_REPLAY_LUX 600000 // Maximum time to send values (Lux) even if not changed 34 | #define TIME_MAX_REPLAY_TH 600000 // Maximum time to send values (TH) even if not changed 35 | #define TIME_MIN_REPLAY_LUX 1000 // Minimum time to send values (Lux) even if changed 36 | #define TIME_MIN_REPLAY_TH 60000 // Minimum time to send values (TH) even if changed 37 | #define TIME_MIN_REPLAY_MOT 1000 // Minimum time to send values (Motion) even if changed 38 | 39 | #define MAX_DIFF_T 1 // Send immediately when the difference is greater than X degree 40 | #define MAX_DIFF_H 5 // Send immediately when the difference is greater than X percent 41 | 42 | #define INTERRUPT_MODE CHANGE 43 | 44 | //unsigned long SLEEP_TIME = 1000; // Sleep time between Distance reads (in milliseconds) 45 | // Aufpassen bei SleepTime wg. Watchdog! 46 | #define SLEEP_TIME 1000 // Sleep time between Distance reads (in milliseconds) (be careful with watchdogbe careful with watchdog (if used)!) 47 | 48 | 49 | #define DEF_BATTERY_ENABLE_PIN 7 // enablePin: The pin which enables the external measurement helper hardware. Set to 0 if not needed. 50 | #define DEF_BATTERY_ADC_PIN 1 // adcPin: The ADC pin for external measurement. Set to 0 if not needed. 51 | 52 | #define BATTERY_MODE_BANDGAP_MESSUREMENT 1 53 | #define BATTERY_MODE_EXTERNAL_MESSUREMENT 2 54 | 55 | #define DEF_BATTERY_FACT 18 56 | #define DEF_BATTERY_TIME 3600000 57 | 58 | // Ideen: Parameter aus der Ferne aendern und in EEPROM speichern: MIN/MAX Time, Sende-Grenzwerte, LED-Benutzung 59 | 60 | //----------------------------------------------------------------------------------------------- 61 | 62 | MySensor gw; 63 | 64 | //BH1750 lightSensor; 65 | AS_BH1750 lightSensor; 66 | 67 | MyMessage msgLux(CHILD_ID_LIGHT, V_LIGHT_LEVEL); 68 | float lastLux=-1; 69 | 70 | MyMessage msgMot(CHILD_ID_MOTION, V_TRIPPED); 71 | uint16_t lastMot=0; 72 | 73 | boolean metric = true; 74 | 75 | DHT dht; 76 | float lastTemp=-999; 77 | float lastHum=-1; 78 | 79 | MyMessage msgHum(CHILD_ID_HUM, V_HUM); 80 | MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); 81 | 82 | //----------------------------------------------------------------------------------------------- 83 | boolean mot_present = true; // can not be autodetected 84 | boolean dht_present = false; 85 | boolean lux_present = false; 86 | //----------------------------------------------------------------------------------------------- 87 | 88 | void setup() 89 | { 90 | #if REPEATER == 1 91 | // The third argument enables repeater mode. 92 | // Keep node awake all time (no slepping!). Pump the radio network by calling process() in your loop(). The MySensors library will take care of all routing in the background. 93 | gw.begin(NULL, AUTO, true); 94 | #else 95 | // Normal Node 96 | gw.begin(); 97 | #endif 98 | 99 | // Init Sensors 100 | 101 | // autodetect DHT 102 | dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 103 | // warm up 104 | delay(dht.getMinimumSamplingPeriod()); 105 | float temperature = dht.getTemperature(); 106 | dht_present=!isnan(temperature); 107 | #if DEBUG > 0 108 | if(!dht_present) { 109 | Serial.println("LightSensor not found"); 110 | } else { 111 | Serial.println("LightSensor found"); 112 | } 113 | #endif 114 | 115 | // autodetect BH1750 116 | if(!lightSensor.begin()) { 117 | lux_present = false; 118 | #if DEBUG > 0 119 | Serial.println("LightSensor not found"); 120 | #endif 121 | } else { 122 | lux_present = true; 123 | #if DEBUG > 0 124 | Serial.println("LightSensor found"); 125 | #endif 126 | } 127 | 128 | // sets the motion sensor digital pin as input 129 | pinMode(MOT_SENSOR_PIN, INPUT); 130 | 131 | // Define LED pins 132 | //pinMode(PIN_LED_RED, OUTPUT); 133 | pinMode(PIN_LED_GREEN, OUTPUT); 134 | //digitalWrite(PIN_LED_RED,0); // LED red 135 | digitalWrite(PIN_LED_GREEN,0); // LED green 136 | 137 | // Send the sketch version information to the gateway and Controller 138 | //gw.sendSketchInfo("Temp+Hum+Lux+Motion", "1.0"); 139 | const char *sketch_name = "Universal sensor ("; 140 | //+(mot_present?"M ":""+lux_present?"L ":""+dht_present?"T H":""); 141 | if(mot_present) { sketch_name = strcat(const_cast(sketch_name),"M"); } 142 | if(lux_present) { sketch_name = strcat(const_cast(sketch_name),"L"); } 143 | if(dht_present) { sketch_name = strcat(const_cast(sketch_name),"TH"); } 144 | sketch_name = strcat(const_cast(sketch_name),")"); 145 | 146 | #if DEBUG > 0 147 | Serial.print("Sketch: "); 148 | Serial.print(sketch_name); 149 | Serial.print(" Version: "); 150 | Serial.println(VERSION); 151 | #endif 152 | 153 | gw.sendSketchInfo(sketch_name, VERSION); 154 | 155 | // Register all sensors to gw (they will be created as child devices) 156 | if(mot_present) { 157 | gw.present(CHILD_ID_MOTION, S_MOTION); 158 | } 159 | 160 | if(lux_present) { 161 | gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL); 162 | } 163 | 164 | if(dht_present) { 165 | gw.present(CHILD_ID_HUM, S_HUM); 166 | gw.present(CHILD_ID_TEMP, S_TEMP); 167 | } 168 | 169 | //metric = gw.getConfig().isMetric; 170 | 171 | #if defined (INTERRUPT) 172 | if(mot_present) { 173 | attachInterrupt(INTERRUPT, sendMot, INTERRUPT_MODE); 174 | } 175 | #endif 176 | 177 | //BATTERY_MODE_BANDGAP_MESSUREMENT 178 | setupBattery(BATTERY_MODE_EXTERNAL_MESSUREMENT, DEF_BATTERY_ENABLE_PIN, DEF_BATTERY_ADC_PIN, DEF_BATTERY_FACT, DEF_BATTERY_TIME); 179 | } 180 | 181 | void loop() 182 | { 183 | sendBat(); 184 | 185 | // send sensor events 186 | 187 | //sendMot(); 188 | 189 | sendLux(); 190 | 191 | sendTH(); 192 | 193 | #if REPEATER == 0 194 | Serial.println("1->"); 195 | 196 | #if defined (INTERRUPT) 197 | // Sleep until interrupt comes in on motion sensor. Send update every X minutes. 198 | if(mot_present) { 199 | detachInterrupt(INTERRUPT); 200 | } 201 | #endif 202 | 203 | Serial.println("2->"); 204 | 205 | unsigned long periode = 60000; 206 | unsigned long timeMark = cMillis(); 207 | while((cMillis()-timeMark)"); 213 | Serial.println(cMillis()); 214 | #if DEBUG == 1 215 | Serial.println(cMillis()); 216 | #endif 217 | #if defined (INTERRUPT) 218 | if(mot_present) { 219 | attachInterrupt(INTERRUPT, sendMot, INTERRUPT_MODE); 220 | } 221 | #endif 222 | Serial.println("4->"); 223 | #endif 224 | 225 | #if REPEATER != 0 226 | Serial.println("X->"); 227 | sendMot(); 228 | // process radio messages (use for repeater and aktor nodes) 229 | gw.process(); 230 | #endif 231 | } 232 | 233 | //----------------------------------------------------------------------------------------------- 234 | // TODO: ggf. nach MSUtils verlagern 235 | unsigned long timeCorrection = 0; 236 | unsigned long cMillis() { 237 | return millis()+timeCorrection; 238 | } 239 | 240 | void sleep(unsigned long ms) { 241 | gw.sleep(ms); 242 | timeCorrection += ms; 243 | } 244 | 245 | bool sleep(uint8_t interrupt, uint8_t mode, unsigned long ms) { 246 | bool ret = gw.sleep(interrupt,mode, ms); 247 | if(ret) { 248 | // interrupted 249 | // Statistisch dürfe im Mittel dir Hälfte der Zeit ein akzeptabler Wert bei Interrupts sein 250 | timeCorrection += (ms/2); 251 | } else { 252 | timeCorrection += ms; 253 | } 254 | return ret; 255 | } 256 | 257 | //----------------------------------------------------------------------------------------------- 258 | 259 | unsigned long lastTimeTH=cMillis()+TIME_MIN_REPLAY_TH+1; 260 | void sendTH() 261 | { 262 | if(!dht_present) return; 263 | 264 | unsigned long time = cMillis(); 265 | 266 | // Zeitdifferenz zum letzten Senden 267 | unsigned long delayTime = 0; 268 | 269 | // Auf Ueberlauf pruefen 270 | if(time 1 280 | Serial.print("TimeDiff: "); 281 | Serial.println(delayTime); 282 | #endif 283 | 284 | // Mindestabstand beachten 285 | if(delayTime= TIME_MAX_REPLAY_TH; 294 | 295 | // DHT22 braucht 2 Sekunden 296 | // delay(dht.getMinimumSamplingPeriod()); 297 | 298 | float temperature = dht.getTemperature(); 299 | if (isnan(temperature)) { 300 | #if DEBUG > 0 301 | Serial.println("Failed reading temperature from DHT"); 302 | #endif 303 | } 304 | else if (sendAnyway || (abs(temperature - lastTemp) > MAX_DIFF_T)) 305 | { 306 | lastTemp = temperature; 307 | if (!metric) { 308 | temperature = dht.toFahrenheit(temperature); 309 | } 310 | 311 | #if DEBUG > 0 312 | Serial.print("T: "); 313 | Serial.println(temperature); 314 | #endif 315 | 316 | gw.send(msgTemp.set(temperature, 1)); 317 | lastTimeTH=cMillis(); 318 | } 319 | 320 | float humidity = dht.getHumidity(); 321 | if (isnan(humidity)) { 322 | #if DEBUG > 0 323 | Serial.println("Failed reading humidity from DHT"); 324 | #endif 325 | } 326 | else if (sendAnyway || abs(humidity - lastHum) > MAX_DIFF_H) 327 | { 328 | lastHum = humidity; 329 | 330 | #if DEBUG > 0 331 | Serial.print("H: "); 332 | Serial.println(humidity); 333 | #endif 334 | 335 | gw.send(msgHum.set(humidity, 1)); 336 | lastTimeTH=cMillis(); 337 | } 338 | } 339 | 340 | 341 | unsigned long lastTimeLux=cMillis()+TIME_MIN_REPLAY_LUX+1; 342 | void sendLux() 343 | { 344 | if(!lux_present) return; 345 | 346 | // Prüfen, ob Sensor antwortet 347 | if(!lightSensor.isPresent()) { 348 | #if DEBUG > 0 349 | Serial.println("LightSensor not found"); 350 | #endif 351 | return; 352 | } 353 | 354 | unsigned long time = cMillis(); 355 | 356 | // Zeitdifferenz zum letzten Senden 357 | unsigned long delayTime = 0; 358 | // Auf Ueberlauf pruefen 359 | if(time 1 369 | Serial.print("TimeDiff: "); 370 | Serial.println(delayTime); 371 | #endif 372 | 373 | // Mindestabstand beachten 374 | if(delayTime= TIME_MAX_REPLAY_LUX; 384 | 385 | //uint16_t lux = lightSensor.readLightLevel();// Get Lux value 386 | float lux = lightSensor.readLightLevel();// Get Lux value 387 | 388 | #if DEBUG > 1 389 | Serial.print("Lux: "); 390 | Serial.println(lux); 391 | #endif 392 | 393 | float diff = abs(lux - lastLux); 394 | boolean doSend = false; 395 | // Weil exponentielle Funktion, mehrere Stufen 396 | if(lastLux<1) { 397 | doSend = diff>0.5; 398 | } else if (lastLux<5) { 399 | doSend = diff>1; 400 | } else if (lastLux<10) { 401 | doSend = diff>2; 402 | } else if (lastLux<100) { 403 | doSend = diff>10; 404 | } else if (lastLux<1000) { 405 | doSend = diff>100; 406 | } else if (lastLux<10000) { 407 | doSend = diff>1000; 408 | } else { 409 | doSend = diff>10000; 410 | } 411 | 412 | 413 | // Senden, wenn Abweichung > als 1% ist. 414 | //uint16_t aDiff = abs(lux - lastLux); 415 | //uint16_t pAbw = (min(lux,lastLux)/100); 416 | 417 | //#if DEBUG > 1 418 | //Serial.print("aDiff: "); 419 | //Serial.println(aDiff); 420 | //Serial.print("pAbw: "); 421 | //Serial.println(pAbw); 422 | //#endif 423 | 424 | //if (sendAnyway || aDiff > pAbw) { 425 | if (sendAnyway || doSend) { 426 | #if DEBUG > 0 427 | Serial.print("send Lux: "); 428 | Serial.println(lux); 429 | #endif 430 | //gw.send(msgLux.set(lux)); 431 | gw.send(msgLux.set(lux,2)); 432 | lastLux = lux; 433 | // Zeit merken 434 | lastTimeLux=cMillis(); 435 | } 436 | } 437 | 438 | unsigned long lastTimeMot=cMillis()+TIME_MIN_REPLAY_MOT+1; 439 | void sendMot() 440 | { 441 | if(!mot_present) return; 442 | 443 | unsigned long time = cMillis(); 444 | 445 | // Zeitdifferenz zum letzten Senden 446 | unsigned long delayTime = 0; 447 | // Auf Ueberlauf pruefen 448 | if(time 1 467 | Serial.print("Motion: "); 468 | Serial.println(tripped); 469 | #endif 470 | 471 | if(tripped && !lastMot) // muss zwischendurch mal 'false' werden 472 | { 473 | #if DEBUG > 0 474 | Serial.print("send Motion: "); 475 | Serial.println(tripped); 476 | #endif 477 | //gw.send(msgMot.set(tripped?"1":"0")); // Send tripped value to gw 478 | gw.send(msgMot.set("1")); // Send tripped value to gw 479 | // Zeit merken 480 | lastTimeMot=cMillis(); 481 | } 482 | 483 | lastMot = tripped; 484 | } 485 | 486 | // --- Bat ------------------------------------------------------------------ 487 | #define BATTERY_STATE_HYSTERESIS 1 // battery state should reset only if voltage rise greater than given value 488 | #define BATTERY_NUM_MESS_ADC 64 489 | #define BATTERY_DUMMY_NUM_MESS_ADC 10 490 | #define AVR_BANDGAP_VOLTAGE 1100UL // Band gap reference for Atmega328p 491 | 492 | uint8_t tEnablePin; 493 | uint8_t tAdcPin; 494 | uint8_t tFact; 495 | uint8_t tMode = 0; 496 | uint16_t tTime; // remember the time for periodic check 497 | uint32_t nTime; 498 | uint16_t voltage; 499 | uint8_t oldVoltage; 500 | 501 | /** 502 | * Cyclic battery measurement function. 503 | */ 504 | void sendBat(void) { 505 | //uint8_t batteryVoltage; 506 | 507 | if ((tMode == 0) || (cMillis() - nTime < tTime)) { 508 | return; // nothing to do, step out 509 | 510 | } else if (tMode == BATTERY_MODE_BANDGAP_MESSUREMENT) { 511 | voltage = getBatteryVoltageInternal(); 512 | 513 | } else if (tMode == BATTERY_MODE_EXTERNAL_MESSUREMENT) { 514 | voltage = getBatteryVoltageExternal(); 515 | } 516 | 517 | #if DEBUG > 0 518 | Serial.print("Bat Voltage: "); 519 | Serial.println(voltage); 520 | #endif 521 | 522 | if ((voltage > oldVoltage && (voltage - oldVoltage) > BATTERY_STATE_HYSTERESIS) || voltage < oldVoltage) { 523 | oldVoltage = voltage; 524 | gw.sendBatteryLevel(voltage); 525 | } 526 | 527 | nTime = cMillis(); 528 | 529 | } 530 | 531 | uint16_t readAdcValue(uint8_t voltageReference, uint8_t inputChannel) { 532 | uint16_t adcValue = 0; 533 | 534 | ADMUX = (voltageReference | inputChannel); 535 | 536 | ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // Enable ADC and set ADC prescaler 537 | for(int i = 0; i < BATTERY_NUM_MESS_ADC + BATTERY_DUMMY_NUM_MESS_ADC; i++) { 538 | ADCSRA |= (1 << ADSC); // start conversion 539 | while (ADCSRA & (1 << ADSC)) {} // wait for conversion complete 540 | 541 | if (i >= BATTERY_DUMMY_NUM_MESS_ADC) { // we discard the first dummy measurements 542 | adcValue += ADCW; 543 | } 544 | } 545 | 546 | ADCSRA &= ~(1 << ADEN); // ADC disable 547 | 548 | adcValue = adcValue / BATTERY_NUM_MESS_ADC; 549 | 550 | return adcValue; 551 | } 552 | 553 | /** 554 | * Configure the battery measurement 555 | * 556 | * mode: Measurement mode BATTERY_MODE_BANDGAP_MESSUREMENT or BATTERY_MODE_EXTERNAL_MESSUREMENT 557 | * enablePin: The pin which enables the external measurement helper hardware. Set to 0 if not needed. 558 | * adcPin: The ADC pin for external measurement. Set to 0 if not needed. 559 | * time: interval to check the battery voltage 560 | */ 561 | void setupBattery(uint8_t mode, uint8_t enablePin, uint8_t adcPin, uint8_t fact, uint16_t time) { 562 | tMode = mode; 563 | tEnablePin = enablePin; 564 | tAdcPin = adcPin; 565 | tFact = fact; 566 | tTime = time; 567 | nTime = time; 568 | 569 | if (tEnablePin > 0) { 570 | pinMode(tEnablePin, INPUT); 571 | } 572 | 573 | #if DEBUG > 0 574 | Serial.println("Bat Setup. Mode: "+mode); 575 | #endif 576 | } 577 | 578 | /** 579 | * get battery voltage 580 | * Measure AVCC again the the internal band gap reference 581 | * 582 | * REFS1 REFS0 --> internal bandgap reference 583 | * MUX3 MUX2 MUX1 MUX0 --> 1110 1.1V (VBG) (for instance Atmega 328p) 584 | */ 585 | uint8_t getBatteryVoltageInternal() { 586 | // Voltage Reference = AVCC with external capacitor at AREF pin 587 | // Input Channel = 1.1V (V BG) 588 | uint16_t adcValue = readAdcValue( (0 << REFS1) | (1 << REFS0), (1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (0 << MUX0) ); 589 | adcValue = AVR_BANDGAP_VOLTAGE * 1023 / adcValue / 100; // calculate battery voltage in 1/10 V 590 | #if DEBUG > 1 591 | Serial.print("adc internal: "); 592 | Serial.println(adcValue); 593 | #endif 594 | 595 | return adcValue; 596 | } 597 | 598 | uint8_t getBatteryVoltageExternal() { 599 | pinMode(tEnablePin, OUTPUT); 600 | digitalWrite(tEnablePin, LOW); 601 | 602 | // Voltage Reference = Internal 1.1V Voltage Reference 603 | uint16_t adcValue = readAdcValue( (1 << REFS1) | (1 << REFS0), tAdcPin ); 604 | //adcValue = analogRead(tAdcPin); 605 | #if DEBUG > 1 606 | Serial.print("adc external: "); 607 | Serial.println(adcValue); 608 | #endif 609 | adcValue = adcValue * AVR_BANDGAP_VOLTAGE / 1023 / tFact; // calculate battery voltage in 1/10 V 610 | pinMode(tEnablePin, INPUT); 611 | 612 | return adcValue; 613 | } 614 | 615 | 616 | -------------------------------------------------------------------------------- /WDT_Reset_Test/WDT_Reset_Test.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // Prüfung, ob Watchdog funktioniert, oder das Davice in einer Reset-Schleife hängen bleibt 4 | 5 | void setup() { 6 | wdt_disable(); // bis hier kommt man wg. bootloop nicht mehr 7 | Serial.begin(9600); 8 | Serial.println("Setup.."); 9 | 10 | Serial.println("Wait 5 sec.."); 11 | delay(5000); // Pause, um beim bootloop Zeit zum reprogrammieren zu habn 12 | wdt_enable (WDTO_8S); // 13 | Serial.println("Watchdog enabled."); 14 | } 15 | 16 | int timer = 0; 17 | 18 | void loop(){ 19 | // Wenns funktioniert, dann durch Blinken anzeigen 20 | boolean b = true; 21 | while(true){ 22 | timer++; 23 | Serial.println(timer); 24 | digitalWrite(13, b?0:1); 25 | b=!b; 26 | delay(1000); 27 | } 28 | // wdt_reset(); 29 | } 30 | -------------------------------------------------------------------------------- /WriteDesiredNodeID/WriteDesiredNodeID.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define NODE_ID 250 6 | 7 | void setup() 8 | { 9 | Serial.begin(BAUD_RATE); 10 | 11 | Serial.print("Write desiren NodeID: "); 12 | Serial.print(NODE_ID); 13 | Serial.println(" Please wait..."); 14 | 15 | uint8_t _nodeId = NODE_ID; 16 | hw_writeConfig(EEPROM_NODE_ID_ADDRESS, _nodeId); 17 | 18 | Serial.println("Done. You're ready to go!"); 19 | } 20 | 21 | void loop() 22 | { 23 | boolean b = true; 24 | while(true){ 25 | digitalWrite(13, b?0:1); 26 | b=!b; 27 | delay(100); 28 | } 29 | } 30 | 31 | --------------------------------------------------------------------------------