Pages: [1] 2   Go Down
Author Topic: Seeeduino Stalker Sketches  (Read 9178 times)
0 Members and 1 Guest are viewing this topic.
Washington State, US
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have been working with the Seeeduino Stalker for a couple of weeks and thought I would pass on what I have learned about it. I bought mine from Robotshop, I also bought a Seeedstudio UartSB V2.2 USB to Serial module to interface with it. Info can be found at:

http://www.robotshop.com/seeedstudio-stalker-wireless-sensor-network-node.html
http://www.robotshop.com/seeedstudio-uartsb-v2-2-usb-to-serial.html

I've noticed that the documentation and demo sketches for the Stalker is somewhat sparse so I am going to post some of the code I have been working on here. I will start with a rework of the demo code that is supplied with the Stalker. I will follow up with more sketches as time permits.

Code:
#include "FileLogger.h" // http://code.google.com/p/arduino-filelogger/
#include <Time.h>  
#include <Wire.h>  
#include <DS1307RTC.h>  // a basic DS1307 library - http://www.arduino.cc/playground/Code/Time

byte start[7]= {
  'B','e','g','i','n',0x0D,0x0A};
byte Buffer[23]; //Buffer for printing to SD card
int temp; //temp test data
time_t oldtime=0; //last time loop has ran
int result; //status of SD card write - 0 = "OK", 1 = "Fail initializing", 2 = "Fail appending"
unsigned long loggingRate=5; //logging rate in seconds
int length; //length of buffer string

void setup(void)
{
  do
  {
    result = FileLogger::append("data.txt", start, 7);//Initialize the SD Card
  }
  while(result != 0);

  // the next two lines can be removed if the RTC has been set

  //  setTime(17,05,0,1,3,10); // set time to 17:05:00  1 Mar 2010 (see below)
  //  RTC.set(now());  // set the RTC to the current time (set in the previous line)

  // format for setting time - setTime(hr,min,sec,day,month,yr);

  setSyncProvider(RTC.get);   // the function to get the time from the RTC

  Serial.begin(9600); //initialize serial port
}

void loop(void)
{
  //if( now() >= oldtime + loggingRate) //proceed with loop if loggingRate seconds have elapsed
  if(minute() != oldtime) //use this if 1 minute intervals is desired
  {
    //oldtime = now(); //use this if loggingRate seconds is desired
    oldtime = minute(); //use this if 1 minute intervals is desired
    do
    {
      temp=month();
      Buffer[0]=(temp/10)+'0';
      Buffer[1]=(temp%10)+'0';
      Buffer[2]='/';
      temp=day();
      Buffer[3]=(temp/10)+'0';
      Buffer[4]=(temp%10)+'0';
      Buffer[5]='/';
      temp=year();
      Buffer[6]=((temp-2000)/10)+'0';
      Buffer[7]=((temp-2000)%10)+'0';
      Buffer[8]=' ';
      temp=hour();
      Buffer[9]=(temp/10)+'0';
      Buffer[10]=(temp%10)+'0';
      Buffer[11]=':';
      temp=minute();
      Buffer[12]=(temp/10)+'0';
      Buffer[13]=(temp%10)+'0';
      Buffer[14]=':';
      temp=second();
      Buffer[15]=(temp/10)+'0';
      Buffer[16]=(temp%10)+'0';
      Buffer[17]=' ';
      temp=999;
      Buffer[18]=(temp/100)+'0';
      Buffer[19]=((temp%100)/10)+'0';
      Buffer[20]=(temp%10)+'0';
      Buffer[21]=0x0D;
      Buffer[22]=0x0A;

      length=sizeof(Buffer);
      result = FileLogger::append("data.txt", Buffer, length); //write data to SD card
    }
    while( result != 0); //repeat loop until successful write to SD card

    for (int i=0; i < length ;i++) {
      Serial.print(Buffer[i]); //Serial print buffer string to serial monitor or xBee
    }
  }
}

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi
You got that right .... nice improvement on the original code, as I'm new to arduino and stalker it was a good insite ... cant wait for your next instalment.

cheers
Jack
Logged

Washington State, US
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Jack,
There has been a discussion about the Stalker demo code in the Syntax & Program section that you might want to look at. The link is:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1267698132

