weather_Transmitter / weather_Transmitter.inoon commit Added readme code notes (00df5ca)
   1/*
   2 *      Arduino Weather Station - Transmitter Unit
   3 *      Code by Andrew Lorimer (http://lorimer.id.au)
   4 *      Credit to @bram2202 (Instructables) and Leo Nutz (http://altduino.de)
   5 */
   6
   7
   8// Libraries
   9#include <Wire.h>         // Used for BMP180
  10#include <VirtualWire.h>  // Used for 433 MHz transmitter
  11#include "DHT.h"          // Adafruit DHTxx lib
  12
  13
  14// Sensor setup
  15
  16DHT dht(2, DHT22);            // Set up DHT22 object on digital pin 2
  17#define bmppin 0x77           // I2C address of BMP180
  18const unsigned char OSS = 0;  // Oversampling Setting for BMP180
  19
  20// Calibration values for BMP180
  21int ac1, ac2, ac3, b1, b2, mb, mc, md;
  22unsigned int ac4, ac5, ac6;
  23long b5; 
  24
  25// Transmitter setup
  26#define INTEGER_MAX (powx(2,31)-1)
  27#define E_MAX (pow(10, 7))
  28#define E_MIN (pow(10, -6))
  29#define EPSILON 0.000000119209
  30int txpin = 12;     // Transmit pin of 433 MHz transmitter
  31int linenumber = 0; // Tracks how many lines of data sent (0-3)
  32
  33
  34
  35void setup()
  36{
  37  Serial.begin(9600);
  38  Serial.println("Entering setup routine...");
  39
  40  // DHT22 (humidity & temp)
  41  dht.begin();
  42  Serial.println("> Successfully started DHT22");
  43  
  44  //Pressure sensor
  45  Wire.begin();
  46  CalibratePressure();
  47  Serial.println("> Successfully started BMP180");
  48
  49  // Setup transmitter
  50  pinMode('D12', OUTPUT);
  51  vw_set_tx_pin(txpin); 
  52  vw_setup(2000); //
  53  Serial.println("> Successfully started 433 MHz transmitter");
  54
  55  Serial.println("Finished setup routine.\n");
  56}
  57
  58
  59
  60
  61void loop() {
  62
  63  // Humidity (DHT22)
  64  float humidity = dht.readHumidity(); // Read humidity
  65  if (isnan(humidity)) {Serial.println("ERROR: Failed to read humidity from DHT22.");}
  66  SendData("#H"+ ((String)humidity)); // Send humidity data
  67  Serial.println("   Humidity: " + String(humidity) + " %     (sent)");
  68
  69  // Temperature (BMP180)
  70  float temperature = GetTemp(); // Read temperature
  71  if (isnan(temperature)) {Serial.println("ERROR: Failed to read temperature from BMP180.");}
  72  SendData("#C"+(String(temperature,2))); // Send temperature data
  73  Serial.println("Temperature: " + String(temperature) + " " + char(176) + "C    (sent)");
  74
  75  // Barometric pressure (BMP180)
  76  float pressure = GetPressure(); // Read pressure
  77  if (isnan(pressure)) {Serial.println("ERROR: Failed to read pressure from BMP180.");}
  78  SendData("#P"+(String(pressure/100,2)));
  79  Serial.println("   Pressure: " + String(temperature) + " hPa   (sent)");
  80
  81  Serial.println();
  82  
  83  delay(5000); //Wait for next loop
  84  
  85}
  86
  87
  88
  89
  90void SendData(String data) { // Transmit data over 433 MHz  
  91  const char* rawdata = data.c_str(); // Convert input string to char array
  92  digitalWrite(13, true); // Flash onboard TX light
  93  vw_send((uint8_t *)rawdata, strlen(rawdata)); //Send Data
  94  vw_wait_tx(); // Wait until the whole message is gone
  95  digitalWrite(13, false); 
  96}
  97
  98
  99
 100
 101void CalibratePressure() {
 102  ac1 = BMP180ReadInt(0xAA);
 103  ac2 = BMP180ReadInt(0xAC);
 104  ac3 = BMP180ReadInt(0xAE);
 105  ac4 = BMP180ReadInt(0xB0);
 106  ac5 = BMP180ReadInt(0xB2);
 107  ac6 = BMP180ReadInt(0xB4);
 108  b1 = BMP180ReadInt(0xB6);
 109  b2 = BMP180ReadInt(0xB8);
 110  mb = BMP180ReadInt(0xBA);
 111  mc = BMP180ReadInt(0xBC);
 112  md = BMP180ReadInt(0xBE);
 113}
 114
 115
 116
 117
 118float GetTemp(){ // Calculate temperature (deg C) based on calibration data
 119
 120  unsigned int ut;
 121
 122  // Write 0x2E into Register 0xF4
 123  // This requests a temperature reading
 124  Wire.beginTransmission(bmppin);
 125  Wire.write(0xF4);
 126  Wire.write(0x2E);
 127  Wire.endTransmission();
 128
 129  delay(5); // Must be >4.5 ms
 130  
 131  ut = BMP180ReadInt(0xF6); // Read two bytes from registers 0xF6 and 0xF7
 132  
 133  long x1, x2;
 134  x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
 135  x2 = ((long)mc << 11)/(x1 + md);
 136  b5 = x1 + x2;
 137  float temp = ((b5 + 8)>>4);
 138  temp = temp /10;
 139
 140  return temp;
 141}
 142
 143
 144
 145
 146long GetPressure(){ // Calculate pressure based on calibration data
 147unsigned char msb, lsb, xlsb;
 148  unsigned long up = 0;
 149
 150  // Write 0x34+(OSS<<6) into register 0xF4
 151  // Request a pressure reading w/ oversampling setting
 152  Wire.beginTransmission(bmppin);
 153  Wire.write(0xF4);
 154  Wire.write(0x34 + (OSS<<6));
 155  Wire.endTransmission();
 156
 157  // Wait for conversion, delay time dependent on OSS
 158  delay(2 + (3<<OSS));
 159
 160  // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
 161  msb = BMP180Read(0xF6);
 162  lsb = BMP180Read(0xF7);
 163  xlsb = BMP180Read(0xF8);
 164
 165  up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);
 166
 167  
 168  long x1, x2, x3, b3, b6, p;
 169  unsigned long b4, b7;
 170
 171  b6 = b5 - 4000;
 172  // Calculate B3
 173  x1 = (b2 * (b6 * b6)>>12)>>11;
 174  x2 = (ac2 * b6)>>11;
 175  x3 = x1 + x2;
 176  b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
 177
 178  // Calculate B4
 179  x1 = (ac3 * b6)>>13;
 180  x2 = (b1 * ((b6 * b6)>>12))>>16;
 181  x3 = ((x1 + x2) + 2)>>2;
 182  b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
 183
 184  b7 = ((unsigned long)(up - b3) * (50000>>OSS));
 185  if (b7 < 0x80000000)
 186    p = (b7<<1)/b4;
 187  else
 188    p = (b7/b4)<<1;
 189
 190  x1 = (p>>8) * (p>>8);
 191  x1 = (x1 * 3038)>>16;
 192  x2 = (-7357 * p)>>16;
 193  p += (x1 + x2 + 3791)>>4;
 194
 195  long temp = p;
 196  return temp;
 197}
 198
 199
 200
 201
 202char BMP180Read(unsigned char address) { // Read 1 byte
 203  unsigned char data;
 204
 205  Wire.beginTransmission(bmppin);
 206  Wire.write(address);
 207  Wire.endTransmission();
 208
 209  Wire.requestFrom(bmppin, 1);
 210  while(!Wire.available());
 211
 212  return Wire.read();
 213}
 214
 215int BMP180ReadInt(unsigned char address) { // Read 2 bytes - first from 'address', second from 'address' + 1
 216  unsigned char msb, lsb;
 217
 218  Wire.beginTransmission(bmppin);
 219  Wire.write(address);
 220  Wire.endTransmission();
 221
 222  Wire.requestFrom(bmppin, 2);
 223  while(Wire.available()<2)
 224    ;
 225  msb = Wire.read();
 226  lsb = Wire.read();
 227
 228  return (int) msb<<8 | lsb;
 229}