These are slightly more expensive than analogue sensors, but they are pre-calibrated and in my opinion much nicer to use.
I bought a pack of 10 from China for under US$9 which is amazing value compared to local options.
Using the simple, but extremely useful details at http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html I was up and running in no time at all. This site appealed over others as it specifically tells you how to identify each DS18b20 you have on your network, and get it's address - something which most other tutorials miss, and instead just return all sensors, which is useless if you wish to monitor specific ones (and have multiple on the same network).
I didn't have any 4.7K resistors to hand, so paralleled up a couple of 10k's which seem to work fine - infact I think even a 10k would work over short distances from my testing. I've not bothered with parasitic power.
// Present a "Will be back soon web page", as stand-in webserver. // 2011-01-30 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php #include <EtherCard.h> #include <OneWire.h> #include <DallasTemperature.h> #define STATIC 0 // set to 1 to disable DHCP (adjust myip/gwip values below) #define ONE_WIRE_BUS 3 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); DeviceAddress insideThermometer = { 0x28, 0xE8, 0x94, 0x3C, 0x02, 0x00, 0x00, 0x2B }; #if STATIC // ethernet interface ip address static byte myip[] = { 192,168,1,200 }; // gateway ip address static byte gwip[] = { 192,168,1,1 }; #endif // ethernet mac address - must be unique on your network static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 }; byte Ethernet::buffer[500]; // tcp/ip send and receive buffer void setup(){ Serial.begin(57600); Serial.println("\n[backSoon]"); sensors.begin(); sensors.setResolution(insideThermometer, 10); if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) Serial.println( "Failed to access Ethernet controller"); #if STATIC ether.staticSetup(myip, gwip); #else if (!ether.dhcpSetup()) Serial.println("DHCP failed"); #endif ether.printIp("IP: ", ether.myip); ether.printIp("GW: ", ether.gwip); ether.printIp("DNS: ", ether.dnsip); } //byte Ethernet::buffer[500]; BufferFiller bfill; static word homePage() { sensors.requestTemperatures(); float tempC = sensors.getTempC(insideThermometer)*100; Serial.println(tempC); int tempCi = (int)tempC; bfill = ether.tcpOffset(); bfill.emit_p(PSTR( "HTTP/1.0 200 OK\r\n" "Content-Type: text/html\r\n" "Pragma: no-cache\r\n" "\r\n" "<title>RBBB server</title>" "<h1>Temp: $D</h1>"), tempCi); return bfill.position(); } void printTemperature(DeviceAddress deviceAddress) { float tempC = sensors.getTempC(deviceAddress); if (tempC == -127.00) { Serial.print("Error getting temperature"); } else { Serial.print(tempC); } } void loop(){ Serial.print("Getting temperatures...\n\r"); sensors.requestTemperatures(); Serial.print("Inside temperature is: "); printTemperature(insideThermometer); Serial.print("\n\r"); word len = ether.packetReceive(); word pos = ether.packetLoop(len); if (pos) // check if valid tcp data is received ether.httpServerReply(homePage()); // send web page data }
Following my experiments I decided to approach this from a different way. I now run a webclient on the Arduino which fetches a PHP page every so often with a bunch of temperatures in the query string. The code for this is below:
#include <EtherCard.h> #include <OneWire.h> #include <DallasTemperature.h> #define STATIC 0 // set to 1 to disable DHCP (adjust myip/gwip values below) #define ONE_WIRE_BUS 3 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); DeviceAddress Office = { 0x28, 0xE8, 0x94, 0x3C, 0x02, 0x00, 0x00, 0x2B }; DeviceAddress Outside = { 0x28, 0xE8, 0x94, 0x3C, 0x02, 0x00, 0x00, 0x2B }; DeviceAddress Master = { 0x28, 0xE8, 0x94, 0x3C, 0x02, 0x00, 0x00, 0x2B }; DeviceAddress Howard = { 0x28, 0xE8, 0x94, 0x3C, 0x02, 0x00, 0x00, 0x2B }; byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 }; char website[] PROGMEM = "<hostname of remote server>"; uint32_t timer; byte Ethernet::buffer[700]; Stash stash; char buffer[25]; void setup () { Serial.begin(57600); Serial.println("\n[DS18b20 HTTP Updater]"); sensors.begin(); sensors.setResolution(Office, 12); sensors.setResolution(Outside, 12); sensors.setResolution(Master, 12); sensors.setResolution(Howard, 12); if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) Serial.println( "Failed to access Ethernet controller"); if (!ether.dhcpSetup()) Serial.println("DHCP failed"); ether.printIp("IP: ", ether.myip); ether.printIp("GW: ", ether.gwip); ether.printIp("DNS: ", ether.dnsip); Serial.println("Please wait. Resolving DNS..."); if (!ether.dnsLookup(website)) Serial.println("DNS failed"); ether.printIp("DNS Resolved...Server IP: ", ether.hisip); } void loop () { ether.packetLoop(ether.packetReceive()); if (millis() > timer) { timer = millis() + 30000; sensors.requestTemperatures(); float tempOffice = sensors.getTempC(Office); float tempOutside = sensors.getTempC(Outside); float tempMaster = sensors.getTempC(Master); float tempHoward = sensors.getTempC(Howard); updateTemp(tempOffice, tempOutside, tempMaster, tempHoward); } } static void updateTemp ( float tempOffice, float tempOutside, float tempMaster, float tempHoward ) { byte sd = stash.create(); stash.print("GET /heatmiser/update_temp.php?"); stash.print("Office="); stash.print(tempOffice); stash.print("&Outside="); stash.print(tempOutside); stash.print("&Master="); stash.print(tempMaster); stash.print("&Howard="); stash.print(tempHoward); stash.print(" HTTP/1.0 \r\n"); stash.println("\r\n"); stash.save(); Stash::prepare(PSTR("$H"), sd); ether.tcpSend(); }
There is some PHP on my server which decodes the query string and adds the data to the database. Currently each of the 4 sensors actually reference the same ds19b20 but that's just for testing, I have a bag full of them I plan to add over the coming days around the house.
Downside to this code is that it requires each sensor to be hardcoded, but that gives them friendly names rather than just index ID's which would mean you didn't know which sensor was which.
Hi Paul, Can you put the php code here? Your project is exactly what I was looking for.
ReplyDeleteMy PHP code simply takes the parameter passed and inserts it into a database. Using something like temp = $_REQUEST['Office'] with a simple mysql insert.
ReplyDeleteHi Paul
ReplyDeleteIf i'm using local server with static ip, how can i set remote address of this server ?
Manu