tue, 07-feb-2012, 17:19
data logger

Today was the first day where I got some good data skiing to and from work using my data logger. There’s a photo of it in it’s protective box on the right. The Arduino and data logging shield (with the sensors soldered to it) is sitting on top of a battery pack holding six AA batteries. The accelerometer is the little square board that is sticking up on the left side of the logger, and you can see the SD card on the right side. The cord under the rubber bands leads to the external temperature sensor.

This morning it took about four minutes for the sensor to go from room temperature to outside temperature (-12°F), which means I need to pre-acclimate it before going out for a ski. A thermocouple would respond faster (much less mass), but they’re not as accurate because they have such a wide response range (-200°C to 1,350°C). A thermistor might be a good compromise, but I haven’t fiddled with those yet.

Here’s the temperature data from my ski home:

When I left work, the temperature at our house was 12°F, and I figured it would be warmer almost everywhere else, so I used “extra green” kick wax, which has a range of 12 to 21°F. I’ve highlighted this range on the plot with a transparent green box. In general, if you’ve chosen wax that’s too warm for the conditions, you won’t get much glide, and if the wax is rated too cold, you won’t have much kick. The plot shows that as I got near the end of the route and the temperature dropped below the lower range of the wax, I should have lost some glide, which is pretty much exactly what happened. Normally this isn’t a big issue on the Goldstream Valley Trail because it’s often very smooth, which means that a warmer wax is needed to get a grip, but this afternoon’s trail had seen a lot of snowmachine traffic, it wasn’t very smooth, and I didn’t get as much glide as earlier in the ski.

The other interesting thing is the dramatic dip marked “Goldstream Creek” on the plot. This is where the trail crosses the Creek on a small bridge designed for light recreational traffic (nothing bigger than a snowmachine or four-wheeler). It’s probably the lowest place in the trail. Our house is also on the Creek, so the two coldest spots on the trail are exactly where I’d expect them to be, right on the Creek.

sun, 05-feb-2012, 13:50

Over the past couple weeks I’ve been experimenting with a data logging shield from adafruit. My original idea was to build a unit I could take with my on my commute to work to see how the temperatures change over the route. I’m also interested in watching the temperatures inside a dog house when there’s a dog sleeping in there. During the cold snap, where temperatures got as low as -55°F, how warm could the dogs keep their houses (which are insulated)?

I added a three axis accelerometer (ADXL335) with the idea it could tell me when I was moving, but I don’t think I can afford to read (and log) the sensors that often when it’s running off batteries (6 AA cells) at cold temperature. Instead, it’ll tell me the position (relative to the ground) of the logger, and I’ll use that to indicate when I start whatever activity I want to measure. The data logger starts logging as soon as it gets power, and even though it has a clock, it may drift relative to GPS time, so I can time the start based on when the logger’s position changes.

Here’s the schematic:

Data logger circuit

I wired it on a breadboard first to confirm the circuit was correct and to get the program storing the data. The data logger shield has a 10 x 10 perfboard section, so once everything was working, I soldered the parts directly onto the board using the plan below. The black lines are above the board and the orange lines are the solder joins below the board.

Perfboard layout

I don’t know yet how long the battery will last, but I ran it last night in the arctic entryway and got the following data:

The orange dots are from the temperature sensor on the board, wrapped in bubble wrap and sitting inside a cardboard box. The cyan dots are from the waterproof sensor outside of the box. Our arctic entryway is heated with a ventilation fan that blows warm air from the house into the room, so the oscillation in the temperature shows the fan going on at the bottom of the sweep and then off at the top. The insulation in the box reduces the temperature fluctuations and traps the slight amount of heat produced by the electronics.

Time to watch the Super Bowl.

sun, 22-may-2011, 08:06
Arduino temperature display

Arduino temperature display

