The sensor board itself has gone through three generations, independent of which logger/network generation it's plugged into: the SparkFun Weather Board V3 (v1), a custom board built around the same two sensors (v2), and a BME280-based custom board (v3) that's what's actually in use today.

Part of the same ZigBee Sensor Network (v1.0) generation as the coop's other Fio-based nodes, but built on a different, off-the-shelf board instead of a bare Arduino: SparkFun's USB Weather Board V3. This was the first version used for real weather/environmental sensing (as opposed to the earlier breadboard Weather Station prototype, which never left the bench). It used the same sensor pairing as that prototype - SHT15 (temperature/humidity) and BMP085 (pressure), a genuinely popular combo at the time, a good balance of precision and cost - plus TEMT6000 (ambient light), just integrated onto one purpose-built board running SparkFun's own stock firmware instead of loose breakout boards wired to a bare Arduino by hand. It also added onboard connectors for SparkFun's Weather Meters kit (wind speed, wind direction, rain), which the breadboard prototype had no way to support.

The firmware declares a few more pins than it actually does anything with - a couple are defined as constants and never touched again anywhere in the sketch (left over from the board's RF header). Below are only the pins the code actually reads, writes, or explicitly drives high/low, even where that's as trivial as holding a reset line high:

Arduino pin Name Purpose
DIGITAL 2RAINRain gauge bucket-tip counter (reed switch) - only wired up as an external interrupt when the Weather Meters kit is attached (see below)
DIGITAL 3WSPEEDAnemometer wind-speed pulses - same conditional interrupt attach as RAIN
DIGITAL 4STATUSLEDStatus LED heartbeat - not a sensor, just an activity blink
DIGITAL 8EOCBMP085 end-of-conversion input, held low to disable its pullup - never actually polled
DIGITAL 9XCLRBMP085 reset line, held high to keep the sensor out of reset - never toggled again
ANALOG 0WDIRWind vane heading, read from a resistor-ladder lookup table
ANALOG 4 / ANALOG 5-Shared between the SHT15 and the BMP085 - see below
ANALOG 6BATT_LVLBattery voltage divider

Two digital pins (RF_RTS/RF_CTS, 5 and 6, left over from the board's radio header) are declared but never referenced by a single pinMode() or digitalWrite() anywhere else - genuinely dead, not just idle. The TEMT6000's LIGHT pin (ANALOG 7) is in a similar spot: the sensor is wired to the board, but the line that would call analogRead(LIGHT) is commented out. So of the three sensors this board shares with the Weather Station prototype, only two - SHT15 and BMP085 - actually make it into a logged reading here.

The TEMT6000 was never worth wiring up in the first place: it's a simple ambient-light sensor, and what a weather station actually needs is solar radiation, a different (and differently measured) quantity. That's why the coop later got a dedicated Solar Radiation sensor instead - the TEMT6000 reading was never going to be useful for this, logged or not.

The SHT15 and the BMP085 both sit on the same two physical pins, analog 4 and 5 - but they don't actually share a bus, they use those pins two completely different ways. The BMP085 talks real I2C over hardware analog 4/5 (SDA/SCL). The SHT15 library instead bit-bangs its own two-wire protocol on the same two pins as plain GPIO (data + clock); it just happens to reuse the same physical header pins, not the I2C peripheral itself. Since the ATmega's hardware I2C engine keeps those pins under its own control once enabled, reading the SHT15 required disabling the chip's I2C peripheral first, then re-enabling it before talking to the BMP085 again:

TWCR &= ~(_BV(TWEN));  // turn off I2C enable bit so we can access the SHT15 humidity sensor

// get humidity and temp (SHT15)
SHT15_temp = humidity_sensor.readTemperatureC();
SHT15_humidity = humidity_sensor.readHumidity();

...

TWCR |= _BV(TWEN);  // turn on I2C enable bit so we can access the BMP085 pressure sensor

TWCR is the ATmega's Two-Wire (I2C) Control Register, and TWEN is its enable bit. Toggling that bit off before every SHT15 read and back on before every BMP085 read is what let two sensors sit on the same two pins without one's bit-banged protocol colliding with the other's real I2C traffic.

The firmware exists as two builds off the same source, hand-copied rather than switched at runtime: a small-station build reporting just the SHT15 and BMP085 (temperature, humidity, dew point, pressure), and a big-station build that also has SparkFun's Weather Meters kit (SEN-08942) attached for wind speed, wind direction, and rainfall. The two differ by a single boolean flag, weather_meters_attached, which gates whether the wind/rain interrupts get attached in setup() and whether their readings get included in the output - everything else in the sketch is identical between the two builds.

The SparkFun board was still too expensive to put one on every small weather station, so the next step was a custom board built around just the two sensors that actually mattered: SHT15 and BMP085 (later BMP180, its pin- and register-compatible successor). No wind/rain connectors, no TEMT6000, no onboard menu/EEPROM system - just the two sensors that were actually being logged, at a fraction of the SparkFun board's cost.

Once Bosch's BME280 came out - combining temperature, humidity, and pressure in one part - it replaced both the SHT15 and the BMP085/BMP180 outright: fewer components, fewer pins, one I2C device instead of two sensors awkwardly sharing a bus. This became v3, and it's what every station uses today, via the ESP32 Sensor Node platform's BME280Node firmware.