Measure some environmental values in my parents' heating unit

Aus DL8RDS Wiki
Version vom 28. Juni 2013, 23:02 Uhr von Dl8rds (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „== Project == This little project has a manifold background: * My parents have a heating room in their house which holds an oil heater. * My parents recently…“)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

1 Project

This little project has a manifold background:

  • My parents have a heating room in their house which holds an oil heater.
  • My parents recently had a solar water heater installed on their roof.
  • My mother usually dries the washed clothes in that room, which results in some higher air moisture, which can be measured.

So I decided to build a networked arduino that does all these measurements. The temperature measuring facility should be extensible in order to cover some more measuring points.

2 Hardware

3 Sketch

I tried a number of libraries over some time. Particularly the SHT1x library didn't seem to work. Then I discovered another sketch by somebody on the internet which eventually worked. Another sketch that

So I integrated the two sketches with the standard Webserver example and this was the result:

//Based of the wiring code at http://wiring.org.co/learning/basics/humiditytemperaturesht15.html

#include <SPI.h>
#include <Ethernet.h>
#include <OneWire.h>

byte mac[] = { 0xAE, 0xAD, 0xAE, 0xAF, 0xAE, 0xAD };
IPAddress gateway(192, 168, 1, 1);
IPAddress ip(192, 168, 1, 175);
IPAddress dns(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

int SHT_clockPin = 4;  // pin used for clock
int SHT_dataPin  = 6;  // pin used for data

OneWire  ds(9);  // on pin 9

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);

void setup(){
  Serial.begin(9600); // open serial at 9600 bps
  Ethernet.begin(mac, ip, dns, gateway, subnet);
}

void loop(){
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          //these can take a bit to get the values (100ms or so)
          float temperature = getTemperature();
          float humidity = getHumidity();
 
          client.print("Temperaturen und Feuchtigkeit im Heizungsraum\n");
           client.print("\n");
           
           client.print("

Temperaturen und Feuchtigkeit im Heizungsraum

\n
\n"); client.print("\n"); client.print(""); client.print(""); while ( ds.search(addr)) { if (OneWire::crc8(addr, 7) != addr[7]) { Serial.println("CRC is not valid!"); continue; } Serial.println(); // the first ROM byte indicates which chip switch (addr[0]) { case 0x10: Serial.println(" Chip = DS18S20"); // or old DS1820 type_s = 1; break; case 0x28: Serial.println(" Chip = DS18B20"); type_s = 0; break; case 0x22: Serial.println(" Chip = DS1822"); type_s = 0; break; default: Serial.println("Device is not a DS18x20 family device."); continue; } ds.reset(); ds.select(addr); ds.write(0x44,1); // start conversion, with parasite power on at the end delay(1000); // maybe 750ms is enough, maybe not // we might do a ds.depower() here, but the reset will take care of it. present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } unsigned int raw = (data[1] << 8) | data[0]; if (type_s) { raw = raw << 3; // 9 bit resolution default if (data[7] == 0x10) { // count remain gives full 12 bit resolution raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60); if (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms // default is 12 bit resolution, 750 ms conversion time } celsius = (float)raw / 16.0; fahrenheit = celsius * 1.8 + 32.0; client.print(""); } client.print("
Lufttemperatur: "); client.print(temperature); client.print("
Luftfeuchtigkeit: "); client.print(humidity); client.print("
Sensor: "); for( i = 0; i < 8; i++) { client.print(" "); client.print(addr[i], HEX); } client.print(""); client.print(celsius); client.print("
\n\n\n"); break; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } // give the web browser time to receive the data delay(1); // close the connection: client.stop(); ds.reset_search(); } } float getTemperature(){ //Return Temperature in Celsius SHT_sendCommand(B00000011, SHT_dataPin, SHT_clockPin); SHT_waitForResult(SHT_dataPin); int val = SHT_getData(SHT_dataPin, SHT_clockPin); SHT_skipCrc(SHT_dataPin, SHT_clockPin); return (float)val * 0.01 - 40; //convert to celsius } float getHumidity(){ //Return Relative Humidity SHT_sendCommand(B00000101, SHT_dataPin, SHT_clockPin); SHT_waitForResult(SHT_dataPin); int val = SHT_getData(SHT_dataPin, SHT_clockPin); SHT_skipCrc(SHT_dataPin, SHT_clockPin); return -4.0 + 0.0405 * val + -0.0000028 * val * val; } void SHT_sendCommand(int command, int dataPin, int clockPin){ // send a command to the SHTx sensor // transmission start pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); digitalWrite(dataPin, HIGH); digitalWrite(clockPin, HIGH); digitalWrite(dataPin, LOW); digitalWrite(clockPin, LOW); digitalWrite(clockPin, HIGH); digitalWrite(dataPin, HIGH); digitalWrite(clockPin, LOW); // shift out the command (the 3 MSB are address and must be 000, the last 5 bits are the command) shiftOut(dataPin, clockPin, MSBFIRST, command); // verify we get the right ACK digitalWrite(clockPin, HIGH); pinMode(dataPin, INPUT); if (digitalRead(dataPin)) Serial.println("ACK error 0"); digitalWrite(clockPin, LOW); if (!digitalRead(dataPin)) Serial.println("ACK error 1"); } void SHT_waitForResult(int dataPin){ // wait for the SHTx answer pinMode(dataPin, INPUT); int ack; //acknowledgement //need to wait up to 2 seconds for the value for (int i = 0; i < 1000; ++i){ delay(2); ack = digitalRead(dataPin); if (ack == LOW) break; } if (ack == HIGH) Serial.println("ACK error 2"); } int SHT_getData(int dataPin, int clockPin){ // get data from the SHTx sensor // get the MSB (most significant bits) pinMode(dataPin, INPUT); pinMode(clockPin, OUTPUT); byte MSB = shiftIn(dataPin, clockPin, MSBFIRST); // send the required ACK pinMode(dataPin, OUTPUT); digitalWrite(dataPin, HIGH); digitalWrite(dataPin, LOW); digitalWrite(clockPin, HIGH); digitalWrite(clockPin, LOW); // get the LSB (less significant bits) pinMode(dataPin, INPUT); byte LSB = shiftIn(dataPin, clockPin, MSBFIRST); return ((MSB << 8) | LSB); //combine bits } void SHT_skipCrc(int dataPin, int clockPin){ // skip CRC data from the SHTx sensor pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); digitalWrite(dataPin, HIGH); digitalWrite(clockPin, HIGH); digitalWrite(clockPin, LOW); }

4 Pictures