Following are two updated demo codes. The first has a small modification for the time function.

Code:
#include "FileLogger.h" // http://code.google.com/p/arduino-filelogger/
#include <Time.h>  
#include <Wire.h>  
#include <DS1307RTC.h>  // a basic DS1307 library - http://www.arduino.cc/playground/Code/Time

byte start[7]= {
  'B','e','g','i','n',0x0D,0x0A};
byte Buffer[23]; //Buffer for printing to SD card
int temp; //temp test data
time_t oldtime=0; //last time loop has ran
int result; //status of SD card write - 0 = "OK", 1 = "Fail initializing", 2 = "Fail appending"
unsigned long loggingRate=5; //logging rate in seconds
int length; //length of buffer string

void setup(void)
{
  do
  {
    result = FileLogger::append("data.txt", start, 7);//Initialize the SD Card
  }
  while(result != 0);

  // the next two lines can be removed if the RTC has been set

  //  setTime(17,05,0,1,3,10); // set time to 17:05:00  1 Mar 2010 (see below)
  //  RTC.set(now());  // set the RTC to the current time (set in the previous line)

  // format for setting time - setTime(hr,min,sec,day,month,yr);

  setSyncProvider(RTC.get);   // the function to get the time from the RTC

  Serial.begin(9600); //initialize serial port
}

void loop(void)
{
  time_t t = now();
  //if( t >= oldtime + loggingRate) //proceed with loop if loggingRate seconds have elapsed
  if(minute(t) != oldtime) //use this if 1 minute intervals is desired
  {
    //oldtime = t; //use this if loggingRate seconds is desired
    oldtime = minute(t); //use this if 1 minute intervals is desired
    do
    {
      temp=month(t);
      Buffer[0]=(temp/10)+'0';
      Buffer[1]=(temp%10)+'0';
      Buffer[2]='/';
      temp=day(t);
      Buffer[3]=(temp/10)+'0';
      Buffer[4]=(temp%10)+'0';
      Buffer[5]='/';
      temp=year(t);
      Buffer[6]=((temp-2000)/10)+'0';
      Buffer[7]=((temp-2000)%10)+'0';
      Buffer[8]=' ';
      temp=hour(t);
      Buffer[9]=(temp/10)+'0';
      Buffer[10]=(temp%10)+'0';
      Buffer[11]=':';
      temp=minute(t);
      Buffer[12]=(temp/10)+'0';
      Buffer[13]=(temp%10)+'0';
      Buffer[14]=':';
      temp=second(t);
      Buffer[15]=(temp/10)+'0';
      Buffer[16]=(temp%10)+'0';
      Buffer[17]=' ';
      temp=999;
      Buffer[18]=(temp/100)+'0';
      Buffer[19]=((temp%100)/10)+'0';
      Buffer[20]=(temp%10)+'0';
      Buffer[21]=0x0D;
      Buffer[22]=0x0A;

      length=sizeof(Buffer);
      result = FileLogger::append("data.txt", Buffer, length); //write data to SD card
    }
    while( result != 0); //repeat loop until successful write to SD card

    for (int i=0; i < length ;i++) {
      Serial.print(Buffer[i]); //Serial print buffer string to serial monitor or xBee
    }
  }
}

For the second demo sketch I wrote a function that will pad the data values without the cascading modulo divide statements. On the demo sketch it increased the sketch size slightly but on another sketch I wrote it reduced the sketch size by about 600 bytes.

Code:
#include "FileLogger.h" // http://code.google.com/p/arduino-filelogger/
#include <Time.h>  
#include <Wire.h>  
#include <DS1307RTC.h>  // a basic DS1307 library - http://www.arduino.cc/playground/Code/Time

byte start[7]= {
  'B','e','g','i','n',0x0D,0x0A};
byte Buffer[23]; //Buffer for printing to SD card
int temp; //temp test data
time_t oldtime=0; //last time loop has ran
int result; //status of SD card write - 0 = "OK", 1 = "Fail initializing", 2 = "Fail appending"
unsigned long loggingRate=5; //logging rate in seconds
int length; //length of buffer string

