Pages: [1]   Go Down
Author Topic: pulsenteller dmv interrupts  (Read 5030 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hoi allen,

Gebeten door het Arduino virus naar aanleiding van deze webpagina:
http://www.fun-tech.se/FunTechHouse/ElectricityMeter/index.php

Ben ik druk bezig om ongeveer hetzelfde te bouwen met mijn Arduino Uno rev3
een weerstand van 10K tussen GND en pin2
+5V via de opto coupel van de kWh meter verbonden met pin 2
Alleen registreert de Arduino soms meerdere pulsen van de kWh teller terwijl er in werkelijkheid maar ééntje geweest is.

Ik heb al geprobeerd om een delay in de interrupt functie te zetten maar dat is helaas niet de oplossing. Blijkbaar worden alle pulsen gebufferd en als er 5 pulsen tegelijk komen gebeurt die vertraging ook 5x na mekaar.

Bestaat hier een oplossing voor ?

Alvast bedankt,
Bart
Logged

Belgium
Offline Offline
Full Member
***
Karma: 6
Posts: 135
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ik heb al een tijdje iets soortgelijks,  ik lees echter het knipperledje uit. blijkbaar heb jij een echt schakelcontact.

Google sites webpage https://sites.google.com/site/yaeuls/
De energiemeter(kWh) via de knipperled die daar opzit (1pulse/Wh) uitlezen en via ethernet/internet versturen naar een 'internet of things' logging server Cosm.


Laat ff je code zien, kijken we even mee.
Logged

Gear: Arduino- Uno,Due,Ethernet,  OLS, Buspirate, J-Link, TDS1002, Rigol DG1022

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

Ik heb de code niet zo direkt bij de hand maar ze is zowat één op één dezelfde als in de link hierboven, alleen dan voor één meter ipv 2.
Code:
void onPulse1()
{
    //pulseCounter
    pulseCount1_Wh++;
    if(pulseCount1_Wh == 1000)
    {
        pulseCount1_Wh = 0;
        pulseCount1_kWh++;
    }
}
maar dit stukje van uw link is zeer interessant:
Code:
/-------------------------------------------------------------------------------------
//- Interupt routine - count number of pulses, initialized in setup()
//-                                                                                   -
//-------------------------------------------------------------------------------------
void Int_LedPulse()
{ if ( digitalRead(LEDPIN) == LOW )            // to flush false triggers
  { LedPulse.EventMillis = millis();           // capture timer
    LedPulse.Event=true;                       // set flag to signal PulseSensor_manager()
    LedPulse.Watthour++;
    if (LedPulse.Cnt++ == 0)
      LedPulse.Overflow = true;
  }
}//Int_LedPulse

// to flush false triggers  smiley-lol

... eigelijk is dat hele programma wel interessant, bedankt hiervoor !
Ook het ethernet gedeelte, voorlopig zit ik met een laptop die op de kast ligt te prutsen, maar je moet ergens beginnen, toch ?

Ik hou jullie op de hoogte  smiley-wink

Logged

Global Moderator
Netherlands
Online Online
Shannon Member
*****
Karma: 227
Posts: 14013
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Wat je moet doen is de tijd vd puls meten en onthouden en vergelijken met de vorige tijdstempel
Dit is zo ongeveer de simpelste vorm
Code:
volatile unsigned long prevTime = 0;

ISR()
{
  if (millis() - prevTime < 10) // minder dan 10 millisec geleden?
  {
    return;  // ignore irq
  }
  // langer dan 10 millis.. dat is een echte
  prevTime = millis();
  kwhCount++;
}
   

Logged

Rob Tillaart

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

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

Om een of andere reden kreeg ik tussendoor en snachts af en toe nog een 'puls' ingelezen terwijl dit onmogelijk kon. Na wat ge-experimenteer  lijkt deze code redelijk waterdicht te zijn als ik mijn pulsenteller vergelijk met de kWh meter zelf.
Mocht iemand hier nog wat aan hebben :
Code:
void onPulse1()
{
 
   if (millis() - prevTime < 10000) // minder dan 10 sec geleden?
  {
    return;  // dit kan niet goed zijn  ...
  }
 
  if ( digitalRead(PULSEPIN) == HIGH ) {           // kijken hoelang de pin hoog blijft ...
    delay(10);   //30 mili sec 
    if ( digitalRead(PULSEPIN) == HIGH ) {         // na 30 ms nog steeds hoog ?
       pulseCount1_10Wh++;                              // is een echte puls
        prevTime = millis();                                  // start 10 sec timer
        Serial.println("PULS");
    }
  }
  return;
}
Logged

Global Moderator
Netherlands
Online Online
Shannon Member
*****
Karma: 227
Posts: 14013
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks, werkende code is altijd nuttig

Code:
delay(10);   //30 mili sec 
conflict between comment and code ....

Quote
nog een 'puls' ingelezen terwijl dit onmogelijk kon
Hoe weet je dat zo zeker?
Logged

Rob Tillaart

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

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

Ik heb de commentaar achteraf toegevoegd blijkbaar is daar dan wat mis mee  smiley-kiss

Dat ik valse pulsen kreeg weet ik omdat de zonnepanelen in het midden van de nacht electriciteit aant produceren waren  smiley
Logged

Global Moderator
Netherlands
Online Online
Shannon Member
*****
Karma: 227
Posts: 14013
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
omdat de zonnepanelen in het midden van de nacht electriciteit aant produceren waren
Die zou ik eens heel vlug patenteren als ik jou was smiley-wink

Maar inderdaad een onwaarschijnlijke puls! (ik moet wel denken aan die meteoriet in Rusland pas, gaf ook veel licht)
Logged

Rob Tillaart

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

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

De pulsenteller werkt ondertussen vlekkeloos en nu hebben we er een Ethernet shield op gezet zodat het opzet zelfstandig kan werken.
We hebben er ook enkele temp sensoren bij gehangen om de status van de zonneboiler te meten en dan gelijk ook een warmluchtcollector 'sturing' bijgebouwd.
Dit alles werkt netjes  smiley ... voor een paar uur en dan stopt de arduino ermee  smiley-confuse
Wel lastig om de oorzaak te vinden aangezien je een dag of een halve dag moet wachten bij elke verandering om te kijken of het nog mis loopt maar dat zie ik als onderdeel van de hobby    smiley-twist

Mocht iemand interesse hebben hier is de code die ik verzonnen heb als daar grote hiaten in zitten hoor ik dat graag natuurlijk:
Code:
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPI.h>
#include <Ethernet.h>

// PIN definition
#define PULSEPIN 2      // kWh meter puls pin
#define ONE_WIRE_BUS 3  // temp data wire
#define FAN_RELAY 4     // fan for solar collector
#define ERROR_LED 5     // Error led


#define TEMP_VERSCHIL 10  // delta-T to activate keuken fa


// ethernet
byte mac[] = {  
  0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
char serverName[] = "emon.site";
EthernetClient client;
// temperature stuff
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress BruineThermometerKeuken = {
  0x28, 0xE6, 0xAC, 0x00, 0x04, 0x00, 0x00, 0x09 };//bruin
DeviceAddress BlauweThermometerKeuken = {
  0x28, 0x2D, 0xC5, 0x00, 0x04, 0x00, 0x00, 0x8C}; //blauw
//  DeviceAddress BruineThermometer = { 0x28, 0x36, 0xD7, 0x00, 0x04, 0x00, 0x00, 0xD0 };//bruin
DeviceAddress BruineThermometer = {
  0x28, 0xED, 0xD4, 0x00, 0x04, 0x00, 0x00, 0xA2 };//bruin
DeviceAddress BlauweThermometer = {
  0x28, 0xFF, 0xDA, 0x00, 0x04, 0x00, 0x00, 0x35 }; //blauw

//interupt pulse counter
volatile unsigned int pulseCount1_10Wh  = 0;  
volatile unsigned long prevTime = 0;
int busy = 0;

// global variabeles
char urlStr[128];

/******************************************
 *  Pulse interupt handler
 ******************************************/
void onPulse1()
{
    Serial.println("interupt");
  if (millis() - prevTime < 5000){ // less than 5 sec ago?
    return;  // ignore irq
  }
  if ( digitalRead(PULSEPIN) == HIGH ) {           // to flush false triggers
    delay(10);   //30 mili sec  
    if ( digitalRead(PULSEPIN) == HIGH ) {         // still low
      pulseCount1_10Wh++;            // it must be a pulse
      prevTime = millis();
      Serial.println("PULS");
    }
  }
  return;
}
/******************************************
 *  SETUP
 ******************************************/
void setup(void)
{
  // start serial port
  Serial.begin(9600);  //start serial port
  Serial.println("Hello");
 
  sensors.begin();     // Start up the library
  sensors.setResolution(BruineThermometerKeuken, 9); // set the resolution to 10 bit (good enough?)
  sensors.setResolution(BlauweThermometerKeuken, 9);
  sensors.setResolution(BruineThermometer, 9); // set the resolution to 10 bit (good enough?)
  sensors.setResolution(BlauweThermometer, 9);  
  //sensors.requestTemperatures();
  delay(3000);
  pinMode(FAN_RELAY, OUTPUT);
  pinMode(ERROR_LED, OUTPUT);
  initEth();
  delay(3000);
   attachInterrupt(0,onPulse1,RISING);

}
/******************************************
 *  Initialise Ethernet
 ******************************************/
void initEth()
{
  Serial.println("Init Ethernet");
  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
  // give the Ethernet shield a second to initialize:
  delay(3000);
  Serial.println("connecting...");
}

/******************************************
 *  get temperature from sensor
 ******************************************/
float getTemperature(DeviceAddress deviceAddress)
{
  sensors.requestTemperatures();
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
    Serial.println("Failed to read temperature");
    return (0);
  }
    Serial.print("Temp is:");
    Serial.println(tempC);

  return (tempC);
}
/******************************************
 *  Switch keuken ventilator
 ******************************************/
void fanControl()
{
  float deltaT = getTemperature(BruineThermometerKeuken) - getTemperature(BlauweThermometerKeuken);
  if (deltaT > TEMP_VERSCHIL){
    digitalWrite(FAN_RELAY, HIGH);
  }
  else {
    digitalWrite(FAN_RELAY, LOW);
  }
}
/******************************************
 *  Format URL to update emon site
 ******************************************/
void sendData2()
{
  if (client.connect(serverName, 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    //client.println("GET http://emoncms.org/input/post.json?json={power:**************** HTTP/1.0");
    client.print("GET http://emoncms.org/input/post.json?node=2&csv=");
    client.print(pulseCount1_10Wh*10*12); // avge Watt 5min
    client.print(",");
    client.print(getTemperature(BruineThermometer));
    client.print(",");
    client.print(getTemperature(BlauweThermometer));
    client.print(",");
    client.print(getTemperature(BruineThermometerKeuken));
    client.print(",");
    client.print(getTemperature(BlauweThermometerKeuken));
    if ( digitalRead(FAN_RELAY) == HIGH ) {         // fan on
      client.print(",10");
    }
    else {
      client.print(",0");
    }
    client.println("&apikey=***************** HTTP/1.0");


    client.println();

    Serial.println("read from server.");
    while (client.available()) { // print response ...
      char c = client.read();
      Serial.print(c);
    }

    Serial.println("done sending data, disconnect from emon.");
    client.stop();  //disconnect
    pulseCount1_10Wh = 0;  //reset counter
    digitalWrite(ERROR_LED, LOW); // disable alarm

  }
  else {
    digitalWrite(ERROR_LED, HIGH);
    // kf you didn't get a connection to the server:
    Serial.println("connection failed");
  }

}

/******************************************
 *  Format URL to update emon site (1st attempt)
 ******************************************/
void sendData()
{

  if (client.connect(serverName, 80)) {
    Serial.println("start sending data to emon server :-) ");
    // Make a HTTP request:
    client.print("GET http://emoncms.org/input/post.json?node=2&cvs=0,");
    //client.print("GET http://emoncms.org/input/post.json?json={power:220}");
    client.print(pulseCount1_10Wh*10*12); // avge Watt 5min
    client.print(",");
    client.print(getTemperature(BruineThermometer));
    client.print(",");
    client.print(getTemperature(BlauweThermometer));
    client.print(",");
    client.print(getTemperature(BruineThermometerKeuken));
    client.print(",");
    client.print(getTemperature(BlauweThermometerKeuken));
    if ( digitalRead(FAN_RELAY) == HIGH ) {         // fan on
      client.print(",10");
    }
    else {
      client.print(",0");
    }
    client.println("&apikey=****************** HTTP/1.0");
    client.println();



    Serial.print("GET http://emoncms.org/input/post.json?node=2&csv=0,");
    //Serial.print("GET http://emoncms.org/input/post.json?json={power:220}");
    Serial.print(pulseCount1_10Wh*10*12); // avge Watt 5min
    Serial.print(",");
    Serial.print(getTemperature(BruineThermometer));
    Serial.print(",");
    Serial.print(getTemperature(BlauweThermometer));
    Serial.print(",");
    Serial.print(getTemperature(BruineThermometerKeuken));
    Serial.print(",");
    Serial.print(getTemperature(BlauweThermometerKeuken));
    if ( digitalRead(FAN_RELAY) == HIGH ) {         // fan on
      Serial.print(",10");
    }
    else {
      Serial.print(",0");
    }
    Serial.println("&apikey=**************** HTTP/1.0");


    Serial.println("read from server.");
    while (client.available()) { // print response ...
      char c = client.read();
      Serial.print(c);
    }

    Serial.println("done sending data, disconnect from emon.");
    client.stop();  //disconnect
    pulseCount1_10Wh = 0;  //reset counter

  }
  else {
    // if you didn't get a connection to the server:
    Serial.println("cannot connect to emon server :-(");
  }

}

/******************************************
 *  Main loop
 ******************************************/
void loop(void)
{
  //delay(2000);

  // Serial.print(",");
  //  Serial.println(getTemperature(BruineThermometer));
  //  Serial.println(",");
  //  Serial.println(getTemperature(BlauweThermometer));

  //  
  for (int i = 0; i < 5; i++) { // loop 5 times/minutes

    fanControl(); // check fan evry minute
    Serial.println("check fan");
    delay(60000);   //60 000 =1min  
  }
  Serial.println("send url");
  sendData2();  // evry 5 mins update site


}



« Last Edit: March 31, 2013, 05:19:35 am by postbus24 » Logged

Forum Moderator
Belgium
Offline Offline
Edison Member
*****
Karma: 68
Posts: 1926
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Bart
Voor dit probleem is de watchog uitgevonden als "workaround".
Met vriendelijke groet.
Jantje
Logged

Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

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

Bedankt voor de tip, hij blijft nu al enkele dagen draaien zonder vast te lopen !  smiley-grin

Logged

Forum Moderator
Belgium
Offline Offline
Edison Member
*****
Karma: 68
Posts: 1926
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

leuk te horen dat het helpt
Logged

Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Pages: [1]   Go Up
Jump to: