Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Troubleshooting
  3. Node only works for a few days

Node only works for a few days

Scheduled Pinned Locked Moved Troubleshooting
22 Posts 10 Posters 5.2k Views 7 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • b0rmannB Offline
    b0rmannB Offline
    b0rmann
    wrote on last edited by
    #6

    ...same problem :(

    1 Reply Last reply
    0
    • wallyllamaW Offline
      wallyllamaW Offline
      wallyllama
      wrote on last edited by
      #7

      My wild guess would be a memory leak in the code. Turning on debug uses more memory so it takes less time to fail.

      1 Reply Last reply
      0
      • F Offline
        F Offline
        Fabien
        wrote on last edited by
        #8

        First switch your gateway to 2.1.0 stable.
        I think sensors.begin must be in setup not in loop.
        And I think you have perhaps TX problem on gateway side (after reading logs).
        Retry with 2.1.0 on both sides, compile node sketch with sensors.begin in setup, turn on log on node and gw.
        When you have failure, try to reboot only gateway and wait until node try to find parent. Make the same test but this time reboot only node.

        raptorjrR 1 Reply Last reply
        0
        • raptorjrR raptorjr

          @Geert-Massa

          Thank you for looking.
          I hope not a repeater is needed. They are only 2-3 meters apart. And that don't explain why it works for a few days after a restart.
          I have capacitors on both node and gateway, so that should not be a problem either.

          tekkaT Offline
          tekkaT Offline
          tekka
          Admin
          wrote on last edited by
          #9

          @raptorjr Looking at your logs

          GW log, line 578

          mysgw: TSF:MSG:READ,1-1-0,s=171,c=5,t=42,pt=7,l=13,sg=0:30713023823872.00000000
          mysgw: !TSF:MSG:LEN,12!=20
          

          I assume a power/bad cable issue and/or a EMP interference caused by a switching relay.

          1 Reply Last reply
          0
          • F Fabien

            First switch your gateway to 2.1.0 stable.
            I think sensors.begin must be in setup not in loop.
            And I think you have perhaps TX problem on gateway side (after reading logs).
            Retry with 2.1.0 on both sides, compile node sketch with sensors.begin in setup, turn on log on node and gw.
            When you have failure, try to reboot only gateway and wait until node try to find parent. Make the same test but this time reboot only node.

            raptorjrR Offline
            raptorjrR Offline
            raptorjr
            wrote on last edited by
            #10

            @Fabien said:

            First switch your gateway to 2.1.0 stable.
            I think sensors.begin must be in setup not in loop.
            And I think you have perhaps TX problem on gateway side (after reading logs).
            Retry with 2.1.0 on both sides, compile node sketch with sensors.begin in setup, turn on log on node and gw.
            When you have failure, try to reboot only gateway and wait until node try to find parent. Make the same test but this time reboot only node.

            Will try this first. To me it feels that if it was something wrong with the hardware in some way it would happen right away, not only after a few days.

            But I'll start with this before I consider to buy new hardware.

            1 Reply Last reply
            0
            • gohanG Offline
              gohanG Offline
              gohan
              Mod
              wrote on last edited by
              #11

              Before buying new hw it's better to do some cross tests to pin point where the problem is.

              1 Reply Last reply
              0
              • FotoFieberF Offline
                FotoFieberF Offline
                FotoFieber
                Hardware Contributor
                wrote on last edited by
                #12

                I had a similar problem with the control of a heating mixer and three dallas sensors. I solved the problem with:

                • replacement of the relays with solid state relays
                • moved conttroller more in distance of the high voltage parts

                I also added a watchdog and a reboot mechanism in case of sensor problems.

                Maybe this sketch can give you an inspiration: (work in progress, MYS-Part not tested in depth)

                // Enable debug prints to serial monitor
                //#define MY_DEBUG      // in Mysensors
                #define EN_DEBUG      // in this sketch
                //#define NO_MYS      // ohne Mysensors Unterstützung?
                //#define SIMULATION
                #define NO_AC_DETECT  // ohne AC sensor
                #define NO_RTC
                
                // RTC nur zusammen mit Mysensors
                #ifdef NO_MYS
                #ifndef NO_RTC
                #define NO_RTC
                #endif
                #endif
                
                #ifdef SIMULATION
                // für Simulation ohne Sensoren
                #define SIMULATE_VOR  35
                #define SIMULATE_RUE  30
                #define SIMULATE_ZU   65
                
                
                #ifdef SIMULATE_VOR
                #warning Achtung! Keine Echtentemperaturmessungen -> Simulation
                #endif
                
                #ifdef SIMULATE_RUE
                #warning Achtung! Keine Echtentemperaturmessungen -> Simulation
                #endif
                
                #ifdef SIMULATE_ZU
                #warning Achtung! Keine Echtentemperaturmessungen -> Simulation
                #endif
                #endif
                
                
                #define START_TARGET_TEMP 40
                #define EEPROM_TARGET_TEMP 900            // Save Porisiton. It is above the Mysensors range of lib 2.1
                #define EEPROM_POWERSTATE  902            // Save Porisiton. It is above the Mysensors range of lib 2.1
                #define MAX_TEMP 50
                #define VORLAUF 0
                #define RUECKLAUF 1
                #define ZULAUF 2
                #define PUMPE 0
                #define MISCHER_ZU  1
                #define MISCHER_AUF 2
                #define POWERLED 7                        // 8. LED
                #define TEMPDOWNLED 5                     // 6. Led
                #define TEMPUPLED 6                       // 7. Led
                #ifndef NO_AC_DETECT
                #define BUDERUSLED 4                      // 5. Led
                #endif
                #define RETRY_TIMEOUT_PUMP 2*60*1000UL     // alle 2 Minuten testen, ob Vorlauf nicht besser (5 Sekunden pumpen)
                #define REGULATION_TIMEOUT_PUMP 30*1000UL  // 30 Sekunden warten nach neuer Einstellung
                #define PROBE_TIMEOUT_PUMP 5*1000UL        // 5 Sekunden Pumpe für Test einschalten, wenn Zulauf zu kalt
                #define BUDERUS_PIN 3                     // Buderus Powererkennung Pumpe auf PIN 3
                
                #ifndef SIMULATION
                #define MISCHER_RESET_TIME 120*1000UL      // 2 Minuten bis Nullstellung
                #else
                #define MISCHER_RESET_TIME 10*1000UL      // 10 Sekunden bis Nullstellung nei Simulation
                #endif
                
                
                
                #ifdef EN_DEBUG
                #define DEBUG_PRINT(x) Serial.print (x)
                #else
                #define DEBUG_PRINT(x)
                #endif
                
                #ifdef EN_DEBUG
                #define DEBUG_PRINTLN(x)  Serial.println (x)
                #else
                #define DEBUG_PRINTLN(x)
                #endif
                
                #ifndef NO_MYS
                // Radio Configuration
                #define MY_TRANSPORT_WAIT_READY_MS (10000ul)
                #define MY_RADIO_RFM69
                #define MY_RFM69_FREQUENCY RF69_868MHZ
                #define MY_RFM69_NETWORKID 13
                #define MY_RFM69_ENABLE_ENCRYPTION
                #define MY_NODE_ID 168
                //#define MY_IS_RFM69HW
                #endif
                
                
                #include <Arduino.h>
                #include <avr/wdt.h>
                #include <EEPROM.h>
                #include <MemoryFree.h>
                
                #ifndef NO_MYS
                #define MIN_REPORT_INTERVAL  5 * 60 * 1000L   // mindestens alle 5 Minuten melden
                #include <SPI.h>
                #include <MySensors.h>
                #include <Time.h>        //http://www.arduino.cc/playground/Code/Time
                #include <Timezone.h>    //https://github.com/JChristensen/Timezone
                #include <TimeLib.h>
                
                //Central European Time (Frankfurt, Paris)
                TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120};     //Central European Summer Time
                TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60};       //Central European Standard Time
                Timezone CE(CEST, CET);
                bool timeReceived = false;
                unsigned long lastUpdate = 0, lastRequest = 0;
                #endif
                
                #ifndef NO_RTC
                #include <DS3232RTC.h>  // A  DS3231/DS3232 library
                #endif
                
                #define MAX_LEDS 8
                
                byte lastButtonState = 0;
                #define RELAY_ON HIGH
                #define RELAY_OFF LOW
                #define RELAY_1  A0         // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
                #define NUMBER_OF_RELAYS 4  // Total number of attached relays
                
                
                boolean ledState[MAX_LEDS] = { false, false, false, false, false, false, false, false };
                boolean relState[NUMBER_OF_RELAYS] = { false, false, false, false };
                
                #include <TM1638.h>
                #include <DallasTemperature.h>
                #include <OneWire.h>
                
                #define ONE_WIRE_BUS 6 // Pin where dallase sensor is connected 
                #define TEMPERATURE_PRECISION 9
                #define MAX_ATTACHED_DS18B20 3
                
                //28B404080000804A
                DeviceAddress Probe01 = { 0x28, 0xB4, 0x04, 0x08, 0x00, 0x00, 0x80, 0x4A };
                //28C606080000803F
                DeviceAddress Probe02 = { 0x28, 0xC6, 0x06, 0x08, 0x00, 0x00, 0x80, 0x3F };
                //28750808000080C3
                DeviceAddress Probe03 = { 0x28, 0x75, 0x08, 0x08, 0x00, 0x00, 0x80, 0xC3 };
                
                OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
                DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature.
                int numSensors = 0;
                int lastTemperature[MAX_ATTACHED_DS18B20] = { -100, -100, -100 };
                int16_t conversionTime;
                unsigned long previousTempMillis = -1;
                static unsigned long nowms = millis();    // update at start of loop()
                
                
                // define LCD module
                TM1638 ledModule(8, 9, 7);
                
                int displayInfo = -1;
                unsigned long previousDisplayMillis = 0;
                
                int targetTemp = START_TARGET_TEMP;
                #ifdef SIMULATION
                bool powerOn = true;
                #ifndef NO_AC_DETECT
                bool powerOnBuderus = true;
                #endif
                #else
                bool powerOn = false;
                #ifndef NO_AC_DETECT
                bool powerOnBuderus = false;
                #endif
                #endif
                bool resetMischer = true; // mischer zuerst in Nullstellung
                
                #ifndef NO_AC_DETECT
                bool testStateBuderus = false;
                unsigned long lastResetBuderus = -1;
                #endif
                
                #ifndef NO_MYS
                // Initialize messages
                MyMessage msgTemp(0, V_TEMP);
                MyMessage msgStatus(0, V_STATUS);
                MyMessage msgTargetTemp(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS, V_HVAC_SETPOINT_HEAT);
                MyMessage msgPower(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 1, V_STATUS);
                #ifndef NO_AC_DETECT
                MyMessage msgPowerBuderus(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 2, V_STATUS);
                #endif
                MyMessage msgDebug(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 3, V_TEXT);
                #endif
                
                // the setup function runs once when you press reset or power the board
                void setup() {
                  DEBUG_PRINTLN(F("Starte setup"));
                  wdt_enable(WDTO_8S);
                  Serial.begin(115200);
                
                #ifndef NO_RTC
                  // the function to get the time from the RTC
                  setSyncProvider(RTC.get);
                #endif
                #ifndef NO_MYS
                  // Request latest time from controller at startup
                  requestTime();
                #endif
                
                
                
                
                  // Zieltemperatur aus EERPOM lesem:
                  targetTemp = EEPROM.read(EEPROM_TARGET_TEMP);
                  if ((targetTemp < 30) || (targetTemp > MAX_TEMP)) {
                    targetTemp = START_TARGET_TEMP;
                    EEPROM.write(EEPROM_TARGET_TEMP, targetTemp);
                  }
                
                  int state = EEPROM.read(EEPROM_POWERSTATE);
                  if (state == 0) {
                    powerOn = false;
                  }
                  else powerOn = true;
                
                #ifndef NO_AC_DETECT
                  // Buderuserkennung auf PIN3
                  attachInterrupt(digitalPinToInterrupt(BUDERUS_PIN), buderusSet, CHANGE);
                  testStateBuderus = false;
                  lastResetBuderus = millis();
                #ifndef NO_MYS
                  send(msgPowerBuderus.set(powerOnBuderus));
                #endif
                #endif
                
                  // Relayausgänge initialisiern
                  for (int sensor = 1, pin = RELAY_1; sensor <= NUMBER_OF_RELAYS; sensor++, pin++) {
                    // Then set relay pins in output mode
                    pinMode(pin, OUTPUT);
                    // Set relay to last known state (using eeprom storage)
                    digitalWrite(pin, RELAY_OFF);
                  }
                
                  // Dallas Temperatursensoren
                  sensors.begin();
                  sensors.setWaitForConversion(false);
                  numSensors = sensors.getDeviceCount();
                  DEBUG_PRINT(F("Dallas Sensoren "));
                  DEBUG_PRINTLN(numSensors);
                  DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address
                
                  for (int i = 0; i < numSensors; i++)
                  {
                    wdt_reset();
                    // Search the wire for address
                    if (sensors.getAddress(tempDeviceAddress, i))
                    {
                      DEBUG_PRINT(F("Found device "));
                #ifdef EN_DEBUG
                      Serial.print(i, DEC);
                #endif
                      DEBUG_PRINT(F(" with address: "));
                      printAddress(tempDeviceAddress);
                      DEBUG_PRINTLN();
                
                      DEBUG_PRINT(F("Setting resolution to "));
                #ifdef EN_DEBUG
                      Serial.println(TEMPERATURE_PRECISION, DEC);
                #endif
                      // set the resolution to 12 bit (Each Dallas/Maxim device is capable of several different resolutions)
                      sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);
                
                      DEBUG_PRINT(F("Resolution actually set to: "));
                
                #ifdef EN_DEBUG
                      Serial.print(sensors.getResolution(tempDeviceAddress), DEC);
                #endif
                      DEBUG_PRINTLN();
                    } else {
                      DEBUG_PRINT(F("Found ghost device at "));
                
                #ifdef EN_DEBUG
                      Serial.print(i, DEC);
                #endif
                      DEBUG_PRINT(F(" but could not detect address. Check power and cabling"));
                    }
                  }
                
                  wdt_reset();
                  sensors.requestTemperatures();
                
                  // query conversion time and sleep until conversion completed
                  conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
                }
                
                /*****************************************************/
                // the loop function runs over and over again forever
                void loop() {
                  nowms = millis();
                
                #ifndef NO_MYS
                  // If no time has been received yet, request it every 10 second from controller
                  // When time has been received, request update every hour
                  if ((!timeReceived && (nowms - lastRequest) > (10UL * 1000UL))
                      || (timeReceived && (nowms - lastRequest) > (60UL * 1000UL * 60UL))) {
                    // Request time from controller.
                    DEBUG_PRINTLN("requesting time");
                    requestTime();
                    lastRequest = nowms;
                  }
                #endif
                
                  wdt_reset();
                
                #ifndef NO_AC_DETECT
                  readAC();
                #endif
                
                  readTemp();
                  readButtons();
                
                  updateDisp();
                
                  // Temperaturen senden
                
                #ifndef NO_MYS
                  sendTemp();
                #endif
                
                  // Kontroller
                  control();
                
                  // Loop 2x pro Sekunde ist aureichend
                  unsigned long loopTime = millis() - nowms;
                  if (loopTime < 450) {
                #ifdef NO_MYS
                    delay (500 - loopTime);
                #else
                    wait (500 - loopTime);
                #endif
                  }
                }
                // end loop
                
                /**************************************************************/
                // Steuerung
                void control()
                {
                
                  wdt_reset();
                
                  static unsigned long lastPumpTest = 0;
                  static unsigned long lastRegulation = -REGULATION_TIMEOUT_PUMP;
                  static unsigned long resetStart = 0;                     // wann wurde die Rücksetzung des Mischers gestartet
                  static bool lastPower = powerOn;
                  static float moveSeconds = 0.0;                 // Zeiten für Stellmotor Mischer
                
                  // controllerState
                  // 0 initialized
                  // 1 Pumpe für kurzen test aktiviert, warten auf Timeout für Deaktivierung
                  // 2 in der Regelung, warten auf Timeout für Deaktivierung
                  // 3 in Ausganglage fahren
                
                  static int controllerState = 0;
                
                  // Emergency
                  if  (lastTemperature[VORLAUF] > MAX_TEMP) {
                    if (resetStart == 0) {
                      if (relState[PUMPE]) {
                        DEBUG_PRINT(F("Zu heiss. Emergency Mischer schliessen"));
                        DEBUG_PRINTLN(lastTemperature[VORLAUF]);
                      }
                      closeMischer();
                      controllerState = 0;
                      return;
                    }
                  }
                
                
                  // Temperatur noch nicht gelesen;
                  if (lastTemperature[VORLAUF] == -100) return;
                
                  // Fehler mit den Sensoren
                  if ((lastTemperature[VORLAUF] < 0) ||
                      (lastTemperature[VORLAUF] > 100) ||
                      (lastTemperature[RUECKLAUF] < 0) ||
                      (lastTemperature[RUECKLAUF] > 100) ||
                      (lastTemperature[ZULAUF] < 0) ||
                      (lastTemperature[ZULAUF] > 100)) {
                    relState[PUMPE] = false;
                    updateRelays();
                    ledState[PUMPE] = relState[PUMPE];
                    // Test
                    //powerOn = false;
                #ifndef NO_MYS
                    //send(msgPower.set(powerOn));
                #endif
                
                    controllerState = 0;
                    DEBUG_PRINTLN(F("Fehler mit den Sensoren, Temperaturen unter 0 oder über 100. Poweroff!"));
                    return;
                  }
                
                  if (resetMischer) {
                    DEBUG_PRINTLN(F("Mischer initialisieren"));
                    closeMischer();
                    resetStart = millis();
                    resetMischer = false;
                    controllerState = 0;
                    return;
                  }
                
                  if (resetStart > 0) {
                    if ((millis() - resetStart) > MISCHER_RESET_TIME) {
                      DEBUG_PRINTLN(F("Mischer fertig initialisiert"));
                      relState[MISCHER_ZU] = false;
                      updateRelays();
                      ledState[PUMPE] = relState[PUMPE];
                      ledState[MISCHER_ZU] = relState[MISCHER_ZU];
                      resetStart = 0;
                      controllerState = 0;
                    }
                    return;
                  }
                
                  // wenn ausser Betrieb -> verlassen;
                  if (powerOn == false) {
                    if (lastPower == false) return;
                
                    DEBUG_PRINTLN("Go to power off state");
                
                #ifndef NO_MYS
                    send(msgPower.set(powerOn));
                #endif
                
                    lastPower = false;
                    relState[PUMPE] = false;
                    relState[MISCHER_ZU] = false;
                    relState[MISCHER_AUF] = false;
                    updateRelays();
                    ledState[PUMPE] = relState[PUMPE];
                    ledState[MISCHER_ZU] = relState[MISCHER_ZU];
                    ledState[MISCHER_AUF] = relState[MISCHER_AUF];
                    controllerState = 0;
                    EEPROM.write(EEPROM_POWERSTATE, 0);
                    return;
                  }
                  //DEBUG_PRINTLN("a");
                  lastPower = true;
                
                  switch (controllerState) {
                    case  0:  // Initialisiert
                      if (lastTemperature[ZULAUF] < 30) {
                        if ((millis() - lastPumpTest) > RETRY_TIMEOUT_PUMP) {
                          controllerState = 1;
                          lastPumpTest = millis();
                          DEBUG_PRINTLN(F("Zulauf zu kalt. Schalte Pumpe für 5 Sekunden ein."));
                          relState[PUMPE] = true;
                          updateRelays();
                          ledState[PUMPE] = relState[PUMPE];
                        }
                        return;
                      }
                      //DEBUG_PRINTLN("x");
                
                      relState[PUMPE] = true;
                      updateRelays();
                      ledState[PUMPE] = relState[PUMPE];
                
                
                      // nicht regulieren, wenn schon genau genug
                      if (abs(lastTemperature[VORLAUF] - targetTemp) <= 1) {
                        // DEBUG_PRINTLN("diff zu klein, keine Steuerung notwendig");
                        return;
                      }
                
                
                      if ((millis() - lastRegulation) > REGULATION_TIMEOUT_PUMP) {
                        controllerState = 2;
                        lastRegulation = millis();
                
                        int diffZualaufRuecklauf = lastTemperature[ZULAUF] - lastTemperature[RUECKLAUF];
                
                        float actPercent = (float)(lastTemperature[VORLAUF] - lastTemperature[RUECKLAUF]) * 100.0 / (float)diffZualaufRuecklauf;
                        float shoulPercent = (float)(targetTemp - lastTemperature[RUECKLAUF]) * 100.0 / (float)diffZualaufRuecklauf;
                
                        // 120 Sekunden für ganzen Weg
                        moveSeconds = (float)MISCHER_RESET_TIME / 1000.0 / 100.0 * abs(shoulPercent - actPercent);
                        DEBUG_PRINT(F("Berechnete Sekunden fuer Mischerumstellung "));
                        DEBUG_PRINTLN(moveSeconds);
                        if (moveSeconds > 8)
                          moveSeconds = 8;
                
                        if (targetTemp > lastTemperature[VORLAUF]) {
                          DEBUG_PRINTLN(F("Mischer auf"));
                          relState[MISCHER_ZU] = false;
                          relState[MISCHER_AUF] = true;
                          updateRelays();
                          ledState[MISCHER_ZU] = relState[MISCHER_ZU];
                          ledState[MISCHER_AUF] = relState[MISCHER_AUF];
                        }
                        else
                        {
                          DEBUG_PRINTLN(F("Mischer zu"));
                          relState[MISCHER_ZU] = true;
                          relState[MISCHER_AUF] = false;
                          updateRelays();
                          ledState[MISCHER_ZU] = relState[MISCHER_ZU];
                          ledState[MISCHER_AUF] = relState[MISCHER_AUF];
                        }
                        return;
                      }
                      return;
                      break;
                    case  1: // in Testmodus bei zu wenig  Temp im Zulauf
                      if ((millis() - lastPumpTest) > PROBE_TIMEOUT_PUMP) {
                        relState[PUMPE] = false;
                        updateRelays();
                        ledState[PUMPE] = relState[PUMPE];
                        DEBUG_PRINTLN(F("Pumpe ausgeschaltet"));
                        controllerState = 0;
                        lastPumpTest = millis();
                      }
                      return;
                      break;
                    case  2: // in der Regelung
                      if ((millis() - lastRegulation) > moveSeconds * 1000.0) {
                        DEBUG_PRINTLN("Mischer zu.");
                        relState[MISCHER_ZU] = false;
                        relState[MISCHER_AUF] = false;
                        updateRelays();
                        ledState[MISCHER_ZU] = relState[MISCHER_ZU];
                        ledState[MISCHER_AUF] = relState[MISCHER_AUF];
                        lastRegulation = millis();
                        controllerState = 0;
                      }
                      return;
                      break;
                    default:
                      DEBUG_PRINT(F("ERROR, unknown state :"));
                      DEBUG_PRINTLN(controllerState);
                      controllerState = 0;
                      return;
                  }
                }
                
                // function to print a device address
                void printAddress(DeviceAddress deviceAddress)
                {
                  for (uint8_t i = 0; i < 8; i++)
                  {
                    if (deviceAddress[i] < 16) DEBUG_PRINT("0");
                
                #ifdef EN_DEBUG
                    Serial.print(deviceAddress[i], HEX);
                #endif
                  }
                }
                
                void updateRelays() {
                  static boolean relayStateReported[8] = { false, false, false, false, false, false, false, false };
                #ifndef NO_MYS
                  static unsigned long previousStateMillis[NUMBER_OF_RELAYS] = { 0, 0, 0, 0 };
                #endif
                
                  for (int i = 0; i < NUMBER_OF_RELAYS; i++) {
                    if (relState[i]) {
                      digitalWrite(RELAY_1 + i, RELAY_ON);
                    }
                    else
                    {
                      digitalWrite(RELAY_1 + i, RELAY_OFF);
                    }
                
                #ifndef NO_MYS
                    bool bSend = false;
                    if (previousStateMillis[i] == 0) {                               // noch nie gesendet
                      bSend = true;
                    }
                    else if (relayStateReported[i] != relState[i] ) { // Änderungen melden
                      bSend = true;
                    }
                    else if ((millis() - previousStateMillis[i]) > MIN_REPORT_INTERVAL) {
                      bSend = true;
                    }
                
                    if (bSend) {
                      // TODO: Check if we want to look at the return value of send
                      send(msgStatus.setSensor(i + MAX_ATTACHED_DS18B20).set(relState[i] ? 1 : 0));
                      previousStateMillis[i] = millis();
                      relayStateReported[i] = relState[i];
                    }
                #endif
                  }
                }
                
                void updateDisp() {
                  static char s[8];
                  static unsigned long previousDisplayMillis = 0;
                
                  // update display?
                  if ((millis() - previousDisplayMillis) > 1000) {
                    previousDisplayMillis = millis();
                    displayInfo++;
                #ifdef NO_MYS
                    if (displayInfo > 4) displayInfo = 0;
                #else
                    if (displayInfo > 5) displayInfo = 0;
                #endif
                
                
                
                    ledModule.clearDisplay();
                    // sind die Temperaturen schon gelesen worden? Wenn nicht, abbrechen.
                    if (lastTemperature[0] == -100) return;
                
                    for (byte i = 0; i <= 7; i++) {
                      if (ledState[i])
                        ledModule.setLED(1, i);
                      else
                        ledModule.setLED(0, i);
                    }
                
                    // 0 Vorlauf, 1 Rücklauf, 2 Zulauf, 3 Sollwert
                    switch (displayInfo) {
                      case 0: // Vorlauf
                        sprintf(s, "Vor %2i",  lastTemperature[VORLAUF]);
                        break;
                      case 1: // Rücklauf
                        sprintf(s, "Rue %2i",  lastTemperature[RUECKLAUF]);
                        break;
                      case 2: // Zulauf
                        sprintf(s, "Zu %2i",  lastTemperature[ZULAUF]);
                        break;
                      case 3: // Zielwert
                        sprintf(s, "Soll %2i",  targetTemp);
                        break;
                      case 4: // Power
                        if (powerOn) {
                          sprintf(s, "PowerOn");
                        }
                        else {
                          sprintf(s, "PowerOff");
                        }
                        break;
                #ifndef NO_MYS
                      case 5: //clock
                        TimeChangeRule *tcr;
                        time_t utc = millis();
                        time_t t = CE.toLocal(utc, &tcr);
                        unsigned long dispTime = hour(t) * 100 * 100 + minute(t) * 100 + second(t);
                        if (hour(t) < 10) {
                          sprintf(s, "U 0%lu",  dispTime);
                        }
                        else
                        {
                          sprintf(s, "U %lu",  dispTime);
                        }
                        break;
                #endif
                    }
                
                    ledModule.setDisplayToString(s);
                  }
                }
                
                void closeMischer() {
                  relState[PUMPE] = false;
                  relState[MISCHER_ZU] = true;
                  relState[MISCHER_AUF] = false;
                  updateRelays();
                  ledState[PUMPE] = relState[PUMPE];
                  ledState[MISCHER_ZU] = relState[MISCHER_ZU];
                  ledState[MISCHER_AUF] = relState[MISCHER_AUF];
                }
                
                
                #ifndef NO_MYS
                
                void before()
                {
                
                }
                
                // 0 Vorlauf, 1 Rücklauf, 2 Zulauf
                void presentation() {
                  // Send the sketch version information to the gateway and Controller
                  sendSketchInfo("Mischer Node", "1.1");
                
                  // Fetch the number of attached temperature sensors
                  numSensors = sensors.getDeviceCount();
                  DEBUG_PRINT(F("Numsensors "));
                  DEBUG_PRINTLN(numSensors);
                
                  // Present all sensors to controller
                  for (int i = 0; i < numSensors && i < MAX_ATTACHED_DS18B20; i++) {
                    present(i, S_TEMP);
                  }
                
                  for (int sensor = MAX_ATTACHED_DS18B20, pin = RELAY_1; sensor < (MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS); sensor++, pin++) {
                    // Register all sensors to gw (they will be created as child devices)
                    present(sensor, S_BINARY);
                  }
                
                  // Thermopunkt
                  present(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS, S_HVAC);
                
                  // Power
                  present(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 1, S_HEATER);
                
                #ifndef NO_AC_DETECT
                  // AC Buderuus
                  present(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 2, S_BINATY);
                #endif
                
                  // Power
                  present(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 3, S_INFO);
                
                  // Initialltemperatur mitteilen
                  send(msgTargetTemp.set(targetTemp));
                  send(msgPower.set(powerOn));
                }
                
                
                void receive(const MyMessage & message)
                {
                  DEBUG_PRINT(F("Meldung an Sensor "));
                  DEBUG_PRINT(message.sensor);
                  DEBUG_PRINT(F(" mit type "));
                  DEBUG_PRINTLN(message.type);
                  if (message.type == V_STATUS) {
                    int i = message.sensor - MAX_ATTACHED_DS18B20;
                    if ((i >= 0) && (i < NUMBER_OF_RELAYS)) {
                      DEBUG_PRINT(F("Schaltbefehl für Relay "));
                      DEBUG_PRINT(i);
                      DEBUG_PRINT(F(" auf "));
                      DEBUG_PRINTLN(message.getBool());
                      relState[i] = message.getBool();
                      ledState[i] = relState[i];
                    }
                    else if (i == MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 1) {
                      powerOn = message.getBool();
                      send(msgPower.set(powerOn));
                
                      if (powerOn)
                        EEPROM.write(EEPROM_POWERSTATE, 1);
                      else
                        EEPROM.write(EEPROM_POWERSTATE, 0);
                
                      if (powerOn == false) {
                        relState[PUMPE] = false;
                        ledState[POWERLED] = false;
                        DEBUG_PRINTLN(F("Befehl für PowerOff"));
                      }
                      else {
                        ledState[POWERLED] = true;
                        DEBUG_PRINTLN(F("Befehl für PowerOn"));
                      }
                    }
                
                    updateRelays();
                  }
                  else if (message.type == V_HVAC_SETPOINT_HEAT) {
                    if (message.sensor == (MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS)) {
                      targetTemp = message.getInt();
                      DEBUG_PRINT(F("Zieltemp gesetzt auf "));
                      DEBUG_PRINTLN(targetTemp);
                      if (targetTemp > MAX_TEMP) targetTemp = START_TARGET_TEMP;
                      if (targetTemp < 20) targetTemp = 20;
                      send(msgTargetTemp.set(targetTemp));
                    }
                  }
                }
                
                // This is called when a new time value was received
                void receiveTime(unsigned long controllerTime) {
                  // Ok, set incoming time
                  DEBUG_PRINT(F("Time value received: "));
                  DEBUG_PRINTLN(controllerTime);
                #ifndef NO_RTC
                  RTC.set(controllerTime);
                  else
                    setTime(controllerTime);
                #endif
                  timeReceived = true;
                }
                
                void sendTemp() {
                  static int lastSentTemperature[MAX_ATTACHED_DS18B20] = { -100, -100, -100 };
                  static unsigned long previousTempMillis[MAX_ATTACHED_DS18B20] = { 0, 0, 0 };
                
                  for (int i = 0; i < MAX_ATTACHED_DS18B20 ; i++) {
                    if (lastTemperature[i] != -100) {
                      bool bSend = false;
                      if (previousTempMillis[i] == 0) {                               // noch nie gesendet
                        bSend = true;
                      }
                      else if (abs(lastSentTemperature[i] - lastTemperature[i]) >= 2) { // Differenz von >= zwei Grad werden gemeldet
                        bSend = true;
                      }
                      else if ((millis() - previousTempMillis[i]) > MIN_REPORT_INTERVAL) {
                        bSend = true;
                      }
                
                      if (bSend) {
                        // TODO: Check if we want to look at the return value of send
                        send(msgTemp.setSensor(i).set(lastTemperature[i], 1));
                        previousTempMillis[i] = millis();
                        lastSentTemperature[i] = lastTemperature[i];
                      }
                    }
                  }
                }
                #endif
                
                #ifndef NO_AC_DETECT
                void buderusSet() {
                  testStateBuderus = true;
                }
                #endif
                
                void reboot() {
                  wdt_enable(WDTO_30MS);
                  while (1) {};
                }
                
                void readButtons() {
                
                  byte buttons = ledModule.getButtons();
                
                  if (lastButtonState != buttons) {
                    lastButtonState = buttons;
                    if (buttons > 0) {
                      for (byte i = 0; i <= 7; i++) {
                        if ((buttons >> i) & 1) {
                          ledState[i] = !ledState[i];
                          if (i < NUMBER_OF_RELAYS) relState[i] = ledState[i];
                          updateRelays();
                          if (ledState[i])
                            ledModule.setLED(1, i);
                          else
                            ledModule.setLED(0, i);
                          if (i == POWERLED) {
                            powerOn = ledState[i];
                #ifndef NO_MYS
                            send(msgPower.set(powerOn));
                #endif
                            if (powerOn)
                              EEPROM.write(EEPROM_POWERSTATE, 1);
                            else
                              EEPROM.write(EEPROM_POWERSTATE, 0);
                
                          }
                
                          if (i == TEMPDOWNLED) {
                            targetTemp--;
                            if (targetTemp < 30) targetTemp = 30;
                            EEPROM.write(EEPROM_TARGET_TEMP, targetTemp);
                          }
                          if (i == TEMPUPLED) {
                            targetTemp++;
                            if (targetTemp > MAX_TEMP) targetTemp = MAX_TEMP;
                            EEPROM.write(EEPROM_TARGET_TEMP, targetTemp);
                          }
                          DEBUG_PRINT(F("ButtonState changed "));
                          DEBUG_PRINTLN(i);
                        }
                      }
                    }
                  }
                }
                
                void readTemp() {
                  static float temp;
                  static int tempi;
                  static unsigned long lastReadTemp1 = -1;
                  static unsigned long lastReadTemp2 = -1;
                  static unsigned long lastReadTemp3 = -1;
                
                  if (previousTempMillis == -1) {
                    // Dallas
                    sensors.requestTemperatures();
                    previousTempMillis = nowms;
                  }
                
                  if ((millis() - previousTempMillis) >= conversionTime) {
                    temp = sensors.getTempC(Probe01);
                    if (temp != DEVICE_DISCONNECTED_C) {
                      tempi = (int)(temp + 0.5);
                      lastTemperature[VORLAUF] = tempi;
                      lastReadTemp1 = nowms;
                    }
                
                    if (temp != DEVICE_DISCONNECTED_C) {
                      temp = sensors.getTempC(Probe02);
                      tempi = (int)(temp + 0.5);
                      lastTemperature[RUECKLAUF] = tempi;
                      lastReadTemp2 = nowms;
                    }
                
                    if (temp != DEVICE_DISCONNECTED_C) {
                      temp = sensors.getTempC(Probe03);
                      tempi = (int)(temp + 0.5);
                      lastTemperature[ZULAUF] = tempi;
                      lastReadTemp3 = nowms;
                    }
                
                    if (nowms > 60000) {    // ersta nach einer minute prüfen
                      unsigned long compare = nowms - 60000; // vor 1 Minute
                      if ((lastReadTemp1 < compare) || (lastReadTemp2 < compare) || (lastReadTemp3 < compare)) {
                        DEBUG_PRINTLN(F("Zu lange keine Temeratur -> reset"));
                        lastReadTemp1 = -1;
                        lastReadTemp2 = -1;
                        lastReadTemp3 = -1;
                        ledModule.setDisplayToString(F("ERR Reb"));
                        delay(1000);
                        reboot();
                      }
                    }
                
                    previousTempMillis = -1;
                  }
                
                #ifdef SIMULATE_VOR
                  lastTemperature[VORLAUF] = SIMULATE_VOR;
                  lastReadTemp1 = nowms;
                #endif
                
                #ifdef SIMULATE_RUE
                  lastTemperature[RUECKLAUF] = SIMULATE_RUE;
                  lastReadTemp3 = nowms;
                #endif
                
                #ifdef SIMULATE_ZU
                  lastTemperature[ZULAUF] = SIMULATE_ZU;
                  lastReadTemp3 = nowms;
                #endif
                }
                
                #ifndef NO_AC_DETECT
                
                void readAC() {
                  if ((millis() - lastResetBuderus) > 100) // bei 50 HZ sind das 25 Durchgänge...
                  {
                    noInterrupts();
                    if (testStateBuderus != powerOnBuderus ) {
                      powerOnBuderus = testStateBuderus;
                      testStateBuderus = false;
                      interrupts();
                      ledState[BUDERUSLED] = powerOnBuderus;
                #ifndef NO_MYS
                      send(msgPowerBuderus.set(powerOnBuderus));
                #endif
                    }
                    lastResetBuderus = nowms;
                    testStateBuderus = false;
                  } else
                    interrupts();
                }
                #endif
                
                raptorjrR 1 Reply Last reply
                1
                • FotoFieberF FotoFieber

                  I had a similar problem with the control of a heating mixer and three dallas sensors. I solved the problem with:

                  • replacement of the relays with solid state relays
                  • moved conttroller more in distance of the high voltage parts

                  I also added a watchdog and a reboot mechanism in case of sensor problems.

                  Maybe this sketch can give you an inspiration: (work in progress, MYS-Part not tested in depth)

                  // Enable debug prints to serial monitor
                  //#define MY_DEBUG      // in Mysensors
                  #define EN_DEBUG      // in this sketch
                  //#define NO_MYS      // ohne Mysensors Unterstützung?
                  //#define SIMULATION
                  #define NO_AC_DETECT  // ohne AC sensor
                  #define NO_RTC
                  
                  // RTC nur zusammen mit Mysensors
                  #ifdef NO_MYS
                  #ifndef NO_RTC
                  #define NO_RTC
                  #endif
                  #endif
                  
                  #ifdef SIMULATION
                  // für Simulation ohne Sensoren
                  #define SIMULATE_VOR  35
                  #define SIMULATE_RUE  30
                  #define SIMULATE_ZU   65
                  
                  
                  #ifdef SIMULATE_VOR
                  #warning Achtung! Keine Echtentemperaturmessungen -> Simulation
                  #endif
                  
                  #ifdef SIMULATE_RUE
                  #warning Achtung! Keine Echtentemperaturmessungen -> Simulation
                  #endif
                  
                  #ifdef SIMULATE_ZU
                  #warning Achtung! Keine Echtentemperaturmessungen -> Simulation
                  #endif
                  #endif
                  
                  
                  #define START_TARGET_TEMP 40
                  #define EEPROM_TARGET_TEMP 900            // Save Porisiton. It is above the Mysensors range of lib 2.1
                  #define EEPROM_POWERSTATE  902            // Save Porisiton. It is above the Mysensors range of lib 2.1
                  #define MAX_TEMP 50
                  #define VORLAUF 0
                  #define RUECKLAUF 1
                  #define ZULAUF 2
                  #define PUMPE 0
                  #define MISCHER_ZU  1
                  #define MISCHER_AUF 2
                  #define POWERLED 7                        // 8. LED
                  #define TEMPDOWNLED 5                     // 6. Led
                  #define TEMPUPLED 6                       // 7. Led
                  #ifndef NO_AC_DETECT
                  #define BUDERUSLED 4                      // 5. Led
                  #endif
                  #define RETRY_TIMEOUT_PUMP 2*60*1000UL     // alle 2 Minuten testen, ob Vorlauf nicht besser (5 Sekunden pumpen)
                  #define REGULATION_TIMEOUT_PUMP 30*1000UL  // 30 Sekunden warten nach neuer Einstellung
                  #define PROBE_TIMEOUT_PUMP 5*1000UL        // 5 Sekunden Pumpe für Test einschalten, wenn Zulauf zu kalt
                  #define BUDERUS_PIN 3                     // Buderus Powererkennung Pumpe auf PIN 3
                  
                  #ifndef SIMULATION
                  #define MISCHER_RESET_TIME 120*1000UL      // 2 Minuten bis Nullstellung
                  #else
                  #define MISCHER_RESET_TIME 10*1000UL      // 10 Sekunden bis Nullstellung nei Simulation
                  #endif
                  
                  
                  
                  #ifdef EN_DEBUG
                  #define DEBUG_PRINT(x) Serial.print (x)
                  #else
                  #define DEBUG_PRINT(x)
                  #endif
                  
                  #ifdef EN_DEBUG
                  #define DEBUG_PRINTLN(x)  Serial.println (x)
                  #else
                  #define DEBUG_PRINTLN(x)
                  #endif
                  
                  #ifndef NO_MYS
                  // Radio Configuration
                  #define MY_TRANSPORT_WAIT_READY_MS (10000ul)
                  #define MY_RADIO_RFM69
                  #define MY_RFM69_FREQUENCY RF69_868MHZ
                  #define MY_RFM69_NETWORKID 13
                  #define MY_RFM69_ENABLE_ENCRYPTION
                  #define MY_NODE_ID 168
                  //#define MY_IS_RFM69HW
                  #endif
                  
                  
                  #include <Arduino.h>
                  #include <avr/wdt.h>
                  #include <EEPROM.h>
                  #include <MemoryFree.h>
                  
                  #ifndef NO_MYS
                  #define MIN_REPORT_INTERVAL  5 * 60 * 1000L   // mindestens alle 5 Minuten melden
                  #include <SPI.h>
                  #include <MySensors.h>
                  #include <Time.h>        //http://www.arduino.cc/playground/Code/Time
                  #include <Timezone.h>    //https://github.com/JChristensen/Timezone
                  #include <TimeLib.h>
                  
                  //Central European Time (Frankfurt, Paris)
                  TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120};     //Central European Summer Time
                  TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60};       //Central European Standard Time
                  Timezone CE(CEST, CET);
                  bool timeReceived = false;
                  unsigned long lastUpdate = 0, lastRequest = 0;
                  #endif
                  
                  #ifndef NO_RTC
                  #include <DS3232RTC.h>  // A  DS3231/DS3232 library
                  #endif
                  
                  #define MAX_LEDS 8
                  
                  byte lastButtonState = 0;
                  #define RELAY_ON HIGH
                  #define RELAY_OFF LOW
                  #define RELAY_1  A0         // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
                  #define NUMBER_OF_RELAYS 4  // Total number of attached relays
                  
                  
                  boolean ledState[MAX_LEDS] = { false, false, false, false, false, false, false, false };
                  boolean relState[NUMBER_OF_RELAYS] = { false, false, false, false };
                  
                  #include <TM1638.h>
                  #include <DallasTemperature.h>
                  #include <OneWire.h>
                  
                  #define ONE_WIRE_BUS 6 // Pin where dallase sensor is connected 
                  #define TEMPERATURE_PRECISION 9
                  #define MAX_ATTACHED_DS18B20 3
                  
                  //28B404080000804A
                  DeviceAddress Probe01 = { 0x28, 0xB4, 0x04, 0x08, 0x00, 0x00, 0x80, 0x4A };
                  //28C606080000803F
                  DeviceAddress Probe02 = { 0x28, 0xC6, 0x06, 0x08, 0x00, 0x00, 0x80, 0x3F };
                  //28750808000080C3
                  DeviceAddress Probe03 = { 0x28, 0x75, 0x08, 0x08, 0x00, 0x00, 0x80, 0xC3 };
                  
                  OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
                  DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature.
                  int numSensors = 0;
                  int lastTemperature[MAX_ATTACHED_DS18B20] = { -100, -100, -100 };
                  int16_t conversionTime;
                  unsigned long previousTempMillis = -1;
                  static unsigned long nowms = millis();    // update at start of loop()
                  
                  
                  // define LCD module
                  TM1638 ledModule(8, 9, 7);
                  
                  int displayInfo = -1;
                  unsigned long previousDisplayMillis = 0;
                  
                  int targetTemp = START_TARGET_TEMP;
                  #ifdef SIMULATION
                  bool powerOn = true;
                  #ifndef NO_AC_DETECT
                  bool powerOnBuderus = true;
                  #endif
                  #else
                  bool powerOn = false;
                  #ifndef NO_AC_DETECT
                  bool powerOnBuderus = false;
                  #endif
                  #endif
                  bool resetMischer = true; // mischer zuerst in Nullstellung
                  
                  #ifndef NO_AC_DETECT
                  bool testStateBuderus = false;
                  unsigned long lastResetBuderus = -1;
                  #endif
                  
                  #ifndef NO_MYS
                  // Initialize messages
                  MyMessage msgTemp(0, V_TEMP);
                  MyMessage msgStatus(0, V_STATUS);
                  MyMessage msgTargetTemp(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS, V_HVAC_SETPOINT_HEAT);
                  MyMessage msgPower(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 1, V_STATUS);
                  #ifndef NO_AC_DETECT
                  MyMessage msgPowerBuderus(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 2, V_STATUS);
                  #endif
                  MyMessage msgDebug(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 3, V_TEXT);
                  #endif
                  
                  // the setup function runs once when you press reset or power the board
                  void setup() {
                    DEBUG_PRINTLN(F("Starte setup"));
                    wdt_enable(WDTO_8S);
                    Serial.begin(115200);
                  
                  #ifndef NO_RTC
                    // the function to get the time from the RTC
                    setSyncProvider(RTC.get);
                  #endif
                  #ifndef NO_MYS
                    // Request latest time from controller at startup
                    requestTime();
                  #endif
                  
                  
                  
                  
                    // Zieltemperatur aus EERPOM lesem:
                    targetTemp = EEPROM.read(EEPROM_TARGET_TEMP);
                    if ((targetTemp < 30) || (targetTemp > MAX_TEMP)) {
                      targetTemp = START_TARGET_TEMP;
                      EEPROM.write(EEPROM_TARGET_TEMP, targetTemp);
                    }
                  
                    int state = EEPROM.read(EEPROM_POWERSTATE);
                    if (state == 0) {
                      powerOn = false;
                    }
                    else powerOn = true;
                  
                  #ifndef NO_AC_DETECT
                    // Buderuserkennung auf PIN3
                    attachInterrupt(digitalPinToInterrupt(BUDERUS_PIN), buderusSet, CHANGE);
                    testStateBuderus = false;
                    lastResetBuderus = millis();
                  #ifndef NO_MYS
                    send(msgPowerBuderus.set(powerOnBuderus));
                  #endif
                  #endif
                  
                    // Relayausgänge initialisiern
                    for (int sensor = 1, pin = RELAY_1; sensor <= NUMBER_OF_RELAYS; sensor++, pin++) {
                      // Then set relay pins in output mode
                      pinMode(pin, OUTPUT);
                      // Set relay to last known state (using eeprom storage)
                      digitalWrite(pin, RELAY_OFF);
                    }
                  
                    // Dallas Temperatursensoren
                    sensors.begin();
                    sensors.setWaitForConversion(false);
                    numSensors = sensors.getDeviceCount();
                    DEBUG_PRINT(F("Dallas Sensoren "));
                    DEBUG_PRINTLN(numSensors);
                    DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address
                  
                    for (int i = 0; i < numSensors; i++)
                    {
                      wdt_reset();
                      // Search the wire for address
                      if (sensors.getAddress(tempDeviceAddress, i))
                      {
                        DEBUG_PRINT(F("Found device "));
                  #ifdef EN_DEBUG
                        Serial.print(i, DEC);
                  #endif
                        DEBUG_PRINT(F(" with address: "));
                        printAddress(tempDeviceAddress);
                        DEBUG_PRINTLN();
                  
                        DEBUG_PRINT(F("Setting resolution to "));
                  #ifdef EN_DEBUG
                        Serial.println(TEMPERATURE_PRECISION, DEC);
                  #endif
                        // set the resolution to 12 bit (Each Dallas/Maxim device is capable of several different resolutions)
                        sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);
                  
                        DEBUG_PRINT(F("Resolution actually set to: "));
                  
                  #ifdef EN_DEBUG
                        Serial.print(sensors.getResolution(tempDeviceAddress), DEC);
                  #endif
                        DEBUG_PRINTLN();
                      } else {
                        DEBUG_PRINT(F("Found ghost device at "));
                  
                  #ifdef EN_DEBUG
                        Serial.print(i, DEC);
                  #endif
                        DEBUG_PRINT(F(" but could not detect address. Check power and cabling"));
                      }
                    }
                  
                    wdt_reset();
                    sensors.requestTemperatures();
                  
                    // query conversion time and sleep until conversion completed
                    conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
                  }
                  
                  /*****************************************************/
                  // the loop function runs over and over again forever
                  void loop() {
                    nowms = millis();
                  
                  #ifndef NO_MYS
                    // If no time has been received yet, request it every 10 second from controller
                    // When time has been received, request update every hour
                    if ((!timeReceived && (nowms - lastRequest) > (10UL * 1000UL))
                        || (timeReceived && (nowms - lastRequest) > (60UL * 1000UL * 60UL))) {
                      // Request time from controller.
                      DEBUG_PRINTLN("requesting time");
                      requestTime();
                      lastRequest = nowms;
                    }
                  #endif
                  
                    wdt_reset();
                  
                  #ifndef NO_AC_DETECT
                    readAC();
                  #endif
                  
                    readTemp();
                    readButtons();
                  
                    updateDisp();
                  
                    // Temperaturen senden
                  
                  #ifndef NO_MYS
                    sendTemp();
                  #endif
                  
                    // Kontroller
                    control();
                  
                    // Loop 2x pro Sekunde ist aureichend
                    unsigned long loopTime = millis() - nowms;
                    if (loopTime < 450) {
                  #ifdef NO_MYS
                      delay (500 - loopTime);
                  #else
                      wait (500 - loopTime);
                  #endif
                    }
                  }
                  // end loop
                  
                  /**************************************************************/
                  // Steuerung
                  void control()
                  {
                  
                    wdt_reset();
                  
                    static unsigned long lastPumpTest = 0;
                    static unsigned long lastRegulation = -REGULATION_TIMEOUT_PUMP;
                    static unsigned long resetStart = 0;                     // wann wurde die Rücksetzung des Mischers gestartet
                    static bool lastPower = powerOn;
                    static float moveSeconds = 0.0;                 // Zeiten für Stellmotor Mischer
                  
                    // controllerState
                    // 0 initialized
                    // 1 Pumpe für kurzen test aktiviert, warten auf Timeout für Deaktivierung
                    // 2 in der Regelung, warten auf Timeout für Deaktivierung
                    // 3 in Ausganglage fahren
                  
                    static int controllerState = 0;
                  
                    // Emergency
                    if  (lastTemperature[VORLAUF] > MAX_TEMP) {
                      if (resetStart == 0) {
                        if (relState[PUMPE]) {
                          DEBUG_PRINT(F("Zu heiss. Emergency Mischer schliessen"));
                          DEBUG_PRINTLN(lastTemperature[VORLAUF]);
                        }
                        closeMischer();
                        controllerState = 0;
                        return;
                      }
                    }
                  
                  
                    // Temperatur noch nicht gelesen;
                    if (lastTemperature[VORLAUF] == -100) return;
                  
                    // Fehler mit den Sensoren
                    if ((lastTemperature[VORLAUF] < 0) ||
                        (lastTemperature[VORLAUF] > 100) ||
                        (lastTemperature[RUECKLAUF] < 0) ||
                        (lastTemperature[RUECKLAUF] > 100) ||
                        (lastTemperature[ZULAUF] < 0) ||
                        (lastTemperature[ZULAUF] > 100)) {
                      relState[PUMPE] = false;
                      updateRelays();
                      ledState[PUMPE] = relState[PUMPE];
                      // Test
                      //powerOn = false;
                  #ifndef NO_MYS
                      //send(msgPower.set(powerOn));
                  #endif
                  
                      controllerState = 0;
                      DEBUG_PRINTLN(F("Fehler mit den Sensoren, Temperaturen unter 0 oder über 100. Poweroff!"));
                      return;
                    }
                  
                    if (resetMischer) {
                      DEBUG_PRINTLN(F("Mischer initialisieren"));
                      closeMischer();
                      resetStart = millis();
                      resetMischer = false;
                      controllerState = 0;
                      return;
                    }
                  
                    if (resetStart > 0) {
                      if ((millis() - resetStart) > MISCHER_RESET_TIME) {
                        DEBUG_PRINTLN(F("Mischer fertig initialisiert"));
                        relState[MISCHER_ZU] = false;
                        updateRelays();
                        ledState[PUMPE] = relState[PUMPE];
                        ledState[MISCHER_ZU] = relState[MISCHER_ZU];
                        resetStart = 0;
                        controllerState = 0;
                      }
                      return;
                    }
                  
                    // wenn ausser Betrieb -> verlassen;
                    if (powerOn == false) {
                      if (lastPower == false) return;
                  
                      DEBUG_PRINTLN("Go to power off state");
                  
                  #ifndef NO_MYS
                      send(msgPower.set(powerOn));
                  #endif
                  
                      lastPower = false;
                      relState[PUMPE] = false;
                      relState[MISCHER_ZU] = false;
                      relState[MISCHER_AUF] = false;
                      updateRelays();
                      ledState[PUMPE] = relState[PUMPE];
                      ledState[MISCHER_ZU] = relState[MISCHER_ZU];
                      ledState[MISCHER_AUF] = relState[MISCHER_AUF];
                      controllerState = 0;
                      EEPROM.write(EEPROM_POWERSTATE, 0);
                      return;
                    }
                    //DEBUG_PRINTLN("a");
                    lastPower = true;
                  
                    switch (controllerState) {
                      case  0:  // Initialisiert
                        if (lastTemperature[ZULAUF] < 30) {
                          if ((millis() - lastPumpTest) > RETRY_TIMEOUT_PUMP) {
                            controllerState = 1;
                            lastPumpTest = millis();
                            DEBUG_PRINTLN(F("Zulauf zu kalt. Schalte Pumpe für 5 Sekunden ein."));
                            relState[PUMPE] = true;
                            updateRelays();
                            ledState[PUMPE] = relState[PUMPE];
                          }
                          return;
                        }
                        //DEBUG_PRINTLN("x");
                  
                        relState[PUMPE] = true;
                        updateRelays();
                        ledState[PUMPE] = relState[PUMPE];
                  
                  
                        // nicht regulieren, wenn schon genau genug
                        if (abs(lastTemperature[VORLAUF] - targetTemp) <= 1) {
                          // DEBUG_PRINTLN("diff zu klein, keine Steuerung notwendig");
                          return;
                        }
                  
                  
                        if ((millis() - lastRegulation) > REGULATION_TIMEOUT_PUMP) {
                          controllerState = 2;
                          lastRegulation = millis();
                  
                          int diffZualaufRuecklauf = lastTemperature[ZULAUF] - lastTemperature[RUECKLAUF];
                  
                          float actPercent = (float)(lastTemperature[VORLAUF] - lastTemperature[RUECKLAUF]) * 100.0 / (float)diffZualaufRuecklauf;
                          float shoulPercent = (float)(targetTemp - lastTemperature[RUECKLAUF]) * 100.0 / (float)diffZualaufRuecklauf;
                  
                          // 120 Sekunden für ganzen Weg
                          moveSeconds = (float)MISCHER_RESET_TIME / 1000.0 / 100.0 * abs(shoulPercent - actPercent);
                          DEBUG_PRINT(F("Berechnete Sekunden fuer Mischerumstellung "));
                          DEBUG_PRINTLN(moveSeconds);
                          if (moveSeconds > 8)
                            moveSeconds = 8;
                  
                          if (targetTemp > lastTemperature[VORLAUF]) {
                            DEBUG_PRINTLN(F("Mischer auf"));
                            relState[MISCHER_ZU] = false;
                            relState[MISCHER_AUF] = true;
                            updateRelays();
                            ledState[MISCHER_ZU] = relState[MISCHER_ZU];
                            ledState[MISCHER_AUF] = relState[MISCHER_AUF];
                          }
                          else
                          {
                            DEBUG_PRINTLN(F("Mischer zu"));
                            relState[MISCHER_ZU] = true;
                            relState[MISCHER_AUF] = false;
                            updateRelays();
                            ledState[MISCHER_ZU] = relState[MISCHER_ZU];
                            ledState[MISCHER_AUF] = relState[MISCHER_AUF];
                          }
                          return;
                        }
                        return;
                        break;
                      case  1: // in Testmodus bei zu wenig  Temp im Zulauf
                        if ((millis() - lastPumpTest) > PROBE_TIMEOUT_PUMP) {
                          relState[PUMPE] = false;
                          updateRelays();
                          ledState[PUMPE] = relState[PUMPE];
                          DEBUG_PRINTLN(F("Pumpe ausgeschaltet"));
                          controllerState = 0;
                          lastPumpTest = millis();
                        }
                        return;
                        break;
                      case  2: // in der Regelung
                        if ((millis() - lastRegulation) > moveSeconds * 1000.0) {
                          DEBUG_PRINTLN("Mischer zu.");
                          relState[MISCHER_ZU] = false;
                          relState[MISCHER_AUF] = false;
                          updateRelays();
                          ledState[MISCHER_ZU] = relState[MISCHER_ZU];
                          ledState[MISCHER_AUF] = relState[MISCHER_AUF];
                          lastRegulation = millis();
                          controllerState = 0;
                        }
                        return;
                        break;
                      default:
                        DEBUG_PRINT(F("ERROR, unknown state :"));
                        DEBUG_PRINTLN(controllerState);
                        controllerState = 0;
                        return;
                    }
                  }
                  
                  // function to print a device address
                  void printAddress(DeviceAddress deviceAddress)
                  {
                    for (uint8_t i = 0; i < 8; i++)
                    {
                      if (deviceAddress[i] < 16) DEBUG_PRINT("0");
                  
                  #ifdef EN_DEBUG
                      Serial.print(deviceAddress[i], HEX);
                  #endif
                    }
                  }
                  
                  void updateRelays() {
                    static boolean relayStateReported[8] = { false, false, false, false, false, false, false, false };
                  #ifndef NO_MYS
                    static unsigned long previousStateMillis[NUMBER_OF_RELAYS] = { 0, 0, 0, 0 };
                  #endif
                  
                    for (int i = 0; i < NUMBER_OF_RELAYS; i++) {
                      if (relState[i]) {
                        digitalWrite(RELAY_1 + i, RELAY_ON);
                      }
                      else
                      {
                        digitalWrite(RELAY_1 + i, RELAY_OFF);
                      }
                  
                  #ifndef NO_MYS
                      bool bSend = false;
                      if (previousStateMillis[i] == 0) {                               // noch nie gesendet
                        bSend = true;
                      }
                      else if (relayStateReported[i] != relState[i] ) { // Änderungen melden
                        bSend = true;
                      }
                      else if ((millis() - previousStateMillis[i]) > MIN_REPORT_INTERVAL) {
                        bSend = true;
                      }
                  
                      if (bSend) {
                        // TODO: Check if we want to look at the return value of send
                        send(msgStatus.setSensor(i + MAX_ATTACHED_DS18B20).set(relState[i] ? 1 : 0));
                        previousStateMillis[i] = millis();
                        relayStateReported[i] = relState[i];
                      }
                  #endif
                    }
                  }
                  
                  void updateDisp() {
                    static char s[8];
                    static unsigned long previousDisplayMillis = 0;
                  
                    // update display?
                    if ((millis() - previousDisplayMillis) > 1000) {
                      previousDisplayMillis = millis();
                      displayInfo++;
                  #ifdef NO_MYS
                      if (displayInfo > 4) displayInfo = 0;
                  #else
                      if (displayInfo > 5) displayInfo = 0;
                  #endif
                  
                  
                  
                      ledModule.clearDisplay();
                      // sind die Temperaturen schon gelesen worden? Wenn nicht, abbrechen.
                      if (lastTemperature[0] == -100) return;
                  
                      for (byte i = 0; i <= 7; i++) {
                        if (ledState[i])
                          ledModule.setLED(1, i);
                        else
                          ledModule.setLED(0, i);
                      }
                  
                      // 0 Vorlauf, 1 Rücklauf, 2 Zulauf, 3 Sollwert
                      switch (displayInfo) {
                        case 0: // Vorlauf
                          sprintf(s, "Vor %2i",  lastTemperature[VORLAUF]);
                          break;
                        case 1: // Rücklauf
                          sprintf(s, "Rue %2i",  lastTemperature[RUECKLAUF]);
                          break;
                        case 2: // Zulauf
                          sprintf(s, "Zu %2i",  lastTemperature[ZULAUF]);
                          break;
                        case 3: // Zielwert
                          sprintf(s, "Soll %2i",  targetTemp);
                          break;
                        case 4: // Power
                          if (powerOn) {
                            sprintf(s, "PowerOn");
                          }
                          else {
                            sprintf(s, "PowerOff");
                          }
                          break;
                  #ifndef NO_MYS
                        case 5: //clock
                          TimeChangeRule *tcr;
                          time_t utc = millis();
                          time_t t = CE.toLocal(utc, &tcr);
                          unsigned long dispTime = hour(t) * 100 * 100 + minute(t) * 100 + second(t);
                          if (hour(t) < 10) {
                            sprintf(s, "U 0%lu",  dispTime);
                          }
                          else
                          {
                            sprintf(s, "U %lu",  dispTime);
                          }
                          break;
                  #endif
                      }
                  
                      ledModule.setDisplayToString(s);
                    }
                  }
                  
                  void closeMischer() {
                    relState[PUMPE] = false;
                    relState[MISCHER_ZU] = true;
                    relState[MISCHER_AUF] = false;
                    updateRelays();
                    ledState[PUMPE] = relState[PUMPE];
                    ledState[MISCHER_ZU] = relState[MISCHER_ZU];
                    ledState[MISCHER_AUF] = relState[MISCHER_AUF];
                  }
                  
                  
                  #ifndef NO_MYS
                  
                  void before()
                  {
                  
                  }
                  
                  // 0 Vorlauf, 1 Rücklauf, 2 Zulauf
                  void presentation() {
                    // Send the sketch version information to the gateway and Controller
                    sendSketchInfo("Mischer Node", "1.1");
                  
                    // Fetch the number of attached temperature sensors
                    numSensors = sensors.getDeviceCount();
                    DEBUG_PRINT(F("Numsensors "));
                    DEBUG_PRINTLN(numSensors);
                  
                    // Present all sensors to controller
                    for (int i = 0; i < numSensors && i < MAX_ATTACHED_DS18B20; i++) {
                      present(i, S_TEMP);
                    }
                  
                    for (int sensor = MAX_ATTACHED_DS18B20, pin = RELAY_1; sensor < (MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS); sensor++, pin++) {
                      // Register all sensors to gw (they will be created as child devices)
                      present(sensor, S_BINARY);
                    }
                  
                    // Thermopunkt
                    present(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS, S_HVAC);
                  
                    // Power
                    present(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 1, S_HEATER);
                  
                  #ifndef NO_AC_DETECT
                    // AC Buderuus
                    present(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 2, S_BINATY);
                  #endif
                  
                    // Power
                    present(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 3, S_INFO);
                  
                    // Initialltemperatur mitteilen
                    send(msgTargetTemp.set(targetTemp));
                    send(msgPower.set(powerOn));
                  }
                  
                  
                  void receive(const MyMessage & message)
                  {
                    DEBUG_PRINT(F("Meldung an Sensor "));
                    DEBUG_PRINT(message.sensor);
                    DEBUG_PRINT(F(" mit type "));
                    DEBUG_PRINTLN(message.type);
                    if (message.type == V_STATUS) {
                      int i = message.sensor - MAX_ATTACHED_DS18B20;
                      if ((i >= 0) && (i < NUMBER_OF_RELAYS)) {
                        DEBUG_PRINT(F("Schaltbefehl für Relay "));
                        DEBUG_PRINT(i);
                        DEBUG_PRINT(F(" auf "));
                        DEBUG_PRINTLN(message.getBool());
                        relState[i] = message.getBool();
                        ledState[i] = relState[i];
                      }
                      else if (i == MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 1) {
                        powerOn = message.getBool();
                        send(msgPower.set(powerOn));
                  
                        if (powerOn)
                          EEPROM.write(EEPROM_POWERSTATE, 1);
                        else
                          EEPROM.write(EEPROM_POWERSTATE, 0);
                  
                        if (powerOn == false) {
                          relState[PUMPE] = false;
                          ledState[POWERLED] = false;
                          DEBUG_PRINTLN(F("Befehl für PowerOff"));
                        }
                        else {
                          ledState[POWERLED] = true;
                          DEBUG_PRINTLN(F("Befehl für PowerOn"));
                        }
                      }
                  
                      updateRelays();
                    }
                    else if (message.type == V_HVAC_SETPOINT_HEAT) {
                      if (message.sensor == (MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS)) {
                        targetTemp = message.getInt();
                        DEBUG_PRINT(F("Zieltemp gesetzt auf "));
                        DEBUG_PRINTLN(targetTemp);
                        if (targetTemp > MAX_TEMP) targetTemp = START_TARGET_TEMP;
                        if (targetTemp < 20) targetTemp = 20;
                        send(msgTargetTemp.set(targetTemp));
                      }
                    }
                  }
                  
                  // This is called when a new time value was received
                  void receiveTime(unsigned long controllerTime) {
                    // Ok, set incoming time
                    DEBUG_PRINT(F("Time value received: "));
                    DEBUG_PRINTLN(controllerTime);
                  #ifndef NO_RTC
                    RTC.set(controllerTime);
                    else
                      setTime(controllerTime);
                  #endif
                    timeReceived = true;
                  }
                  
                  void sendTemp() {
                    static int lastSentTemperature[MAX_ATTACHED_DS18B20] = { -100, -100, -100 };
                    static unsigned long previousTempMillis[MAX_ATTACHED_DS18B20] = { 0, 0, 0 };
                  
                    for (int i = 0; i < MAX_ATTACHED_DS18B20 ; i++) {
                      if (lastTemperature[i] != -100) {
                        bool bSend = false;
                        if (previousTempMillis[i] == 0) {                               // noch nie gesendet
                          bSend = true;
                        }
                        else if (abs(lastSentTemperature[i] - lastTemperature[i]) >= 2) { // Differenz von >= zwei Grad werden gemeldet
                          bSend = true;
                        }
                        else if ((millis() - previousTempMillis[i]) > MIN_REPORT_INTERVAL) {
                          bSend = true;
                        }
                  
                        if (bSend) {
                          // TODO: Check if we want to look at the return value of send
                          send(msgTemp.setSensor(i).set(lastTemperature[i], 1));
                          previousTempMillis[i] = millis();
                          lastSentTemperature[i] = lastTemperature[i];
                        }
                      }
                    }
                  }
                  #endif
                  
                  #ifndef NO_AC_DETECT
                  void buderusSet() {
                    testStateBuderus = true;
                  }
                  #endif
                  
                  void reboot() {
                    wdt_enable(WDTO_30MS);
                    while (1) {};
                  }
                  
                  void readButtons() {
                  
                    byte buttons = ledModule.getButtons();
                  
                    if (lastButtonState != buttons) {
                      lastButtonState = buttons;
                      if (buttons > 0) {
                        for (byte i = 0; i <= 7; i++) {
                          if ((buttons >> i) & 1) {
                            ledState[i] = !ledState[i];
                            if (i < NUMBER_OF_RELAYS) relState[i] = ledState[i];
                            updateRelays();
                            if (ledState[i])
                              ledModule.setLED(1, i);
                            else
                              ledModule.setLED(0, i);
                            if (i == POWERLED) {
                              powerOn = ledState[i];
                  #ifndef NO_MYS
                              send(msgPower.set(powerOn));
                  #endif
                              if (powerOn)
                                EEPROM.write(EEPROM_POWERSTATE, 1);
                              else
                                EEPROM.write(EEPROM_POWERSTATE, 0);
                  
                            }
                  
                            if (i == TEMPDOWNLED) {
                              targetTemp--;
                              if (targetTemp < 30) targetTemp = 30;
                              EEPROM.write(EEPROM_TARGET_TEMP, targetTemp);
                            }
                            if (i == TEMPUPLED) {
                              targetTemp++;
                              if (targetTemp > MAX_TEMP) targetTemp = MAX_TEMP;
                              EEPROM.write(EEPROM_TARGET_TEMP, targetTemp);
                            }
                            DEBUG_PRINT(F("ButtonState changed "));
                            DEBUG_PRINTLN(i);
                          }
                        }
                      }
                    }
                  }
                  
                  void readTemp() {
                    static float temp;
                    static int tempi;
                    static unsigned long lastReadTemp1 = -1;
                    static unsigned long lastReadTemp2 = -1;
                    static unsigned long lastReadTemp3 = -1;
                  
                    if (previousTempMillis == -1) {
                      // Dallas
                      sensors.requestTemperatures();
                      previousTempMillis = nowms;
                    }
                  
                    if ((millis() - previousTempMillis) >= conversionTime) {
                      temp = sensors.getTempC(Probe01);
                      if (temp != DEVICE_DISCONNECTED_C) {
                        tempi = (int)(temp + 0.5);
                        lastTemperature[VORLAUF] = tempi;
                        lastReadTemp1 = nowms;
                      }
                  
                      if (temp != DEVICE_DISCONNECTED_C) {
                        temp = sensors.getTempC(Probe02);
                        tempi = (int)(temp + 0.5);
                        lastTemperature[RUECKLAUF] = tempi;
                        lastReadTemp2 = nowms;
                      }
                  
                      if (temp != DEVICE_DISCONNECTED_C) {
                        temp = sensors.getTempC(Probe03);
                        tempi = (int)(temp + 0.5);
                        lastTemperature[ZULAUF] = tempi;
                        lastReadTemp3 = nowms;
                      }
                  
                      if (nowms > 60000) {    // ersta nach einer minute prüfen
                        unsigned long compare = nowms - 60000; // vor 1 Minute
                        if ((lastReadTemp1 < compare) || (lastReadTemp2 < compare) || (lastReadTemp3 < compare)) {
                          DEBUG_PRINTLN(F("Zu lange keine Temeratur -> reset"));
                          lastReadTemp1 = -1;
                          lastReadTemp2 = -1;
                          lastReadTemp3 = -1;
                          ledModule.setDisplayToString(F("ERR Reb"));
                          delay(1000);
                          reboot();
                        }
                      }
                  
                      previousTempMillis = -1;
                    }
                  
                  #ifdef SIMULATE_VOR
                    lastTemperature[VORLAUF] = SIMULATE_VOR;
                    lastReadTemp1 = nowms;
                  #endif
                  
                  #ifdef SIMULATE_RUE
                    lastTemperature[RUECKLAUF] = SIMULATE_RUE;
                    lastReadTemp3 = nowms;
                  #endif
                  
                  #ifdef SIMULATE_ZU
                    lastTemperature[ZULAUF] = SIMULATE_ZU;
                    lastReadTemp3 = nowms;
                  #endif
                  }
                  
                  #ifndef NO_AC_DETECT
                  
                  void readAC() {
                    if ((millis() - lastResetBuderus) > 100) // bei 50 HZ sind das 25 Durchgänge...
                    {
                      noInterrupts();
                      if (testStateBuderus != powerOnBuderus ) {
                        powerOnBuderus = testStateBuderus;
                        testStateBuderus = false;
                        interrupts();
                        ledState[BUDERUSLED] = powerOnBuderus;
                  #ifndef NO_MYS
                        send(msgPowerBuderus.set(powerOnBuderus));
                  #endif
                      }
                      lastResetBuderus = nowms;
                      testStateBuderus = false;
                    } else
                      interrupts();
                  }
                  #endif
                  
                  raptorjrR Offline
                  raptorjrR Offline
                  raptorjr
                  wrote on last edited by
                  #13

                  @FotoFieber

                  That was very advanced =) I don't have any high voltage involved. Only have a test setup on a breadboard.

                  I tried to move the sensors.begin to the setup, but then I don't get any temperature readings?

                  1 Reply Last reply
                  0
                  • gohanG Offline
                    gohanG Offline
                    gohan
                    Mod
                    wrote on last edited by
                    #14

                    Try post your code so we can take a look. Did you cross check the hw yet?

                    raptorjrR 1 Reply Last reply
                    0
                    • gohanG gohan

                      Try post your code so we can take a look. Did you cross check the hw yet?

                      raptorjrR Offline
                      raptorjrR Offline
                      raptorjr
                      wrote on last edited by
                      #15

                      @gohan

                      It is the same sketch as my second post.

                      Haven't done anything with the hardware yet. Was following Fabiens advice with using 2.1 on both sketch and gateway. And restart gateway with problem. And then test again and restart node when the problem occurs.

                      1 Reply Last reply
                      0
                      • Darren McInnesD Offline
                        Darren McInnesD Offline
                        Darren McInnes
                        wrote on last edited by
                        #16

                        You may want to check which version of the onewire library you are running. I was having exactly the same issue and fixed it by upgrading the onewire library from 2.7.2 (I think?) To the latest version.

                        It's been a few weeks now with no crashes.

                        raptorjrR 1 Reply Last reply
                        1
                        • Darren McInnesD Darren McInnes

                          You may want to check which version of the onewire library you are running. I was having exactly the same issue and fixed it by upgrading the onewire library from 2.7.2 (I think?) To the latest version.

                          It's been a few weeks now with no crashes.

                          raptorjrR Offline
                          raptorjrR Offline
                          raptorjr
                          wrote on last edited by
                          #17

                          @Darren-McInnes said:

                          You may want to check which version of the onewire library you are running. I was having exactly the same issue and fixed it by upgrading the onewire library from 2.7.2 (I think?) To the latest version.

                          It's been a few weeks now with no crashes.

                          In the Arduino IDE version 2.3.2 seems to be the latest. But is there a newer one that I can download and install?

                          Maybe should figure out why I don't get any sensor readings when I have sensors.begin() in the setup. Maybe that is a problem also that I have it in the loop()?

                          1 Reply Last reply
                          0
                          • Darren McInnesD Offline
                            Darren McInnesD Offline
                            Darren McInnes
                            wrote on last edited by
                            #18

                            Sorry i meant the dallastemperature library!

                            i'm running 3.7.5 now without issues but had problems after a day with 3.7.2

                            my ide version is 1.6.9 and onewire version 2.3.2

                            raptorjrR 1 Reply Last reply
                            0
                            • Darren McInnesD Darren McInnes

                              Sorry i meant the dallastemperature library!

                              i'm running 3.7.5 now without issues but had problems after a day with 3.7.2

                              my ide version is 1.6.9 and onewire version 2.3.2

                              raptorjrR Offline
                              raptorjrR Offline
                              raptorjr
                              wrote on last edited by
                              #19

                              @Darren-McInnes

                              I have 3.7.6 installed. On thing might just be updated libraries. I have been using Visual Studio for development with the plugin from Visual Micro. But then the libraries don't get updated. Had some problems with a update from Visual Micro so I went back to the Arduino IDE.
                              Have been running since Monday now. Although it could take more than a week before any problem, but I'm keeping my fingers crossed.

                              gohanG 1 Reply Last reply
                              0
                              • raptorjrR raptorjr

                                @Darren-McInnes

                                I have 3.7.6 installed. On thing might just be updated libraries. I have been using Visual Studio for development with the plugin from Visual Micro. But then the libraries don't get updated. Had some problems with a update from Visual Micro so I went back to the Arduino IDE.
                                Have been running since Monday now. Although it could take more than a week before any problem, but I'm keeping my fingers crossed.

                                gohanG Offline
                                gohanG Offline
                                gohan
                                Mod
                                wrote on last edited by
                                #20

                                @raptorjr
                                I am also using visual studio but libraries and boards get updated through the arduino ide without problems

                                raptorjrR 1 Reply Last reply
                                0
                                • gohanG gohan

                                  @raptorjr
                                  I am also using visual studio but libraries and boards get updated through the arduino ide without problems

                                  raptorjrR Offline
                                  raptorjrR Offline
                                  raptorjr
                                  wrote on last edited by
                                  #21

                                  @gohan

                                  But if you never open the Arduino IDE it can't get updated? Or are you saying that they get updated through Visual Studio?

                                  I hadn't used the IDE for several months. Thought I was a step closer to the problem and that it was bugs in older libraries.

                                  gohanG 1 Reply Last reply
                                  0
                                  • raptorjrR raptorjr

                                    @gohan

                                    But if you never open the Arduino IDE it can't get updated? Or are you saying that they get updated through Visual Studio?

                                    I hadn't used the IDE for several months. Thought I was a step closer to the problem and that it was bugs in older libraries.

                                    gohanG Offline
                                    gohanG Offline
                                    gohan
                                    Mod
                                    wrote on last edited by
                                    #22

                                    @raptorjr

                                    Visual Studio uses libraries from Arduino ide, so the only way to get updates is through the Arduino ide unless you install libraries manually. So it's a good thing to open Arduino ide every now and then if you want updates

                                    1 Reply Last reply
                                    0
                                    Reply
                                    • Reply as topic
                                    Log in to reply
                                    • Oldest to Newest
                                    • Newest to Oldest
                                    • Most Votes


                                    24

                                    Online

                                    11.7k

                                    Users

                                    11.2k

                                    Topics

                                    113.1k

                                    Posts


                                    Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                    • Login

                                    • Don't have an account? Register

                                    • Login or register to search.
                                    • First post
                                      Last post
                                    0
                                    • MySensors
                                    • OpenHardware.io
                                    • Categories
                                    • Recent
                                    • Tags
                                    • Popular