I’ve had an Arduino-based weather station since June 2009, but one problem with it has been that there hasn’t been any easy way to display the data in real time without going to the database (or the raw import files) to see what the latest observations were. I wrote a quick web page for this (home display), and this is convenient if I want to see what the temperatures are around the house when I’m not at home. But sitting in the living room, it’d be nice to know what the temperatures are just by looking.

The choices for displays aren’t all that great. Arduino can drive the classic seven segment LED displays (like old calculators, for those who remember what a calculator is), which are big and bright, but it requires a lot of pins, and even more power to light enough of them to display the amount of data I need (at least four temperatures, and possibly other sensor values like pressure or light). There are graphical LCD panels, which you control pixel by pixel but are expensive and aren’t all that large. And then there are text LCD displays that use the Hitachi HD44780 controller (or one based on it). These are more like old terminal screens where you can write to each character position on the screen. Common sizes are 16 characters across x 2 rows and 20 x 4 displays.

I chose a white on black, 16 x 2 display (SparkFun LCD-00709). It requires 5 volts to power the display and the LED backlight, and uses six of the digital pins on the Arduino board. The Arduino Uno (and earlier Duemilanove) have fourteen digital pins (two of which are the serial TX/RX pins), so one could hook up two of these displays to a single Arduino. The hookup for a single display, and the code I’m using follows. The Arduino Cookbook was invaluable for getting the everything working.

LCD / Arduino circuit diagram

The Arduino code reads four comma-delimited numbers from the serial port. They’re formatted as integer values representing the temperature in Fahrenheit multiplied by ten (50.2°F = 502). If the value is negative, the minus sign appears at the end of the number (-40.0°F = 400-). Here’s the Arduino code that displays the incoming data to the LCD:

#include <LiquidCrystal.h>

const int numRows = 2;
const int numCols = 16;
const int NUMBER_OF_FIELDS = 4; // t_west, t_back, t_up, t_down
int fieldIndex = 0;
int values[NUMBER_OF_FIELDS]; // temp * 10

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  lcd.begin(numCols, numRows);
  lcd.print("SWINGLEYDEV.COM");
  Serial.begin(9600);
}

void displayVal(int val) {
  int ival;
  int dval;
  if (val >= 0) {
    ival = floor(val / 10.0);
    dval = val - (ival * 10);
  } else {
    ival = ceil(val / 10.0);
    dval = -1 * (val - (ival * 10));
  }
  if (ival >= 0) {
    lcd.print(" ");
  }
  lcd.print(ival);
  lcd.print(".");
  lcd.print(dval);
}

void loop() {
  if (Serial.available()) { // Read message
    delay(100);
    while (Serial.available()) {
      char ch = Serial.read();
      if (ch >= '0' && ch <= '9') {
        values[fieldIndex] = (values[fieldIndex] * 10) + (ch - '0');
      } else if (ch == ',') {
        if (fieldIndex < NUMBER_OF_FIELDS - 1) {
          fieldIndex++;
        }
      } else if (ch == '-') {
        values[fieldIndex] = values[fieldIndex] * -1;
      } else {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("W "); // West outdoor sensor
        displayVal(values[0]);
        values[0] = 0;
        lcd.setCursor(9, 0);
        lcd.print("B "); // Back outdoor
        displayVal(values[1]);
        values[1] = 0;
        lcd.setCursor(0, 1);
        lcd.print("U "); // Upstairs
        displayVal(values[2]);
        values[2] = 0;
        lcd.setCursor(9, 1);
        lcd.print("D "); // Downstairs
        displayVal(values[3]);
        values[3] = 0;
        fieldIndex = 0;
      }
    }
  }
}

To make this work, I need a program on the computer the Arduino is plugged into that will read the weather data from the database and dump it to the serial port that the display Arduino is plugged into. Here’s that code:

#! /usr/bin/env python

import serial, time, shutil, os
import psycopg2

connection = psycopg2.connect(host='HOSTNAME', database='DB')
cursor = connection.cursor()
ser = serial.Serial('/dev/ttyACM0', timeout=1)

