A wireless outdoor thermometer

What it does is to measure two temperatures (one inside a case and one external), an ambient light value and a battery voltage. The data is collected every 5 minutes and sent to the gateway inside the house. Self-heating of the NTCs is minimized to zero because the microprocessor goes in sleep mode except for 10 milliseconds every 5 minutes. But self heating effects of the house and the case of course remain. The 8 second watchdog timer is used, after 33 counts I enable the atmel 328p, and this means that we receive data every 5 minutes at the gateway. On the outside wall of our house it looks like this next to a cresta sensor:

outdoor_mounting

On the inside you find this:

inside_case

And on 13-sep-2014 I collected the following data:

graph_130914
red is the external temperature, blue is the internal temperature, green is the light curve direct from inverse voltage across the LDR. The temperature data is obtained by a linear calibration model, prior to -130 hours the data is not calibrated, and at -50 hours I put the model for an hour 5m away from the house, so you see the self-heating effect of the house which is approximately 1,5 degree Celsius.

The battery voltage is recorded as well, after 40 hours the voltage drop stabilized, since then it stablized at 4958 millivolt this morning. The moteino board draws 150 microamperes it should last 6 months I suspect because the battery (4 soldered 1.2 volt NiMh’s) has a capacity of 650mAh.

Millivolts obtain by a linear calibration model from the ADC reading over the R2 resistor. The initial voltage drop is caused by charging the battery, this is normal, from this point on it should slowly decrease until it goes under 4500 mV after which it starts to accelerate and die. The discharge current is 150 microamperes. This feature only exists with the P models from Atmel (the atmega328p chip is used on the moteino r4 board).
Millivolts obtain by a linear calibration model from the ADC reading over the R2 resistor. The initial voltage drop is caused by charging the battery, this is normal, from this point on it should slowly decrease until it goes under 4500 mV after which it starts to accelerate and die. The discharge current is 150 microamperes. This feature only exists with the P models from Atmel (the atmega328p chip is used on the moteino r4 board).

The circuit is relatively straightforward, this model comes with its own battery charger circuit, a 4.8V NiMh battery and a 5mm plug. When the voltage across the R0 (2.2Ohm) resistor reaches 0.6 volt the bc337 grounds the adjust pin of the lm317 regulator, it effectively limits the charge current to 270mA until the maximum voltage is reached. This voltage is set by the potentiometer R4, so that the voltage at point A does not exceed 6V, or if you measure it before the diode D2 6.7V, to prevent trouble I adjusted it to 6.3V before the diode. At point B you need a minimum voltage of 7.5 volts, so that 0.7 volt more is needed at point C. In other words, you need at least 8.2 volt and 270 milliamp to charge this model. Jumper JP1 is not really needed, but is convenient when you remove the battery and the moteino board.
To measure the battery voltage I inserted a voltage divider across the battery consisting of R1 and R2 so that the ADC at A1 can readout the voltage across R2. A bc337 is inserted to control the voltage divider, you only open the BC337 for 10 milliseconds every 5 minutes, so that the divider doesn’t discharge the battery at 8.8 mA which would drain the battery in 3 days.

circuit_130914

The case is mounted on a nail which protrudes the case just behind the FTDI adapter pins. I’ve not made an opening for the FTDI adapter because it is an outside model, and to protect the FTDI against accidental contacts through the mounting hole a piece of anti-ESD foam suffices.

The last 2 days
The last 2 days

The last 2 days

The last 30 hours actually show the previous day cycle and today up to 14:00. Usually the blue internal temperatures slightly lag the red external ones, but I rarely find more than 0.5 degree difference. Todays light curve shows that the morning started more rapidly because there was no fog, this is the dent in the graph yesterday morning when the skies were bright at 6am, but when we had fog till 11, this is not uncommon for a September. Today the day started a bit grey, but then the sun kicked in later and we have plenty of  cumuli passing along, that is the wiggly part in the light curve. At 10 o’clock this morning I opened the box, so the rapid gradient is artificial. The peak at 2:30am is light coming from in the kitchen, the dishes went into the dishwasher. Sunrise and sunset can also be estimated, once I have a few months worth of data I will insert the graph into this blog.

Sketch

