Go Down

Topic: Weather Sensors - How to turn on & off? (Read 2 times) previous topic - next topic

capo12

Dear forum members

I am writing because I have a question. I just recently started playing & learning with the arduino uno, and I am find it fascinating the many things that this little guy can do. So, I would like to make a project but I'm confused on how the coding works, so I wanted to ask you for some advice/assistance.

Basically, I have a small outdoor project that I want to make that records temperature, humidity and time (all hooked up to a datalogger). Since it will be outdoors running on battery for a few days, I wanted to see if there is a way to tell the arduino to turn "on" and "off" these sensors during the day.

Specifically, I would like to have the arduino turn on the sensors every 30 minutes, print within one line the temperature-humidity (adafruit DHT22 - http://www.ladyada.net/learn/sensors/dht.html) and time (adafruit DS1307 - http://www.ladyada.net/learn/breakoutplus/ds1307rtc.html) every 10 seconds, and after 5 minutes, I would like to to turn the sensors off, and have this process repeat throughout the day.

So far I am using sketches from adafruit that I slightly modified (attached below for reference), but I don't know how to make these work together in one sketch.

By any chance, anyone has any thoughts & ideas on how this could be done?

Thanks!!

Code: [Select]

// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain

#include "DHT.h"

#define DHTPIN 2     // what pin we're connected to

// Uncomment whatever type you're using!

#define DHTTYPE DHT22   // DHT 22  (AM2302)

// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  Serial.println("DHTxx test!");

  dht.begin();
}

void loop() {
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h)) {
    Serial.println("Failed to read from DHT");
  } else {
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.println(" *C");
  }
}


Code: [Select]

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib

#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 RTC;

void setup () {
//    Serial.begin(57600);
    Serial.begin(9600);
    Wire.begin();
    RTC.begin();

  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
}

void loop () {
    DateTime now = RTC.now();
   
    Serial.print(now.month(), DEC);
    Serial.print('-');
    Serial.print(now.day(), DEC);
    Serial.print('-');
    Serial.print(now.year(), DEC);
    Serial.print(' ');
   
   
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

       
    Serial.println();
    delay(3000);
}

Grumpy_Mike


trendski

#2
Apr 22, 2012, 12:45 pm Last Edit: Apr 22, 2012, 01:00 pm by trendski Reason: 1
Hi,

I can't help with code-merge, but I can recommend this tutorial for power saving with the arduino, by Nick Gammon:


http://www.gammon.com.au/forum/?id=11497

Edit: also this thread might be useful http://arduino.cc/forum/index.php/topic,86611.0.html


cheers
Craig Turner, blog: http://gampageek.blogspot.co.uk/ It helps with my learning if I write things down, esp. for others to follow (constructive comments welcomed to improve)

robtillaart


this is essentially the trick do read and print once per 30 minutes
Code: [Select]

unsigned long lastHT= 0;
unsigned long lastSE = 0;


void loop()
{
  // HANDLE TEMP AND HUMID
  if (millis() - (30*60*1000UL) > lastHT)  // once every 30 minutes
  {
    lastHT= millis();
    printHT();
  }

  ?? HANDLE SOMETHING ELSE
  if (millis() - (5*60*1000UL) > lastSE)  // once every 5 minutes
  {
    lastSE= millis();
    Serial.println("do something else here");
  }
 
  // ETC
 
  delay(100);
}


void printHT()
{
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h)) {
    Serial.println("Failed to read from DHT");
  } else {
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.println(" *C");
  }
}
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

capo12

This is great info, guys! Thank you so much!

As I read through the various links and learned more and more about how arduino works and what it can do, I realized that perhaps, what I need to do is take a slightly different and more "manageable" approach for this project.

