Skip to content

Arduino Clone Home Temperature Sensor

  • by

TempuratureSensor

Living in the great north, the winter cold always presents interesting challenges. A common fear is that your furnace will happen to give out while your away, then your pipes will freeze and burst, transforming your house into an indoor water park. Way back when, in the days of land line telephones, then made little devices that would watch the temp and give you a call if the temperature in your house fell too low. While I could have probably picked up something like that cheap, it wouldn’t have done much good since I don’t have a telephone line in my house. However, I saw it as a good opportunity to exercise my micro-controller skills with my a very simple internet based temperature sensor. While I had played with controllers before, I had never done much beyond blinking lights on a Of course, because I like to dive into things head first, I decided to layout my own custom board for the project. While I was at it, I though it would be a good time to learn SMD soldering as well.

The design is pretty simple, mostly just a combination of the Arduino board and an Ethernet shield. So an Atmega328 with a Wiznet 5100 Ethernet chip. For the temperature sensor, I went with the DS18B20. I had originally put a barrel jack, and the 3.3 and 5 volt regulators in the layout, but since I included the FTDI USB/Serial chip, that actually provides 5v and 3.3v rails from the USB. That way I could just use a cheap used micro USB phone charger for the power supply. I decided to put the Arduino headers in the layout as well, I’m not sure why since it just made routing the board more complicated, but I figured that way I could re-purpose it if needed. I think the rest of the passive parts I ordered from Digi-Key. If you are afraid of working with SMD parts like I was, just watch this, http://www.youtube.com/watch?v=b9FC9fAlfQE. Dave’s lesson is pretty good, and I was able to put my board together with just my 30W Radio Shack iron.

TempSense

Here is the Eagle files for the design. Two things about this design, first I’m not entirely sure about the regulator setup with the barrel jack. I built two boards, on the first one I populated those spots, and the rails seemed to be the right voltage, but the Ethernet never worked on that first board after I tried plugging a supply into the barrel jack. So I left those parts off the second board. Two, the board layout itself is terrible. I mean it works, and I’m no expert on board layout, but it just looks ugly to me looking back on this projects now. The one for sure issue I had was that I forgot to put the 4.7K pullup resistor on the sensors data pin (its missing from the linked files). That’s important, and it doesn’t work without it. However its was really easy just to drop it in between the pins on the back side of the board.

The coding for this was very simple. Usually, the biggest issue with devices like this, is how to access your data over the internet. Without a static IP address or dynamic DNS service, the best way to go is to send your data to a server. I decided to use a free service, Cosm (which is now Xively). The coding was done in the Arduino IDE and was literally just a combination of the DS18B20 example and the Cosm example code. Note in the below code I took out my API key and Feed number.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/**
 * Cosm Arduino sensor client example.
 *
 * This sketch demonstrates connecting an Arduino to Cosm (https://cosm.com),
 * using the new Arduino library to send and receive data.
 *
 * Requirements
 *   * Arduino with Ethernet shield or Arduino Ethernet (board must use the
 *     Wiznet Ethernet chipset)
 *   * Arduino software with version >= 1.0
 *   * An account at Cosm (https://cosm.com)
 *
 * Optional
 *   * An analog sensor connected to pin 2 (note we can still read a value from
 *     the pin without this)
 *
 * Created 8th January, 2013 using code written by Adrian McEwen with
 * modifications by Sam Mulube
 *
 * Full tutorial available here: https://cosm.com/docs/quickstart/arduino.html
 *
 * This code is in the public domain.
 */
 
#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Cosm.h>
#include <OneWire.h>
 
 
#define API_KEY "" // your Cosm API key
#define FEED_ID 0 // your Cosm feed ID
 
 
int DS18S20_Pin = 2; //DS18S20 Signal pin on digital 2
 
//Temperature chip i/o
OneWire ds(DS18S20_Pin); // on digital pin 2
 
 
// MAC address for your Ethernet shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
 