#include <LowPower.h>
#include <RFM69.h>               // radio library
#include <SPI.h>                 // we need SPI
#include <SPIFlash.h>            // maybe we need also flash
//#include <Adafruit_GPS.h>        // GPS receiver
//#include <SoftwareSerial.h>      // GPS needs software serial
//#define GPSECHO false

#define GATEWAY     1
#define NODEID      95   // ID of this station
#define NETWORKID   50
#define FREQUENCY   RF69_868MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define KEY         "thisIsEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
#define DEBUG       false

const int countdown = 33;

RFM69 radio;
bool promiscuousMode = false; //set to 'true' to sniff all packets on the same network
SPIFlash flash(8, 0xEF30);

const int n60 = 60;
char topstr[n60];

long int cc;
const int ntcpin = A0;  // 10 k with blue NTC at base, we measure over the NTC
const int batpin = A1;  // 470ohm BC337 100om to ground, supply at Vbat, voltage over 100 Ohm, 
const int extntcpin = A3;  // 3.3 V to 10k to ntc to ground at 3.3 volt, voltage over ntc 
const int extldrpin = A2;  // 3.3 V to 10k to ldr to ground at 3.3 volt, voltage over ldr 
const int suppin = 3;   // via 10k to base of BC337, high means that we measure, low is off 
const int led = 9;

void setup() 
{ 
  Serial.begin(115200);
  Serial.println(F("% TEMPRFM device")); 
  pinMode(led,OUTPUT);
  pinMode(suppin,OUTPUT);
  // 
  // turn on the radio
  //
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
  radio.promiscuous(promiscuousMode);
  radio.encrypt(KEY);
  sprintf(topstr, "%% Radio operating at %d Mhz ", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  Serial.println(topstr);
  //
  // what do we know about the flash chip
  //
  Serial.print(F("% ")); 
  if (flash.initialize())
    Serial.println(F("SPI Flash Init OK!"));
  else
    Serial.println(F("SPI Flash Init FAIL! (is chip present?)"));  
  Serial.print(F("% DeviceID: "));  
  word jedecid = flash.readDeviceId();
  Serial.println(jedecid, HEX);  
  {
    sprintf(topstr,"TEMPRFM starting"); 
    radio.sendWithRetry(GATEWAY, topstr, sizeof(topstr)); 
    radio.sleep(); 
  }
  //
  // set the timers
  //
  cc = 0;
}

//----------------------------------------------------------------------------------------------------------------------

void loop() 
{
  if ( !DEBUG ) { LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); }
  if ((cc++ % countdown) == 0) { // roughly every 5 minutes we take a temperature
    pinMode(led,OUTPUT); 
    digitalWrite(led,HIGH);
    pinMode(suppin,OUTPUT); 
    digitalWrite(suppin,HIGH);
    delay(3);
    int c = analogRead(ntcpin); delay(3);
    int s = analogRead(batpin); delay(3);
    int xc = analogRead(extntcpin); delay(3);
    int xl = analogRead(extldrpin); delay(3);
    digitalWrite(led,LOW); 
    digitalWrite(suppin,LOW);
    float V0 = s; V0 = V0/1024.0*3.3; 
    float V = 5.515*V0 + 0.1589; V = V * 1000.0; // reconstructed supply voltage in millivolt
    int vs = V;
    sprintf(topstr,"TEMP %3d %3d %4d %4d %6ld",c,xc,xl,vs,cc);
    radio.sendWithRetry(GATEWAY, topstr, sizeof(topstr));
    radio.sleep(); 
    if (DEBUG) Serial.println(topstr);
  }
  if (DEBUG) delay(1000);
}

Air pressure is recorded at the gateway

And that gives the following graph where you see long periodic motions and a twice per day wiggle that contains physics, it is the so-called S2 air tide caused by solar radiation.

Time series of air pressure recorded at the gateway
Time series of air pressure recorded at the gateway, x-axis hours relative to midnight at 13-sep-2014 and y-axis in hecto Pascal

The power spectrum of the above graph with the x-axis representing cycles per day rather than Hertz is:

Power spectrum of the air pressure clearly showing the twice per day S2 air tide
Power spectrum of the air pressure clearly showing the twice per day S2 air tide, x-axis in cycles per day, y-axis is log10 of the pressure signal

More on air-tides can be read here.

Last update: 13-Sep-2014, schematics and graphs replaced by better images.

Advertisements

2 thoughts on “A wireless outdoor thermometer

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s