Giter Site home page Giter Site logo

temperature-monitor's Introduction

temperature-monitor

Indoor and outdoor temperature measurements on a 24h time period.

A project using thermistors for temperature sensing, arduino for data acquisition, memcached for short term-storage and mathplotlib for plotting temperature variations.

The circuit

Every second, arduino measures voltage across a voltage divider made of negative temperature coefficient thermistor (NTC) taken from a salvaged indoor/outdoor thermometer and a 5k6 resistor. (See diagram temperature_monitor_diagram.png in Samples directory).

The NTC and the resistor are connected in series, between the Arduino 5v reference voltage and the ground. A wire connected at the junction of the NTC and the resistor is also connected to an analog input of the arduino.

This circuit can be repeated to have more temperature sensors if desired. I chose to use two, one for indoor temperature, one for outdoor temperature.

The maths

NTCs have a non-linear temperature to resistance relationship, which can be modelized with a third order polynomial.

In order to figure out the coefficients of the polynomial, you have to measure the resistance of the NTC at different temperatures, using an ohmmeter, a freezer, some ice, water that you will heat and a reference thermometer. These are the readings I got. Yours will probably be different.

T(c)Rntc(Ko)
-18 48.8
-15 42
0 24
20 12.4
40 5.4
50 4
60 2.8
70 2.15
80 1.65
90 1.34
100 1.01

Now the resistance values are fine, but the arduino measures voltages, not resistances. You must convert the resistance readings in voltage values as seen by the arduino, applying Ohm's Law to a voltage divider network, where the output voltage measured across the series resistor is

Vo = Vref * (R /(Rntc+R))

where Vref is the reference voltage taken from the arduino (5 volts), Rntc is the measured resistance, and R is the series resistor (5.6Ko).

Using this formula, you can determine Vo for all Rntc values.

T(c)Rntc(Ko)Vo
-1848.8 0.51
-15420.59
0240.95
2012.41.56
405.42.55
5042.92
602.83.33
702.153.61
801.653.86
901.344.03
1001.014.24

The resistor is chosen in order to have a voltage range that is roughly linear in the target temperature range, and total resistance should be around 10k for optimal results with the arduino.

In my case, 5k6 gave the best results.

Using Vo as the independant variable and T as the dependant variable, we can now find a third order polynomial describing our system.

The polynomial that best fits this dataset is

T = 3.296v^3 -22.378v^2 +70.951v -49.382

(See diagram ntc_measurements_and_polynomial_regression.png in Samples directory).

You can find online polynomial regression tools to determine these coefficients at http://www.xuru.org/rt/pr.asp

Data acquisition

Every second, the arduino measures the voltages at one of the two analog inputs, and sends a temperature reading to the usb port, converting the voltage values in temperature values using the polynomial equation, and indicating which input was read.

Data storage

Saving the data every second does seem like overkill, but the readings vary slightly on every reading.

I chose to average the data sent on a one minute period, to get a less noisy measurement, and then save the averaged value in memory. I chose memcache as the data storage because the data does not require a long conservation time.

A one day period seems enough for reporting purposes. With two inputs and a measurement every minute, it requires to store 2880 measurements per day.

A longer period would probably use a database to store the potentially ever growing data.

Data structure

I chose to save the measurements in a stack-like structure. Every measurement is saved sequentially, with a new key indicating the measurement and a sequence number. Three infos have to be stored, the timestamp, the analog input number, and the temperature measurement.

Using a global counter, whose value is saved under a constant key, I can access to the last measurement, and all the ones before. The values expire after 24 hours.

Program workflow

Using memcache as the storage allows to divide the work between distinct programs, keeping them small and maintenable.

A single program is responsible to get the measurements from the arduino, compute the average temperature and store the value and timestamp in memcache. Only one instance of the storage program should be running.

A different program can then get the data from memcache and display it or use it for other purposes. There is no limit to the number of simultaneous programs for reading.

Commands available

  • tempstore: reads temperature readings from arduino and stores them to memcache
  • tempread: prints last readings on the console
  • templast: prints readings for the last 24 hours on the console
  • tempgraphsaver: saves last day readings as a graph in a png file. Add labels to readings on command line.
  • tempgraph: displays last readings as a graph in an interactive display

Customizing via environment variables

A few settings can be changed using environment variables:

  • ARDUINO_USB_PORT: The usb device to use to communicate with the arduino
  • ARDUINO_BAUD_RATE: The baud rate of the communication
  • ARDUINO_NUMBER_OF_INPUTS: The number of analog inputs to track (1 to 5)
  • GRAPHS_OUTPUT_DIRECTORY: a directory where to save the graphs
  • MEMCACHED_HOST = ip:port of the memcached used to store the readings
  • MEMCACHE_EXPIRATION_TIME: ttl in number of seconds of memcache entries
  • SAMPLE_PERIOD: number of seconds to average before storing in memcache
  • SAMPLE_WINDOW: number of readings to keep in the graph.

Installing

Requires memcached, python_memcached, pyserial and matplotlib.

tempgraph command requires matplotlib compiled with a tk backend.

git clone https://github.com/pchartrand/temperature-monitor.git

cd temperature-monitor

System-wide installation

sudo pip install .

Virtualenv installation

pip install .

Uninstall

pip uninstall temperature-monitor

Usage example

A setup with 5 ntc for outside, basement, ground floor, second floor and attic temperatures.

The temperatures are displayed on a lcd display shield atop of the arduino.

The shield illuminates when it's bushbuttons are pressed and gives readings in Celsius, Farenheit, Volts or 0-1023 range.

The temperature readings are stored in a memcached instance of a raspberrypi housed in the same box.

The raspberrypy readings are accessible on the local network thru memcached using the same library.

temperature-monitor's People

Contributors

pchartrand avatar

Watchers

 avatar James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.