Video How To - Monitor your Refrigerator


  • Admin

    2016-12-31 Edit: Updated code to MySensors Version 2.1 and added LEDs for door status (optional).

    Recently we have been having problems with our refrigerator door not fully closing. Usually it's a result of something not pushed fully in and it stops the door from closing. Our fridge is old and doesn't have any built in alarms so I thought I'd "MySensorize" it so we get alerts if the door says open. I also added some Dallas Temp sensors to monitor the temperature. Nothing to advanced or sophisticated but it gets the job done.

    Refrigerator Monitoring with Arduino and MySensors – 09:23
    — Pete B

    Fritzing Fridge Monitoring Wiring

    Parts List

    Here is the code to find your Dallas Temp Sensor addresses. I chose to find the addresses and program them in based on recommendations from the DS18B20 datasheet. You could change the Refrigerator Monitoring code to have it automatically find them each time the device is powered up if you prefer.

    #include <OneWire.h>
    #include <DallasTemperature.h>
    
    // Data wire is plugged into port 2 on the Arduino
    #define ONE_WIRE_BUS 3 //Pin where Dallas sensor is connected
    
    // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
    OneWire oneWire(ONE_WIRE_BUS);
    
    // Pass our oneWire reference to Dallas Temperature.
    DallasTemperature dallasTemp(&oneWire);
    
    // arrays to hold device addresses
    DeviceAddress tempAddress[7];
    
    void setup(void)
    {
      // start serial port
      Serial.begin(115200);
    
      // Start up the library
      dallasTemp.begin();
    
      // show the addresses we found on the bus
      for (uint8_t i = 0; i < dallasTemp.getDeviceCount(); i++) {
        if (!dallasTemp.getAddress(tempAddress[i], i))
        {
          Serial.print("Unable to find address for Device ");
          Serial.println(i);
          Serial.println();
        }
        Serial.print("Device ");
        Serial.print(i);
        Serial.print(" Address: ");
        printAddress(tempAddress[i]);
        Serial.println();
      }
    }
    
    void printAddress(DeviceAddress deviceAddress)
    {
      for (uint8_t i = 0; i < 8; i++)
      {
        // zero pad the address if necessary
        //if (deviceAddress[i] < 16) Serial.print("0");
        Serial.print("0x");
        Serial.print(deviceAddress[i], HEX);
        if (i < 7) {
          Serial.print(", ");
        }
      }
    }
    
    
    void loop(void)
    {
    
    }
    

    And here is the code for the Fridge monitoring

    /*
       The MySensors Arduino library handles the wireless radio link and protocol
       between your home built sensors/actuators and HA controller of choice.
       The sensors forms a self healing radio network with optional repeaters. Each
       repeater and gateway builds a routing tables in EEPROM which keeps track of the
       network topology allowing messages to be routed to nodes.
    
       Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
       Copyright (C) 2013-2015 Sensnology AB
       Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
    
       Documentation: http://www.mysensors.org
       Support Forum: http://forum.mysensors.org
    
       This program is free software; you can redistribute it and/or
       modify it under the terms of the GNU General Public License
       version 2 as published by the Free Software Foundation.
    
     *******************************
    
       REVISION HISTORY
       Version 1.0 - PeteWill
       2016-12-29 Version 1.1 - PeteWill Updated to MySensors 2.1 and added status LEDs for the doors
    
       DESCRIPTION
       This sketch is used to monitor your refrigerator temperature and door states.
       You will need to find the addresses for your Dallas temp sensors and change them in the dallasAddresses array
    
       Watch the How To video here: https://youtu.be/2vAYAbtQfjs
    */
    
    
    //#include <SPI.h>
    #include <DallasTemperature.h>
    #include <OneWire.h>
    #include <Bounce2.h>
    
    
    //MySensors configuration options
    //#define MY_DEBUG //Uncomment to enable MySensors related debug messages (additional debug options  are below)
    #define MY_RADIO_NRF24 // Enable and select radio type attached
    //#define MY_NODE_ID 1  //Manually set the node ID here. Comment out to auto assign
    #include <MySensors.h>
    
    #define SKETCH_NAME "Refrigerator Monitor"
    #define SKETCH_VERSION "1.1"
    
    #define DWELL_TIME 70 //value used in all wait calls (in milliseconds) this allows for radio to come back to power after a transmission, ideally 0
    
    
    #define ONE_WIRE_BUS 3 // Pin where dallas sensors are connected 
    #define TEMPERATURE_PRECISION 12  //The resolution of the sensor
    
    OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
    DallasTemperature dallasTemp(&oneWire); // Pass our oneWire reference to Dallas Temperature.
    
    //MySensor gw;
    unsigned long tempDelay = 425000;
    float lastTemperature[2];
    unsigned long tempMillis;
    bool metric = false;
    
    // arrays to hold device addresses
    DeviceAddress dallasAddresses[] = {
      {0x28, 0xD0, 0xD3, 0x41, 0x7, 0x0, 0x0, 0xDF}, //Freezer Address -- Modify for your sensors
      {0x28, 0xFF, 0x22, 0xA0, 0x68, 0x14, 0x3, 0x2F} //Fridge Address -- Modify for your sensors
    };
    
    //Set up debouncer (used for door sensors)
    Bounce debouncer[] = {
      Bounce(),
      Bounce()
    };
    
    //Make sure to match the order of doorPins to doorChildren.
    //The pins on your Arduino
    int doorPins[] = {4, 5};
    //The child ID that will be sent to your controller
    int doorChildren[] = {2, 3};
    //Freezer temp will be Child 0 and Fridge temp will be Child 1
    
    //used to keep track of previous values contact sensor values
    uint8_t oldValueContact[] = {1, 1};
    
    uint8_t doorLedPins[] = {6, 7};
    
    // Initialize temperature message
    MyMessage dallasMsg(0, V_TEMP);
    MyMessage doorMsg(0, V_TRIPPED);
    
    void presentation()  
    { 
      // Send the sketch version information to the gateway
      sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
      
      // Register all sensors to gw (they will be created as child devices)
      // Present temp sensors to controller
      for (uint8_t i = 0; i < 2; i++) {
        present(i, S_TEMP);
        wait(DWELL_TIME);
      }
      // Present door sensors to controller
      for (uint8_t i = 0; i < 2; i++) {
        present(doorChildren[i], S_DOOR);
        wait(DWELL_TIME);
      }
    }
    
    void setup()
    {
      // Startup OneWire
      dallasTemp.begin();
    
      // set the temp resolution
      for (uint8_t i = 0; i < 2; i++) {
        dallasTemp.setResolution(dallasAddresses[i], TEMPERATURE_PRECISION);
      }
    
    //  // Startup and initialize MySensors library. Set callback for incoming messages.
    //  gw.begin(NULL, NODE_ID);
    //
    //  // Send the sketch version information to the gateway and Controller
    //  gw.sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
    
      //Set up door contacts & LEDs
      for (uint8_t i = 0; i < 2; i++) {
    
        // Setup the pins & activate internal pull-up
        pinMode(doorPins[i], INPUT_PULLUP);
    
        // Activate internal pull-up
        //digitalWrite(doorPins[i], HIGH);
    
        // After setting up the button, setup debouncer
        debouncer[i].attach(doorPins[i]);
        debouncer[i].interval(700); //This is set fairly high because when my door was shut hard it caused the other door to bounce slightly and trigger open.
    
        //Set up LEDs
        pinMode(doorLedPins[i], OUTPUT);
        digitalWrite(doorLedPins[i], LOW);
      }
    
    
    }
    
    
    void loop()
    {
      unsigned long currentMillis = millis();
    
      if (currentMillis - tempMillis > tempDelay) {
        // Fetch temperatures from Dallas sensors
        dallasTemp.requestTemperatures();
    
        // Read temperatures and send them to controller
        for (uint8_t i = 0; i < 2; i++) {
    
          // Fetch and round temperature to one decimal
          float temperature = static_cast<float>(static_cast<int>((metric ? dallasTemp.getTempC(dallasAddresses[i]) : dallasTemp.getTempF(dallasAddresses[i])) * 10.)) / 10.;
          // Only send data if temperature has changed and no error
          if (lastTemperature[i] != temperature && temperature != -127.00) {
    
            // Send in the new temperature
            send(dallasMsg.setSensor(i).set(temperature, 1));
            lastTemperature[i] = temperature;
          }
        }
        tempMillis = currentMillis;
      }
    
      for (uint8_t i = 0; i < 2; i++) {
        debouncer[i].update();
        // Get the update value
        uint8_t value = debouncer[i].read();
        if (value != oldValueContact[i]) {
          // Send in the new value
          send(doorMsg.setSensor(doorChildren[i]).set(value == HIGH ? "1" : "0"));
          digitalWrite(doorLedPins[i], value);
          oldValueContact[i] = value;
        }
      }
    
    }
    
    
    

  • Mod

    @petewill Again, another classic! πŸ‘
    Thanks for the project!



  • @petewill every 425 seconds your door sensors will be blind up to 750 ms because of you using blocking call to dallasTemp.requestTemperatures(). It is very unlikely that this will happen, but it can be πŸ™‚ Safer way is to use non-blocking access to dallas sensors: https://github.com/mysensors/Arduino/blob/master/libraries/MySensors/examples/DallasTemperatureSensor/DallasTemperatureSensor.ino


  • Admin

    @robosensor Cool, thanks for pointing that out. I'll check it out!



  • Another nice project, you to also put in a check for millis() rolling over to zero otherwise in about 50 days the temperature will no longer be updated as the current millis() will be less then your temp stored last time check.


  • Mod

    @lagore said:

    put in a check for millis() rolling over to zero

    Wrong, not required. Pete's code is essentially:

      unsigned long tempMillis;
      unsigned long currentMillis = millis();
    
      if (currentMillis - tempMillis > tempDelay) {
        // .. do something..
        tempMillis = currentMillis;
      }
    

    Substracting two unsigned type values will return the modulo of the maximum value of that type, e.g.:

    #include <iostream>
    using namespace std;
    
    int main() {
    	unsigned long a = 0xFFFFFF10;
    	unsigned long b = 0x00000010;
    	cout << b - a << endl;
    	return 0;
    }
    

    Will print 256. Pete will be safe when the millis() counter wraps.

    Try it here if you don't believe it πŸ˜„



  • Nice project! I particularly like the switch you designed. Very simple and yet functional.
    Do you have a video/instruction on how to set up the phone app part of this project. I'm new to MySensors but have been looking for a way to monitor/control sensors from my iPhone for quite some time without success.
    Thanks.
    B


  • Admin

    @bruster999 said:

    Do you have a video/instruction on how to set up the phone app part of this project. I'm new to MySensors but have been looking for a way to monitor/control sensors from my iPhone for quite some time without success.

    The app is actually part of Vera (my home automation controller). What controller are you using?



  • Well done, thanks Pete!

    The freezer actually was one of my reasons for starting with the homeautomation stuff: Left the door open twice and was literally "fed up" with having to eat all the stuff πŸ™‚

    But guess which project I haven't finished yet. Yeah, You've got it ...

    One thing I realized with the tests I've done so far: even the small wires I've used for
    the internal temperature sensors will keep the silicone isolation in the door frame from sealing off the freezer. So after some time there's always some condensation around the entry point of the wires which can't be good. Something I'll have to look into yet. And I still haven't quite reached the cellar with my MySensors network (maximum distance, 2 and a half floors below) πŸ™‚

    Christoph


  • Admin

    @hyla Thankfully our freezer wasn't left open that long but it was long enough to warrant a sensor πŸ™‚

    I have had my internal temp sensors installed for over a month and haven't had any condensation yet. Maybe I just had lucky placement of the wires? I used the wires from a usb cable (I actually cut it off a broken computer mouse). They are incredibly thin. Maybe you can try that?

    As for the distance, can you place a relay (repeater) node somewhere in the middle? http://www.mysensors.org/download/sensor_api_15#create-repeating-nodes



  • Thanks for a nice project.
    I am trying this but I always get Fahrenheit temperatuers in Domoticz.
    I have change this line in the code.

    From
    boolean metric = false;

    To
    boolean metric = true;

    Something else I should do?


  • Mod

    That should be enough. What value does the gatway log say it received from the sensor?



  • Thank you for one more interesting solution. Just want to suggest useful thing which might be more simple and durable as contact pair. I mean "Switch Reed" http://www.ebay.com/itm/1PC-Recessed-Magnetic-Window-Door-Contact-Security-Safety-Alarm-Switch-Reed-/310770552546?hash=item485b5e4ee2:g:eGcAAOSwNSxU2BfU

    Best regards!


  • Admin

    @Igor The reason I didn't use these is because most of the time my fridge door would stay open just slightly but enough that a reed switch would still register it as closed. Normally I like to use reed switches though.



  • A nice project.

    I had a similar problem with a freezer located in the garage.

    As I already had other temperature sensors and an energy meter running there (based on MySensors stuff) I just added one of these waterproof DS18B to the setup, drilled a hole through the fridge wall and stuck it in.

    I use OpenHab and can see the temperature on any browser or at the cell phone client. OpenHab also emails me when temperature raises above a certain temperature.

    Not as sophisticated as your solution but it works πŸ™‚



  • I have now solved this problem with Fahrenheit instead of Celcius.

    I had to change to this --->
    float temperature = static_cast<float>(static_cast<int>((dallasTemp.getTempCByIndex(i)) * 10.)) / 10.;

    From this --->
    float temperature = static_cast<float>(static_cast<int>((gw.getConfig().isMetric ? dallasTemp.getTempC(dallasAddresses[i]) : dallasTemp.getTempF(dallasAddresses[i])) * 10.)) / 10.;

    Now it gives me celcius.
    Thanks for nice example.


  • Admin

    @mbj Cool, thanks for sharing. I'd love to check out OpenHAB some day.

    @sneaksneak Interesting. I wonder why you had to do that...? Oh well, glad it's working for you now!



  • When I arrived at work today and started checking mails, I had received a bunch of them saying that the temperature in the fridge was too high, so I had to drive home and close the door. I would have gotten a notification earlier through jabber if the server software we use for jabber wasn't acting up :(.
    MySensors stuff was not involved in that particular sensor (esic sensor + tellstick + perl + perl), but the need to monitor this stuff was definitely there.


  • Admin

    @Stric Dang. Glad you caught it in time! The need to monitor is definitely real. I also want to get my house outfitted with leak detectors at some point...



  • I'm sorry to ask a seemingly dumb question, but what do I need to do to get a third Dallas sensor to work? (I have a top/bottom fridge and a deep freezer).
    I edited the following lines:
    DeviceAddress dallasAddresses[] = {
    {0x28, 0x29, 0x4F, 0x1, 0x0, 0x0, 0x80, 0xBB}, //Freezer Address -- Modify for your sensors
    {0x28, 0x22, 0x53, 0x1, 0x0, 0x0, 0x80, 0x1E}, //Fridge Address -- Modify for your sensors
    ** {0x28, 0xA6, 0x58, 0x1, 0x0, 0x0, 0x80, 0x58} //Deep Freezer I added**

    // set the temp resolution
    for (uint8_t i = 0; i < 3; i++) { //i changed from 2

    // Present temp sensors to controller
    ** for (int i = 0; i < 3; i++) { // i changed from 2**
    gw.present(i, S_TEMP);

    // Read temperatures and send them to controller
    ** for (int i = 0; i < 3; i++) { //i changed from 2**

    I'm not sure what I'm missing. Thank you in advance for your help and great project!!!



  • @Krieghund
    Ok, I think I found it. I needed to have the door sensors start at a higher ID:

    int doorChildren[] = {3, 4}; //i changed from 2,3

    Thank you


  • Admin

    @Krieghund Glad you found it! Sorry, I couldn't respond sooner.



  • any chance this has been updated to 2.0? I am having issues getting the internal pull up for the temp sensors working.


  • Admin

    @Jason-Brunk Sorry for the delay. What's the problem? I don't think that would be related to v2.0 but I could be wrong. Have you tried an external resistor?



  • my 4.7k resistors showed up today. So i will try with the external.

    I have been able to get basic arduino sketches to work with the internal pull up and the temp sensor. but as soon as I put mysensors on it, it doesn't pick it up any more. That's why i figured i would see if you updated your sketch to 2 without the need for the external


  • Admin

    @Jason-Brunk Interesting. I haven't updated it yet. I need to get a spare weekend to make the jump to 2.0 but I don't know when that will be. I have so many sensors in my house it will take me a while to get everything up to date.



  • I can only imagine. I have seen your youtube channel. jealous



  • This is my first sensor so be nice if I'm missing something obvious. πŸ˜„

    Your sketch has #include <MySensor.h>

    In the mysensors library it is MySensors.h with an s

    If I change it to #include <MySensors.h> with the s then on the line with MySensor gw; I get the error: 'MySensor' does not have a name type.

    I'm trying to figure out how everything works together but can't figure this out.

    For reference, my programming background consists of an 8th grade computer class where we learned to make something go from one side of the monitor to the other and yes, it was all green.



  • @TXSpazz This difference depends on what version you are using. For version 2 it is Mysensors.h . Earlier versions used Mysensor.h.



  • @mbj Thank you, I was wondering if that was it. I started trying to convert it but since I haven't slept in 23 hours it made my brains hurt, but at least I know what direction to go now.


  • Admin

    @TXSpazz Yeah, @mbj is right, it needs to be updated to v2.0. Still haven't had a chance to do it yet 😬



  • Hello,

    Great work. I've watched almost all your videos. Very instructive.

    One thing I am wondering about are the gray connectors 'knob like' to quickly wire your cables together. What are they? Where can I buy me some? :bowtie:


  • Admin



  • Yes. those! thank you



  • HI

    Do you think you can use the PT1000 two wire temp sensor for this project? I have a number of them and they are water proof and very durable.



  • @Newzwaver If you Google on this subject you will find threads like this one which may help you understand the issue: http://forum.arduino.cc/index.php?topic=16731.0

    Basically I think the answer is that if you already have the electronics to read the signal from the PT1000 and can communicate that to a Mysensors sensor it should be fairly easy. If you have to build it all by yourself it is a bit more work to do like the thread above shows.

    On the other hand, buying a few DS18B20 is dirt cheap and and then everything you need is already available. They come in waterproof versions as well if you feel you need this. One example from Ebay is http://www.ebay.com/itm/NEW-Waterproof-Digital-Thermal-Probe-or-Sensor-DS18B20-Length-1M-/172243763999?hash=item281a87431f:g:Lj8AAOSw3YNXYu7h



  • Hi
    And thanks for the reply, I do have the PT1000 as well as those sensors. The only thing is I am trying to find a use for the PT1000. I have already placed one in my deep freeze and one out door but have several more that I just want to use. It's not the cost as most of the projects on this are cheap, it's the challenge of getting it done.

    Thanks again, I


 

452
Online

7.9k
Users

8.8k
Topics

94.3k
Posts