unsigned long lastConnectionTime = 0;                // last time we connected to Cosm
const unsigned long connectionInterval = 15000;      // delay between connecting to Cosm in milliseconds
 
// Initialize the Cosm library
 
// Define the string for our datastream ID
char sensorId[] = "home_temp";
 
CosmDatastream datastreams[] = {
  CosmDatastream(sensorId, strlen(sensorId), DATASTREAM_FLOAT),
};
 
// Wrap the datastream into a feed
CosmFeed feed(FEED_ID, datastreams, 1 /* number of datastreams */);
 
EthernetClient client;
CosmClient cosmclient(client);
 
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
 
  Serial.println("Cosm Sensor Client Example");
  Serial.println("==========================");
 
  Serial.println("Initializing network");
  while (Ethernet.begin(mac) != 1) {
    Serial.println("Error getting IP address via DHCP, trying again...");
    delay(15000);
  }
 
  Serial.println("Network initialized");
  Serial.println();
}
 
void loop() {
  // main program loop
  if (millis() - lastConnectionTime > connectionInterval) {
    // read a value from the pin
    float sensorValue = getTemp();
    // send it to Cosm
    sendData(sensorValue);
    // read the datastream back from Cosm
    getData();
    // update connection time so we wait before connecting again
    lastConnectionTime = millis();
  }
}
 
// send the supplied value to Cosm, printing some debug information as we go
void sendData(float sensorValue) {
  datastreams[0].setFloat(sensorValue);
 
  Serial.print("Read sensor value ");
  Serial.println(datastreams[0].getFloat());
 
  Serial.println("Uploading to Cosm");
  int ret = cosmclient.put(feed, API_KEY);
  Serial.print("PUT return code: ");
  Serial.println(ret);
 
  Serial.println();
}
 
// get the value of the datastream from Cosm, printing out the value we received
void getData() {
  Serial.println("Reading data from Cosm");
 
  int ret = cosmclient.get(feed, API_KEY);
  Serial.print("GET return code: ");
  Serial.println(ret);
 
  if (ret > 0) {
    Serial.print("Datastream is: ");
    Serial.println(feed[0]);
 
    Serial.print("Sensor value is: ");
    Serial.println(feed[0].getFloat());
  }
 
  Serial.println();
}
 
float getTemp(){
 //returns the temperature from one DS18S20 in DEG Celsius
 
 byte data[12];
 byte addr[8];
 
 if ( !ds.search(addr)) {
   //no more sensors on chain, reset search
   ds.reset_search();
   return -1000;
 }
 
 if ( OneWire::crc8( addr, 7) != addr[7]) {
   Serial.println("CRC is not valid!");
   return -1000;
 }
 
 if ( addr[0] != 0x10 && addr[0] != 0x28) {
   Serial.print("Device is not recognized");
   return -1000;
 }
 
 ds.reset();
 ds.select(addr);
 ds.write(0x44,1); // start conversion, with parasite power on at the end
 
 byte present = ds.reset();
 ds.select(addr); 
 ds.write(0xBE); // Read Scratchpad
 
  
 for (int i = 0; i < 9; i++) { // we need 9 bytes
  data[i] = ds.read();
 }
  
 ds.reset_search();
  
 byte MSB = data[1];
 byte LSB = data[0];
 
 float tempRead = ((MSB << 8) | LSB); //using two's compliment
 float TemperatureSum = tempRead / 16;
 //convert to farenheit
 TemperatureSum = ((9.0/5.0) * TemperatureSum) + 32;
 return TemperatureSum;
  
}

And that’s pretty much it. I can watch my house temp wherever I am. https://xively.com/feeds/100416. Since Cosm changed to Xively, I’m not sure what their current pricing scheme is, but the public feed is still free on my current account.

Leave a Reply

Your email address will not be published. Required fields are marked *

 characters available