def make_arduino_str(value):
    integer = int(round(value * 10))
    if value < 0:
        return "{0}-".format(integer * -1)
    else:
        return "{0}".format(integer)

while 1:
    query = "SELECT west, back, down, up FROM arduino_view;"
    params = ()
    cursor.execute(query, params)
    if cursor.rowcount:
        rows = cursor.fetchall()
        for row in rows:
            (west, back, down, up) = row
        (west, back, down, up) = map(make_arduino_str,
                (west, back, down, up))
        message = "{0},{1},{2},{3}\n".format(west, back, up, down)
        ser.write(message)
    time.sleep(60)
ser.close()
cursor.close()
connection.close()

Each minute, it reads the temperatures from a database view that consolidates the latest readings from the weather sensors (arduino_view), formats them in the manner the Arduino display code expects, and sends them to the serial port for display.

It works really well, and looks good. I wish the display itself were larger, however. I’ll probably get a second LCD panel so I can display more data, but if someone would make a 20 x 4 display that was twice as large as the one I’ve got now, I’d buy it. The 16 x 2 is easy to read from the couch (five feet away), but isn’t readable from the kitchen.

tags: Arduino  lcd  weather 
sun, 15-may-2011, 11:25
Battery, Arduino, XBee

Battery, Arduino, XBee

Several years ago when I started messing around with Arduino and building my own weather station, I bought a few XBee radio chips with the idea of setting up some more remote sites without having to run wires out to the sensor stations. I spend several frustrating hours trying to get the radios to talk to each other, but couldn’t get them to work (I think this was because they were in API mode instead of AT mode). Then I got Building Wireless Sensor Networks and Arduino Cookbook and finally got everything working.

At the same time, the batteries in our UPS at work needed to be replaced, and rather than immediately recycling them, I took a couple home to see if they still had enough juice in them to work in a remote sensing capacity. They’re 12 volt lead-acid batteries (which may make them unsuitable for winter) that were rated for 5 Amp-hours when they were new. That should be plenty of power to drive an Arduino, XBee and a couple sensors. The XBee chips have some data pins on them, so I may be able to eliminate the Arduino from each sensor station, depending on the type of sensor I use.

The current setup, shown in the photo at the top, is designed to see how long a remote station can run on one of the batteries without any sensors and at springtime temperatures (typically between 20°F and 60°F at our house). The Arduino is reading the input voltage and sending it wirelessly to an XBee coordinator plugged into a SparkFun explorer board and connected to my small eeeBox computer.

Here’s the circuit diagram:

Circuit diagram

The analog input pins on the Arduino board are expecting voltages between 0 and 5 volts, so I’m using three resistors as a voltage divider to reduce the input voltage (nominally 12 volts, but potentially as high as 15V) to a range safe for the board. The sketch looks like this (almost identical to the sketch in the Arduino Cookbook except that the formula for resistorFactor is incorrect in the book):

const float referenceVolts = 5;

const float R1 = 2000; // A0 to V+
const float R2 = 1000; // A0 to GND

const float resistorFactor = 1023.0 * (R2/(R1 + R2));

const int batteryPin = 0; // A0

void setup() {
   Serial.begin(9600); // to XBee
}

void loop() {
   int val = analogRead(batteryPin);
   float volts =
     (val / resistorFactor) * referenceVolts * 10;
   Serial.println(volts);
   delay(1000);
}

Because the Arduino transmit pin (D1) is connected to the XBee receive pin (DIN) and the Arduino receive (D0) is connected to the XBee send (DOUT), anything the Arduino sends to the serial port is redirected to the XBee, which immediately transmits it wirelessly to the XBee receiver chip in the house.

