Temperature serial sketch



  • Hi all,

    I'm not sure where to start this, Ill give a quick simple description of my setup.
    I have an pi4 running with domoticz as thermostat primarily.
    First I had 4x DS18B20 temperature sensors hooked up to gpio4 on the pi without the resistor, this worked fine for some time till this gave some issues, I figured out quickly what went wrong here, so I hooked those sensors up to an arduino mega 2560. After some playing around and not getting the results in to domoticz like i would like to I was pointed to MySensors and use the serial sketch, I added some lines from an DS18B20 sketch in there and uploaded this.. straight away this worked awesome!

    Till last night where it all came to an hold, the temperature data was not updating any more to domoticz and this just kept going. resulting in a kitchen floor of about 60°c

    My question, can someone check for me if the scetch I'm running is any good or does it have any flaws? I'm totally not in to programming and I'm just getting slowly in to this.
    My sketch:

    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable RS485 transport layer
    #define MY_RS485
    
    // Define this to enables DE-pin management on defined pin
    #define MY_RS485_DE_PIN 7
    
    // Set RS485 baud rate to use
    #define MY_RS485_BAUD_RATE 9600
    
    // Enable this if RS485 is connected to a hardware serial port
    //#define MY_RS485_HWSERIAL Serial1
    
    // Enable serial gateway
    #define MY_GATEWAY_SERIAL
    
    
    // Enable inclusion mode
    #define MY_INCLUSION_MODE_FEATURE
    // Enable Inclusion mode button on gateway
    #define MY_INCLUSION_BUTTON_FEATURE
    // Set inclusion mode duration (in seconds)
    #define MY_INCLUSION_MODE_DURATION 60
    // Digital pin used for inclusion mode button
    #define MY_INCLUSION_MODE_BUTTON_PIN  3
    
    // Set blinking period
    #define MY_DEFAULT_LED_BLINK_PERIOD 300
    
    // Flash leds on rx/tx/err
    #define MY_DEFAULT_ERR_LED_PIN 4  // Error led pin
    #define MY_DEFAULT_RX_LED_PIN  5  // Receive led pin
    #define MY_DEFAULT_TX_LED_PIN  6  // the PCB, on board LED
    
    #include <MySensors.h>
    #include <OneWire.h>
    #include <DallasTemperature.h>
    
    #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
    
    #define ONE_WIRE_BUS 2 // Pin where dallase sensor is connected 
    #define MAX_ATTACHED_DS18B20 16
    
    unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
    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. 
    float lastTemperature[MAX_ATTACHED_DS18B20];
    int numSensors=0;
    bool receivedConfig = false;
    bool metric = true;
    // Initialize temperature message
    MyMessage msg(0,V_TEMP);
    
    void before()
    {
      // Startup up the OneWire library
      sensors.begin();
    }
    
    void setup()  
    { 
      // requestTemperatures() will not block current thread
      sensors.setWaitForConversion(false);
      
    }
    
    void presentation() {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Temp Sensor", "1");
    
      // Fetch the number of attached temperature sensors  
      numSensors = sensors.getDeviceCount();
    
      // Present all sensors to controller
      for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
         present(i, S_TEMP);
      }
    }
    
    void loop()  
    {     
      // Fetch temperatures from Dallas sensors
      sensors.requestTemperatures();
    
      // query conversion time and sleep until conversion completed
      int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
      // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
      //sleep(conversionTime);
      wait(conversionTime);
    
      // Read temperatures and send them to controller 
      for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
    
        // Fetch and round temperature to one decimal
        float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
    
        // Only send data if temperature has changed and no error
        #if COMPARE_TEMP == 1
        if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
        #else
        if (temperature != -127.00 && temperature != 85.00) {
        #endif
    
          // Send in the new temperature
          send(msg.setSensor(i).set(temperature,1));
          // Save new temperatures for next compare
          lastTemperature[i]=temperature;
    
        }
      }
    }
    
    

    Thanks in advance Olaf,


  • Mod

    @Olaf-Jacobs you seem to configure the gateway for rs485 transport, but I understand you don't have nodes at all, only the gateway. It's this correct?
    You also loop over all possible sensors in the main loop, not the actual mount detected. Not sure if that's OK...



  • @Yveaux
    Correct I have no nodes in use, I only use this to get the data in to domoticz (what seems to work a bit)
    For looping trough sensors, I have no clou. To be honest I just get the Mysensor bit from the arduino examples and found some DS18B20 sketch and tried to combine this in to an single working sketch, as soon as i had no compiling errors I uploaded it and see that I had some working sensors added to my Domoticz.


  • Mod

    @Olaf-Jacobs I cleaned your sketch a little, and changed the DS18B20 code to more or less reflect the way I read these sensors in some of my nodes:

    #include <Arduino.h>
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable serial gateway
    #define MY_GATEWAY_SERIAL
    
    #include <MySensors.h>
    #include <OneWire.h>
    #include <DallasTemperature.h>
    
    #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
    
    #define ONE_WIRE_BUS 2 // Pin where dallase sensor is connected 
    #define MAX_ATTACHED_DS18B20 16
    
    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. 
    float lastTemperature[MAX_ATTACHED_DS18B20];
    int numSensors = 0;
    
    // Initialize temperature message
    MyMessage msg(0,V_TEMP);
    int16_t conversion_wait_time_ms;
    
    void presentation()
    {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo(F("Temp Sensor"), F("1"));
    
      // Startup up the OneWire library
      sensors.begin();
    
      // Fetch the number of attached temperature sensors  
      numSensors = min(sensors.getDeviceCount(), MAX_ATTACHED_DS18B20);
    
      // requestTemperatures() will not block current thread
      sensors.setWaitForConversion(false);
      sensors.setCheckForConversion(false);
      conversion_wait_time_ms = sensors.millisToWaitForConversion( sensors.getResolution() );
    
      // Present all sensors to controller
      for (int i=0; i<numSensors; i++) {   
         present(i, S_TEMP);
      }
    }
    
    void setup()  
    { 
    }
    
    void loop()  
    {     
      // Fetch temperatures from Dallas sensors
      sensors.requestTemperatures();
    
      // sleep until conversion completed
      wait(conversion_wait_time_ms);
    
      // Read temperatures and send them to controller 
      for (int i=0; i<numSensors; i++) {
    
        // Fetch and round temperature to one decimal
        float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
    
        // Only send data if temperature has changed and no error
    #if COMPARE_TEMP == 1
        if (lastTemperature[i] != temperature)
    #endif
        {
          if ((temperature > -127.) and (temperature < 85.))
          {
            // Send in the new temperature
            send(msg.setSensor(i).set(temperature,1));
          }
          // Save new temperatures for next compare
          lastTemperature[i]=temperature;
        }
      }
    }
    

    Main changes:

    • Removed the RS485 transport and any stuff you don't use/need (inclusion mode, leds, unused variables)
    • Removed before, as all initialization can be done in presentation()
    • Added setCheckForConversion() as my sketches do so too
    • Store the conversion time in a variable as it won't change at runtime. This silences the bus communication during conversion.
    • Removed the check for maximum sensors from the loops (I missed the check for numSensors in my first comment) and also calculate it only once, as these will also not change at runtime.
    • Cleaned the COMPARE_TEMP a bit and added a range check on min/max temperatures -- checking for exact floating point values is tricky, so better just check if they are in range

    Disclaimer: It compiles, but I didn't check it for correct functioning.

    All in all I didn't see any obvious reasons for a freeze in your sketch.
    If it runs ok for a while and then freezes, there could be other issues like power supply or faulty sensors.
    Capture the gateway output over time to see what happened just before the freeze.

    In any case you should always protect against missing or wrong updates!



  • @Yveaux

    Wow I didn't expect this haha but thanks a lot. Ill give this a try and give some feedback as soon as I have some steady results.

    Dank u.
    Regards Olaf.



  • Quick update,

    within 24hr the system already stopped it self, in my domoticz log is no error about this. If I read the arduino it shows me nothing in the serial.
    I just restart the whole system and all is back online working just like nothing happend, I did had an close look at all four sensors but all for seems to be working fine till the arduino freezes up.
    Is there a way of having an debug log?

    Cheers/thanks



  • @Olaf-Jacobs I've run DS18B20s and learned that with "1-wire" the wiring details and are important unless wire runs are short. Also, parasitic mode (2 wires only) is less stable than using three wires. The type of wire, capacitance of the cable run, interference from nearby electrical, especially high voltage AC, and the topology (with star topology being the worst). I have no idea if this could be an issue for you, but if you want to test it you could try testing with the same number of sensors with very short runs and see if that improves the instability you are seeing.



  • @Olaf-Jacobs DS18B20s are usually reliable, but seconded on the comment from @Grubstake regarding cable type and topography for reliability, although generally if working at the start it should continue uninterrupted.
    To illustrate the point, all of mine are connected to a Node rather than a Gateway on a single line of Cat5e for the house, and a short length of phone wire for two on the boiler. A random weird reading on all the house sensors (not simultaneously) turned up when I'd extended the last sensor on the Cat5E with a length of phone wire until I got some more Cat5E. Uniform cable characteristics seem important.

    You might also check the Arduino version and libraries being used, have seen strange things happen with mismatched libraries etc..



  • @Olaf-Jacobs said in Temperature serial sketch:

    First I had 4x DS18B20 temperature sensors hooked up to gpio4 on the pi without the resistor, this worked fine for some time till this gave some issues

    Can you write what issues.
    Why you connect DS18B20s to RPi without resistor ?
    Is it some experiment?



  • Hi all,
    First of all I wish all an happy and healthy new year!
    @Grubstake @zboblamont sensors hooked up only one is extended with 1,5mtr of cat5 cable. This seems to be working fine, although this is probably also the sensor that gives issues. The temperature it's measuring i from an woodstove in the kitchen and I'm not constantly using this stove and the temperature is pretty much stationary @20° so I think the system times out on this sensor because there are hardly any changes.

    Sins the last failure what I reported here also the system is running fine/perfect without any interrupts, I do had my Pi4 freeze up couldn't do any else then rebooting the system.

    But to make it some how workable for me I have the Pi system switching between the thermostat I'm using in Domoticz, when this goes in to any failure mode it goes in to pause and the good old honeywel is backing up the system just a couple degrees set below te regular set-point. Due to be living alone here in the middle of nowhere and working sometimes several days from home I have installed an secondary Pi in the network so I can always remotely access the system and cut the power off and reboot that way.

    But fingers crossed the arduino with the four sensors is working top!

    @kimot
    No this was done by mistake, 🤦 I have an replacment Pi ready to go but as long as the system is working fine I don't want to touch it.



  • @Olaf-Jacobs Good.
    I did read short spurs CAN work and the waterproof versions are on pre-made cables, but not sure of the limit.
    If you hit occasional problems it may be worth trying cross wiring the Cat5e to maintain a series connection and see if that fixes it, that's what I did to stitch in an intermediate sensor and it worked fine.
    Good luck.



  • Pull up resistors might help if not already in place. Also fake ds18b20's have been found being sold so maybe get a good one from a reliable source and try again if more problems occur.



  • @skywatch
    I do have the resistor in place now, like mentioned it works and still works.👍


Log in to reply
 

Suggested Topics

17
Online

11.4k
Users

11.1k
Topics

112.7k
Posts