void setup(void)
{
  do
  {
    result = FileLogger::append("data.txt", start, 7);//Initialize the SD Card
  }
  while(result != 0);

  // the next two lines can be removed if the RTC has been set

  //  setTime(17,05,0,1,3,10); // set time to 17:05:00  1 Mar 2010 (see below)
  //  RTC.set(now());  // set the RTC to the current time (set in the previous line)

  // format for setting time - setTime(hr,min,sec,day,month,yr);

  setSyncProvider(RTC.get);   // the function to get the time from the RTC

  Serial.begin(9600); //initialize serial port
}

void loop(void)
{
  time_t t = now();
  //if(t >= oldtime + loggingRate) //proceed with loop if loggingRate seconds have elapsed
  if(minute(t) != oldtime) //use this if 1 minute intervals is desired
  {
    //oldtime = t; //use this if loggingRate seconds is desired
    oldtime = minute(t); //use this if 1 minute intervals is desired
    do
    {
      printDigits(month(t),0,2); //month
      Buffer[2]='/';
      printDigits(day(t),3,2); //day
      Buffer[5]='/';
      printDigits(year(t)-2000,6,2); //year-yy
      Buffer[8]=',';
      printDigits(hour(t),9,2); //hour
      Buffer[11]=':';
      printDigits(minute(t),12,2); //minutes
      Buffer[14]=':';
      printDigits(second(t),15,2); //seconds
      Buffer[17]=',';
      printDigits(123,18,3); //test data
      Buffer[21]=0x0D;
      Buffer[22]=0x0A;

      length=sizeof(Buffer);
      result = FileLogger::append("data.txt", Buffer, length); //write data to SD card
    }
    while( result != 0); //repeat loop until successful write to SD card

    for (int i=0; i < length ;i++) {
      Serial.print(Buffer[i]); //Serial print buffer string to serial monitor or xBee
    }
  }
}

void printDigits(unsigned long tempBuffer, int bufferPntr, int numberDigits)
{
  unsigned long modDivide = 1;
  for (int i = 0; i < numberDigits; i++) {
    Buffer[bufferPntr+numberDigits-1-i]=((tempBuffer%(modDivide*10))/modDivide)+'0';
    modDivide=modDivide*10;
  }
}
Logged

Washington State, US
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The original reason I started with the Arduino was to log data from my smart electrical meter. The following is the latest code from that project and is built using the demo code. I have another version that shows the data on a LCD but I need to adapt it to the Stalker.

Code:
//Meter reading program using Itron smart meter
//Added LED that turns on/off with each watt

#include "FileLogger.h" // http://code.google.com/p/arduino-filelogger/
#include <Time.h>  
#include <Wire.h>  
#include <DS1307RTC.h> // a basic DS1307 library - http://www.arduino.cc/playground/Code/Time

const int ledPin = 14; // LED watt indicator initialization. Turns on or off each time a watt is measured
int ledState = LOW;

volatile unsigned long wattSensor=0;  //Counts power pulses in interrupt, 1 pulse = 1 watt
unsigned long wattSensorTemp=0;  //Temporary power pulse counts for printing - watts
unsigned long totalWatts=0; //Temporary total power used for printing - watts

byte start[7]= {
  'B','e','g','i','n',0x0D,0x0A};
byte Buffer[31]; //Buffer for printing to SD card
time_t oldtime=0; //last time loop has ran
int result; //status of SD card write - 0 = "OK", 1 = "Fail initializing", 2 = "Fail appending"
unsigned long loggingRate=5; //logging rate in seconds
int length; //length of buffer string

void setup(void)
{
  pinMode(ledPin, OUTPUT);  // LED watt indicator initialization
  attachInterrupt(1, wattSensorInterrupt, FALLING);  //interrupt1 - digital pin 3 - If we detect a change from HIGH to LOW we call wattSensorInterrupt

  do
  {
    result = FileLogger::append("data.txt", start, 7);//Initialize the SD Card
  }
  while(result != 0);

  // the next two lines can be removed if the RTC has been set
  //  setTime(17,05,0,1,3,10); // set time to 17:05:00  1 Mar 2010
  //  RTC.set(now());  // set the RTC to the current time (set in the previous line)

  // format for setting time - setTime(hr,min,sec,day,month,yr);

  setSyncProvider(RTC.get);   // the function to get the time from the RTC

  Serial.begin(9600);
}