At the moment, I’m only able to have the sender and receiver about 50 feet from each other before losing the signal, but I think that a pair of boards with whip antennas will work better than the chip antennas I’m currently using. I also set up my network such that the XBee Pro board (which has a supposed range of a mile) is the coordinator receiving messages, but I think it will work better as the sender. When the battery experiment is over, I’ll reverse the position of the XBee boards and see if I get better performance. I’d like to have a station out at the red cabin and potentially somewhere on the hillside, and for that to work the radios will need to be able to communicate over several hundred feet.

The circuit diagram was generated using circuit macros, which take circuit diagrams written in the m4 language and turn them into PIC files which are converted into LaTeX code using dpic. That sounds complicated (and it sort of is), but I much prefer describing the circuits in a text file than to trying to draw them using XCircuits or some other graphical tool. If you’re curious, you can download the code and a Makefile for generating the images.

Here’s what the data looks like so far:

Voltage over time

So far all I can see is a diurnal pattern associated with temperature: it was about 56°F at 6:30 PM last night when the data started, dropped to a minimum of 27°F at around 5:30 AM, and it’s been rising since, hitting 50°F at the end of the period shown on the plot.

sat, 15-aug-2009, 08:58

Inside of station enclosure

Inside of station enclosure

In my previous post on my weather station I included a graph of the relationship between the three temperature sensors I’m collecting data from. It turns out that the plot is incorrect because I had messed up the program that converts the raw data from one of my Arduino stations. What became clear after looking at the (fixed!) data is that the enclosure I built isn’t adequate at keeping the sensors cool when in direct sunlight. I could probably improve the design of the enclosure somewhat, but I decided to aspirate the sensors instead.

The photo on the right shows the inside of the enclosure. The sensors are sitting on a platform inside the pipe, and there’s a small muffin fan (the kind you’d use to vent a computer case) on the top. It’s a 12V fan, and at the moment it’s being driven by a 9V AC/DC converter. The plan is to replace the converter with a 12V solar cell that is sufficient to drive the fan. This way it doesn’t consume any electricity, and the fan is only spinning when it’s necessary (when the sun is out). Thus far, I haven’t found a suitable solar panel. The small ones designed to charge a cell phone battery don’t operate at the correct voltage (and probably don’t produce enough current anyway), and the big ones designed to keep a car battery charged are expensive and overpowered for my needs. With winter rapidly approaching, I’ve got plenty of time to figure something out.

The pipe is a piece of 4” sewer pipe that’s been spray painted white and has a series of holes drilled into the bottom. The fan pulls air up through these holes and over the sensor array in the middle. If I had it to do over again, I’d cut the pipe a bit shorter so it’s not so difficult to get into the enclosure. But for keeping the sensors bathed in atmospheric air, it works quite well.

Temperature summary, effect of aspiration

The plot shows the observed temperature for each of the three sensors I’ve got. The blue line is the “west” sensor that’s inside the enclosure I built and is the subject of this post. The red line is the reported temperature from the Rainwise station that sits atop a post attached to the dog yard gate. The green line is the sensor that’s behind the house and under the oil tank. I built the enclosure for the west sensors on July 12th and installed it that evening. You can immediately see the effect of the shielding during the high temperature peak on the 13th. But you can still see the two little peaks that are present in the previous plots. These peaks come from direct sun on the station, split by some trees that shade the station for an hour or two.

On the evening of the 13th I installed the pipe and fan. It was smoky on the 14th and cloudy on the 15th, but you can see the effect of the fan on the following dates. The double peaks are now gone, and the temperature from the west sensors at the high point during the day is now a few degrees cooler than the measurement from the Rainwise station. Also notice that all three sensors are virtually identical on the 15th when it was cloudy and raining.

What this demonstrates to me is that the aspirated west sensor is now the best reference sensor for our site. The Rainwise sensor is a close second, but it’s Gill multi-plate radiation shield isn’t as effective as my aspiration system at reducing the effect of solar heating on the station.


<< 0 1 2 >>
Meta Photolog Archives