Going to Production after Prototyping

Hello all,
I recently finished prototyping an indoor/outdoor weather station. For my outdoor unit, I presently have an Arduino Mini Pro, DS18S20, and FS1000A transmitter hooked up to a 9V battery. I included the watchdog sleep code and minimized transmissions to once every 20 minutes, which is fine for this value and since I want to maximize battery life. At the moment, the outdoor unit is using around 0.10V of my battery/day, so it is definitely not going to last very long. Here is my math: 10 days per Volt, so in 40 days it my 9V battery will be down to 5V and then start causing issues once it falls below what the Arduino needs.

Question: My current setup has the DS12S20 & FS1000A powered via vcc connection and this appears to always be 4.98V. Can I power the transmitter and DS18S20 via digital pin by configuring it as OUTPUT and setting HIGH to use and LOW to turn off? If so, I tried this and nothing seemed to work. How do I find out how long to wait after sending HIGH to pin and can I add this delay to my loop? Here is my current code:

#include <OneWire.h>
#include <VirtualWire.h>
#include <avr/sleep.h> 
#include <avr/wdt.h> 
#define DS18S20_SENSOR_PIN 2
#define LED_PIN 13
#define TRANSMIT_PIN 12
#define ADDR 1
#define sleepTime 75    //number of 8 second sleep cycles
volatile byte wdt=100;  //used to count number of sleep cycles

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

volatile boolean f_wdt=1;

OneWire  ds(DS18S20_SENSOR_PIN);
byte temp;
float tempF;
int tempF1, tempF2;

// Watchdog Interrupt Service / is executed when  watchdog timed out
ISR(WDT_vect) {
 f_wdt=1;  // set global flag
}

// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {
 byte bb;
 int ww;
 if (ii > 9 ) ii=9;
 bb=ii & 7;
 if (ii > 7) bb|= (1<<5);
 bb|= (1<<WDCE);
 ww=bb;
 MCUSR &= ~(1<<WDRF);
 // start timed sequence
 WDTCSR |= (1<<WDCE) | (1<<WDE);
 // set new watchdog timeout value
 WDTCSR = bb;
 WDTCSR |= _BV(WDIE);
}

// set system into the sleep state
// system wakes up when wtchdog is timed out
void system_sleep() {
  cbi(ADCSRA,ADEN);  // switch Analog to Digitalconverter OFF
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
  sleep_enable();
  while (wdt < sleepTime) {                 // sleep for sleepTime * 8sec
    wdt++;
    sleep_mode();                          // activate system sleep
  }
  sleep_disable();      // System continues execution here when watchdog timed out
  sbi(ADCSRA,ADEN);     // switch Analog to Digitalconverter ON
  wdt=0;
}

void setup(void) {
  cbi( SMCR,SE );      // sleep enable, power down mode
  cbi( SMCR,SM0 );     // power down mode
  sbi( SMCR,SM1 );     // power down mode
  cbi( SMCR,SM2 );     // power down mode
  setup_watchdog(9);
  
  vw_set_tx_pin(TRANSMIT_PIN);
  vw_set_ptt_inverted(true);
  vw_setup(2000);
}

void loop(void) {
  if (f_wdt==1) {
    f_wdt=0; 

    float tempF = getTemperature();
  
    if (tempF != NULL) {
       digitalWrite(LED_PIN, HIGH);
       tempF1 = (int)tempF;
       tempF2 = (int)((tempF - tempF1) * 100.0); // For two decimal points
       char msg[24];
       sprintf(msg, "%i.%i", tempF1, tempF2);
       vw_send((uint8_t *)msg, strlen(msg));
       vw_wait_tx();
       digitalWrite(LED_PIN, LOW);
    }
    
    system_sleep(); 
  }  
}

float getTemperature() {
 byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    ds.reset_search();
    delay(20000);    // Pause 20 seconds between passes
    return NULL;
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {  //CRC is not valid!
      return NULL;
  }
 
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:  //DS18S20
      type_s = 1;
      break;
    case 0x28:  //DS18B20
      type_s = 0;
      break;
    case 0x22:  //DS1822
      type_s = 0;
      break;
    default:  //unknown
      return NULL;
  } 

  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
  
  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();
  }
 
  // convert the data to actual temperature

  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;
  
  return fahrenheit; 
}

Question: Are there any other things I can turn off to save move power like turning unused pins off and brown-out detection?

Question: Instead of using the fairly expensive Arduino Mini Pro, what are you all going to Production with? Should I wire up one of these breadboard arduinos and go with that? I bought one of these Diavolino boards and it looks like exactly what I need for my final product.

Question: If my indoor unit will be powered by Arduino Mini Pro running at 16Mhz and 5V, can I use something like attiny85 on the outdoor unit or do they need to be the same? I am guessing the transmitter and receiver need to be the same speed.

Thanks in advance,
Brent

xlr8tn:
Can I power the transmitter and DS18S20 via digital pin by configuring it as OUTPUT and setting HIGH to use and LOW to turn off?

If the maximum power draw is well under 40 mA (the Arduino Absolute Maximum) then you can power a device from a digital pin. The device specifications should tell you how long to wait after applying power before you use the device.

You can use an output pin for the DS18S20, but I'm not sure about the current for the FS1000A.
I would wait 500ms after the pin is set high.
But the DS18S20 already uses very little power, and can be set in standby. Using an output pin is perhaps useless for the DS18S20.
You have to measure the FS1000A yourself, I don't know the idle current.

If the voltage regulator makes 5V out of 9V, almost half the enery is lost.

Is your Arduino Pro Mini with the ATmega328P ? The 'P' indicates "pico power".
There are a few things you can do with the ATmega328P.
For example the input circuits are still active. You can set the pull-up resistors for the inputs, or you can connect the inputs to ground (without the internal pull-up resistors).

I hope you are using VirtualWire for the communcation. Using that in a ATtiny85 would be hard. And the timing is a problem. I think that the ATmega328P idle current is in the same range at the ATtiny85.

Ditch the regulator and run from 3 AA, C, or D batteries.
Even better, run from 2 batteries and 8MHz, 4 MHz, 2MHz, the slower you can go the longer the battery will last.

RF frequencies and data rate being used need to the same, processors don't need to be.