void loop(void)
{
  time_t t = now();
  //  if(t >= oldtime + loggingRate) //proceed with loop if loggingRate seconds have elapsed
  if( minute(t) != oldtime) //use this if 1 minute intervals is desired
  {
    wattSensorTemp=wattSensor; //number of watts for interval
    wattSensor=0; //reset watts counter
    totalWatts=totalWatts+wattSensorTemp; //total watts counter
    oldtime = minute(t); //use this for one minute interval
    //oldtime = t; //or this for loggingRate interval

    do
    {
      Buffer[0]='A'; //start packet/Site ID
      Buffer[1]=','; //start of data string
      //format of printDigits - printDigits(tempBuffer,bufferPntr,numberDigits)
      printDigits(t,2,10); //t = now()
      Buffer[12]=',';
      printDigits(wattSensorTemp,13,5); //wattSensorTemp
      Buffer[18]=',';
      printDigits(totalWatts,19,8); //totalWatts
      Buffer[27]=',';
      Buffer[28]='>'; //end data packet
      Buffer[29]=0x0D;
      Buffer[30]=0x0A;

      length=sizeof(Buffer);
      result = FileLogger::append("data.txt", Buffer, length);
    }
    while( result != 0);

    for (int i=0; i < length ;i++) {
      Serial.print(Buffer[i]); //Serial print buffer string to serial monitor or xBee
    }
  }
}

void wattSensorInterrupt() //Interrupt1 counter routine for counting watts
{
  wattSensor=wattSensor+1;  //Update number of pulses, 1 pulse = 1 watt
  if (ledState == LOW) //Cycle LED on or off each time one watt is counted
    ledState = HIGH;
  else
    ledState = LOW;
  digitalWrite(ledPin, ledState);
}

void printDigits(unsigned long tempBuffer, int bufferPntr, int numberDigits) //assign data to output array
{
  unsigned long modDivide = 1;
  for (int i = 0; i < numberDigits; i++) {
    Buffer[bufferPntr+numberDigits-1-i]=((tempBuffer%(modDivide*10))/modDivide)+'0';
    modDivide=modDivide*10;
  }
}

edit: corrected the location of the time library
« Last Edit: May 15, 2010, 08:06:53 pm by CRS8291 » Logged

UK
Offline Offline
Sr. Member
****
Karma: 1
Posts: 278
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi CRS8291,

Thanks for sharing - much appreciated.

I would like to try your meter logger out here in the UK, can I check I understand the code right :-)

You have a light sensor hooked up to pin 14 and placed over the meter LED.
Stalker counts how many light impuleses occur on the meter LED in a 5 second interval (each pulse being 1W).
At the end of every 5 second time frame Stalker writes to the SD card the time stamp and number of impulses (watts)......

About right?   smiley

Logged

Washington State, US
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi point5,

The IR sensor is connected to digital pin 3 and is declared in the attachInterrupt statement:

Code:
 attachInterrupt(1, wattSensorInterrupt, FALLING);  //interrupt1 - digital pin 3 - If we detect a change from HIGH to LOW we call wattSensorInterrupt

The LED connected to pin 14 is a visual indicator that turns on or off each time the IR sensor detects an IR pulse. This is not needed but lets the user know that the Stalker is detecting pulses.

The sketch has two time options. As it it written now, it will record pulse totals every minute. This can be easily changed by commenting out the one minute options and uncommenting the two lines that use the 5 second intervals. Here are the lines of the sketch that control the time:

Code:
[glow]  //  if(t >= oldtime + loggingRate) //proceed with loop if loggingRate seconds have elapsed
  if( minute(t) != oldtime) //use this if 1 minute intervals is desired[/glow]
  {
    wattSensorTemp=wattSensor; //number of watts for interval
    wattSensor=0; //reset watts counter
    totalWatts=totalWatts+wattSensorTemp; //total watts counter
[glow]    oldtime = minute(t); //use this for one minute interval
    //oldtime = t; //or this for loggingRate interval[/glow]

You can change the loggingRate interval variable for other intervals or replace the minute(t) with other logging intervals such as hour(t), day(t), month(t) or year(t).

I have been gone for about two weeks and just checked the Stalker and it looks like it has collected all of the power data while I was away.
Logged

UK
Offline Offline
Sr. Member
****
Karma: 1
Posts: 278
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi CRS8291,

Thanks for getting back to me with a clear explaination - I understand much better now :-)

