openenergy project with 2 or 3 led pulses? (seeeduino stalker)

http://www.airsensor.co.uk/component/zoo/item/energy-monitor.html

I made this project and works perfect.
now i want to add my gas meter as well ( also with a led puls for every 0,01 M3)

I try to add this in the sketch, but it seems that i have not enough knowledge about C.

Does sombody allready made a sketch for 2 or 3 input? and do you wan to share it with me?
I will be very pleased with it.

A quick scan of the code revealed that you are using interrupts for counting the pulses. As an Arduino has two external IRQ's lines - http://arduino.cc/en/Reference/AttachInterrupt - so it should be easily expanded to 2 lines. I don't know how long the LEDS of the various meters flashes but if that is long enough you could use polling instead, enabling more lines.

-- update --

I saw 1000 impulses /KWH on the device; from the piece of the spreadsheet I see only about 10 pulses/minute; from the graph the maxpeak = 375 pulses in 5 minutes = 1.25 pulse per second => so the maximum in practice is in the order of 10 per second, meaning 50 msec flashes - could be pollable - but it depends on the length of the flash.

There might be another way.

I haven't played around with this myself yet, just kind of tossed it around in my head, but I don't see why it wouldn't work for a digital signal.

You could use a single interrupt, with all of your interrupting signals wired into it, and also wired into their own individual input pins. The one interrupt signal would be isolated with diodes allowing current to flow toward the arduino. This way you have a single interrupt listener which within itself detects which input triggered it and calls an appropriate function.

There are a few caveats with this method. What immediately jumps out at me is that it wouldn't work if you have frequently triggering inputs which have a long duration. This would lead to more than one input to be enabled at the same time. You could use a debounce type of logic to check for this and detect it in software, but it makes it more complicated.\

Again, this is just an idea which I'm going to implement in my smart house design, 3 inputs will trigger a single interrupt. Light switch and 2 trip-wire IR sensors. With the other interrupt for a touch screen lcd

There's no reason you can't wire-AND many inputs together using diodes (or logic) as long as the signals are appropriate, and you have mentioned one example that may break the system.

Another way to do this is to delve deeper into the AVR and use pin change interrupts. That affectively does the same thing, ie up to 8 pins can share an interrupt.


Rob

attachInterrupt(gaslogInterrupt, gasinterruptHandler, FALLING);

When i add the line above, i get a error writing SD card.

It seems that the scetch has a problem with mij void gasinterruptHandler.
When i change it in elektrainterruptHandler, there is no problem.

Who can help me?

I add the full sketch below this line.

#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

const long logInterval = 10; // De intervaltijd tussen elke log

// LED pins
const int elektraLedPin = 4; // LED indicatie elektra puls gesignaleerd
const int schrijfLedPin = 5; // LED indicatie dat er data naar de SD kaart wordt weggeschreven
const int errorLedPin = 6; // LED indicatie error met SD kaart
const int gasLedPin = 7; // LED indicatie gas puls gesignaleerd

const char *fileName = “logdata.csv”; // De naam van de logfile

const int elektralogInterrupt = 1; // ATmega 168 and 328 - interrupt 0 = pin 2, 1 = pin 3
const int elektrainterruptPin = 3; // Elektra pulsen input

const int gaslogInterrupt = 0; // ATmega 168 and 328 - interrupt 0 = pin 2, 1 = pin 3
const int gasinterruptPin = 2; // Gas pulsen input

SdCard card;
Fat16 LogFile;

volatile unsigned long wattSensor = 0; // Telt elektra pulsen in interrupt, 1 pulse = 1 watt
volatile unsigned long gasSensor = 0; // Telt gas pulsen in interrupt, 1 pulse = 1 watt

volatile byte dataState = 0; // Gebruikt om de elektraLedPin te blinken in geval van data update
unsigned long totalWatts = 0; // Totaal elektra pulsen sinds de sketch is gestart

time_t nextTrigger;

void setup(void)
{
setSyncProvider(RTC.get); // Deze fuctie geeft de tijd van de RTC
//setTime(21,30,0,19,2,11); // set tijd en datum op 17:05:00 1 Mar 2010
//RTC.set(now()); // set de RTC met de tijd zoals in voorgande regeld ingesteld is.

pinMode(elektraLedPin, OUTPUT); // LED interrupt indicator initialization
pinMode(gasLedPin, OUTPUT);
pinMode(schrijfLedPin, OUTPUT);
pinMode(errorLedPin, OUTPUT);

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

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

attachInterrupt(elektralogInterrupt, elektrainterruptHandler, FALLING);

attachInterrupt(gaslogInterrupt, gasinterruptHandler, FALLING);

nextTrigger = now() + logInterval; // schedule the logging time

// 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”);
}

void loop(void)
{
time_t timeStamp = now();
if( timeStamp >= nextTrigger)
{
digitalWrite(schrijfLedPin, HIGH);
printDateTime(timeStamp);
MeterPulseLog();
LogFile.println();
// write the data to the card at the end of every line
if (!LogFile.sync())
error(4);

nextTrigger += logInterval;// schedule the next log time
digitalWrite(schrijfLedPin, LOW);
}

// blink the LED to show meter pulses

if( digitalRead(elektrainterruptPin)== LOW ) // Led oplichten als de PIN 3 low is.
{
digitalWrite(elektraLedPin, HIGH);
delay(100); // Led oplichten voor 100 ms
}
else
digitalWrite(elektraLedPin, LOW);

if( digitalRead(gasinterruptPin)== LOW ) // Led oplichten als de PIN 2 low is.
{
digitalWrite(gasLedPin, HIGH);
delay(100); // Led oplichten voor 100 ms
}
else
digitalWrite(gasLedPin, LOW);
}

void MeterPulseLog()
{
unsigned long wattSensorCount; //number of watts during this logging interval
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(errorLedPin, HIGH);
delay(err * 200);
digitalWrite(errorLedPin, LOW);
delay(200);
}
}

void printDateTime(time_t t)
{
printDigits(hour(t),’:’ );
printDigits(minute(t),’:’ );
printDigits(second(t),’,’ ); // uncomment this to print seconds (and replace the comma above with colon)
// print a space here if you need it
printDigits(day(t),’//’ );
printDigits(month(t),’//’ );
// LogFile.print(year(t)); // prints year using 4 digits
LogFile.print(year(t)-2000); // prints year using 2 digits
LogFile.print(’,’);
}

void printDigits(int digits, char seperator)
{
// utility function time with leading 0
if(digits < 10)
LogFile.print(‘0’);
LogFile.print(digits);
LogFile.print(seperator);
}

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

void gasinterruptHandler() // routine called when external interrupt is triggered
{
gasSensor = gasSensor + 1; //Update number of pulses, 1 pulse = 0,01 m3
}

Given that gasSensor is never used I can't see why that ISR would cause problems.

However this is a little strange

void MeterPulseLog()
{
    unsigned long wattSensorCount;   //number of watts during this logging interval 
    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);        
}

a) theres a cli() with no matching sei() b) if Logfile.print need interrupts you're in trouble

SREG = oldSREG; should restore the interrupt bit but this is a strange way to do things.


Rob