So... I guess that were I need to start is finding out first, how to make the arduino go to sleep and wake up. Among the great responses that you guys provided, one of them talked about specific commands for making the IC go to sleep. As I researched more into this topic, I quickly learned that I would need a sparate "real time clock" to do this. At first, I thought I could perhaps use a ds1307 (see http://www.ladyada.net/learn/breakoutplus/ds1307rtc.html) that I already have, but it seems that this would NOT work because it cannot store nor send the alarm commands to the arduino. Is this correct?

If the ds1307 isn't suitable for making the arduino sleep & wake up... which time & alarm circuit should I get, that would allow me to wake the arduino at specific intervals and run various sensors (e.g.: record air temperature, etc)?

Luc

trendski

Re: avr library avr-libc. 29-Dec-2011 14:42  :- I hope this is the right one. Can anyone else confirm?

Hi, you should be able to find it amongst these pages. I didn't get it direct from here, it was installed when I installed avr studio 4. So I hope it goes well for you.

http://www.nongnu.org/avr-libc/

http://download.savannah.gnu.org/releases/avr-libc/ The one you need (I think) is 29-Dec-2011 14:42    1.4M   .

A quick note also. I used a very minimal board called a Xino http://proto-pic.co.uk/xino-basic-for-the-atmel-atmega-series-and-arduino/. This is in UK. Maybe you can something similar in your locale. Anyway it uses very few components and less power. Even eliminated the led to save more! It's a nice little board, easy to make and you can program it using a serial cable or ICP.

Cheers
Craig Turner, blog: http://gampageek.blogspot.co.uk/ It helps with my learning if I write things down, esp. for others to follow (constructive comments welcomed to improve)

trendski

Hi, thanks for the messages in my in-box. I thought I would put my replies here in case anyone else wanted to chip in.



Quote
Using the following code, I get

"core.a(main.cpp.o): In function `main':
C:\arduino-1.0\hardware\arduino\cores\arduino/main.cpp:11: undefined reference to `setup'"


Although there is nothing in setup, you still need to include it to avoid the error ie

Code: [Select]
void setup(){
}


Quote
Can you explain the math you used to set the time that the arduino sleeps in line "  for (int

myLoop= 0; myLoop < 64; myLoop++) // loop around and give delay of 64 = 600 sec (10 mins)"?


Yes, sorry it incorrect maths. I was playing around with different loop iterations but didn't alter the

comment.
64 iterations of 8 seconds for the WDIE here:

Code: [Select]
// set interrupt mode and an interval
    WDTCSR = _BV (WDIE) | _BV (WDP3) | _BV (WDP0);    // set WDIE, and 8 seconds delay



64 x 8 = 512 seconds = 8.53 minutes. But you can easily change the loop iteration to suite your needs.

Quote
math for duration that it stays awake?


er...mmm.. As far as I understand it, the Watchdog timer goes to sleep for 8 seconds, wakes up for a split

second while the next iteration of the loop is executed, then goes back to sleep for the next 8 seconds,

and so on and on, until all the iterations have finished. Then the data log method is called.
ie this commented out code:
Code: [Select]
//  LogData (); // now awake so log the data - this is my datalogging method call when avr is awake

it logs sensor data and call rtc etc.. then write to SD card


There may be a more efficient way of doing it but I couldn't think of it at the time.

Quote
if I upload the code into the arduino successfully and nothing happens because it entered a sleep

mode but has no wake up signal, can I just press the "reset" button in the arduino board to bring it back

to life?


Yes that will awake it but then it will go right back to sleep.

You will need to write an Interrupt Service Routine (ISR) that does something when the sleep is

interrupted.

So for example, write a test method that lights led's when LogData() method is called. Put LEDs on pins 14

and 15 (I used green and red ones) also put  470 to 560 ohm resistors in series so the led's don't blow.

and connect the cathodes to ground.
eg
Code: [Select]

#include <avr/sleep.h>
#include <avr/wdt.h>
//#include <SdFat.h> for SD card


#define ledPINgrn 14 // on when logging
#define ledPINred 15 // on when sleeping


byte old_ADCSRA;
// watchdog interrupt
ISR (WDT_vect)
{
  wdt_disable();  // disable watchdog
}

void LogData ()//START of datalogger

METHODS***************************************************************************
{
  // TO DO code here for datalogger
   
  digitalWrite (ledPINgrn, HIGH); //led on when logging during testing
  delay(5000); // delay 5 sec
}  // end of Datalogger

methods***********************************************************************************


void setup()
{
  // when testing using leds initialise outputs for leds
  pinMode(ledPINred, OUTPUT);
  pinMode(ledPINgrn, OUTPUT);
  digitalWrite (ledPINred, LOW);
  digitalWrite (ledPINgrn, LOW);

}

void loop ()
{
old_ADCSRA = ADCSRA; //save old status of ADC
  //=============SLEEP ROUTINES========================================================================
  for (int myLoop= 0; myLoop < 64; myLoop++) // SLEEP-LOOP loop around and give delay of 64 = 600 sec (10

mins)

  {
   
digitalWrite (ledPINred, HIGH); //led on when sleep
     
    // disable ADC
    ADCSRA = 0; 

    // clear various "reset" flags
    MCUSR = 0;     
    // allow changes, disable reset
    WDTCSR = _BV (WDCE) | _BV (WDE);

    // set interrupt mode and an interval
    WDTCSR = _BV (WDIE) | _BV (WDP3) | _BV (WDP0);    // set WDIE, and 8 seconds delay

    wdt_reset();  // pat the dog

    set_sleep_mode (SLEEP_MODE_PWR_DOWN); 
    sleep_enable();

    // turn off brown-out enable in software
    MCUCR = _BV (BODS) | _BV (BODSE);
    MCUCR = _BV (BODS);
   
    sleep_cpu ();  //nighty-night :)
  }

  // cancel sleep as a precaution
  sleep_disable();

digitalWrite (ledPINred, LOW); //red led off when logging

  //++++++++++++++++++++WAKE and CALL DATALOGGER++++++++++++++++++++++++++++++++++++++++
  ADCSRA = old_ADCSRA; //enable ADC need to enable so ADC can get sensor data
LogData (); // now awake so log the data - this is my datalogging method call when avr is awake it logs

sensor data and call rtc etc.. then write to SD card
digitalWrite (ledPINgrn, LOW); //indicate finished logging
} // end




If it's working the red led should come on for 512 seconds (or however long you set the sleep-loop for)

and then go off. Then the green led should come on for 5 seconds [delay(5000)] as the LogData() method is

called. I suggest for this exercise setting the sleep-loop to a low number or else you will seem to be

waiting for ages.

cheers

Craig Turner, blog: http://gampageek.blogspot.co.uk/ It helps with my learning if I write things down, esp. for others to follow (constructive comments welcomed to improve)

Go Up