May I ask a couple more questions?

What type of sensor should I use, IR photodiode or IR phototransistor?
I also noticed my suppernoob mistake in that there is no pin 14... would this mean that the onboard 'user' LED is used in this case?

It all seems to be working fine but of course counting = 0 as I have no sensor as yet :-)

Thanks
Logged

Washington State, US
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

point5,

Pin 14 is the designation for analog pin 0. I was using pin 13 on the Arduino but the Stalker uses pin 13 to indicate writes to the SD card. The onboard led at pin 13 is useful to see that the Stalker is functioning properly. Everytime data is written to the card the onboard led should flash. The Stalker uses a number of pins for the SD card and the RTC so they need to be avoided in sketches. Details about Stalker pin usage can be found at:

http://www.seeedstudio.com/forum/viewtopic.php?f=4&t=727

I have not found the perfect sensor yet because the ones I have been using are affected by ambient light. I have gotten around this by covering the meter with a bucket to keep light out. I would like to find a better solution but have not had time. I think I need to use a light filter like the ones on the front of a TV, DVD player, etc. The sensor I am using now is a Light to Voltage TAOS Photodiode part number TSL267-LF from Mouser. I like this sensor because it is easy to hook up and is side looking so it lays flat on the meter port. I've tried other sensors which all work but require playing with resistor values to get a good signal. Pictures of my light cover and other sensor and sketch ideals can be found at:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1258971285/15

For testing, I connected a red LED and IR LED to a pin and added code to the sketch that would flash them at a known rate which I then could measure with the sensor. I also tested the code by connecting the sensor pin to the test 500 hz signal on the JYEscope. This worked but can over run the buffer quickly.
Logged

UK
Offline Offline
Sr. Member
****
Karma: 1
Posts: 278
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi CRS8291,

Becoming clearer all the time :-)

I have hunted round for a filtered IR photodiode and found these which I though could be worth a try?  OSRAM SFH203-FA - I will let you know how I get on - hopefully later this week - I would be happy to send you couple of these as a small token of thanks if you fancy a play?

And another noob question.... relating to the time stamp.  My output is shown below..... how would I get the time to be formated as follows.... 20:13:00,07/06/10 - ie time,date?
 
A,1275941545,00000,00000000,>
A,1275941580,00000,00000000,>
Logged

Washington State, US
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi point5,

Quote
And another noob question.... relating to the time stamp.  My output is shown below..... how would I get the time to be formated as follows.... 20:13:00,07/06/10 - ie time,date?

A,1275941545,00000,00000000,>

It depends whether you want the Stalker sketch to do it or post process the data. If you want to go the Stalker route, the demo sketches that I posted earlier would require minor adjustments to get the format you want. You might want to play with the demo code and reorder the date and time to your specifications.

Currently the power meter sketch is outputting the date in Unix time which is the number of seconds since 1/1/1970. I am using Excel and Access to handle the data and they measure the date/time as the number of days since 1/1/1900. To convert a value from Unix to Excel/Access I use the following formula:

Excel/Access Date/Time = (Unix Time/86400)+25569

From here the data can be formated to your needs. The link I posted on May 15 to the Syntax and Program section offers more info regarding date and time. On that thread mem posted example code that would calculate time in Excel/Access format but would require floating point math which might tax the limited amount of resources the Stalker has available.
Logged

UK
Offline Offline
Sr. Member
****
Karma: 1
Posts: 278
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi CRS8291,

I have now got the sensor working correctly with the test code below.  Unfortunately I don't understand, at all, how the digital pin 3 is assigned to the sensor in your code and was wondering if you might be able to help me merge the two to get my analog sensor working in your sketch?

Code:
int ledPin =  13;    // LED connected to digital pin 13
int sensorPin = 1;   // SFH203FA connected to analog pin 1
int sensorState = 0;



void setup()   {
  // initialize the digital pin as an output:
  pinMode(ledPin, OUTPUT);
  pinMode(sensorPin, INPUT);
 Serial.begin(9600);
}

void loop(){
  // read the state of the sensor value:
  sensorState = analogRead(sensorPin);

  // check if the sensor is receiving.
  // if it is, the ledState is HIGH - have guessed a theshhold value of 100?
  if (sensorState > 100) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
  }
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
  Serial.println(sensorState);
}
Logged

Washington State, US
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi point5,

The sketch is using an interrupt for counting pulses. I have configured the interrupt to count a pulse whenever it sees the signal falling. I did this because I was picking up low light signals that were giving false counts when using the rising condition. The interrupt is called out in the following line:

Code:
attachInterrupt(1, wattSensorInterrupt, FALLING);  //interrupt1 - digital pin 3 - If we detect a change from HIGH to LOW we call wattSensorInterrupt

The interrupt calls function wattSensorIntterupt any time it detects a falling signal. There is a good explanation of the attachInterrupt in the help section:

http://www.arduino.cc/en/Reference/AttachInterrupt

There are further examples and help in the playground:

http://www.arduino.cc/playground/Main/GeneralCodeLibrary

I hope that helps and look forward to seeing your project.
Logged

UK
Offline Offline
Sr. Member
****
Karma: 1
Posts: 278
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi CRS8291,

Thanks for helping - I get it now :-)  I have the logger running at the moment - looking forward to seeing the results.

One of the problems I was having turned out to be the power supply - I was running the Stalker off the Seeedstudio Solar Sheild with LiPo battery - this casued the sensor to flicker on and off very quickly.  Swapping to a 9V battery straight in to the Stalker has solved this, I guess it must be noise of some kind?

Anyway, thanks again CRS8291 - you have been a great help and it's much appreciated.
Logged

East Coast, USA
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rock salt
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Great thread! It's really helping me set up my Stalker.

Here's a very basic sketch for someone who just wants to set / read the RTC and don't need the SD card code. I'm sure most people can figure it out from the code above, but this is it stripped to the bare minimum:

Code:
#include <Wire.h>

#include "Time.h"
#include "DS1307RTC.h"


void setup()
{
     Serial.begin(9600);

  // the next two lines can be removed if the RTC has been set

  //  setTime(6,51,0,6,8,10); // set time to 17:05:00  1 Mar 2010 (see below)
  //  RTC.set(now());  // set the RTC to the current time (set in the previous line)

  // format for setting time - setTime(hr,min,sec,day,month,yr);

  setSyncProvider(RTC.get);   // the function to get the time from the RTC

}


void loop()
{
   Serial.print( "The time is ");

  Serial.print( year() );
   Serial.write('/');

   Serial.print( month() );
   Serial.write('/');

   Serial.print( day() );
   Serial.write(' ');

   Serial.print( hour() );
   Serial.write(':');

   Serial.print( minute() );
   Serial.write(':');

   Serial.println( second() );
        

}

Logged

Washington State, US
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There has been a new example for power monitoring posted on the Seeedunio forum. It has good documentation and will be useful for many users. I have rewritten my sketch using some of the code from the example with some other changes to fit my needs.

One change was using a Switch....Case statement for determining when different events would happen. At this time when seconds = 0 it averages the power usage and writes the data to the SD card. This allows me to easily add other timed events as needed.

Code:
/*
 * StalkerFile16Logger.pde - Meter reading logic for logging
 * This version logs pulses on digital pin 3
 *
 * This program is combination of Stalker example sketch:
 * http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1273413449%20
 * and
 * AirSensorMeterLogger example
 * http://www.airsensor.co.uk/component/zoo/item/energy-monitor.html
 *
 * CRS8291 - Arduino forum username
 */

#include <Fat16.h>      // the SD Card library - http://code.google.com/p/fat16lib/
#include <Wire.h>  
#include <Time.h>  
#include <DS1307RTC.h> // a basic DS1307 library - http://www.arduino.cc/playground/Code/Time

// LED pins
const int  dataLedPin    =  4;  // LED indicating sensor data is received
const int  logLedPin     =  5;  // LED flashes during a log attemp
const int  fileLedPin    =  6;  // LED turns on if a file error occurs

const int  siteID        =  10;  // Site identifier

const char *fileName = "logdata.csv";  // the name of the log file

const int logInterrupt = 1; // ATmega 168 and 328 - interrupt 0 = pin 2, 1 = pin 3
const int interruptPin = 3;

SdCard card;
Fat16 LogFile;

volatile unsigned long wattSensor = 0;  // Counts power pulses in interrupt, 1 pulse = 1 watt
volatile byte          dataState  = 0;  // used to blink the Led to indicate data updates

unsigned long wattSensorCount; //number of watts during logging interval
unsigned long totalWatts = 0;  // Total power used since the sketch started ???

unsigned long startDelayMillis;

void setup(void)
{
  setSyncProvider(RTC.get);   // the function to get the time from the RTC

  pinMode(dataLedPin, OUTPUT);    // LED interrupt indicator initialization
  pinMode(logLedPin, OUTPUT);      
  pinMode(fileLedPin, OUTPUT);  

  pinMode(interruptPin, INPUT);    
  digitalWrite(interruptPin, HIGH);  

  attachInterrupt(logInterrupt, interruptHandler, FALLING);

  // initialize the SD card
  if (!card.init())
    error(1);

  // initialize a FAT16 volume
  if (!Fat16::init(&card))
    error(2);

  // open file for append, create if it doesn't exist
  if (!LogFile.open(fileName, O_CREAT | O_APPEND | O_WRITE))
    error(3);

  // clear write error
  LogFile.writeError = false;
  LogFile.println("Start");

  Serial.begin(9600);
}

void loop(void)
{  
  time_t t = now();

  switch(second(t)) {

  case 0: // Log data if second(t) = 0
    digitalWrite(logLedPin, HIGH);
    LogFile.print(siteID); //Site identifier
    LogFile.print(',');
    LogFile.print(t); //Unix time - Excel Time = (t/86400)+25569
    MeterPulseLog(); // Number of watts during logging interval
    LogFile.println();
    // write the data to the card at the end of every line
    if (!LogFile.sync())
      error(4);

    Serial.print(siteID); //Site identifier
    Serial.print(',');
    Serial.print(t); //Unix time - Excel Time = (t/86400)+25569
    Serial.print(',');
    Serial.print(wattSensorCount); // Number of watts during logging interval
    Serial.print(',');
    Serial.println(totalWatts); // Total power used since the sketch started

    digitalWrite(logLedPin, LOW);
    pauseWithoutDelay (1000); // Delay sketch for one second
    break;
    // default:
  }
  // blink the LED to show meter pulses
  if( digitalRead(interruptPin)== LOW ) // Light the LED when data pin is LOW
  {
    digitalWrite(dataLedPin, HIGH);    
    pauseWithoutDelay (50); // light for at least 100 ms
  }
  else
    digitalWrite(dataLedPin, LOW);  
}

void MeterPulseLog()
{
  uint8_t oldSREG = SREG;   // save interrupt register
  cli();                    // prevent interrupts while accessing the count  
  wattSensorCount = wattSensor; //get the count from the interrupt handler
  wattSensor = 0;           //reset the watts count
  SREG = oldSREG;           // restore interrupts

  totalWatts = totalWatts + wattSensorCount; //total watts counter
  LogFile.print(',');   // print comma to seprate from previous data
  LogFile.print(wattSensorCount);
  LogFile.print(',');
  LogFile.print(totalWatts);        
}

// routine handle file errors
void error(int err)
{
  // blink forever
  while(1)
  {
    digitalWrite(fileLedPin, HIGH);
    delay(err * 200);
    digitalWrite(fileLedPin, LOW);
    delay(200);  
  }
}

void pauseWithoutDelay (unsigned long delayInterval)
{
  startDelayMillis = millis();
  do {
  }
  while (millis() - startDelayMillis < delayInterval);
}

void interruptHandler() // routine called when external interrupt is triggered
{
  wattSensor = wattSensor + 1;  //Update number of pulses, 1 pulse = 1 watt
}
Logged

Pages: [1] 2   Go Up
Jump to: